PDA

View Full Version : I modified a simple program to introduce A strange problem about FBO!



spring
01-05-2007, 05:52 AM
Today , I modified a FBO example from Gamedev, the program is simple,but could introduce my trouble : after GL_COLOR_ATTACHMENT4_EXT, the FBO could not render a texture target correct!

Hope some good guy could run code to see trouble, and could give me some idea to get me out of trouble!

thanks advanced!



#include <GL/glew.h>
#include <GL/glut.h>

#include <iostream>

GLuint fbo;// Our handle to the FBO
GLuint depthBuffer;// Our handle to the depth render buffer

const int TexNum = 8;
GLuint texID[TexNum];// Our handle to a textures
const int width = 512;// The hight of the texture we'll be rendering to
const int height = 512; // The width of the texture we'll be rendering to

// Used for drawing the 3D cube with our rendered texture on it
GLfloat xrot = 0; // X Rotation
GLfloat yrot = 0; // Y Rotation
GLfloat xspeed = 0.2f; // X Rotation Speed
GLfloat yspeed = 0.1f; // Y Rotation Speed
GLuint ATTACHMENT_ARRAY[10] ={
GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT,
GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT,
GL_COLOR_ATTACHMENT4_EXT, GL_COLOR_ATTACHMENT5_EXT,
GL_COLOR_ATTACHMENT6_EXT, GL_COLOR_ATTACHMENT7_EXT,
GL_COLOR_ATTACHMENT8_EXT, GL_COLOR_ATTACHMENT9_EXT};
void initFBO()
{
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.2f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glViewport(0,0,512,512);

// Setup our FBO
glGenFramebuffersEXT(1, &amp;fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

// Create the render buffer for depth
glGenRenderbuffersEXT(1, &amp;depthBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);

int jx ;
//initialize texture
for (jx = 0 ;jx < TexNum;++jx)
{
glGenTextures(1, &amp;texID[jx]);
glBindTexture(GL_TEXTURE_2D, texID[jx]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// And attach it to the FBO so we can render to it
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, ATTACHMENT_ARRAY[jx], GL_TEXTURE_2D, texID[jx], 0);
}

}

void ShutDown(GLvoid)
{
glDeleteFramebuffersEXT(1, &amp;fbo);
glDeleteRenderbuffersEXT(1, &amp;depthBuffer);
for(int jx = 0;jx < TexNum;++jx)
{
glDeleteTextures(1,&amp;texID[jx]);
}

}

void reshape(int w,int h)
{
glViewport( 0, 0, w, h );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if ( h==0 )
gluPerspective(80,(float)w,1.0,5000.0);
else
gluPerspective(80,(float)w/(float)h,1.0,5000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void keyboard(unsigned char key,int x,int y)
{
switch(key)
{
case 27: // When Escape Is Pressed...
ShutDown();
exit(0); // Exit The Program
break;
default:
break;
}
}

void idle(void)
{
glutPostRedisplay();
}
void drawCube(float r,float g,float b)
{
glClearColor(r, g, b, 0.5f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity();

glTranslatef(0.0f,0.0f,-2.0f);
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);

glBegin(GL_QUADS);
// Front Face
glColor4f(0.0f,1.0f,0.0f,1.0f);
glVertex3f(-0.5f, -0.5, 0.5);
glVertex3f( 0.5, -0.5, 0.5);
glVertex3f( 0.5, 0.5, 0.5);
glVertex3f(-0.5, 0.5, 0.5);
// Back Face
glColor4f(1.0f,0.0f,0.0f,1.0f);
glVertex3f(-0.5, -0.5, -0.5);
glVertex3f(-0.5, 0.5, -0.5);
glVertex3f( 0.5, 0.5, -0.5);
glVertex3f( 0.5, -0.5, -0.5);
// Top Face
glColor4f(0.0f,0.0f,1.0f,1.0f);
glVertex3f(-0.5, 0.5, -0.5);
glVertex3f(-0.5, 0.5, 0.5);
glVertex3f( 0.5, 0.5, 0.5);
glVertex3f( 0.5, 0.5, -0.5);
// Bottom Face
glColor4f(0.0f,1.0f,1.0f,1.0f);
glVertex3f(-0.5, -0.5, -0.5);
glVertex3f( 0.5, -0.5, -0.5);
glVertex3f( 0.5, -0.5, 0.5);
glVertex3f(-0.5, -0.5, 0.5);
// Right face
glColor4f(1.0f,1.0f,0.0f,1.0f);
glVertex3f( 0.5, -0.5, -0.5);
glVertex3f( 0.5, 0.5, -0.5);
glVertex3f( 0.5, 0.5, 0.5);
glVertex3f( 0.5, -0.5, 0.5);
// Left Face
glColor4f(1.0f,1.0f,1.0f,1.0f);
glVertex3f(-0.5, -0.5, -0.5);
glVertex3f(-0.5, -0.5, 0.5);
glVertex3f(-0.5, 0.5, 0.5);
glVertex3f(-0.5, 0.5, -0.5);
glEnd();

}

void drawTextureCube(GLuint tex)
{
glBindTexture(GL_TEXTURE_2D, tex);
glBegin(GL_QUADS);
// Front Face
glNormal3f( 0.0f, 0.0f, 1.0);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f, -0.5, 0.5);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 0.5, -0.5, 0.5);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 0.5, 0.5, 0.5);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5, 0.5, 0.5);
// Back Face
glNormal3f( 0.0f, 0.0f,-1.0);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-0.5, -0.5, -0.5);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-0.5, 0.5, -0.5);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 0.5, 0.5, -0.5);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 0.5, -0.5, -0.5);
// Top Face
glNormal3f( 0.0f, 1.0, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5, 0.5, -0.5);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5, 0.5, 0.5);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 0.5, 0.5, 0.5);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 0.5, 0.5, -0.5);
// Bottom Face
glNormal3f( 0.0f,-1.0, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-0.5, -0.5, -0.5);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 0.5, -0.5, -0.5);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 0.5, -0.5, 0.5);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-0.5, -0.5, 0.5);
// Right face
glNormal3f( 1.0, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 0.5, -0.5, -0.5);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 0.5, 0.5, -0.5);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 0.5, 0.5, 0.5);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 0.5, -0.5, 0.5);
// Left Face
glNormal3f(-1.0, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5, -0.5, -0.5);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-0.5, -0.5, 0.5);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-0.5, 0.5, 0.5);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5, 0.5, -0.5);
glEnd();

}
void display(void)
{
// First we bind the FBO so we can render to it
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

// Save the view port and set it to the size of the texture
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0,0,width,height);

