尝试使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我的纹理单位在哪里的方式。但是我不知道如何改变它。
两个问题。首先,您将两个统一变量设置为相同的值:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);
glUniform1f(uTextureUnit0Location, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textureId2);
glUniform1f(uTextureUnit1Location, 0);
您为统一变量设置的值必须与相应纹理绑定到的纹理单位的索引匹配。由于第二个纹理绑定到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);