Opengl vao 与 ebo
Posted
技术标签:
【中文标题】Opengl vao 与 ebo【英文标题】:Opengl vao with ebo 【发布时间】:2015-10-24 21:37:54 【问题描述】:我目前正在空闲时间学习 OpenGL,最近我遇到了一个我不明白的“错误”。
问题是,我没有错误,我的屏幕上只显示什么。我正在使用带有 SFML 的 OpenGL。
这是我的代码。这是我的方法:
void CreateObjet(GLuint& vao, GLuint& vbo, GLuint& ebo, GLuint& textureLocation)
//I create my arrays here.. Don't worry they are fine.
CreateTexture(textureLocation);
glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);
glGenVertexArrays (1, &vao);
glBindVertexArray (vao); //On travaille dans le VAO
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData (GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), NULL);
glEnableVertexAttribArray(0);
glBufferData (GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3* sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBufferData (GL_ARRAY_BUFFER, sizeof(texCoords), texCoords, GL_STATIC_DRAW);
glVertexAttribPointer (2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6* sizeof(GLfloat)));
glEnableVertexAttribArray(2);
//EBO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indiceFinal), indiceFinal, GL_STATIC_DRAW);
glBindVertexArray(0);
我知道我的问题不在于我的着色器,因为我在控制台中使用 GlshaderRiv() 没有收到任何错误。
我想知道我的订单是否正确。
-
我创建了一个 VBO 和一个 EBO
我创建了一个 VAO
我绑定当前的VAO来修改它
我在 VAO 中绑定了当前的 VBO
我在我的 VBO 中绑定了我的第一个数组(顶点位置向量 3f),并将它们放在第一个指针中,并具有正确的偏移量和步幅。
我在我的 VBO 中绑定了我的第二个数组(颜色位置向量 3f),并将它们放在第一个指针中,并具有正确的偏移量和步幅。
我在我的 VBO 中绑定了我的第三个数组(纹理位置向量 2f),并将它们放在具有正确偏移和步幅的第一个指针中。
我在 VAO 中绑定了一个 EBO
我将 EBO 与我的元素位置(矢量 3u)绑定。
我从内存中取消绑定 VAO,因为我的绘图循环在代码中相当晚,所以我不想白白使用内存空间。别担心,在我画之前我把 glBindVertexArray(&vao);
【问题讨论】:
glBindVertexArray(&vao);
肯定是错误的,因为这将是变量的地址,而不是对象的名称。另外,您为什么认为不绑定 VAO 会以某种方式节省内存?
【参考方案1】:
这绝对看起来不正确。您正在将所有属性的值写入同一个缓冲区,每个属性都会覆盖前一个:
glBufferData (GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), NULL);
glEnableVertexAttribArray(0);
glBufferData (GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
...
当您进行第二次glBufferData()
调用时,它将用colors
数据覆盖您之前存储在缓冲区中的points
数据。
误解可能是关于glVertexAttribPointer()
的作用。它指定给定属性来自哪个缓冲区,以及数据布局(组件计数、类型等)。但它不会创建缓冲区数据的副本或类似的东西。您要使用的属性数据在绘制调用时仍必须存储在缓冲区中。
要解决此问题,您必须为每个属性使用不同的缓冲区,或者排列属性数据,以便所有 3 个属性的值可以存储在同一个缓冲区中。 glVertexAttribPointer()
调用的参数实际上表明您打算将所有属性值交错存储在同一个缓冲区中。要使其正常工作,您必须相应地安排属性值,然后通过单个 glBufferData()
调用将它们存储在缓冲区中。
您需要的内存排列将依次包含第一个顶点的所有属性值,然后是第二个顶点的值,依此类推。pi
顶点的位置i
,ci
颜色和ti
纹理坐标,正确的内存布局是:
p0x p0y p0z c0r c0g c0b t0s t0t
p1x p1y p1z c1r c1g c1b t1s t1t
p2x p2y p2z c2r c2g c2b t2s t2t
...
【讨论】:
你说的我都做了。我创建了 2 个新缓冲区,生成了它们,然后正确地完成了我的订单。 pastebin.com/wBpawmHz 可悲的是,我的屏幕上仍然没有显示任何内容:(以上是关于Opengl vao 与 ebo的主要内容,如果未能解决你的问题,请参考以下文章