1/* Framebuffer object test */ 2 3 4#include <GL/glew.h> 5#include "glut_wrap.h" 6#include <assert.h> 7#include <stdio.h> 8#include <stdlib.h> 9 10/* For debug */ 11 12 13static int Win = 0; 14static int Width = 512, Height = 512; 15 16static GLenum TexTarget = GL_TEXTURE_2D; 17static int TexWidth = 512, TexHeight = 512; 18 19static GLuint MyFB; 20static GLuint TexObj; 21static GLboolean Anim = GL_FALSE; 22static GLfloat Rot = 0.0; 23static GLuint TextureLevel = 4; /* which texture level to render to */ 24static GLenum TexIntFormat = GL_RGB; /* either GL_RGB or GL_RGBA */ 25 26 27static void 28CheckError(int line) 29{ 30 GLenum err = glGetError(); 31 if (err) { 32 printf("GL Error 0x%x at line %d\n", (int) err, line); 33 } 34} 35 36 37static void 38Idle(void) 39{ 40 Rot = glutGet(GLUT_ELAPSED_TIME) * 0.1; 41 glutPostRedisplay(); 42} 43 44 45static void 46RenderTexture(void) 47{ 48 GLenum status; 49 50 glMatrixMode(GL_PROJECTION); 51 glLoadIdentity(); 52 glOrtho(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); 53 glMatrixMode(GL_MODELVIEW); 54 glLoadIdentity(); 55 glTranslatef(0.0, 0.0, -15.0); 56 57 if (1) { 58 /* draw to texture image */ 59 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); 60 61 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 62 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { 63 printf("Framebuffer incomplete!!!\n"); 64 } 65 66 glViewport(0, 0, 67 TexWidth / (1 << TextureLevel), 68 TexHeight / (1 << TextureLevel)); 69 glClearColor(0.5, 0.5, 1.0, 0.0); 70 glClear(GL_COLOR_BUFFER_BIT); 71 72 CheckError(__LINE__); 73 74 glBegin(GL_POLYGON); 75 glColor3f(1, 0, 0); 76 glVertex2f(-1, -1); 77 glColor3f(0, 1, 0); 78 glVertex2f(1, -1); 79 glColor3f(0, 0, 1); 80 glVertex2f(0, 1); 81 glEnd(); 82 83 /* Bind normal framebuffer */ 84 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 85 } 86 else { 87 } 88 89 CheckError(__LINE__); 90} 91 92 93 94static void 95Display(void) 96{ 97 float ar = (float) Width / (float) Height; 98 99 RenderTexture(); 100 101 /* draw textured quad in the window */ 102 glMatrixMode(GL_PROJECTION); 103 glLoadIdentity(); 104 glFrustum(-ar, ar, -1.0, 1.0, 5.0, 25.0); 105 glMatrixMode(GL_MODELVIEW); 106 glLoadIdentity(); 107 glTranslatef(0.0, 0.0, -7.0); 108 109 glViewport(0, 0, Width, Height); 110 111 glClearColor(0.25, 0.25, 0.25, 0); 112 glClear(GL_COLOR_BUFFER_BIT); 113 114 glPushMatrix(); 115 glRotatef(Rot, 0, 1, 0); 116 glEnable(TexTarget); 117 glBindTexture(TexTarget, TexObj); 118 119 { 120 glBegin(GL_POLYGON); 121 glColor3f(0.25, 0.25, 0.25); 122 glTexCoord2f(0, 0); 123 glVertex2f(-1, -1); 124 glTexCoord2f(1, 0); 125 glVertex2f(1, -1); 126 glColor3f(1.0, 1.0, 1.0); 127 glTexCoord2f(1, 1); 128 glVertex2f(1, 1); 129 glTexCoord2f(0, 1); 130 glVertex2f(-1, 1); 131 glEnd(); 132 } 133 134 glPopMatrix(); 135 glDisable(TexTarget); 136 137 glutSwapBuffers(); 138 CheckError(__LINE__); 139} 140 141 142static void 143Reshape(int width, int height) 144{ 145 glViewport(0, 0, width, height); 146 Width = width; 147 Height = height; 148} 149 150 151static void 152CleanUp(void) 153{ 154 glDeleteFramebuffersEXT(1, &MyFB); 155 156 glDeleteTextures(1, &TexObj); 157 158 glutDestroyWindow(Win); 159 160 exit(0); 161} 162 163 164static void 165Key(unsigned char key, int x, int y) 166{ 167 (void) x; 168 (void) y; 169 switch (key) { 170 case 'a': 171 Anim = !Anim; 172 if (Anim) 173 glutIdleFunc(Idle); 174 else 175 glutIdleFunc(NULL); 176 break; 177 case 's': 178 Rot += 2.0; 179 break; 180 case 27: 181 CleanUp(); 182 break; 183 } 184 glutPostRedisplay(); 185} 186 187 188static void 189Init(int argc, char *argv[]) 190{ 191 if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { 192 printf("GL_EXT_framebuffer_object not found!\n"); 193 exit(0); 194 } 195 196 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 197 198 199 /* Make texture object/image */ 200 glGenTextures(1, &TexObj); 201 glBindTexture(TexTarget, TexObj); 202 glTexParameteri(TexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 203 glTexParameteri(TexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 204 glTexParameteri(TexTarget, GL_TEXTURE_BASE_LEVEL, TextureLevel); 205 glTexParameteri(TexTarget, GL_TEXTURE_MAX_LEVEL, TextureLevel); 206 207 glTexImage2D(TexTarget, 0, TexIntFormat, TexWidth, TexHeight, 0, 208 GL_RGBA, GL_UNSIGNED_BYTE, NULL); 209 glTexImage2D(TexTarget, TextureLevel, TexIntFormat, 210 TexWidth / (1 << TextureLevel), TexHeight / (1 << TextureLevel), 0, 211 GL_RGBA, GL_UNSIGNED_BYTE, NULL); 212 213 214 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 215 216 217 218 219 /* gen framebuffer id, delete it, do some assertions, just for testing */ 220 glGenFramebuffersEXT(1, &MyFB); 221 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); 222 assert(glIsFramebufferEXT(MyFB)); 223 224 225 CheckError(__LINE__); 226 227 /* Render color to texture */ 228 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 229 TexTarget, TexObj, TextureLevel); 230 231 232 233 CheckError(__LINE__); 234 235 /* bind regular framebuffer */ 236 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 237 238 239} 240 241 242int 243main(int argc, char *argv[]) 244{ 245 glutInit(&argc, argv); 246 glutInitWindowPosition(0, 0); 247 glutInitWindowSize(Width, Height); 248 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 249 Win = glutCreateWindow(argv[0]); 250 glewInit(); 251 glutReshapeFunc(Reshape); 252 glutKeyboardFunc(Key); 253 glutDisplayFunc(Display); 254 if (Anim) 255 glutIdleFunc(Idle); 256 Init(argc, argv); 257 glutMainLoop(); 258 return 0; 259} 260