渲染到附加到帧缓冲区对象的纹理(纹理显示为黑色)
Render to texture attached to Frame Buffer Object (texture appears black)
我生成了一个帧缓冲对象 (FBO),绑定它,将纹理附加到它的 GL_COLOR_ATTACHMENT0
。然后确保我得到它的状态 GL_FRAMEBUFFER_COMPLETE
。我有另一个纹理(显示在显示器上),我们称它为 workingTexture
。现在我想把这个 workingTexture
渲染到 FBO 上,所以我绑定这个 FBO 然后渲染 workingTexture
。
然后我绑定默认帧缓冲区(保留用于显示)并尝试渲染附加到 FBO 的纹理,以为我会显示我的纹理,但我得到黑色纹理。
相关代码
生成工作纹理的代码...
int[] workingTexture = new int[1];
glGenTextures(1, workingTexture, 0); // generate workingTexture
glActiveTexture(GL_TEXTURE0); // attach it to TEXTURE_UNIT0
glBindTexture(GL_TEXTURE_2D, workingTexture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
生成 fbo 的代码
int[] fboName = new int[1];
int[] fboTextureName = new int[1];
final int fboTextureUnit = 1; // attach this texture to texture unit GL_TEXTURE1
glGenFramebuffers(1, fboName, 0);
int generatedTextureNameForFBO =
generateTextureForFBO(fboTextureUnit,
width, height);
fboTextureName[0] = generatedTextureNameForFBO;
glBindFramebuffer(GL_FRAMEBUFFER, fboName[0]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, generatedTextureNameForFBO, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
// created FBO is not complete
throw new RuntimeException("FBO status INCOMPLETE ");
}
用于生成附加到 fbo 的纹理的方法
private int generateTextureForFBO(@IntRange(from = 0) final int textureUnit,
@IntRange(from = 1) final int width,
@IntRange(from = 1) final int height) {
int[] textureName = new int[1];
glGenTextures(1, textureName, 0);
glActiveTexture(GL_TEXTURE0 + textureUnit);
glBindTexture(GL_TEXTURE_2D, textureName[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
// glBindTexture(GL_TEXTURE_2D, 0);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
// glBindTexture(GL_TEXTURE_2D, 0);
return textureName[0];
}
现在进入绘图部分...
@Override
public void onDrawFrame(GL10 unused) {
glClear(GL_COLOR_BUFFER_BIT);
//renderTex(mViewMatrix, 0, texProgram); // this texture is drawing on screen
glBindFramebuffer(GL_FRAMEBUFFER, fboName[0]);
renderTex(mViewMatrix, 0, texProgram); // rendering workingTexture onto FBO
glBindFramebuffer(GL_FRAMEBUFFER, 0);
renderTex(mViewMatrix, fboTextureUnit[0], texProgram); // texture appears black
}
renderTex 是一种渲染纹理的简单方法。它工作正常。
我也检查了 GL_ERROR
但没有错误。
我对应用程序创建的FBO的理解是每次读写glCall
都会在当前绑定的FBO上发生,所以我对FBO的理解不正确,或者我的代码有什么错误。
平台 OpenGL|es 20 on Android
在generateTextureForFBO
中生成的纹理不完整。
如果不生成mipmaps (by glGenerateMipmap
),那么设置GL_TEXTURE_MIN_FILTER
很重要。由于默认过滤器是 GL_NEAREST_MIPMAP_LINEAR
如果您不将缩小功能更改为 GL_NEAREST
或 GL_LINEAR
.
,纹理将是不完整的 mipmap
设置纹理缩小函数(GL_TEXTURE_MIN_FILTER
) glTexParameter
:
glBindTexture(GL_TEXTURE_2D, textureName[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
我生成了一个帧缓冲对象 (FBO),绑定它,将纹理附加到它的 GL_COLOR_ATTACHMENT0
。然后确保我得到它的状态 GL_FRAMEBUFFER_COMPLETE
。我有另一个纹理(显示在显示器上),我们称它为 workingTexture
。现在我想把这个 workingTexture
渲染到 FBO 上,所以我绑定这个 FBO 然后渲染 workingTexture
。
然后我绑定默认帧缓冲区(保留用于显示)并尝试渲染附加到 FBO 的纹理,以为我会显示我的纹理,但我得到黑色纹理。
相关代码
生成工作纹理的代码...
int[] workingTexture = new int[1];
glGenTextures(1, workingTexture, 0); // generate workingTexture
glActiveTexture(GL_TEXTURE0); // attach it to TEXTURE_UNIT0
glBindTexture(GL_TEXTURE_2D, workingTexture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
生成 fbo 的代码
int[] fboName = new int[1];
int[] fboTextureName = new int[1];
final int fboTextureUnit = 1; // attach this texture to texture unit GL_TEXTURE1
glGenFramebuffers(1, fboName, 0);
int generatedTextureNameForFBO =
generateTextureForFBO(fboTextureUnit,
width, height);
fboTextureName[0] = generatedTextureNameForFBO;
glBindFramebuffer(GL_FRAMEBUFFER, fboName[0]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, generatedTextureNameForFBO, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
// created FBO is not complete
throw new RuntimeException("FBO status INCOMPLETE ");
}
用于生成附加到 fbo 的纹理的方法
private int generateTextureForFBO(@IntRange(from = 0) final int textureUnit,
@IntRange(from = 1) final int width,
@IntRange(from = 1) final int height) {
int[] textureName = new int[1];
glGenTextures(1, textureName, 0);
glActiveTexture(GL_TEXTURE0 + textureUnit);
glBindTexture(GL_TEXTURE_2D, textureName[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
// glBindTexture(GL_TEXTURE_2D, 0);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
// glBindTexture(GL_TEXTURE_2D, 0);
return textureName[0];
}
现在进入绘图部分...
@Override
public void onDrawFrame(GL10 unused) {
glClear(GL_COLOR_BUFFER_BIT);
//renderTex(mViewMatrix, 0, texProgram); // this texture is drawing on screen
glBindFramebuffer(GL_FRAMEBUFFER, fboName[0]);
renderTex(mViewMatrix, 0, texProgram); // rendering workingTexture onto FBO
glBindFramebuffer(GL_FRAMEBUFFER, 0);
renderTex(mViewMatrix, fboTextureUnit[0], texProgram); // texture appears black
}
renderTex 是一种渲染纹理的简单方法。它工作正常。
我也检查了 GL_ERROR
但没有错误。
我对应用程序创建的FBO的理解是每次读写glCall
都会在当前绑定的FBO上发生,所以我对FBO的理解不正确,或者我的代码有什么错误。
平台 OpenGL|es 20 on Android
在generateTextureForFBO
中生成的纹理不完整。
如果不生成mipmaps (by glGenerateMipmap
),那么设置GL_TEXTURE_MIN_FILTER
很重要。由于默认过滤器是 GL_NEAREST_MIPMAP_LINEAR
如果您不将缩小功能更改为 GL_NEAREST
或 GL_LINEAR
.
设置纹理缩小函数(GL_TEXTURE_MIN_FILTER
) glTexParameter
:
glBindTexture(GL_TEXTURE_2D, textureName[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);