我无法弄清楚如何使用索引的VBO,恕我直言,缺乏有关它的信息(例如,索引的VBO页面缺少atm at 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);
这不是OpenGL的工作方式。在OpenGL中,顶点是位置,正常,颜色,TextCoord等属性的 set 。索引渲染仅引用顶点。您不能为各种属性具有不同的索引,而是整个集合的一个索引。如果您有两个顶点共享其位置的情况,但是,就GL而言,它们完全是完全是 _Different _ vertices。您不能直接使用Lightwave .OBJ文件中的数据,但必须预处理数据以生成顶点阵列OpenGL可以使用此功能。
有GL_AMD_INTERLEAVED_ELEMENTS扩展名,它在某种程度上实现了您要使用的功能。它仍然使用32位索引,但允许将它们分成2个16位或4个8位指数来用于不同属性,但是此扩展名远非核心GL,不广泛支持,并且仍然非常有限。
如今,使用可编程管道,也可以使用顶点属性在着色器中手动执行索引,并通过纹理缓冲区对象访问真实属性数组不清楚。