如何将纹理绑定到 OpenGLES 中的一个对象?
How to bind texture just to one object in OpenGLES?
我在要绘制的对象之前激活纹理。但是纹理显示在两个对象上。为什么?我应该在绘制第一个对象之前取消绑定纹理吗? - 我尝试使用 glDisable 和 glBindTexture 但没有帮助。
这是我的代码:
@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);
更新
这是我的着色器程序:
#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;
}
OpenGL 是一个状态引擎。设置状态后,它会一直保持到再次更改,甚至超出帧。
在第二个对象之前绑定命名纹理对象,在绘制第二个对象之后绑定默认纹理对象(0)。
此外,在绘制调用之前启用顶点属性并在之后禁用它:
对象 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);
对象 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);
sahder 程序总是从纹理中读取颜色:
void main() {
gl_FragColor = v_Color;
gl_FragColor = texture2D(u_Texture, v_TextureCoordinates);
}
注意,设置gl_FragColor
的第一行是没有用的,因为gl_FragColor
被下面的行覆盖了。
由于未设置颜色属性(黑色)或从纹理读取的颜色为黑色,因此可以对颜色求和:
void main() {
gl_FragColor = v_Color + texture2D(u_Texture, v_TextureCoordinates);
}
我在要绘制的对象之前激活纹理。但是纹理显示在两个对象上。为什么?我应该在绘制第一个对象之前取消绑定纹理吗? - 我尝试使用 glDisable 和 glBindTexture 但没有帮助。 这是我的代码:
@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);
更新 这是我的着色器程序:
#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;
}
OpenGL 是一个状态引擎。设置状态后,它会一直保持到再次更改,甚至超出帧。
在第二个对象之前绑定命名纹理对象,在绘制第二个对象之后绑定默认纹理对象(0)。
此外,在绘制调用之前启用顶点属性并在之后禁用它:
对象 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);
对象 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);
sahder 程序总是从纹理中读取颜色:
void main() {
gl_FragColor = v_Color;
gl_FragColor = texture2D(u_Texture, v_TextureCoordinates);
}
注意,设置gl_FragColor
的第一行是没有用的,因为gl_FragColor
被下面的行覆盖了。
由于未设置颜色属性(黑色)或从纹理读取的颜色为黑色,因此可以对颜色求和:
void main() {
gl_FragColor = v_Color + texture2D(u_Texture, v_TextureCoordinates);
}