1

When attempting to draw a cube loaded from an .obj file all triangles share a single point. Additionally not all of the triangles seem to be rendering.

I've noticed that changing the vertex count for glDrawElements allows the other triangles to draw, but am uncertain as to why the number of points would be greater than the number of indices being used.

I've checked that the file (seems to be) loaded correctly with the debugger as: In the ModelObject class 'vCoords' contains:

{
 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
}

and each MaterialGroup has 6 indices that are offset by -1 from the obj file. (.obj indices start at 1 instead of 0)

Each MaterialGroup's indices are on a separate line (also pulled from debugger during draw calls)

{ 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

In the ModelObject 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();
}

In the MaterialGroup 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 is the index buffer vCoords is a buffer containing all the vertices

The source full can be located at: https://github.com/TheIncgi/GLES_GAME_fixed/blob/master/app/src/main/java/com/theincgi/gles_game_fixed/geometry/ModelLoader2.java

Current result: Current render issue

Goal: What the cube should look like

Edit 1: Fixed formatting issue

TheINCGI
  • 35
  • 5

1 Answers1

0

The 3rd parameter of glDrawElements specifies the type of the values in the list of indices.

The buffer (iv) is an int buffer, where each element has 4 bytes.

IntBuffer   iv, it, in;

But the OpenGL enumerator constant GL_UNSIGNED_SHORT indicated that the buffer is a buffer of short values, where the size of each value is 2 bytes:

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

If the OpenGL ES version supports GL_UNSIGNED_INT, then it is sufficient to change GL_UNSIGNED_SHORT by GL_UNSIGNED_INT to solve the issue:

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

If GL_UNSIGNED_INT is not uspported, then a ShortBuffer has to be crated instead of IntBuffer:

ShortBuffer iv;

GLES20.glDrawElements(GLES20.GL_TRIANGLES, iv.limit(), GLS20.GL_UNSIGNED_SHORT, iv);
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • This worked perfectly. Had a feeling it was something simple I overlooked. Thanks a ton! – TheINCGI Apr 02 '19 at 17:07
  • 1
    Spec though says that in ES 2.0 it only accepts `GL_UNSIGNED_BYTE` and `GL_UNSIGNED_SHORT`. I have tested it though, and on some devices that works with `GL_UNSIGNED_INT`, but you probably shouldn't rely on that too much. – Reaper Apr 02 '19 at 21:46
  • @Reaper Thank's. I was sloppy and didn't consider the OpenGL ES version. – Rabbid76 Apr 02 '19 at 21:54