// Then render as normal
// Today's scene is a wonderful multi-coloured spinning cube ;)
// which we will draw twice, once in one set of colours and once in another
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
drawCube(1.0,0.0,0.0);
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
drawCube(0.0,1.0,0.0);
glDrawBuffer(GL_COLOR_ATTACHMENT2_EXT);
drawCube(0.0,0.0,1.0);
glDrawBuffer(GL_COLOR_ATTACHMENT3_EXT);
drawCube(1.0,1.0,0.0);

/////////////// have ERROR ///////////////
glDrawBuffer(GL_COLOR_ATTACHMENT4_EXT);
drawCube(1.0,0.0,1.0);
glDrawBuffer(GL_COLOR_ATTACHMENT5_EXT);
drawCube(0.0,1.0,1.0);
glDrawBuffer(GL_COLOR_ATTACHMENT6_EXT);
drawCube(1.0,0.50,1.0);
glDrawBuffer(GL_COLOR_ATTACHMENT7_EXT);
drawCube(0.50,1.0,1.0);


// Restore old view port and set rendering back to default frame buffer
// this resets the drawing destination to GL_BACK so we don't need to do it ourselves
glPopAttrib();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

// Now we clear the default frame buffer we are going to render to
glClearColor(1.0f, 1.0f, 1.f, 0.5f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glEnable(GL_TEXTURE_2D);
// Now we get ready to draw the first cube with the first texture attached
glLoadIdentity();

float Z = 5.0;
glTranslatef(-1.2f,3.0f,-Z);
glRotatef(-xrot,1.0f,0.0f,0.0f);
glRotatef(-yrot,0.0f,1.0f,0.0f);
drawTextureCube(texID[0]);

glLoadIdentity();
glTranslatef(1.2f,3.0f,-Z);
glRotatef(-xrot,1.0f,0.0f,0.0f);
glRotatef(-yrot,0.0f,1.0f,0.0f);
drawTextureCube(texID[1]);

glLoadIdentity();
glTranslatef(-1.2f,1.0f,-Z);
glRotatef(-xrot,1.0f,0.0f,0.0f);
glRotatef(-yrot,0.0f,1.0f,0.0f);
drawTextureCube(texID[2]);

glLoadIdentity();
glTranslatef(1.2f,1.0f,-Z);
glRotatef(-xrot,1.0f,0.0f,0.0f);
glRotatef(-yrot,0.0f,1.0f,0.0f);
drawTextureCube(texID[3]);
// Above display result is OK //////////

// Following display result is ERROR ////
glLoadIdentity();
glTranslatef(-1.2f,-1.0f,-Z);
glRotatef(-xrot,1.0f,0.0f,0.0f);
glRotatef(-yrot,0.0f,1.0f,0.0f);
drawTextureCube(texID[4]);

glLoadIdentity();
glTranslatef(1.2f,-1.0f,-Z);
glRotatef(-xrot,1.0f,0.0f,0.0f);
glRotatef(-yrot,0.0f,1.0f,0.0f);
drawTextureCube(texID[5]);


glLoadIdentity();
glTranslatef(-1.2f,-3.0f,-Z);
glRotatef(-xrot,1.0f,0.0f,0.0f);
glRotatef(-yrot,0.0f,1.0f,0.0f);
drawTextureCube(texID[6]);

glLoadIdentity();
glTranslatef(1.2f,-3.0f,-Z);
glRotatef(-xrot,1.0f,0.0f,0.0f);
glRotatef(-yrot,0.0f,1.0f,0.0f);
drawTextureCube(texID[7]);

glDisable(GL_TEXTURE_2D);

xrot+=xspeed;
yrot+=yspeed;

glutSwapBuffers ( );
// Swap The Buffers To Not Be Left With A Clear Screen
}

bool initGLEW()
{
//glReadBuffer(GL_BACK);

glewInit();
if (!glewIsSupported("GL_VERSION_2_0"))
{
printf("OpenGL 2.0 not supported\n");
return false;
}

return true;
}

int main(int argc, char* argv[])
{
glutInit(&amp;argc, (char**)argv);
glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE );
glutInitWindowSize(800,600);
glutCreateWindow( "FrameBuffer Object Example 2 - Press ESC to exit" );
if(!initGLEW())
exit(2);
initFBO();
glutDisplayFunc( display );
glutReshapeFunc( reshape );
glutKeyboardFunc( keyboard );
glutIdleFunc( idle );
glutMainLoop();
return 0;
}

sqrt[-1]
01-05-2007, 11:12 PM
Try calling glGetIntegerv and see what GL_MAX_COLOR_ATTACHMENTS_EXT returns. (guessing it only returns 4)

I think you are mis-using FBO's anyway. The idea is not to use one FBO and attach a lot of color buffers to it and then only render to one color buffer at a time. The idea of FBO's is to create a seperate FBO for each render target (can share the depth buffer).

If you created an array of FBO's with one color attachment each, I bet your application would work.