Opengl VAO绘图不正确

时间:2012-12-04 00:42:41

标签: c++ opengl

最近我在掌握Opengl VAO时遇到了问题。 目前我的代码使用VBO从浮点数组中绘制一个三角形。

这是代码。

float vpp[] = { 0.75f, 0.75f, 0.0f,
                0.75f, -0.75f, 0.0f,
                -0.75f, -0.75f, 0.0f};

// Non Indexed
glGenBuffers(1, &m_mainVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_mainVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vpp), vpp, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_POINTS, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);

现在,当我尝试实现VAO时,程序只抽出1分。 (我会发布一个屏幕上限,但我不能)。

这个代码。

float vp[] = { 0.0f, 0.75f, -0.75f };

//VAO
unsigned short sInds[9] = { 1, 1, 0,
                            1, 2, 0,
                            2, 2, 0};

//Indexed
glGenBuffers(1, &m_mainVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_mainVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vp), vp, GL_STATIC_DRAW);

GLuint elBuf;
glGenBuffers(1, &elBuf);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elBuf);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 9 * sizeof(unsigned short), sInds, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawElements(GL_POINTS, 3, GL_UNSIGNED_SHORT, sInds);
glDisableClientState(GL_VERTEX_ARRAY);


glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

有谁能告诉我我做错了什么?

2 个答案:

答案 0 :(得分:1)

你的代码坏了,这与你的“VAO”无关(或者像Datenwolf指出的那样,你的缺少的VAO)。

您似乎不明白索引缓冲区中的索引实际上是做什么的。您将属性0定义为包含3个浮点值的数组。用C语言,你说float attrib0[numberOfPositions][3];。当OpenGL看到第一个索引时,它将从数组中获取三个值。它将获取:

attrib0 [索引] [0];    attrib0 index;    attrib0 [指数] [2];

您的索引是顶点索引,而不是GL_FLOAT索引。数组元素各3个浮点数,而不是每个浮点数。

您尝试做的事情并非真实可行或有用。正如Datenwolf指出的那样,它与VAO无关(因为你的代码不使用它们)。你在谈论indexed rendering,这是与VAO不同的主题。

答案 1 :(得分:0)

你使用哪个OpenGL版本?到目前为止,您的代码仅使用顶点缓冲区对象,但那里没有顶点数组对象支持代码。如果您使用的是OpenGL-4内核,则需要先创建一个VAO,否则不会绘制任何内容。

如果您不打算使用VAO抽象,则可以在创建上下文后立即创建一个包含全部的VAO。

GLuint vaoID;
glGenVertexArrays(1, &vaoID);
glBindVertexArray(vaoID);

更新

昨天晚上我没注意到,但Nicol Bolas做到了。第二个代码段的某些部分没有意义。 vp只定义了3个浮点数。它现在完全取决于顶点着色器的语义(使用通用顶点属性强制使用着色器)如何解释这些。对元素大小为3的 glVertexAttribPointer 的调用告诉OpenGL,该顶点属性的每个元素都有3个字段,这些字段一起被寻址。

float vp[] = { 0.0f, 0.75f, -0.75f };

              \------------------/ one attribute element

使用您的第一个定义vpp

会更有意义
float vpp[] = { 0.75f, 0.75f, 0.0f,

                \----------------/ attribute element 0

                0.75f, -0.75f, 0.0f,

                \-----------------/ attribute element 1

                -0.75f, -0.75f, 0.0f};

                \------------------/ attribute element 2

如果启用多个顶点属性,它们一起形成多个属性的长向量。

提供给glDrawElements的索引解决了这些顶点属性向量,而不是它们各自的字段。