如何在 OpenGLES 中为多个对象的多个纹理设置片段着色器?
How to setup the fragment shader for multiple textures on multiple objects in OpenGLES?
我尝试将一个纹理绑定到一个对象,将另一个纹理绑定到下一个对象。我在 Whosebug 中问过几乎相同的问题,但当时的不同之处在于,我只有一个纹理和多个对象。
它适用于一个纹理和多个对象,但现在我有多个纹理和多个对象。我听从了答案中的建议,但我坚信这次问题出在片段着色器上。
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GL10.GL_COLOR_BUFFER_BIT);
synchronized (mediaPlayerObject) {
surfaceTextureMediaPlayer.updateTexImage();
mediaPlayeUpdate = false;
}
vertexBuffer.position(0);
GLES20.glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDETEXTURE, vertexBuffer);
vertexBuffer.position(TEXTURE_COMPONENT_COUNT);
GLES20.glVertexAttribPointer(aTextureCoordinatesLocation, TEXTURE_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDETEXTURE, vertexBuffer);
GLES20.glEnableVertexAttribArray(aPositionLocation);
GLES20.glEnableVertexAttribArray(aTextureCoordinatesLocation);
GLES20.glUniform1i(textureUnitLocation2, 1);
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[1]);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
GLES20.glDisableVertexAttribArray(aPositionLocation);
GLES20.glDisableVertexAttribArray(aTextureCoordinatesLocation);
synchronized (camerObject) {
surfaceTextureCamera.updateTexImage();
cameraUpdate = false;
}
vertexBuffer2.position(0);
GLES20.glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDETEXTURE, vertexBuffer2);
vertexBuffer2.position(TEXTURE_COMPONENT_COUNT);
GLES20.glVertexAttribPointer(aTextureCoordinatesLocation, TEXTURE_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDETEXTURE, vertexBuffer2);
GLES20.glEnableVertexAttribArray(aPositionLocation);
GLES20.glEnableVertexAttribArray(aTextureCoordinatesLocation);
GLES20.glUniform1i(textureUnitLocation, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[0]);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
GLES20.glDisableVertexAttribArray(aPositionLocation);
GLES20.glDisableVertexAttribArray(aTextureCoordinatesLocation);
这里是片段着色器:
#extension GL_OES_EGL_image_external : require
precision mediump float;
uniform samplerExternalOES u_Texture;
uniform samplerExternalOES b_Texture;
varying vec2 v_TextureCoordinates;
void main() {
gl_FragColor = texture2D(u_Texture, v_TextureCoordinates) * texture2D(b_Texture, v_TextureCoordinates);
}
片段着色器中不需要第二个纹理采样器,因此删除b_Texture
。将纹理对象绑定到纹理单元并将纹理单元的索引设置为纹理采样器统一就足够了:
#extension GL_OES_EGL_image_external : require
precision mediump float;
uniform samplerExternalOES u_Texture;
varying vec2 v_TextureCoordinates;
void main() {
gl_FragColor = texture2D(u_Texture, v_TextureCoordinates);
}
绘制第一个对象:
GLES20.glUniform1i(textureUnitLocation, 1);
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[1]);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
绘制第二个对象:
GLES20.glUniform1i(textureUnitLocation, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[0]);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
注意,没有必要使用 2 个不同的纹理单元。您可以在这两种情况下使用 GL_TEXTURE0
。
我尝试将一个纹理绑定到一个对象,将另一个纹理绑定到下一个对象。我在 Whosebug 中问过几乎相同的问题,但当时的不同之处在于,我只有一个纹理和多个对象。
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GL10.GL_COLOR_BUFFER_BIT);
synchronized (mediaPlayerObject) {
surfaceTextureMediaPlayer.updateTexImage();
mediaPlayeUpdate = false;
}
vertexBuffer.position(0);
GLES20.glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDETEXTURE, vertexBuffer);
vertexBuffer.position(TEXTURE_COMPONENT_COUNT);
GLES20.glVertexAttribPointer(aTextureCoordinatesLocation, TEXTURE_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDETEXTURE, vertexBuffer);
GLES20.glEnableVertexAttribArray(aPositionLocation);
GLES20.glEnableVertexAttribArray(aTextureCoordinatesLocation);
GLES20.glUniform1i(textureUnitLocation2, 1);
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[1]);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
GLES20.glDisableVertexAttribArray(aPositionLocation);
GLES20.glDisableVertexAttribArray(aTextureCoordinatesLocation);
synchronized (camerObject) {
surfaceTextureCamera.updateTexImage();
cameraUpdate = false;
}
vertexBuffer2.position(0);
GLES20.glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDETEXTURE, vertexBuffer2);
vertexBuffer2.position(TEXTURE_COMPONENT_COUNT);
GLES20.glVertexAttribPointer(aTextureCoordinatesLocation, TEXTURE_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDETEXTURE, vertexBuffer2);
GLES20.glEnableVertexAttribArray(aPositionLocation);
GLES20.glEnableVertexAttribArray(aTextureCoordinatesLocation);
GLES20.glUniform1i(textureUnitLocation, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[0]);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
GLES20.glDisableVertexAttribArray(aPositionLocation);
GLES20.glDisableVertexAttribArray(aTextureCoordinatesLocation);
这里是片段着色器:
#extension GL_OES_EGL_image_external : require
precision mediump float;
uniform samplerExternalOES u_Texture;
uniform samplerExternalOES b_Texture;
varying vec2 v_TextureCoordinates;
void main() {
gl_FragColor = texture2D(u_Texture, v_TextureCoordinates) * texture2D(b_Texture, v_TextureCoordinates);
}
片段着色器中不需要第二个纹理采样器,因此删除b_Texture
。将纹理对象绑定到纹理单元并将纹理单元的索引设置为纹理采样器统一就足够了:
#extension GL_OES_EGL_image_external : require
precision mediump float;
uniform samplerExternalOES u_Texture;
varying vec2 v_TextureCoordinates;
void main() {
gl_FragColor = texture2D(u_Texture, v_TextureCoordinates);
}
绘制第一个对象:
GLES20.glUniform1i(textureUnitLocation, 1);
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[1]);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
绘制第二个对象:
GLES20.glUniform1i(textureUnitLocation, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[0]);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
注意,没有必要使用 2 个不同的纹理单元。您可以在这两种情况下使用 GL_TEXTURE0
。