hi,
here's a tiny little program that does fbos, hope this will help you. (The result you should see is a white triangle)
#include <iostream>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#undef near
#undef far
#endif
#include "GL/glew.h" //the mighty GLEW
#include "SFML/Window.hpp"
/*
* Global variables
*/
sf::Window the_window;
sf::Event the_event;
float fps = 1.0f;
int frames = 0;
sf::Clock the_clock;
std::string app_path;
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
GLuint tex;
GLuint fbo;
/*
* Function declarations
*/
void get_opengl_error( bool ignore = false );
void draw_quad()
{
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();
}
void check_fbo()
{
if( glCheckFramebufferStatus( GL_FRAMEBUFFER ) != GL_FRAMEBUFFER_COMPLETE )
{
std::cerr << "FBO not complete.\n";
the_window.close();
exit( 1 );
}
}
int main( int argc, char* args[] )
{
/*
* Initialize OpenGL context
*/
the_window.create( sf::VideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 32 ), "FBO", 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_3_3 )
{
std::cerr << "Error: OpenGL 3.3 is required\n";
the_window.close();
exit( 1 );
}
/*
* Initialize and load textures
*/
glEnable( GL_TEXTURE_2D );
glGenTextures( 1, &tex );
glBindTexture( GL_TEXTURE_2D, tex );
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_RGBA8, SCREEN_WIDTH, SCREEN_HEIGHT, 0, GL_RGBA, GL_FLOAT, 0 );
get_opengl_error();
/*
* Initialize FBOs
*/
GLenum modes[] = { GL_COLOR_ATTACHMENT0 };
glGenFramebuffers( 1, &fbo );
glBindFramebuffer( GL_FRAMEBUFFER, fbo );
glDrawBuffers( 1, modes );
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0 );
check_fbo();
glBindFramebuffer( GL_FRAMEBUFFER, 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();
/*
* Generate input
*/
glBindFramebuffer( GL_FRAMEBUFFER, fbo );
glClearColor( 0, 0, 0, 0 );
glClear( GL_COLOR_BUFFER_BIT );
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();
/*
* MAIN LOOP
*/
the_clock.restart();
glEnable( GL_TEXTURE_2D );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, tex );
while( true )
{
/*
* Handle events
*/
while( the_window.pollEvent( the_event ) )
{
if( the_event.type == sf::Event::Closed )
{
the_window.close();
exit( 0 );
}
}
/*
* DRAW RESULT
*/
draw_quad();
/*
* Show the result
*/
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 ignore )
{
bool got_error = false;
GLenum error = 0;
error = glGetError();
std::string errorstring = "";
while( error != GL_NO_ERROR )
{
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.
errorstring += "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.
errorstring += "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.
errorstring += "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.
errorstring += "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.
errorstring += "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.
errorstring += "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.
errorstring += "OpenGL error: table too large...\n";
got_error = true;
}
error = glGetError();
}
if( got_error && !ignore )
{
std::cerr << errorstring;
the_window.close();
return;
}
}
Thankyou! I'll try dloading SFML and giving it a bash. Respect!