Guest User

Untitled

a guest
Jun 25th, 2018
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.53 KB | None | 0 0
  1. // compile me with
  2. // gcc -std=c99 -ggdb -Wall fbotest.c `pkg-config --libs --cflags sdl` -lGL -lGLEW -lSDL_image -o fbotest
  3.  
  4. #include <SDL.h>
  5. #include <SDL_image.h>
  6.  
  7. #include <GL/glew.h>
  8. #include <GL/gl.h>
  9. #include <GL/glext.h>
  10.  
  11. //#include <flog.h>
  12.  
  13. #include <stdbool.h>
  14. #include <math.h>
  15.  
  16. #include <signal.h>
  17.  
  18. #define FlogAssert(__v, ...) if(!(__v)) { fprintf(stderr, "error: " __VA_ARGS__); fprintf(stderr, "\n"); exit(1); }
  19. #define FlogV(...) printf(__VA_ARGS__); puts("");
  20. #define FlogD(...) printf(__VA_ARGS__); puts("");
  21.  
  22. const int w = 1024, h = 768;
  23.  
  24. void OrthoMode(int w, int h)
  25. {
  26.     // Set Orthogonal Projection
  27.     glMatrixMode(GL_PROJECTION);
  28.     glLoadIdentity();
  29.  
  30.     glOrtho(0.0f, w, h, 0.0f, -1.0f, 1.0f);
  31.     glMatrixMode(GL_MODELVIEW);
  32.     glLoadIdentity();
  33. }
  34.  
  35. GLuint CreateFBO(int w, int h, GLuint* fboImg)
  36. {
  37.     // FrameBuffer Object
  38.     GLuint fbo;
  39.     glGenFramebuffers(1, &fbo);
  40.  
  41.     glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
  42.  
  43.     /*GLuint depthbuffer;
  44.     glGenRenderbuffers(1, &depthbuffer);
  45.     glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer);
  46.  
  47.     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h);
  48.  
  49.     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer);*/
  50.  
  51.     glGenTextures(1, fboImg);
  52.     glBindTexture(GL_TEXTURE_2D, *fboImg);
  53.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,  w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  54.  
  55.     glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, *fboImg, 0);
  56.  
  57.     glGenerateMipmapEXT(GL_TEXTURE_2D);
  58.  
  59.     FlogAssert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE,
  60.         "Couldn't create framebuffer object");
  61.  
  62.     return fbo;
  63. }
  64.  
  65. int Texture(SDL_Surface* surface)
  66. {
  67.     FlogAssert(surface != NULL, "Couldn't load file");
  68.     FlogAssert(surface->format->BytesPerPixel == 4, "Not a 32bit image file");
  69.     GLuint ret = 0;
  70.    
  71.     glGenTextures(1, &ret);
  72.     glBindTexture(GL_TEXTURE_2D, ret);
  73.  
  74.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  75.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  76.  
  77.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  78.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  79.  
  80.     glTexImage2D(
  81.         GL_TEXTURE_2D,
  82.         0,
  83.         GL_RGBA8,
  84.         surface->w,
  85.         surface->h,
  86.         0,
  87.         GL_RGBA,
  88.         GL_UNSIGNED_BYTE,
  89.         surface->pixels
  90.         );
  91.  
  92.     return ret;
  93. }
  94.  
  95. typedef struct {
  96.     int w, h;
  97.     GLuint texture;
  98.     GLuint fbo;
  99. } Fbo;
  100.  
  101. Fbo* Fbo_Create(int w, int h)
  102. {
  103.     Fbo* fbo = calloc(1, sizeof(Fbo));
  104.     FlogAssert(fbo != NULL, "no ram!");
  105.  
  106.     fbo->w = w;
  107.     fbo->h = h;
  108.  
  109.     fbo->fbo = CreateFBO(w, h, &fbo->texture);
  110.  
  111.     return fbo;
  112. }
  113.  
  114. Fbo* Fbo_Load(const char* filename)
  115. {
  116.     Fbo* fbo = calloc(1, sizeof(Fbo));
  117.     FlogAssert(fbo != NULL, "no ram!");
  118.  
  119.     SDL_Surface* surface = IMG_Load(filename);
  120.  
  121.     fbo->w = surface->w;
  122.     fbo->h = surface->h;
  123.  
  124.     fbo->texture = Texture(surface);
  125.  
  126.     FlogV("Loaded texture [%d x %d] from %s", fbo->w, fbo->h, filename);
  127.     return fbo;
  128. }
  129.  
  130. void Fbo_MakeTextureFbo(Fbo* me)
  131. {
  132.     FlogD("Making texture FBO");
  133.     glDeleteTextures(1, &me->texture);
  134.     me->fbo = CreateFBO(me->w, me->h, &me->texture);
  135. }
  136.  
  137. void Fbo_Enter(Fbo* me)
  138. {
  139.     if(!me->fbo) Fbo_MakeTextureFbo(me);
  140.  
  141.     glBindFramebuffer(GL_FRAMEBUFFER_EXT, me->fbo);
  142.  
  143.     OrthoMode(me->w, me->h);
  144.    
  145.     glPushAttrib(GL_VIEWPORT_BIT);
  146.     glViewport(0, 0, me->w, me->h);
  147.  
  148.     //glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
  149. }
  150.  
  151. void Fbo_Exit(Fbo* me)
  152. {
  153.     glPopAttrib();
  154.     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  155.     OrthoMode(w, h);
  156. }
  157.  
  158. void Fbo_Clear(Fbo* me, float r, float g, float b, float a)
  159. {
  160.     Fbo_Enter(me);
  161.     glClearColor(r, g, b, a);
  162.     glClear(GL_COLOR_BUFFER_BIT);
  163.     Fbo_Exit(me);
  164. }
  165.  
  166.  
  167. void Fbo_Draw(Fbo* fbo, Fbo* target, int x, int y)
  168. {
  169.     if(target) Fbo_Enter(target);
  170.  
  171.     glPushMatrix();
  172.  
  173.     if(target) {
  174.         glTranslatef(0, target->h, 0);
  175.         glScalef(1, -1, 0);
  176.     }
  177.  
  178.     glTranslatef(x, y, 0);
  179.  
  180.     glColor3f(1, 1, 1);
  181.     glBindTexture(GL_TEXTURE_2D, fbo->texture);
  182.  
  183.     glBegin(GL_QUADS);
  184.  
  185.     glTexCoord2f(0, 0);
  186.     glVertex2f(0, 0);
  187.  
  188.     glTexCoord2f(1, 0);
  189.     glVertex2f(fbo->w, 0);
  190.  
  191.     glTexCoord2f(1, 1);
  192.     glVertex2f(fbo->w, fbo->h);
  193.  
  194.     glTexCoord2f(0, 1);
  195.     glVertex2f(0, fbo->h);
  196.  
  197.     glEnd();                   
  198.  
  199.     glPopMatrix();
  200.  
  201.     if(target) Fbo_Exit(target);
  202. }
  203.  
  204. void EnableTextures()
  205. {
  206.     glEnable(GL_TEXTURE_2D);
  207.     glClear(GL_COLOR_BUFFER_BIT);
  208.  
  209.     glEnable(GL_BLEND);
  210.     glEnable(GL_TEXTURE_2D);
  211.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  212.     glEnable(GL_ALPHA_TEST);
  213.  
  214.     glDisable( GL_DEPTH_TEST );
  215.     glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
  216.     glMatrixMode(GL_PROJECTION);
  217.     glLoadIdentity();
  218. }
  219.  
  220. int main(int argc, char** argv)
  221. {
  222.     //Flog_Init("FBO test");
  223.     //Flog_AddTargetStream(stdout, Flog_SDebug1 |Flog_SDebug2 | Flog_SDebug3 | Flog_SVerbose | Flog_SInfo | Flog_SWarning, 1);
  224.     //Flog_AddTargetStream(stderr, Flog_SError | Flog_SFatal, 1);
  225.  
  226.     FlogAssert( SDL_Init(SDL_INIT_EVERYTHING) != -1, "SDL_Init failed" );
  227.     signal(SIGINT, SIG_DFL);
  228.  
  229.     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  230.     SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 1 );
  231.    
  232.     SDL_WM_SetCaption("FBO test", NULL);
  233.  
  234.     SDL_Surface* screen = SDL_SetVideoMode(w, h, 0, SDL_OPENGL);
  235.     FlogAssert(screen != NULL, "SDL_SetVideoMode failed" );
  236.  
  237.     // Load Extensions
  238.     FlogAssert(glewInit() == GLEW_OK, "glewInit failed");
  239.  
  240.     FlogAssert(glewGetExtension("GL_ARB_texture_non_power_of_two"),
  241.         "Driver does not support non-power of two texture sizes");
  242.     FlogAssert(glewGetExtension("GL_EXT_framebuffer_object"),
  243.         "Driver does not support Framebuffer Objects");
  244.  
  245.     EnableTextures();
  246.     OrthoMode(w, h);
  247.  
  248.     bool done = false;
  249.  
  250.     Fbo* logo = Fbo_Load("opengl.png");
  251.     Fbo* target = Fbo_Create(512, 512);
  252.     Fbo* target2 = Fbo_Create(256, 256);
  253.  
  254.     float t = 0;
  255.     float t2 = 1.5;
  256.  
  257.     while(!done){
  258.         SDL_Event event;
  259.  
  260.         while(SDL_PollEvent(&event)){
  261.             if(event.type == SDL_KEYDOWN){
  262.                 switch(event.key.keysym.sym){
  263.                     case SDLK_ESCAPE: done = true; break;
  264.                     default: break;
  265.                 }
  266.             }
  267.         }
  268.    
  269.         glClearColor(0, 0, 0, 0);
  270.         glClear(GL_COLOR_BUFFER_BIT);
  271.  
  272.         t += .01;
  273.         t2 += .02;
  274.  
  275.         Fbo_Clear(target, .1, .1, .1, 1);
  276.         //Fbo_Draw(logo, target, sin(t) * target->w / 4 + target->w / 2 - logo->w / 2,
  277.         //  cos(t) * target->h / 4 + target->h / 2 - logo->h / 2);
  278.  
  279.        
  280.         Fbo_Clear(target2, .1, 0, 0, 1);
  281.         Fbo_Draw(logo, target2, 0, 0);
  282.         Fbo_Draw(target2, target, 100, 100);
  283.  
  284.         Fbo_Draw(target, NULL, sin(t2) * w / 2 + w / 2 - target->w / 2, cos(t2) * h / 2 + h / 2 - target->w / 2);
  285.         //Fbo_Draw(target, NULL, w / 2 - target->w / 2, h / 2 - target->h / 2);
  286.  
  287.         SDL_GL_SwapBuffers();
  288.     }  
  289.    
  290.     return 0;
  291. }
Add Comment
Please, Sign In to add comment