LWJGL索引VBO,很多混乱

时间:2014-03-12 14:44:22

标签: opengl lwjgl vbo vertex-buffer indexed

我无法弄清楚如何使用索引VBO,恕我直言,缺乏相关信息(例如,索引的vbo页面缺少ATM的lwjgl站点)。

我在顶点缓冲区中使用的结构是{pos.x,pos.y pos.z},{tex.u,tex.v tex.W}和{norm.x,norm.y norm.z},我的索引缓冲区结构是{posIndex,texIndex,normIndex} 我从.obj文件中读取所有这些数据,如果缺少tex或norm,我将其设置为{-1,-1,-1}。

这是我将数据发送到GPU缓冲区的代码部分:

    this.VBOSize = Vertices.size();
    FloatBuffer vbo = BufferUtils.createFloatBuffer(this.VBOSize);
    for (int i = 0; i < this.VBOSize; i++) {
        vbo.put(Vertices.get(i));
    }
    vbo.flip();
    glBindBuffer(GL_ARRAY_BUFFER, VBOHandle);
    glBufferData(GL_ARRAY_BUFFER, vbo, GL_STATIC_DRAW);

    this.IBOSize = Indices.size();
    IntBuffer ibo = BufferUtils.createIntBuffer(this.IBOSize);
    for (int i = 0; i < this.IBOSize; i++) {
        ibo.put(Indices.get(i));
    }
    ibo.flip();
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBOHandle);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, ibo, GL_STATIC_DRAW);

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

以及我[错误地]渲染它的方式:

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, Object3D.getVBOHandle());
    glVertexAttribPointer(0, 3, GL_FLOAT, true, 12, 0);//3 floats * 4 sizeof(float)
    glVertexAttribPointer(1, 3, GL_FLOAT, true, 12, 13);
    glVertexAttribPointer(2, 3, GL_FLOAT, true, 12, 25);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Object3D.getIBOHandle());
    glDrawElements(GL_TRIANGLES, Object3D.getIBOSize(), GL_UNSIGNED_INT, 0);

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);

1 个答案:

答案 0 :(得分:0)

这不是opengl的工作方式。在openGL中,顶点是属性的,如position,normal,color,textcoord等等。索引渲染仅引用顶点。您不能为各种属性指定不同的索引,而只能为整个集合指定一个索引。如果您有两个顶点共享其位置的情况,但不是texcoords,就GL而言,它们完全 _different_顶点。你不能直接使用lightwave .obj文件中的数据,但必须预处理数据以生成顶点数组,OpenGL可以使用它。

GL_AMD_interleaved_elements扩展名,它有点实现了您要使用的功能。它仍然使用32位索引,但允许一个将它们分成2个16位或4个8位索引,以便为不同的属性使用不同的索引,但是这个扩展远不是核心GL,没有广泛支持和仍然非常有限。

现在有了可编程管道,人们也可以在着色器中手动进行索引解除引用,基本上(误)使用顶点属性并通过纹理缓冲区对象访问真实属性数组,但这是非常先进的和性能影响不清楚。