132001f49Smrg/* 232001f49Smrg * Use scissor to clear the four quadrants of the FBO to different 332001f49Smrg * colors. Then draw a grey triangle in the middle. 432001f49Smrg */ 532001f49Smrg 632001f49Smrg 732001f49Smrg#include <assert.h> 832001f49Smrg#include <stdio.h> 932001f49Smrg#include <stdlib.h> 1032001f49Smrg#include <math.h> 1132001f49Smrg#include <string.h> 1232001f49Smrg#include <GL/glew.h> 1332001f49Smrg#include "glut_wrap.h" 1432001f49Smrg 1532001f49Smrg 1632001f49Smrgstatic int Width = 512, Height = 512; 1732001f49Smrgstatic GLuint MyFB, MyRB; 1832001f49Smrgstatic GLboolean UseTex = GL_FALSE; 1932001f49Smrgstatic GLboolean UseCopyPix = GL_FALSE; 2032001f49Smrg 2132001f49Smrg 2232001f49Smrg#define CheckError() \ 2332001f49Smrg do { \ 2432001f49Smrg GLenum err = glGetError(); \ 2532001f49Smrg if (err != GL_NO_ERROR) \ 2632001f49Smrg printf("Error: %s\n", gluErrorString(err)); \ 2732001f49Smrg assert(err == GL_NO_ERROR); \ 2832001f49Smrg } while (0) 2932001f49Smrg 3032001f49Smrg 3132001f49Smrgstatic void 3232001f49SmrgInit(void) 3332001f49Smrg{ 3432001f49Smrg GLenum status; 3532001f49Smrg 3632001f49Smrg fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 3732001f49Smrg fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); 3832001f49Smrg fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); 3932001f49Smrg fflush(stderr); 4032001f49Smrg 4132001f49Smrg if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { 4232001f49Smrg printf("GL_EXT_framebuffer_object not found!\n"); 4332001f49Smrg exit(0); 4432001f49Smrg } 4532001f49Smrg 4632001f49Smrg glGenFramebuffersEXT(1, &MyFB); 4732001f49Smrg glGenRenderbuffersEXT(1, &MyRB); 4832001f49Smrg 4932001f49Smrg glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); 5032001f49Smrg 5132001f49Smrg if (UseTex) { 5232001f49Smrg GLuint tex; 5332001f49Smrg glGenTextures(1, &tex); 5432001f49Smrg glBindTexture(GL_TEXTURE_2D, tex); 5532001f49Smrg glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, 5632001f49Smrg GL_RGBA, GL_UNSIGNED_BYTE, NULL); 5732001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 5832001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 5932001f49Smrg glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, 6032001f49Smrg GL_COLOR_ATTACHMENT0_EXT, 6132001f49Smrg GL_TEXTURE_2D, tex, 0); 6232001f49Smrg } 6332001f49Smrg else { 6432001f49Smrg glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, MyRB); 6532001f49Smrg 6632001f49Smrg glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, 6732001f49Smrg GL_COLOR_ATTACHMENT0_EXT, 6832001f49Smrg GL_RENDERBUFFER_EXT, MyRB); 6932001f49Smrg 7032001f49Smrg glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); 7132001f49Smrg } 7232001f49Smrg 7332001f49Smrg status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 7432001f49Smrg if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { 7532001f49Smrg fprintf(stderr, "Framebuffer object is incomplete (0x%x)!\n", status); 7632001f49Smrg } 7732001f49Smrg 7832001f49Smrg glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 7932001f49Smrg} 8032001f49Smrg 8132001f49Smrg 8232001f49Smrgstatic void 8332001f49SmrgReshape(int width, int height) 8432001f49Smrg{ 8532001f49Smrg glViewport(0, 0, width, height); 8632001f49Smrg glMatrixMode(GL_PROJECTION); 8732001f49Smrg glLoadIdentity(); 8832001f49Smrg glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); 8932001f49Smrg glMatrixMode(GL_MODELVIEW); 9032001f49Smrg 9132001f49Smrg Width = width; 9232001f49Smrg Height = height; 9332001f49Smrg if (!UseTex) { 9432001f49Smrg glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); 9532001f49Smrg } 9632001f49Smrg} 9732001f49Smrg 9832001f49Smrg 9932001f49Smrgstatic void 10032001f49SmrgKey(unsigned char key, int x, int y) 10132001f49Smrg{ 10232001f49Smrg if (key == 27) { 10332001f49Smrg exit(0); 10432001f49Smrg } 10532001f49Smrg glutPostRedisplay(); 10632001f49Smrg} 10732001f49Smrg 10832001f49Smrg 10932001f49Smrgstatic void 11032001f49SmrgDraw(void) 11132001f49Smrg{ 11232001f49Smrg GLboolean scissor = GL_TRUE; 11332001f49Smrg 11432001f49Smrg /* draw to user framebuffer */ 11532001f49Smrg glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); 11632001f49Smrg glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); 11732001f49Smrg glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); 11832001f49Smrg 11932001f49Smrg glViewport(0, 0, Width, Height); 12032001f49Smrg CheckError(); 12132001f49Smrg 12232001f49Smrg if (scissor) { 12332001f49Smrg glEnable(GL_SCISSOR_TEST); 12432001f49Smrg 12532001f49Smrg /* lower-left = red */ 12632001f49Smrg glClearColor(1, 0, 0, 0); 12732001f49Smrg glScissor(0, 0, Width / 2, Height / 2); 12832001f49Smrg glClear(GL_COLOR_BUFFER_BIT); 12932001f49Smrg 13032001f49Smrg /* lower-right = green */ 13132001f49Smrg glClearColor(0, 1, 0, 0); 13232001f49Smrg glScissor(Width / 2, 0, Width - Width / 2, Height / 2); 13332001f49Smrg glClear(GL_COLOR_BUFFER_BIT); 13432001f49Smrg 13532001f49Smrg /* upper-left = blue */ 13632001f49Smrg glClearColor(0, 0, 1, 0); 13732001f49Smrg glScissor(0, Height / 2, Width / 2, Height - Height / 2); 13832001f49Smrg glClear(GL_COLOR_BUFFER_BIT); 13932001f49Smrg 14032001f49Smrg /* upper-right = white */ 14132001f49Smrg glClearColor(1, 1, 1, 0); 14232001f49Smrg glScissor(Width / 2, Height / 2, Width - Width / 2, Height - Height / 2); 14332001f49Smrg glClear(GL_COLOR_BUFFER_BIT); 14432001f49Smrg 14532001f49Smrg glDisable(GL_SCISSOR_TEST); 14632001f49Smrg } 14732001f49Smrg else { 14832001f49Smrg glClearColor(0, 1, 0, 0); 14932001f49Smrg glClear(GL_COLOR_BUFFER_BIT); 15032001f49Smrg } 15132001f49Smrg 15232001f49Smrg CheckError(); 15332001f49Smrg 15432001f49Smrg /* gray triangle in middle, pointing up */ 15532001f49Smrg glColor3f(0.5, 0.5, 0.5); 15632001f49Smrg glBegin(GL_TRIANGLES); 15732001f49Smrg glVertex2f(Width/4, Height/4); 15832001f49Smrg glVertex2f(Width*3/4, Height/4); 15932001f49Smrg glVertex2f(Width/2, Height*3/4); 16032001f49Smrg glVertex2f(-0.5, -0.5); 16132001f49Smrg glVertex2f(+0.5, -0.5); 16232001f49Smrg glVertex2f( 0.0, 0.7); 16332001f49Smrg glEnd(); 16432001f49Smrg 16532001f49Smrg CheckError(); 16632001f49Smrg 16732001f49Smrg /* copy fbo to window */ 16832001f49Smrg glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, MyFB); 16932001f49Smrg glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); 17032001f49Smrg glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); 17132001f49Smrg glDrawBuffer(GL_BACK); 17232001f49Smrg 17332001f49Smrg if (UseCopyPix) { 17432001f49Smrg glWindowPos2i(0, 0); 17532001f49Smrg glCopyPixels(0, 0, Width, Height, GL_COLOR); 17632001f49Smrg } 17732001f49Smrg else { 17832001f49Smrg GLubyte *buffer = malloc(Width * Height * 4); 17932001f49Smrg 18032001f49Smrg /* read from user framebuffer */ 18132001f49Smrg glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); 18232001f49Smrg 18332001f49Smrg /* draw to window */ 18432001f49Smrg glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 18532001f49Smrg glWindowPos2iARB(0, 0); 18632001f49Smrg glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); 18732001f49Smrg 18832001f49Smrg free(buffer); 18932001f49Smrg } 19032001f49Smrg 19132001f49Smrg /* Bind normal framebuffer */ 19232001f49Smrg glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 19332001f49Smrg 19432001f49Smrg glutSwapBuffers(); 19532001f49Smrg 19632001f49Smrg CheckError(); 19732001f49Smrg} 19832001f49Smrg 19932001f49Smrg 20032001f49Smrgint 20132001f49Smrgmain(int argc, char *argv[]) 20232001f49Smrg{ 20332001f49Smrg int i; 20432001f49Smrg 20532001f49Smrg glutInit(&argc, argv); 20632001f49Smrg glutInitWindowPosition(100, 0); 20732001f49Smrg glutInitWindowSize(Width, Height); 20832001f49Smrg glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 20932001f49Smrg 21032001f49Smrg for (i = 1; i < argc; i++) { 21132001f49Smrg if (strcmp(argv[i], "-t") == 0) 21232001f49Smrg UseTex = GL_TRUE; 21332001f49Smrg else if (strcmp(argv[i], "-c") == 0) 21432001f49Smrg UseCopyPix = GL_TRUE; 21532001f49Smrg } 21632001f49Smrg 21732001f49Smrg if (UseTex) 21832001f49Smrg printf("Using render to texture\n"); 21932001f49Smrg else 22032001f49Smrg printf("Using user-created render buffer\n"); 22132001f49Smrg 22232001f49Smrg if (!glutCreateWindow(argv[0])) { 22332001f49Smrg exit(1); 22432001f49Smrg } 22532001f49Smrg 22632001f49Smrg glewInit(); 22732001f49Smrg Init(); 22832001f49Smrg glutReshapeFunc(Reshape); 22932001f49Smrg glutKeyboardFunc(Key); 23032001f49Smrg glutDisplayFunc(Draw); 23132001f49Smrg glutMainLoop(); 23232001f49Smrg return 0; 23332001f49Smrg} 234