无法同时运行两个着色器程序,但是在单独使用时,每个程序都可以正常工作

问题描述 投票:1回答:1

Ok对此扼杀了2天。我有一个小的GLES2 / Android应用程序...两个对象(都是正方形,但只有一个具有纹理坐标)。我有两个着色器程序,一个处理纹理及其坐标,另一个仅在片段着色器中使用颜色。

当我仅尝试渲染这些对象之一(并且仅编译和链接一个着色器程序)时,所有事情都可以正常工作,当我对两个对象都这样做时,仅渲染第二个对象(纹理正方形)。是的,在渲染相应的对象之前,我确实切换了着色器程序。一件事值得注意。当我调试时一个着色器程序中的顶点属性指针= 0 =另一个程序中的Texture属性指针下面是一些代码,感谢任何帮助

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);
}
java android opengl-es opengl-es-2.0 vertex-attributes
1个回答
0
投票

问题是绘制第一个对象时启用了纹理坐标的顶点属性数据数组(索引TexturePositionHandle)。注意,OpenGL是一个状态引擎,状态被保留直到再次更改,甚至超出帧。

[您必须启用着色器程序所需的通用顶点属性数组,并且必须确保在绘制对象时禁用其他顶点属性数组:

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);
© www.soinside.com 2019 - 2024. All rights reserved.