正确使用glVertexAttribPointer?

huangapple go评论91阅读模式
英文:

Correct Use of glVertexAttribPointer?

问题

最近我决定开始学习OpenGL,并且买了一本关于OpenGL Core 3.3的书。这本书主要是关于C++的。

所以,在查找了一会儿后,我发现了一个用我比较擅长的语言编写的库,提供了几乎相同的功能:lwjgl

我按照书中的步骤,将C++的语法翻译成了Java的语法,一切都还好,直到实际绘制图形为止。

在这一点上,无论我如何更改代码,JVM都会崩溃。经过一些调试,我发现在调用glVertexAttribPointer或者glDrawArrays时JVM崩溃了。

我对OpenGL非常新手,我想对于有经验的人来说,这个问题肯定听起来很愚蠢,但是:关于这段代码,我需要做什么样的改变?


        float[] vertices = {
            -0.5f, -0.5f, -0.0f,
            0.5f, 0.5f, 0.0f,
            0.0f, 0.5f, 0.0f
        };
        FloatBuffer b = BufferUtils.createFloatBuffer(9);
        b.put(vertices);
        int VBO = glGenBuffers();
        int VAO = glGenVertexArrays();
        log.info("VBO:" + VBO + "VAO: " + VAO);
        // 首先绑定顶点数组对象,然后绑定并设置顶点缓冲区,最后配置顶点属性。
        glBindVertexArray(VAO);

        glVertexAttribPointer(0, 3, GL_FLOAT, false, 12, 0);
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
        glBindVertexArray(0);

        // 在用户尝试关闭窗口或按下ESC键之前,运行渲染循环。
        while (!glfwWindowShouldClose(window)) {
            // 输入
            // -----

            // 渲染
            // ------
            glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);

            // 绘制第一个三角形
            glUseProgram(shaderProgram);
            glBindVertexArray(VAO); // 因为我们只有一个VAO,所以每次都不需要绑定它,但为了保持更有条理一些,我们还是这样做了
            glDrawArrays(GL_TRIANGLES, 0, 3);
            glBindVertexArray(0); // 每次都不需要解绑它

            // glfw:交换缓冲区并轮询IO事件(按下/释放的键,鼠标移动等)
            // -------------------------------------------------------------------------------
            glfwSwapBuffers(window);
            glfwPollEvents();
        }
英文:

I recently decided to start Learning OpenGL and got myself a book about OpenGL Core 3.3. The book is generally about C++.

So, after looking for a bit, I found a library in a language I was better in which provided almost the same functionality: lwjgl.

I followed the book's steps and translated the C++ syntax into java syntax, which worked until it got to actually drawing something.

There, the JVM just kept crashing, no matter what I changed about the code. After doing some debugging, I found out that the JVM crashed when I called either glVertexAttribPointer or glDrawArrays.

I am very new to OpenGL, and I am assuming this question must sound very stupid to someone more experienced, but: What do I need to change about this code?

        

        float[] vertices = {
				-0.5f, -0.5f, -0.0f,	
				0.5f, 0.5f, 0.0f,
				0.0f,0.5f,0.0f
	    };
		FloatBuffer b = BufferUtils.createFloatBuffer(9);
		b.put(vertices);
		int VBO = glGenBuffers();
		int VAO = glGenVertexArrays();
		log.info("VBO:" + VBO + "VAO: " + VAO);
		// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
		glBindVertexArray(VAO);

		    
		glVertexAttribPointer(0, 3, GL_FLOAT, false, 12,  0);
		glEnableVertexAttribArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, VBO);
		glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
		glBindVertexArray(0); 		

		    

		// Run the rendering loop until the user has attempted to close
		// the window or has pressed the ESCAPE key.
		while (!glfwWindowShouldClose(window))
		    {
		        // input
		        // -----

		        // render
		        // ------
		        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		        glClear(GL_COLOR_BUFFER_BIT);

		        // draw our first triangle
		        glUseProgram(shaderProgram);
		        glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
		        glDrawArrays(GL_TRIANGLES, 0, 3);
		         glBindVertexArray(0); // no need to unbind it every time 
		 
		        // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
		        // -------------------------------------------------------------------------------
		        glfwSwapBuffers(window);
		        glfwPollEvents();
		    }

I would be very thankful for any help i can get, if you need more info/ need to see more of my code please let me know. Thanks in advance

答案1

得分: 1

你需要将顶点缓冲对象绑定到目标 GL_ARRAY_BUFFER,然后再指定顶点属性:

glBindBuffer(GL_ARRAY_BUFFER, VBO); 
glVertexAttribPointer(0, 3, GL_FLOAT, false, 12,  0);

当调用 glVertexAttribPointer 时,当前绑定到 ARRAY_BUFFER 目标的缓冲对象将与属性(索引)关联,并且缓冲对象的引用将存储在顶点数组对象的状态向量中。

英文:

You have to bind the vertex buffer object to the target GL_ARRAY_BUFFER, before specifying the vertex attribute:

glBindBuffer(GL_ARRAY_BUFFER, VBO); 
glVertexAttribPointer(0, 3, GL_FLOAT, false, 12,  0);

When glVertexAttribPointer is called, the buffer object currently bound to the ARRAY_BUFFER target is associated to the attribute (index) and a reference to the buffer object is stored in the state vector of the Vertex Array Object.

huangapple
  • 本文由 发表于 2020年10月19日 19:42:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/64426636.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定