1

Ok been strangling with this for 2 days. I have a small GLES2/Android App... two objects (both are squares but only one has texture coordinates). I have two Shader Programs, one deal with textures and its coordinates, the other just use a color in fragment shader.

when I only try to render one of these objects (and only compile and link one shader program ) every thing work fine, when I do this for both objects only the 2nd object (the textured square) is rendered. Yes I do switch the Shader Program before I render the corresponding object. one thing worth noting. when I debug; the vertix attribute pointer in one Shader Program = 0 = the Texture attribute pointer in the other program below is some code, Appreciate any help

public abstract class SquareShader extends ShaderProgram {

public static int ShaderProgramObjectId;

public static int VertexPositionHandle;
public static int ColorUniformHandle;
public static int ProjectionMatrixHandle;
public static int ModelMatrixHandle;

public static void Initialize()
{
    ShaderProgramObjectId = LinkShaderProgram( R.raw.square_vertex_shader, 
 R.raw.square_fragment_shader);

    ColorUniformHandle = GLES20.glGetUniformLocation(ShaderProgramObjectId, "u_Color");
    ProjectionMatrixHandle = GLES20.glGetUniformLocation(ShaderProgramObjectId, 
   "u_ProjectionMatrix");
    ModelMatrixHandle = GLES20.glGetUniformLocation(ShaderProgramObjectId, "u_ModelMatrix");
    VertexPositionHandle = GLES20.glGetAttribLocation(ShaderProgramObjectId, "sq_VertexPosition");

    GLES20.glEnableVertexAttribArray(VertexPositionHandle);
}
}

public abstract class TextureShader extends ShaderProgram {
public static int ShaderProgramObjectId;

public static int VertexPositionHandle;
public static int TexturePositionHandle;
public static int ProjectionMatrixHandle;
public static int ModelMatrixHandle;
public static int TextureUnitHandle;

public static void Initialize()
{
    ShaderProgramObjectId = LinkShaderProgram( R.raw.texture_vertex_shader, 
    R.raw.texture_fragment_shader);

    ProjectionMatrixHandle = GLES20.glGetUniformLocation(ShaderProgramObjectId, 
    "u_ProjectionMatrix");
    ModelMatrixHandle = GLES20.glGetUniformLocation(ShaderProgramObjectId, "u_ModelMatrix");
    TextureUnitHandle = GLES20.glGetUniformLocation(ShaderProgramObjectId, "u_TextureUnit");

    VertexPositionHandle = GLES20.glGetAttribLocation(ShaderProgramObjectId, "a_VertexPosition");
    TexturePositionHandle = GLES20.glGetAttribLocation(ShaderProgramObjectId, "a_TexturePosition");

    GLES20.glEnableVertexAttribArray(VertexPositionHandle);
    GLES20.glEnableVertexAttribArray(TexturePositionHandle);

}
}

public void onDrawFrame(GL10 gl10) {
//Shade Programs are Initialized in (onSurfaceChanged)
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

    GLES20.glUseProgram(SquareShader.ShaderProgramObjectId);
    GLES20.glUniformMatrix4fv(SquareShader.ProjectionMatrixHandle, 1, false, 
    DisplayUtility.ProjectionMatrix, 0);
    SquarePlain.Draw();



    GLES20.glUseProgram(TextureShader.ShaderProgramObjectId);
    GLES20.glUniformMatrix4fv(TextureShader.ProjectionMatrixHandle, 1, false, 
  DisplayUtility.ProjectionMatrix, 0);
    SquareTextured.Draw();
}


  //SquarePlain
  public static void Draw()
 {

    Matrix.setIdentityM(DisplayUtility.ModelMatrix, 0);
    Matrix.translateM(DisplayUtility.ModelMatrix, 0, 100 , 0, 0);
    GLES20.glUniformMatrix4fv(SquareShader.ModelMatrixHandle, 1, false, DisplayUtility.ModelMatrix, 0);

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, VBO_VertexBufferID[0]);
    GLES20.glVertexAttribPointer(SquareShader.VertexPositionHandle, COORDS_PER_VERTEX,
            GLES20.GL_FLOAT, false,
            vertexStride, 0);


    GLES20.glUniform4f(SquareShader.ColorUniformHandle, 0.0f, 0.0f, 1.0f, 1.0f);
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, 
 indicesBuffer);
 }


 //SquareTextured 
 public static void Draw()
 {
    Matrix.setIdentityM(DisplayUtility.ModelMatrix, 0);
    Matrix.translateM(DisplayUtility.ModelMatrix, 0, 600 , 200, 0);

    GLES20.glUniformMatrix4fv(TextureShader.ModelMatrixHandle, 1, false, DisplayUtility.ModelMatrix, 0);

    //Bind vertices & Texture VBO

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, VBO_VertexBufferID[0]);
    GLES20.glVertexAttribPointer(TextureShader.VertexPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, 0);
    GLES20.glVertexAttribPointer(TextureShader.TexturePositionHandle, COORDS_PER_TexTure, GLES20.GL_FLOAT, false, vertexStride, COORDS_PER_VERTEX * Float.BYTES);


    //Switch Texture Buffer
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureBufferId[0]);

    //Bind Indices VBO
    GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, VBO_IndicesBufferID[0]);
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, 0);
}
Rabbid76
  • 202,892
  • 27
  • 131
  • 174

1 Answers1

0

The issue is that the array of vertex attribute data for the texture coordinates (index TexturePositionHandle) is enabled when the first object is drawn.
Note, OpenGL is a state engine and a state is kept util it is changed again, even beyond frames.

You have to enable the generic vertex attribute array which are required for the shader program and you have to ensure that the other vertex attribute arrays are disabled, when an object is drawn:

GLES20.glEnableVertexAttribArray(VertexPositionHandle);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, 
                      indicesBuffer);
GLES20.glDisableVertexAttribArray(VertexPositionHandle);
GLES20.glEnableVertexAttribArray(VertexPositionHandle);
GLES20.glEnableVertexAttribArray(TexturePositionHandle);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, 0);
GLES20.glDisableVertexAttribArray(VertexPositionHandle);
GLES20.glDisableVertexAttribArray(TexturePositionHandle);
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • That didn't work for me, now I don't enable anything inside the Shader program, and Inside the Draw method I enable the attributes, bind the vbos render then disable the attributes, still only one object is rendered. Further more I tried using glBindAttribLocation before I like the shader programs, and made sure that every attribute has a different index.. still not working!! what is going on! – Newbie And Curious Jan 16 '20 at 21:12