Opengl vao with ebo

Opengl vao with ebo

本文关键字:ebo with vao Opengl      更新时间:2023-10-16

我目前正在空闲时间学习OpenGL,最近我遇到了一个我不明白的"错误"。

问题是,我没有错误,只是屏幕上没有出现任何内容。我正在使用OpenGL和SFML。

这是我的代码。这是我的方法:

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(( 的控制台中没有收到任何错误。

想知道我是否正确执行了订单。

  1. 我创建了一个 VBO 和一个 EBO
  2. 我创建一个 VAO
  3. 我绑定当前的VAO进行修改
  4. 我将当前的 VBO 绑定在 VAO 中
  5. 我在 VBO 中绑定我的第一个数组(顶点位置矢量 vector3f(,并将它们放在第一个指针中,具有正确的偏移量和步幅。
  6. 我在 VBO 中绑定我的第二个数组(颜色位置矢量 vector3f(,并将它们放在第一个指针中,具有正确的偏移量和步幅。
  7. 我在 VBO 中绑定了我的第三个数组(纹理位置矢量 vector2f(,并将它们放在第一个指针中,具有正确的偏移量和步幅。
  8. 我在 VAO 中绑定了 EBO
  9. 我将 EBO 与我的元素位置(向量 3u(绑定。
  10. 从内存中解绑 VAO,因为我的绘制循环在代码中很晚,因此,我不想白白使用内存空间。别担心,在我画之前,我把glBindVertexArray(&vao(;

这绝对不对。您将所有属性的值写入同一缓冲区,每个属性都会覆盖前一个:

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顶点的位置ici颜色和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
...