Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // compile me with
- // gcc -std=c99 -ggdb -Wall fbotest.c `pkg-config --libs --cflags sdl` -lGL -lGLEW -lSDL_image -o fbotest
- #include <SDL.h>
- #include <SDL_image.h>
- #include <GL/glew.h>
- #include <GL/gl.h>
- #include <GL/glext.h>
- //#include <flog.h>
- #include <stdbool.h>
- #include <math.h>
- #include <signal.h>
- #define FlogAssert(__v, ...) if(!(__v)) { fprintf(stderr, "error: " __VA_ARGS__); exit(1); }
- #define FlogV(...) printf(__VA_ARGS__)
- #define FlogD(...) printf(__VA_ARGS__)
- const int w = 1024, h = 768;
- void OrthoMode(int w, int h)
- {
- // Set Orthogonal Projection
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0.0f, w, h, 0.0f, -1.0f, 1.0f);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- }
- GLuint CreateFBO(int w, int h, GLuint* fboImg)
- {
- // FrameBuffer Object
- GLuint fbo;
- glGenFramebuffers(1, &fbo);
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
- /*GLuint depthbuffer;
- glGenRenderbuffers(1, &depthbuffer);
- glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer);*/
- glGenTextures(1, fboImg);
- glBindTexture(GL_TEXTURE_2D, *fboImg);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, *fboImg, 0);
- glGenerateMipmapEXT(GL_TEXTURE_2D);
- FlogAssert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE,
- "Couldn't create framebuffer object");
- return fbo;
- }
- int Texture(SDL_Surface* surface)
- {
- FlogAssert(surface != NULL, "Couldn't load file");
- FlogAssert(surface->format->BytesPerPixel == 4, "Not a 32bit image file");
- GLuint ret = 0;
- glGenTextures(1, &ret);
- glBindTexture(GL_TEXTURE_2D, ret);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- glTexImage2D(
- GL_TEXTURE_2D,
- 0,
- GL_RGBA8,
- surface->w,
- surface->h,
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- surface->pixels
- );
- return ret;
- }
- typedef struct {
- int w, h;
- GLuint texture;
- GLuint fbo;
- } Fbo;
- Fbo* Fbo_Create(int w, int h)
- {
- Fbo* fbo = calloc(1, sizeof(Fbo));
- FlogAssert(fbo != NULL, "no ram!");
- fbo->w = w;
- fbo->h = h;
- fbo->fbo = CreateFBO(w, h, &fbo->texture);
- return fbo;
- }
- Fbo* Fbo_Load(const char* filename)
- {
- Fbo* fbo = calloc(1, sizeof(Fbo));
- FlogAssert(fbo != NULL, "no ram!");
- SDL_Surface* surface = IMG_Load(filename);
- fbo->w = surface->w;
- fbo->h = surface->h;
- fbo->texture = Texture(surface);
- FlogV("Loaded texture [%d x %d] from %s", fbo->w, fbo->h, filename);
- return fbo;
- }
- void Fbo_MakeTextureFbo(Fbo* me)
- {
- FlogD("Making texture FBO");
- glDeleteTextures(1, &me->texture);
- me->fbo = CreateFBO(me->w, me->h, &me->texture);
- }
- void Fbo_Enter(Fbo* me)
- {
- if(!me->fbo) Fbo_MakeTextureFbo(me);
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, me->fbo);
- OrthoMode(me->w, me->h);
- glPushAttrib(GL_VIEWPORT_BIT);
- glViewport(0, 0, me->w, me->h);
- //glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
- }
- void Fbo_Exit(Fbo* me)
- {
- glPopAttrib();
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- OrthoMode(w, h);
- }
- void Fbo_Clear(Fbo* me, float r, float g, float b, float a)
- {
- Fbo_Enter(me);
- glClearColor(r, g, b, a);
- glClear(GL_COLOR_BUFFER_BIT);
- Fbo_Exit(me);
- }
- void Fbo_Draw(Fbo* fbo, Fbo* target, int x, int y)
- {
- if(target) Fbo_Enter(target);
- glPushMatrix();
- if(target) {
- glTranslatef(0, target->h, 0);
- glScalef(1, -1, 0);
- }
- glTranslatef(x, y, 0);
- glColor3f(1, 1, 1);
- glBindTexture(GL_TEXTURE_2D, fbo->texture);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0);
- glVertex2f(0, 0);
- glTexCoord2f(1, 0);
- glVertex2f(fbo->w, 0);
- glTexCoord2f(1, 1);
- glVertex2f(fbo->w, fbo->h);
- glTexCoord2f(0, 1);
- glVertex2f(0, fbo->h);
- glEnd();
- glPopMatrix();
- if(target) Fbo_Exit(target);
- }
- void EnableTextures()
- {
- glEnable(GL_TEXTURE_2D);
- glClear(GL_COLOR_BUFFER_BIT);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_ALPHA_TEST);
- glDisable( GL_DEPTH_TEST );
- glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- }
- int main(int argc, char** argv)
- {
- //Flog_Init("FBO test");
- //Flog_AddTargetStream(stdout, Flog_SDebug1 |Flog_SDebug2 | Flog_SDebug3 | Flog_SVerbose | Flog_SInfo | Flog_SWarning, 1);
- //Flog_AddTargetStream(stderr, Flog_SError | Flog_SFatal, 1);
- FlogAssert( SDL_Init(SDL_INIT_EVERYTHING) != -1, "SDL_Init failed" );
- signal(SIGINT, SIG_DFL);
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 1 );
- SDL_WM_SetCaption("FBO test", NULL);
- SDL_Surface* screen = SDL_SetVideoMode(w, h, 0, SDL_OPENGL);
- FlogAssert(screen != NULL, "SDL_SetVideoMode failed" );
- // Load Extensions
- FlogAssert(glewInit() == GLEW_OK, "glewInit failed");
- FlogAssert(glewGetExtension("GL_ARB_texture_non_power_of_two"),
- "Driver does not support non-power of two texture sizes");
- FlogAssert(glewGetExtension("GL_EXT_framebuffer_object"),
- "Driver does not support Framebuffer Objects");
- EnableTextures();
- OrthoMode(w, h);
- bool done = false;
- Fbo* logo = Fbo_Load("opengl.png");
- Fbo* target = Fbo_Create(512, 512);
- Fbo* target2 = Fbo_Create(256, 256);
- float t = 0;
- float t2 = 1.5;
- while(!done){
- SDL_Event event;
- while(SDL_PollEvent(&event)){
- if(event.type == SDL_KEYDOWN){
- switch(event.key.keysym.sym){
- case SDLK_ESCAPE: done = true; break;
- default: break;
- }
- }
- }
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT);
- t += .01;
- t2 += .02;
- Fbo_Clear(target, .1, .1, .1, 1);
- //Fbo_Draw(logo, target, sin(t) * target->w / 4 + target->w / 2 - logo->w / 2,
- // cos(t) * target->h / 4 + target->h / 2 - logo->h / 2);
- Fbo_Clear(target2, .1, 0, 0, 1);
- Fbo_Draw(logo, target2, 0, 0);
- Fbo_Draw(target2, target, 100, 100);
- Fbo_Draw(target, NULL, sin(t2) * w / 2 + w / 2 - target->w / 2, cos(t2) * h / 2 + h / 2 - target->w / 2);
- //Fbo_Draw(target, NULL, w / 2 - target->w / 2, h / 2 - target->h / 2);
- SDL_GL_SwapBuffers();
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment