I modified a simple program to introduce A strange problem about FBO!

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, &fbo);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

	// Create the render buffer for depth
	glGenRenderbuffersEXT(1, &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, &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, &fbo);
	glDeleteRenderbuffersEXT(1, &depthBuffer);
	for(int jx = 0;jx < TexNum;++jx)
	{
		glDeleteTextures(1,&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
");
		return false;
	}

	return true;
}

int main(int argc, char* argv[])
{
	glutInit(&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;
}

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.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.