blob: 1f7c45fc794d04d815f2a23cb92746a6f78e6967 [file] [log] [blame]
Brian Paule4b23562005-05-04 20:11:35 +00001/*
2 * Test GL_EXT_framebuffer_object render-to-texture
3 *
4 * Draw a teapot into a texture image with stenciling.
5 * Then draw a textured quad using that texture.
6 *
7 * Brian Paul
8 * 18 Apr 2005
9 */
10
11
12#define GL_GLEXT_PROTOTYPES
Brian Paul32fe2332005-11-16 14:48:11 +000013#include <GL/glut.h>
Brian Paule4b23562005-05-04 20:11:35 +000014#include <assert.h>
15#include <stdio.h>
16#include <stdlib.h>
Brian Paul32fe2332005-11-16 14:48:11 +000017#include <string.h>
Brian Paule4b23562005-05-04 20:11:35 +000018#include <math.h>
Brian Paul32fe2332005-11-16 14:48:11 +000019
Brian Paul64945412006-03-24 23:17:06 +000020/* For debug */
21#define DEPTH 1
22#define STENCIL 1
23#define DRAW 1
24
Brian Paule4b23562005-05-04 20:11:35 +000025
Brian2282d812007-03-06 16:33:00 -070026static int Win = 0;
Brian Paule4b23562005-05-04 20:11:35 +000027static int Width = 400, Height = 400;
Brian Paul64945412006-03-24 23:17:06 +000028
29static GLenum TexTarget = GL_TEXTURE_2D; /*GL_TEXTURE_RECTANGLE_ARB;*/
Brian Paule4b23562005-05-04 20:11:35 +000030static int TexWidth = 512, TexHeight = 512;
Brian Paul64945412006-03-24 23:17:06 +000031/*static int TexWidth = 600, TexHeight = 600;*/
32
Brian Paule4b23562005-05-04 20:11:35 +000033static GLuint MyFB;
34static GLuint TexObj;
Brian Paul0906f472009-01-22 15:25:10 -070035static GLuint DepthRB = 0, StencilRB = 0;
Brian Paule4b23562005-05-04 20:11:35 +000036static GLboolean Anim = GL_FALSE;
37static GLfloat Rot = 0.0;
Brian Paul32fe2332005-11-16 14:48:11 +000038static GLboolean UsePackedDepthStencil = GL_FALSE;
Brian Paul0906f472009-01-22 15:25:10 -070039static GLboolean UsePackedDepthStencilBoth = GL_FALSE;
40static GLboolean Use_ARB_fbo = GL_FALSE;
41static GLuint TextureLevel = 0; /* which texture level to render to */
Brian Paul64945412006-03-24 23:17:06 +000042static GLenum TexIntFormat = GL_RGB; /* either GL_RGB or GL_RGBA */
Briandf198d22007-12-04 10:48:05 -070043static GLboolean Cull = GL_FALSE;
44static GLboolean Wireframe = GL_FALSE;
Brian Paule4b23562005-05-04 20:11:35 +000045
46
47static void
48CheckError(int line)
49{
50 GLenum err = glGetError();
51 if (err) {
52 printf("GL Error 0x%x at line %d\n", (int) err, line);
53 }
54}
55
56
57static void
58Idle(void)
59{
Brian Paul64945412006-03-24 23:17:06 +000060 Rot = glutGet(GLUT_ELAPSED_TIME) * 0.1;
Brian Paule4b23562005-05-04 20:11:35 +000061 glutPostRedisplay();
62}
63
64
65static void
66RenderTexture(void)
67{
Brian Paule4b23562005-05-04 20:11:35 +000068 GLenum status;
69
70 glMatrixMode(GL_PROJECTION);
71 glLoadIdentity();
72 glOrtho(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
73 glMatrixMode(GL_MODELVIEW);
74 glLoadIdentity();
75 glTranslatef(0.0, 0.0, -15.0);
76
Brian Paul7edf1e82005-10-04 15:16:27 +000077 /* draw to texture image */
Brian Paule4b23562005-05-04 20:11:35 +000078 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
Brian Paule4b23562005-05-04 20:11:35 +000079
80 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
81 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
82 printf("Framebuffer incomplete!!!\n");
83 }
84
85 glViewport(0, 0, TexWidth, TexHeight);
86
87 glClearColor(0.5, 0.5, 1.0, 0.0);
88 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
Brian Paul32fe2332005-11-16 14:48:11 +000089 CheckError(__LINE__);
Brian Paule4b23562005-05-04 20:11:35 +000090
Brian Paul64945412006-03-24 23:17:06 +000091#if DEPTH
Brian Paule4b23562005-05-04 20:11:35 +000092 glEnable(GL_DEPTH_TEST);
Brian Paul64945412006-03-24 23:17:06 +000093#endif
94
95#if STENCIL
Brian Paule4b23562005-05-04 20:11:35 +000096 glEnable(GL_STENCIL_TEST);
97 glStencilFunc(GL_NEVER, 1, ~0);
98 glStencilOp(GL_REPLACE, GL_KEEP, GL_REPLACE);
Brian Paul64945412006-03-24 23:17:06 +000099#endif
Brian Paule4b23562005-05-04 20:11:35 +0000100
Brian Paul32fe2332005-11-16 14:48:11 +0000101 CheckError(__LINE__);
102
Brian Paul64945412006-03-24 23:17:06 +0000103#if DEPTH || STENCIL
Brian Paule4b23562005-05-04 20:11:35 +0000104 /* draw diamond-shaped stencil pattern */
105 glColor3f(0, 1, 0);
106 glBegin(GL_POLYGON);
107 glVertex2f(-0.2, 0.0);
108 glVertex2f( 0.0, -0.2);
109 glVertex2f( 0.2, 0.0);
110 glVertex2f( 0.0, 0.2);
111 glEnd();
Brian Paul64945412006-03-24 23:17:06 +0000112#endif
Brian Paule4b23562005-05-04 20:11:35 +0000113
114 /* draw teapot where stencil != 1 */
Brian Paul64945412006-03-24 23:17:06 +0000115#if STENCIL
Brian Paule4b23562005-05-04 20:11:35 +0000116 glStencilFunc(GL_NOTEQUAL, 1, ~0);
117 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
Brian Paul64945412006-03-24 23:17:06 +0000118#endif
Brian Paule4b23562005-05-04 20:11:35 +0000119
Brian Paul32fe2332005-11-16 14:48:11 +0000120 CheckError(__LINE__);
121
Briandf198d22007-12-04 10:48:05 -0700122 if (Wireframe) {
123 glPolygonMode(GL_FRONT, GL_LINE);
124 }
125 else {
126 glPolygonMode(GL_FRONT, GL_FILL);
127 }
128
129 if (Cull) {
130 /* cull back */
131 glCullFace(GL_BACK);
132 glEnable(GL_CULL_FACE);
133 }
134 else {
135 glDisable(GL_CULL_FACE);
136 }
137
Brian Paule4b23562005-05-04 20:11:35 +0000138#if 0
139 glBegin(GL_POLYGON);
140 glColor3f(1, 0, 0);
141 glVertex2f(-1, -1);
142 glColor3f(0, 1, 0);
143 glVertex2f(1, -1);
144 glColor3f(0, 0, 1);
145 glVertex2f(0, 1);
146 glEnd();
147#else
148 glEnable(GL_LIGHTING);
149 glEnable(GL_LIGHT0);
150 glPushMatrix();
151 glRotatef(0.5 * Rot, 1.0, 0.0, 0.0);
Briandf198d22007-12-04 10:48:05 -0700152 glFrontFace(GL_CW); /* Teapot patches backward */
Brian Paule4b23562005-05-04 20:11:35 +0000153 glutSolidTeapot(0.5);
Briandf198d22007-12-04 10:48:05 -0700154 glFrontFace(GL_CCW);
Brian Paule4b23562005-05-04 20:11:35 +0000155 glPopMatrix();
156 glDisable(GL_LIGHTING);
Brian Paul64945412006-03-24 23:17:06 +0000157 /*
158 PrintStencilHistogram(TexWidth, TexHeight);
159 */
Brian Paule4b23562005-05-04 20:11:35 +0000160#endif
Brian Paul64945412006-03-24 23:17:06 +0000161
Brian Paule4b23562005-05-04 20:11:35 +0000162 glDisable(GL_DEPTH_TEST);
163 glDisable(GL_STENCIL_TEST);
Briandf198d22007-12-04 10:48:05 -0700164 glDisable(GL_CULL_FACE);
165 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
Brian Paule4b23562005-05-04 20:11:35 +0000166
Brian Paul64945412006-03-24 23:17:06 +0000167#if DRAW
Brian Paule4b23562005-05-04 20:11:35 +0000168 /* Bind normal framebuffer */
169 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
Brian Paul64945412006-03-24 23:17:06 +0000170#endif
Brian Paule4b23562005-05-04 20:11:35 +0000171
172 CheckError(__LINE__);
173}
174
175
176
177static void
178Display(void)
179{
180 float ar = (float) Width / (float) Height;
181
182 RenderTexture();
183
184 /* draw textured quad in the window */
Brian Paul64945412006-03-24 23:17:06 +0000185#if DRAW
Brian Paule4b23562005-05-04 20:11:35 +0000186 glMatrixMode(GL_PROJECTION);
187 glLoadIdentity();
188 glFrustum(-ar, ar, -1.0, 1.0, 5.0, 25.0);
189 glMatrixMode(GL_MODELVIEW);
190 glLoadIdentity();
191 glTranslatef(0.0, 0.0, -7.0);
192
193 glViewport(0, 0, Width, Height);
194
195 glClearColor(0.25, 0.25, 0.25, 0);
196 glClear(GL_COLOR_BUFFER_BIT);
197
198 glPushMatrix();
199 glRotatef(Rot, 0, 1, 0);
Brian Paul64945412006-03-24 23:17:06 +0000200 glEnable(TexTarget);
201 glBindTexture(TexTarget, TexObj);
Brian Paule4b23562005-05-04 20:11:35 +0000202 glBegin(GL_POLYGON);
203 glColor3f(0.25, 0.25, 0.25);
Brian Paul64945412006-03-24 23:17:06 +0000204 if (TexTarget == GL_TEXTURE_2D) {
205 glTexCoord2f(0, 0);
206 glVertex2f(-1, -1);
207 glTexCoord2f(1, 0);
208 glVertex2f(1, -1);
209 glColor3f(1.0, 1.0, 1.0);
210 glTexCoord2f(1, 1);
211 glVertex2f(1, 1);
212 glTexCoord2f(0, 1);
213 glVertex2f(-1, 1);
214 }
215 else {
216 assert(TexTarget == GL_TEXTURE_RECTANGLE_ARB);
217 glTexCoord2f(0, 0);
218 glVertex2f(-1, -1);
219 glTexCoord2f(TexWidth, 0);
220 glVertex2f(1, -1);
221 glColor3f(1.0, 1.0, 1.0);
222 glTexCoord2f(TexWidth, TexHeight);
223 glVertex2f(1, 1);
224 glTexCoord2f(0, TexHeight);
225 glVertex2f(-1, 1);
226 }
Brian Paule4b23562005-05-04 20:11:35 +0000227 glEnd();
228 glPopMatrix();
Brian Paul64945412006-03-24 23:17:06 +0000229 glDisable(TexTarget);
230#endif
231
Brian Paule4b23562005-05-04 20:11:35 +0000232 glutSwapBuffers();
233 CheckError(__LINE__);
234}
235
236
237static void
238Reshape(int width, int height)
239{
240 glViewport(0, 0, width, height);
241 Width = width;
242 Height = height;
243}
244
245
246static void
Brian Paul32fe2332005-11-16 14:48:11 +0000247CleanUp(void)
248{
Brian Paul64945412006-03-24 23:17:06 +0000249#if DEPTH
Brian Paul32fe2332005-11-16 14:48:11 +0000250 glDeleteRenderbuffersEXT(1, &DepthRB);
Brian Paul64945412006-03-24 23:17:06 +0000251#endif
252#if STENCIL
Brian Paul0906f472009-01-22 15:25:10 -0700253 glDeleteRenderbuffersEXT(1, &StencilRB);
Brian Paul64945412006-03-24 23:17:06 +0000254#endif
Brian Paul32fe2332005-11-16 14:48:11 +0000255 glDeleteFramebuffersEXT(1, &MyFB);
256
257 glDeleteTextures(1, &TexObj);
258
Brian2282d812007-03-06 16:33:00 -0700259 glutDestroyWindow(Win);
260
Brian Paul32fe2332005-11-16 14:48:11 +0000261 exit(0);
262}
263
264
265static void
Brian Paule4b23562005-05-04 20:11:35 +0000266Key(unsigned char key, int x, int y)
267{
268 (void) x;
269 (void) y;
270 switch (key) {
Briandf198d22007-12-04 10:48:05 -0700271 case 'a':
272 Anim = !Anim;
273 if (Anim)
274 glutIdleFunc(Idle);
275 else
276 glutIdleFunc(NULL);
277 break;
278 case 'c':
279 Cull = !Cull;
280 break;
281 case 'w':
282 Wireframe = !Wireframe;
283 break;
284 case 's':
285 Rot += 2.0;
286 break;
287 case 'S':
288 Rot -= 2.0;
289 break;
290 case 27:
291 CleanUp();
292 break;
Brian Paule4b23562005-05-04 20:11:35 +0000293 }
294 glutPostRedisplay();
295}
296
297
Brian Paul0906f472009-01-22 15:25:10 -0700298/**
299 * Attach depth and stencil renderbuffer(s) to the given framebuffer object.
300 * \param tryDepthStencil if true, try to use a combined depth+stencil buffer
301 * \param bindDepthStencil if true, and tryDepthStencil is true, bind with
302 * the GL_DEPTH_STENCIL_ATTACHMENT target.
303 * \return GL_TRUE for success, GL_FALSE for failure
304 */
305static GLboolean
306AttachDepthAndStencilBuffers(GLuint fbo,
307 GLsizei width, GLsizei height,
308 GLboolean tryDepthStencil,
309 GLboolean bindDepthStencil,
310 GLuint *depthRbOut, GLuint *stencilRbOut)
Briandf198d22007-12-04 10:48:05 -0700311{
Brian Paul0906f472009-01-22 15:25:10 -0700312 GLenum status;
313
314 *depthRbOut = *stencilRbOut = 0;
315
316 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
317
318 if (tryDepthStencil) {
319 GLuint rb;
320
321 glGenRenderbuffersEXT(1, &rb);
322 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb);
323 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
324 GL_DEPTH24_STENCIL8_EXT,
325 width, height);
326 if (glGetError())
327 return GL_FALSE;
328
329 if (bindDepthStencil) {
330 /* attach to both depth and stencil at once */
331 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
332 GL_DEPTH_STENCIL_ATTACHMENT,
333 GL_RENDERBUFFER_EXT, rb);
334 if (glGetError())
335 return GL_FALSE;
336 }
337 else {
338 /* attach to depth attachment point */
339 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
340 GL_DEPTH_ATTACHMENT_EXT,
341 GL_RENDERBUFFER_EXT, rb);
342 if (glGetError())
343 return GL_FALSE;
344
345 /* and attach to stencil attachment point */
346 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
347 GL_STENCIL_ATTACHMENT_EXT,
348 GL_RENDERBUFFER_EXT, rb);
349 if (glGetError())
350 return GL_FALSE;
351 }
352
353 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
354 if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
355 return GL_FALSE;
356
357 *depthRbOut = *stencilRbOut = rb;
358 return GL_TRUE;
359 }
360
361 /* just depth renderbuffer */
362 {
363 GLuint rb;
364
365 glGenRenderbuffersEXT(1, &rb);
366 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb);
367 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
368 GL_DEPTH_COMPONENT,
369 width, height);
370 if (glGetError())
371 return GL_FALSE;
372
373 /* attach to depth attachment point */
374 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
375 GL_DEPTH_ATTACHMENT_EXT,
376 GL_RENDERBUFFER_EXT, rb);
377 if (glGetError())
378 return GL_FALSE;
379
380 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
381 if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
382 return GL_FALSE;
383
384 *depthRbOut = rb;
385 }
386
387 /* just stencil renderbuffer */
388 {
389 GLuint rb;
390
391 glGenRenderbuffersEXT(1, &rb);
392 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb);
393 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
394 GL_STENCIL_INDEX,
395 width, height);
396 if (glGetError())
397 return GL_FALSE;
398
399 /* attach to depth attachment point */
400 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
401 GL_STENCIL_ATTACHMENT_EXT,
402 GL_RENDERBUFFER_EXT, rb);
403 if (glGetError())
404 return GL_FALSE;
405
406 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
407 if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
408 return GL_FALSE;
409
410 *stencilRbOut = rb;
411 }
412
413 return GL_TRUE;
Briandf198d22007-12-04 10:48:05 -0700414}
415
416
417static void
Brian Paul0906f472009-01-22 15:25:10 -0700418ParseArgs(int argc, char *argv[])
Brian Paule4b23562005-05-04 20:11:35 +0000419{
420 GLint i;
Brian Paul0906f472009-01-22 15:25:10 -0700421 for (i = 1; i < argc; i++) {
422 if (strcmp(argv[i], "-ds") == 0) {
423 if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) {
424 printf("GL_EXT_packed_depth_stencil not found!\n");
425 exit(0);
426 }
427 UsePackedDepthStencil = GL_TRUE;
428 printf("Using GL_EXT_packed_depth_stencil\n");
429 }
430 else if (strcmp(argv[i], "-ds2") == 0) {
431 if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) {
432 printf("GL_EXT_packed_depth_stencil not found!\n");
433 exit(0);
434 }
435 if (!glutExtensionSupported("GL_ARB_framebuffer_object")) {
436 printf("GL_ARB_framebuffer_object not found!\n");
437 exit(0);
438 }
439 UsePackedDepthStencilBoth = GL_TRUE;
440 printf("Using GL_EXT_packed_depth_stencil and GL_DEPTH_STENCIL attachment point\n");
441 }
442 else if (strcmp(argv[i], "-arb") == 0) {
443 if (!glutExtensionSupported("GL_ARB_framebuffer_object")) {
444 printf("Sorry, GL_ARB_framebuffer object not supported!\n");
445 }
446 else {
447 Use_ARB_fbo = GL_TRUE;
448 }
449 }
450 else {
451 printf("Unknown option: %s\n", argv[i]);
452 }
453 }
454}
Brian Paule4b23562005-05-04 20:11:35 +0000455
Brian Paul0906f472009-01-22 15:25:10 -0700456
457/*
458 * Make FBO to render into given texture.
459 */
460static GLuint
461MakeFBO_RenderTexture(GLuint TexObj)
462{
463 GLuint fb;
464 GLint sizeFudge = 0;
465
466 glGenFramebuffersEXT(1, &fb);
467 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
468 /* Render color to texture */
469 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
470 TexTarget, TexObj, TextureLevel);
471
472 if (Use_ARB_fbo) {
473 /* use a smaller depth buffer to see what happens */
474 sizeFudge = 90;
475 }
476
477 /* Setup depth and stencil buffers */
478 {
479 GLboolean b;
480 b = AttachDepthAndStencilBuffers(fb,
481 TexWidth - sizeFudge,
482 TexHeight - sizeFudge,
483 UsePackedDepthStencil,
484 UsePackedDepthStencilBoth,
485 &DepthRB, &StencilRB);
486 if (!b) {
487 /* try !UsePackedDepthStencil */
488 b = AttachDepthAndStencilBuffers(fb,
489 TexWidth - sizeFudge,
490 TexHeight - sizeFudge,
491 !UsePackedDepthStencil,
492 UsePackedDepthStencilBoth,
493 &DepthRB, &StencilRB);
494 }
495 if (!b) {
496 printf("Unable to create/attach depth and stencil renderbuffers "
497 " to FBO!\n");
498 exit(1);
499 }
500 }
501
502 /* queries */
503 {
504 GLint bits, w, h;
505
506 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRB);
507 glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT,
508 GL_RENDERBUFFER_WIDTH_EXT, &w);
509 glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT,
510 GL_RENDERBUFFER_HEIGHT_EXT, &h);
511 printf("Color/Texture size: %d x %d\n", TexWidth, TexHeight);
512 printf("Depth buffer size: %d x %d\n", w, h);
513
514 glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT,
515 GL_RENDERBUFFER_DEPTH_SIZE_EXT, &bits);
516 printf("Depth renderbuffer size = %d bits\n", bits);
517
518 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilRB);
519 glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT,
520 GL_RENDERBUFFER_STENCIL_SIZE_EXT, &bits);
521 printf("Stencil renderbuffer size = %d bits\n", bits);
522 }
523
524 /* bind the regular framebuffer */
525 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
526
527 return fb;
528}
529
530
531static void
532Init(void)
533{
Brian Paule4b23562005-05-04 20:11:35 +0000534 if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
535 printf("GL_EXT_framebuffer_object not found!\n");
536 exit(0);
537 }
Brian Paul32fe2332005-11-16 14:48:11 +0000538
Brian Paule4b23562005-05-04 20:11:35 +0000539 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
540
Brian Paul64945412006-03-24 23:17:06 +0000541 /* lighting */
Brian Paul0906f472009-01-22 15:25:10 -0700542 {
543 static const GLfloat mat[4] = { 1.0, 0.5, 0.5, 1.0 };
544 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat);
545 }
546
547 /*
548 * Make texture object/image (we'll render into this texture)
549 */
550 {
551 glGenTextures(1, &TexObj);
552 glBindTexture(TexTarget, TexObj);
553
554 /* make two image levels */
555 glTexImage2D(TexTarget, 0, TexIntFormat, TexWidth, TexHeight, 0,
556 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
557 glTexImage2D(TexTarget, 1, TexIntFormat, TexWidth/2, TexHeight/2, 0,
558 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
559 TexWidth = TexWidth >> TextureLevel;
560 TexHeight = TexHeight >> TextureLevel;
561
562 glTexParameteri(TexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
563 glTexParameteri(TexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
564 glTexParameteri(TexTarget, GL_TEXTURE_BASE_LEVEL, TextureLevel);
565 glTexParameteri(TexTarget, GL_TEXTURE_MAX_LEVEL, TextureLevel);
566 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
567 }
568
569 MyFB = MakeFBO_RenderTexture(TexObj);
570}
571
572
573static void
574Usage(void)
575{
576 printf("Usage:\n");
577 printf(" -ds Use combined depth/stencil renderbuffer\n");
578 printf(" -arb Try GL_ARB_framebuffer_object's mismatched buffer sizes\n");
579 printf(" -ds2 Tye GL_ARB_framebuffer_object's GL_DEPTH_STENCIL_ATTACHMENT\n");
580 printf("Keys:\n");
581 printf(" a Toggle animation\n");
582 printf(" s/s Step/rotate\n");
583 printf(" c Toggle back-face culling\n");
584 printf(" w Toggle wireframe mode (front-face only)\n");
585 printf(" Esc Exit\n");
Brian Paule4b23562005-05-04 20:11:35 +0000586}
587
588
589int
590main(int argc, char *argv[])
591{
592 glutInit(&argc, argv);
593 glutInitWindowPosition(0, 0);
594 glutInitWindowSize(Width, Height);
595 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
Brian2282d812007-03-06 16:33:00 -0700596 Win = glutCreateWindow(argv[0]);
Brian Paule4b23562005-05-04 20:11:35 +0000597 glutReshapeFunc(Reshape);
598 glutKeyboardFunc(Key);
599 glutDisplayFunc(Display);
600 if (Anim)
601 glutIdleFunc(Idle);
Brian Paul0906f472009-01-22 15:25:10 -0700602
603 ParseArgs(argc, argv);
604 Init();
Briandf198d22007-12-04 10:48:05 -0700605 Usage();
Brian Paul0906f472009-01-22 15:25:10 -0700606
Brian Paule4b23562005-05-04 20:11:35 +0000607 glutMainLoop();
608 return 0;
609}