【问题标题】:Multiple texture units GLES 2.0 Android多个纹理单元 GLES 2.0 Android
【发布时间】:2015-03-05 15:00:49
【问题描述】:

试图让 2 个纹理单元工作。

@Override
public void onDrawFrame(GL10 gl) {
    //Clear the Rendering Surface
    glClear(GL_COLOR_BUFFER_BIT);

    multiplyMM(viewProjectionMatrix, 0, projectionMatrix, 0, viewMatrix, 0);

    positionTableInScene();
    textureProgram.useProgram();
    textureProgram.setUniforms(modelViewProjectionMatrix, texture_b, texture_r);
    table.bindData(textureProgram);
    table.draw();
    ...
}

纹理程序:

public class TextureShaderProgram extends ShaderProgram {
//Uniform locations
private final int uMatrixLocation;
private final int uTextureUnit0Location;
private final int uTextureUnit1Location;

//Attribute locations
private final int aPositionLocation;
private final int aTextureCoordinatesLocation;

public TextureShaderProgram(Context context){
    super(context, R.raw.texture_vertex_shader, R.raw.texture_fragment_shader);

    //Retrieve uniform locations for the shader program.
    uMatrixLocation = glGetUniformLocation(program, U_MATRIX);
    uTextureUnit0Location = glGetUniformLocation(program, U_TEXTURE_UNIT_0);
    uTextureUnit1Location = glGetUniformLocation(program, U_TEXTURE_UNIT_1);

    //Retrieve attribute locations for the shader program.
    aPositionLocation = glGetAttribLocation(program, A_POSITION);
    aTextureCoordinatesLocation = glGetAttribLocation(program, A_TEXTURE_COORDINATES);
}
public void setUniforms(float[] matrix, int textureId, int textureId2){
    //Pass the matrix into the shader program
    glUniformMatrix4fv(uMatrixLocation, 1, false, matrix, 0);

    //Set the active texture unit to texture unit 0.
    glActiveTexture(GL_TEXTURE0);
    //Bind the texture to this unit.
    glBindTexture(GL_TEXTURE_2D, textureId);
    //Tell the texture uniform sample to use this texture in the shader by
    //telling it to read from texture unit 0.
    glUniform1f(uTextureUnit0Location, 0);

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, textureId2);
    glUniform1f(uTextureUnit1Location, 0);


}


public int getPositionAttributeLocation(){
    return aPositionLocation;
}

public int getTextureCoordinatesAttributeLocation(){
    return aTextureCoordinatesLocation;
}
}

片段着色器:

precision mediump float;

uniform sampler2D u_TextureUnit0;
uniform sampler2D u_TextureUnit1;
varying vec2 v_TextureCoordinates;

void main()
{

   //gl_FragColor = texture2D(u_TextureUnit0, v_TextureCoordinates);

   gl_FragColor = (v_TextureCoordinates.y > 0.5)
   ?texture2D(u_TextureUnit1, v_TextureCoordinates)
   :texture2D(u_TextureUnit0, v_TextureCoordinates);

}

这并没有为我提供一种纹理的一半和另一种纹理的预期结果。我发现这是因为我的纹理单元拥有相同的图像。始终将图像加载到纹理单元 0 中。更改首先加载的纹理会更改纹理,因此我知道这两种纹理都有效。

我认为这是我通知 opengl 我的纹理单元在哪里的方式。但我不知道如何改变它。

【问题讨论】:

    标签: android opengl-es opengl-es-2.0


    【解决方案1】:

    两个问题。首先,您将两个统一变量设置为相同的值:

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textureId);
    glUniform1f(uTextureUnit0Location, 0);
    
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, textureId2);
    glUniform1f(uTextureUnit1Location, 0);
    

    您为 uniform 变量设置的值必须与对应纹理绑定到的纹理单元的索引匹配。由于第二个纹理绑定到GL_TEXTURE1,所以第二个统一值必须是1,而不是0。

    此外,采样器的统一值必须设置为 glUniform1i(),而不是 glUniform1f()

    所以正确的代码如下所示:

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textureId);
    glUniform1i(uTextureUnit0Location, 0);
    
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, textureId2);
    glUniform1i(uTextureUnit1Location, 1);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-12
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多