问题
I am activating the texture just before the object to draw. But the texture is showing on both objects. Why is that so? Should I unbind the texture before the first object to draw? - I tried with glDisable and glBindTexture but it did not help. Here my code:
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GL10.GL_COLOR_BUFFER_BIT);
synchronized (camerObject) {
surfaceTextureCamera.updateTexImage();
cameraUpdate = false;
}
vertexBuffer.position(0);
GLES20.glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDE, vertexBuffer);
GLES20.glEnableVertexAttribArray(aPositionLocation);
vertexBuffer.position(POSITION_COMPONENT_COUNT);
GLES20.glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDE, vertexBuffer);
GLES20.glEnableVertexAttribArray(aColorLocation);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[0]);
GLES20.glUniform1i(textureUnitLocation, 0);
vertexBuffer2.position(0);
GLES20.glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDETEXTURE, vertexBuffer2);
GLES20.glEnableVertexAttribArray(aPositionLocation);
vertexBuffer2.position(TEXTURE_COMPONENT_COUNT);
GLES20.glVertexAttribPointer(aTextureCoordinatesLocation, TEXTURE_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDETEXTURE, vertexBuffer2);
GLES20.glEnableVertexAttribArray(aTextureCoordinatesLocation);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
UPDATE This is my shader program:
#extension GL_OES_EGL_image_external : require
precision mediump float;
uniform samplerExternalOES u_Texture;
varying vec2 v_TextureCoordinates;
varying vec4 v_Color;
void main() {
gl_FragColor = v_Color;
gl_FragColor = texture2D(u_Texture, v_TextureCoordinates);
}
attribute vec4 a_Position;
attribute vec4 a_Color;
attribute vec2 a_TextureCoordinates;
varying vec2 v_TextureCoordinates;
varying vec4 v_Color;
void main() {
v_Color = a_Color;
v_TextureCoordinates = a_TextureCoordinates;
gl_Position = a_Position;
}
回答1:
OpenGL is a state engine. Once a state is set, it is kept until it is changed again, even beyond frames.
Bind the named texture object before the 2nd object and bind the default texture object (0) after drawing the 2nd object.
Furthermore enable the vertex attributes before the draw call and disable it after:
Object 1
vertexBuffer.position(0);
GLES20.glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDE, vertexBuffer);
vertexBuffer.position(POSITION_COMPONENT_COUNT);
GLES20.glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDE, vertexBuffer);
GLES20.glEnableVertexAttribArray(aPositionLocation);
GLES20.glEnableVertexAttribArray(aColorLocation);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
GLES20.glDisableVertexAttribArray(aPositionLocation);
GLES20.glDisableVertexAttribArray(aColorLocation);
Object 2:
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);
The sahder program always reads the color form the texture:
void main() {
gl_FragColor = v_Color;
gl_FragColor = texture2D(u_Texture, v_TextureCoordinates);
}
Note, the first line which set gl_FragColor
is useless, because gl_FragColor
is overwritten in the following line.
Since either the color attribute is not set (black) or the the color read from the texture is black, the colors can be summed:
void main() {
gl_FragColor = v_Color + texture2D(u_Texture, v_TextureCoordinates);
}
来源:https://stackoverflow.com/questions/59708452/how-to-bind-texture-just-to-one-object-in-opengles