FBO setup fails on different OS

Started by
1 comment, last by Yours3!f 12 years, 2 months ago
Hi,

I've ported my app from Ubuntu 64 bit to Windows XP 32 bit. I use the same drivers (Catalyst 12.1, except for them being 64 and 32 bit verions), still on linux the following FBO setup works fine (and on Windows 7 64 bit as well), but on the XP it throws GL_FRAMEBUFFER_INCOMPLETE_DRAWBUFFER error. Any idea what am I doing wrong?

here's the setup code:

unsigned int w = (unsigned int)objs::get()->conf.SCREEN_WIDTH;
unsigned int h = (unsigned int)objs::get()->conf.SCREEN_HEIGHT;
fbo.create();
fbo.bind();
albedo.create();
normals.create();
depth.create();
glActiveTexture( GL_TEXTURE5 );
albedo.bind();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, GL_FLOAT, 0 ); //diffuse G-Buffer component
albedo.width = w;
albedo.height = h;
glActiveTexture( GL_TEXTURE6 );
normals.bind();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RG16F, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, GL_FLOAT, 0 ); //normal G-Buffer component
normals.width = w;
normals.height = h;
glActiveTexture( GL_TEXTURE7 );
depth.bind();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexImage2D( GL_TEXTURE_2D, 0, GL_R32F, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, GL_FLOAT, 0 ); //depth G-Buffer component, OpenCL doesn't take DEPTH_COMPONENT, YET!
depth.width = w;
depth.height = h;
glActiveTexture( GL_TEXTURE0 );
rbo.create();
rbo.bind();
rbo.set_storage_format( GL_DEPTH_COMPONENT, w, h );
rbo.width = w;
rbo.height = h;
rbo.attach_to_frame_buffer( GL_DEPTH_ATTACHMENT, &fbo );
albedo.attach_to_frame_buffer( GL_COLOR_ATTACHMENT0, &fbo );
normals.attach_to_frame_buffer( GL_COLOR_ATTACHMENT1, &fbo );
depth.attach_to_frame_buffer( GL_COLOR_ATTACHMENT2, &fbo );
GLenum modes[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
glDrawBuffers( 3, modes );
if ( fbo.check() == false )
{
std::cerr << "FBO not complete, DIE!\n";
objs::get()->conf.the_window.Close();
exit( 1 );
}
fbo.unbind();


Best regards,
Yours3!f
Advertisement
OS is not relevant. This is being caused by your driver or your code.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

thanks mhagain,

You're right, I tried to create a small test case, and the code just worked fine on all platforms (see below). So I guess it must be something else... What else can be the cause of this error?

EDIT: omg it was my fault... as you could see in the post above I don't call the OGL functions directly to do some validity checks in case I couldn't load a resource (texture etc.), so that the engine keeps running. Now I didn't set the textures to "valid", so the attach_to_frame_buffer calls failed. *HUGE facepalm* tongue.png, well thanks for the help smile.png


#include <iostream>
#include <GL/glew.h> //the mighty GLEW :)
#include <SFML/Window.hpp>
#include <SFML/Audio.hpp>
/*
* Global variables
*/
sf::Window the_window;
sf::Event the_event;
float fps = 1.0f;
int frames = 0;
sf::Clock the_clock;
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
GLuint fbo;
GLuint rbo;
GLuint albedo;
GLuint normals;
GLuint depth;
/*
* Function declarations
*/
void get_opengl_error();
int main( int argc, char* args[] )
{
/*
* Initialize OpenGL
*/
the_window.Create( sf::VideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 32 ), "cl_gl_test", sf::Style::Default );
if ( !the_window.IsOpen() )
{
std::cerr << "Couldn't initialize SFML.\n";
the_window.Close();
exit( 1 );
}
GLenum glew_error = glewInit();
if ( glew_error != GLEW_OK )
{
std::cerr << "Error initializing GLEW: " << glewGetErrorString( glew_error ) << "\n";
the_window.Close();
exit( 1 );
}
if ( !GLEW_VERSION_2_1 )
{
std::cerr << "Error: OpenGL 2.1 is required\n";
the_window.Close();
exit( 1 );
}
/*
* Initialize experimental FBO
*/
unsigned int w = SCREEN_WIDTH;
unsigned int h = SCREEN_HEIGHT;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glGenTextures(1, &albedo);
glGenTextures(1, &normals);
glGenTextures(1, &depth);
glActiveTexture( GL_TEXTURE5 );
glBindTexture(GL_TEXTURE_2D, albedo);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, ( GLsizei )w, ( GLsizei )h, 0, GL_RGBA, GL_FLOAT, 0 ); //diffuse G-Buffer component
glActiveTexture( GL_TEXTURE6 );
glBindTexture(GL_TEXTURE_2D, normals);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RG16F, ( GLsizei )w, ( GLsizei )h, 0, GL_RGBA, GL_FLOAT, 0 ); //normal G-Buffer component
glActiveTexture( GL_TEXTURE7 );
glBindTexture(GL_TEXTURE_2D, depth);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexImage2D( GL_TEXTURE_2D, 0, GL_R32F, ( GLsizei )w, ( GLsizei )h, 0, GL_RGBA, GL_FLOAT, 0 ); //depth G-Buffer component, OpenCL doesn't take DEPTH_COMPONENT, YET!
glActiveTexture( GL_TEXTURE0 );
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h );
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo );
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, albedo, 0 );
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, normals, 0 );
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, depth, 0 );
GLenum modes2[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
glDrawBuffers( 3, modes2 );
GLenum error_code = glCheckFramebufferStatus( GL_FRAMEBUFFER );
switch ( error_code )
{
case GL_FRAMEBUFFER_COMPLETE:
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
std::cerr << "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT.\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
std::cerr << "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS.\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
std::cerr << "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT.\n";
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
std::cerr << "GL_FRAMEBUFFER_UNSUPPORTED.\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
std::cerr << "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER.\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
std::cerr << "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER.\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
std::cerr << "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE.\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB:
std::cerr << "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS.\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB:
std::cerr << "GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT.\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
std::cerr << "GL_FRAMEBUFFER_INCOMPLETE_FORMATS.\n";
break;
default:
std::cerr << "Unknown Frame Buffer error cause: " << error_code << ".\n";
break;
}

if(error_code != GL_FRAMEBUFFER_COMPLETE)
{
std::cerr << "FBO not complete, DIE!!!.\n";
the_window.Close();
exit(1);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
get_opengl_error();
/*
* Set up matrices
*/
glViewport( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT );
glMatrixMode( GL_PROJECTION );
//x_min:0, x_max:1, y_min:0, y_max:1, z_min:0, z_max:-1
float ortho_matrix[] = { 2, 0, 0, 0,
0, 2, 0, 0,
0, 0, 2, 0,
-1, -1, -1, 1
};
glLoadMatrixf( ortho_matrix );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
get_opengl_error();
/*
* Draw on texture
*/
glBindFramebuffer( GL_FRAMEBUFFER, fbo );
glClearColor( 0, 0, 0, 1 );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glPushMatrix();
//glTranslatef(0.5f, 0.5f, 0.0f);
glBegin( GL_QUADS );
glColor3f( 0, 0, 0 );
glVertex2f( 0.0f, 0.0f );
glVertex2f( 1.0f, 0.0f );
glVertex2f( 1.0f, 1.0f );
glVertex2f( 0.0f, 1.0f );
glEnd();
glPopMatrix();
glPushMatrix();
glTranslatef( 0.5f, 0.5f, 0.0f );
glBegin( GL_TRIANGLES );
glColor3f( 1, 1, 1 );
glVertex2f( -0.25f, -0.25f );
glVertex2f( 0, 0.25f );
glVertex2f( 0.25f, -0.25f );
glEnd();
glPopMatrix();
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
get_opengl_error();
/*
* Display texture
*/
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, albedo );
get_opengl_error();
the_clock.Restart();
while ( true )
{
/*
* Handle events
*/
while ( the_window.PollEvent( the_event ) )
{
if ( the_event.Type == sf::Event::Closed )
{
the_window.Close();
exit( 0 );
}
}
/*
* Draw FBO output
*/
glBegin( GL_QUADS );
glTexCoord2f( 0, 0 );
glVertex2f( 0, 0 );
glTexCoord2f( 1, 0 );
glVertex2f( 1, 0 );
glTexCoord2f( 1, 1 );
glVertex2f( 1, 1 );
glTexCoord2f( 0, 1 );
glVertex2f( 0, 1 );
glEnd();
the_window.Display();
frames++;
if ( the_clock.GetElapsedTime().AsMilliseconds() > 1000.0f )
{
int timepassed = the_clock.GetElapsedTime().AsMilliseconds();
fps = 1000.0f / (( float ) timepassed / ( float ) frames );
std::cout << "FPS: " << fps << " Time: " << ( float ) timepassed / ( float ) frames << "\n";
frames = 0;
timepassed = 0;
the_clock.Restart();
}
}
return 0;
}
void get_opengl_error()
{
bool got_error = false;
GLenum error = glGetError();
if ( error == GL_NO_ERROR )
{
//no error
return;
}
if ( error == GL_INVALID_ENUM )
{
//An unacceptable value is specified for an enumerated argument. The offending command is ignored and has no other side effect than to set the error flag.
std::cerr << "OpenGL error: invalid enum...\n";
got_error = true;
}
if ( error == GL_INVALID_VALUE )
{
//A numeric argument is out of range. The offending command is ignored and has no other side effect than to set the error flag.
std::cerr << "OpenGL error: invalid value...\n";
got_error = true;
}
if ( error == GL_INVALID_OPERATION )
{
//The specified operation is not allowed in the current state. The offending command is ignored and has no other side effect than to set the error flag.
std::cerr << "OpenGL error: invalid operation...\n";
got_error = true;
}
if ( error == GL_STACK_OVERFLOW )
{
//This command would cause a stack overflow. The offending command is ignored and has no other side effect than to set the error flag.
std::cerr << "OpenGL error: stack overflow...\n";
got_error = true;
}
if ( error == GL_STACK_UNDERFLOW )
{
//This command would cause a stack underflow. The offending command is ignored and has no other side effect than to set the error flag.
std::cerr << "OpenGL error: stack underflow...\n";
got_error = true;
}
if ( error == GL_OUT_OF_MEMORY )
{
//There is not enough memory left to execute the command. The state of the GL is undefined, except for the state of the error flags, after this error is recorded.
std::cerr << "OpenGL error: out of memory...\n";
got_error = true;
}
if ( error == GL_TABLE_TOO_LARGE )
{
//The specified table exceeds the implementation's maximum supported table size. The offending command is ignored and has no other side effect than to set the error flag.
std::cerr << "OpenGL error: table too large...\n";
got_error = true;
}
if ( got_error )
{
the_window.Close();
exit( 1 );
}
else
{
std::cerr << "OpenCL error: unknown error...\n";
the_window.Close();
exit( 1 );
}
}
// kate: indent-mode cstyle; space-indent on; indent-width 2; replace-tabs on; replace-tabs on; replace-tabs on; replace-tabs on;

This topic is closed to new replies.

Advertisement