I have generated a frame buffer object(FBO), bind it, attached a texture to its GL_COLOR_ATTACHMENT0
. Then ensure that I get its status as GL_FRAMEBUFFER_COMPLETE
. I have another texture(which is displaying on display), let's call it workingTexture
. Now I want to render this workingTexture
onto FBO, so I bind this FBO and then render workingTexture
.
Then I bind default frame buffer(reserved for display) and try to render the texture attached to FBO, thinking that I will get my texture onto display, but I get black texture.
Relevant code
code to generate workingTexture...
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);
code to generate 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 😔😔");
}
method used to generate texture attached to 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];
}
Now coming to drawing part...
@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 is a simple method to render texture. It is working fine.
Also I have checked for GL_ERROR
but there is no error.
My understanding of application created FBO is that every read and write glCall
will happen on currently bound FBO, so is my understanding of FBO incorrect, or is there some error in my code.
Platform OpenGL|es 20 on Android
The texture which is generated in generateTextureForFBO
is mipmap incomplete.
If you do not generate mipmaps (by glGenerateMipmap
), then setting the GL_TEXTURE_MIN_FILTER
is important. Since the default filter is GL_NEAREST_MIPMAP_LINEAR
the texture would be mipmap incomplete, if you don not change the minifying function to GL_NEAREST
or GL_LINEAR
.
Set the texture minifying function (GL_TEXTURE_MIN_FILTER
) by 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);