Hello.
I have some doubt about FBO. I have written an Android app. I render the scene into framebuffer, do some post-processing and render the scene finally as screen quad.
First i have attached depth buffer as texture. I use rather “old” Xperia, it has 600 MHz CPU with Adreno 200. My first mistake was that i assumed my hardware is very low end and if it works on my phone it will work everywhere. But i was wrong - i have tested the app with one Tegra-2 tablet and there were problems. I found out that Tegra-2 does not support FBO depth texture attachment (?) O.K. - i can workaround it and use renderbuffer depth attachment. The problem is - i am not sure now - may be there are devices which don’t support it too. May be it were better to enable off-screen rendering as option and don’t use it by default.
May be somebody with a deeper knowledge of the stuff could kindly look at my code and give me an advice - is it safe to use it? Or may be you will see something wrong here…
Here is actual version
static bool create_fbos1(unsigned int w,
unsigned int h,
GLuint * framebuffer,
GLuint * color_texture,
GLuint * depth_rb,
const GLenum format = GL_RGBA,
const GLenum type = GL_UNSIGNED_BYTE)
{
glGenRenderbuffers(1, depth_rb);
glBindRenderbuffer(GL_RENDERBUFFER, *depth_rb);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, w, h);
glGenFramebuffers(1, framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, *framebuffer);
glGenTextures(1, color_texture);
glBindTexture(GL_TEXTURE_2D, *color_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, type, NULL);
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *color_texture, 0);
bool ok = false;
switch(glCheckFramebufferStatus(GL_FRAMEBUFFER))
{
case GL_FRAMEBUFFER_COMPLETE:
ok = true;
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
break;
//case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
// break;
default:
break;
}
glBindFramebuffer(GL_FRAMEBUFFER, GL_NONE);
return ok;
}
Here is a part of display function
if (fbo_ok)
{
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
// not sure why this should be every time, but this was so in Adreno example
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_tex, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth);
}
and the old version (works on my Adreno 200), seems not to work with all devices…
static bool create_fbos0(unsigned int w,
unsigned int h,
GLuint * framebuffer,
GLuint * color_texture,
GLuint * depth_texture,
const GLenum format = GL_RGBA,
const GLenum type = GL_UNSIGNED_BYTE)
{
glGenTextures(1, depth_texture);
glBindTexture(GL_TEXTURE_2D, *depth_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_DEPTH_COMPONENT,
w,
h,
0,
GL_DEPTH_COMPONENT,
GL_UNSIGNED_SHORT,
NULL);
glGenTextures(1, color_texture);
glBindTexture(GL_TEXTURE_2D, *color_texture );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, type, NULL);
glGenFramebuffers(1, framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, *framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *color_texture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, *depth_texture, 0);
bool ok = false;
switch(glCheckFramebufferStatus(GL_FRAMEBUFFER))
{
case GL_FRAMEBUFFER_COMPLETE:
ok = true;
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
break;
//case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
// break;
default:
break;
}
glBindFramebuffer(GL_FRAMEBUFFER, GL_NONE);
return ok;
}
and display function was:
if (fbo_ok)
{
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_tex, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fbo_depth, 0);
}
the size of FBO is screen size (however i have tested different sizes for screen and framebuffer and it worked fine, just switched viewport)…
Here is the app… https://play.google.com/store/apps/details?id=com.rokk.solsys
(It is a test…)
Thank you for reading …