#include <stdio.h>
#include <stdlib.h>
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
void checkGLError( const char hdr[] )
{
int err = glGetError();
if( err )
{
fprintf(stderr, "ERROR %s: %s\n", hdr, gluErrorString(err));
exit(1);
}
}
void reshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glutPostRedisplay();
}
void keyboard( unsigned char key, int x, int y )
{
// Key Bindings
switch( key )
{
case 27 : exit(0); break;
}
}
void display()
{
glClearColor( 0,0,1,1 );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glutSwapBuffers();
checkGLError( "display() end" );
}
void checkFBOStatus ()
{
checkGLError( "Before checkStatus" );
GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
checkGLError( "After checkStatus" );
const char *err_str = 0;
char buf[80];
if ( status != GL_FRAMEBUFFER_COMPLETE_EXT )
{
switch ( status )
{
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
err_str = "INCOMPLETE ATTACHMENT";
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
err_str = "INCOMPLETE MISSING ATTACHMENT";
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
err_str = "INCOMPLETE DIMENSIONS";
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
err_str = "INCOMPLETE FORMATS";
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
err_str = "INCOMPLETE DRAW BUFFER";
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
err_str = "INCOMPLETE READ BUFFER";
break;
default:
sprintf( buf, "0x%x", status );
err_str = buf ;
break;
}
fprintf( stderr, "checkFramebufferStatus() returned '%s'\n", err_str );
exit(1);
}
}
void initFBO()
{
GLuint DeferredRendererfbo;
GLuint depthBuffer;
GLuint tex;
const int width = 640;
const int height = 480;
//------------------------------------------------------------------------
// FBO stuff - BEGIN
//------------------------------------------------------------------------
glGenFramebuffersEXT(1, &DeferredRendererfbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, DeferredRendererfbo);
// Create the render buffer for depth
glGenRenderbuffersEXT(1, &depthBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width, height);
// Now setup the first texture to render to
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, width, height, 0, GL_RGBA, GL_FLOAT, 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_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glGenerateMipmapEXT(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
// And attach it to the FBO so we can render to it
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0);
checkFBOStatus();
//------------------------------------------------------------------------
// FBO stuff - END
//------------------------------------------------------------------------
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
main( int argc, char *argv[] )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB );
glutCreateWindow( "window title" );
checkGLError( "Create window" );
initFBO();
glutReshapeFunc ( reshape );
glutDisplayFunc ( display );
glutKeyboardFunc( keyboard );
glutPostRedisplay();
glutMainLoop();
}