如何修复 OpenGLES glDrawElements

How to fix OpenGLES glDrawElements

尝试绘制从 .obj 文件加载的立方体时,所有三角形共享一个点。此外,并非所有三角形都在渲染。

我注意到更改 glDrawElements 的顶点数允许绘制其他三角形,但不确定为什么点数会大于所使用的索引数。

我已检查文件(似乎)已通过调试器正确加载为: 在 ModelObject class 'vCoords' 中包含:

{
 1.0,  1.0,  1.0, 
-1.0, -1.0,  1.0, 
 1.0, -1.0,  1.0, 
-1.0,  1.0,  1.0, 
-1.0, -1.0, -1.0, 
 1.0, -1.0, -1.0, 
 1.0,  1.0, -1.0, 
-1.0,  1.0, -1.0
}

并且每个 MaterialGroup 都有 6 个索引,它们与 obj 文件的偏移量为 -1。 (.obj 索引从 1 而不是 0 开始)

每个 MaterialGroup 的索引都在单独的一行上(也在绘制调用期间从调试器中提取)

{ 3, 6, 7, 3, 0, 6 }  //yellow
{ 0, 5, 6, 0, 2, 5 }  //blue
{ 5, 7, 6, 5, 4, 7 }  //purple
{ 2, 4, 5, 2, 1, 4 }  //red
{ 1, 7, 4, 1, 3, 7 }  //white
{ 0, 1, 2, 0, 3, 1 }  //light green

在模型对象中class:

public void draw(float[] mvpm, GLProgram program){
        int mvpmH  = program.getUniformLocation("mvpm");

        GLES20.glEnableVertexAttribArray(posH);
        GLES20.glVertexAttribPointer(
                posH,
                COORDS_PER_VERTEX,
                GLES20.GL_FLOAT,
                    false,
                COORDS_PER_VERTEX*Float.BYTES,
                vCoords);
        GLES20.glUniformMatrix4fv(mvpmH, 1, false, mvpm,0 );
        GLErrorLogger.check();
        for(MaterialGroup materialGroup : groups){

            materialGroup.draw(program);
        }

        GLES20.glDisableVertexAttribArray(posH);
        GLErrorLogger.check();
}

在材质组中class:

public void draw(GLProgram program){
        GLErrorLogger.check();
        int colorH = program.getUniformAttribLocation("vColor");
        GLErrorLogger.check();
        GLES20.glUniform4fv(colorH, 1, material.diffuse, 0);
        GLErrorLogger.check();

        //GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, points);
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, iv.limit(), 
                 GLES20.GL_UNSIGNED_SHORT, iv);

        GLErrorLogger.check();
}

iv 是索引缓冲区 vCoords 是一个包含所有顶点的缓冲区

完整的源代码位于:https://github.com/TheIncgi/GLES_GAME_fixed/blob/master/app/src/main/java/com/theincgi/gles_game_fixed/geometry/ModelLoader2.java

当前结果: Current render issue

目标: What the cube should look like

编辑 1:修复格式问题

glDrawElements 的第三个参数指定索引列表中值的类型。

缓冲区 (iv) 是一个 int 缓冲区,其中每个元素有 4 个字节。

IntBuffer   iv, it, in;

但是 OpenGL 枚举常量 GL_UNSIGNED_SHORT 表示缓冲区是 short 个值的缓冲区,其中每个值的大小为 2 个字节:

GLES20.glDrawElements(GLES20.GL_TRIANGLES, iv.limit(), GLES20.GL_UNSIGNED_SHORT, iv);

如果OpenGL ES版本支持GL_UNSIGNED_INT,那么将GL_UNSIGNED_SHORT改成GL_UNSIGNED_INT即可解决问题:

GLES20.glDrawElements(GLES20.GL_TRIANGLES, iv.limit(), GLES20.GL_UNSIGNED_INT, iv);

如果不支持 GL_UNSIGNED_INT,则必须创建 ShortBuffer 而不是 IntBuffer:

ShortBuffer iv;

GLES20.glDrawElements(GLES20.GL_TRIANGLES, iv.limit(), GLS20.GL_UNSIGNED_SHORT, iv);