WIP - port to Mali EGL
[mesa-demos/mali.git] / src / demos / fbotexture.c
blobae3894fac8bd361270016400a7adf7d5e94400b9
1 /*
2 * Test GL_EXT_framebuffer_object render-to-texture
4 * Draw a teapot into a texture image with stenciling.
5 * Then draw a textured quad using that texture.
7 * Brian Paul
8 * 18 Apr 2005
9 */
12 #include <assert.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <GL/glew.h>
17 #include "glut_wrap.h"
19 /* For debug */
20 #define DEPTH 1
21 #define STENCIL 1
22 #define DRAW 1
25 static PFNGLISRENDERBUFFERPROC glIsRenderbuffer_func = NULL;
26 static PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer_func = NULL;
27 static PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers_func = NULL;
28 static PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers_func = NULL;
29 static PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage_func = NULL;
30 static PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv_func = NULL;
31 static PFNGLISFRAMEBUFFERPROC glIsFramebuffer_func = NULL;
32 static PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer_func = NULL;
33 static PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers_func = NULL;
34 static PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers_func = NULL;
35 static PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus_func = NULL;
36 static PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D_func = NULL;
37 static PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D_func = NULL;
38 static PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D_func = NULL;
39 static PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer_func = NULL;
40 static PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv_func = NULL;
41 static PFNGLGENERATEMIPMAPPROC glGenerateMipmap_func = NULL;
44 static int Win = 0;
45 static int Width = 400, Height = 400;
47 #if 1
48 static GLenum TexTarget = GL_TEXTURE_2D;
49 static int TexWidth = 512, TexHeight = 512;
50 static GLenum TexIntFormat = GL_RGB; /* either GL_RGB or GL_RGBA */
51 #else
52 static GLenum TexTarget = GL_TEXTURE_RECTANGLE_ARB;
53 static int TexWidth = 200, TexHeight = 200;
54 static GLenum TexIntFormat = GL_RGB5; /* either GL_RGB or GL_RGBA */
55 #endif
56 static GLuint TextureLevel = 0; /* which texture level to render to */
58 static GLuint MyFB;
59 static GLuint TexObj;
60 static GLuint DepthRB = 0, StencilRB = 0;
61 static GLboolean Anim = GL_FALSE;
62 static GLfloat Rot = 0.0;
63 static GLboolean UsePackedDepthStencil = GL_FALSE;
64 static GLboolean UsePackedDepthStencilBoth = GL_FALSE;
65 static GLboolean Use_ARB_fbo = GL_FALSE;
66 static GLboolean Cull = GL_FALSE;
67 static GLboolean Wireframe = GL_FALSE;
70 static void
71 CheckError(int line)
73 GLenum err = glGetError();
74 if (err) {
75 printf("GL Error 0x%x at line %d\n", (int) err, line);
80 static void
81 Idle(void)
83 Rot = glutGet(GLUT_ELAPSED_TIME) * 0.1;
84 glutPostRedisplay();
88 static void
89 RenderTexture(void)
91 GLenum status;
93 glMatrixMode(GL_PROJECTION);
94 glLoadIdentity();
95 glOrtho(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
96 glMatrixMode(GL_MODELVIEW);
97 glLoadIdentity();
98 glTranslatef(0.0, 0.0, -15.0);
100 /* draw to texture image */
101 glBindFramebuffer_func(GL_FRAMEBUFFER_EXT, MyFB);
103 status = glCheckFramebufferStatus_func(GL_FRAMEBUFFER_EXT);
104 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
105 printf("Framebuffer incomplete!!!\n");
108 glViewport(0, 0, TexWidth, TexHeight);
110 glClearColor(0.5, 0.5, 1.0, 0.0);
111 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
112 CheckError(__LINE__);
114 #if DEPTH
115 glEnable(GL_DEPTH_TEST);
116 #endif
118 #if STENCIL
119 glEnable(GL_STENCIL_TEST);
120 glStencilFunc(GL_NEVER, 1, ~0);
121 glStencilOp(GL_REPLACE, GL_KEEP, GL_REPLACE);
122 #endif
124 CheckError(__LINE__);
126 #if DEPTH || STENCIL
127 /* draw diamond-shaped stencil pattern */
128 glColor3f(0, 1, 0);
129 glBegin(GL_POLYGON);
130 glVertex2f(-0.2, 0.0);
131 glVertex2f( 0.0, -0.2);
132 glVertex2f( 0.2, 0.0);
133 glVertex2f( 0.0, 0.2);
134 glEnd();
135 #endif
137 /* draw teapot where stencil != 1 */
138 #if STENCIL
139 glStencilFunc(GL_NOTEQUAL, 1, ~0);
140 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
141 #endif
143 CheckError(__LINE__);
145 if (Wireframe) {
146 glPolygonMode(GL_FRONT, GL_LINE);
148 else {
149 glPolygonMode(GL_FRONT, GL_FILL);
152 if (Cull) {
153 /* cull back */
154 glCullFace(GL_BACK);
155 glEnable(GL_CULL_FACE);
157 else {
158 glDisable(GL_CULL_FACE);
161 #if 0
162 glBegin(GL_POLYGON);
163 glColor3f(1, 0, 0);
164 glVertex2f(-1, -1);
165 glColor3f(0, 1, 0);
166 glVertex2f(1, -1);
167 glColor3f(0, 0, 1);
168 glVertex2f(0, 1);
169 glEnd();
170 #else
171 glEnable(GL_LIGHTING);
172 glEnable(GL_LIGHT0);
173 glPushMatrix();
174 glRotatef(0.5 * Rot, 1.0, 0.0, 0.0);
175 glFrontFace(GL_CW); /* Teapot patches backward */
176 glutSolidTeapot(0.5);
177 glFrontFace(GL_CCW);
178 glPopMatrix();
179 glDisable(GL_LIGHTING);
181 PrintStencilHistogram(TexWidth, TexHeight);
183 #endif
185 glDisable(GL_DEPTH_TEST);
186 glDisable(GL_STENCIL_TEST);
187 glDisable(GL_CULL_FACE);
188 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
190 #if DRAW
191 /* Bind normal framebuffer */
192 glBindFramebuffer_func(GL_FRAMEBUFFER_EXT, 0);
193 #endif
195 CheckError(__LINE__);
200 static void
201 Display(void)
203 float ar = (float) Width / (float) Height;
205 RenderTexture();
207 /* draw textured quad in the window */
208 #if DRAW
209 glMatrixMode(GL_PROJECTION);
210 glLoadIdentity();
211 glFrustum(-ar, ar, -1.0, 1.0, 5.0, 25.0);
212 glMatrixMode(GL_MODELVIEW);
213 glLoadIdentity();
214 glTranslatef(0.0, 0.0, -7.0);
216 glViewport(0, 0, Width, Height);
218 glClearColor(0.25, 0.25, 0.25, 0);
219 glClear(GL_COLOR_BUFFER_BIT);
221 glPushMatrix();
222 glRotatef(Rot, 0, 1, 0);
223 glEnable(TexTarget);
224 glBindTexture(TexTarget, TexObj);
225 glBegin(GL_POLYGON);
226 glColor3f(0.25, 0.25, 0.25);
227 if (TexTarget == GL_TEXTURE_2D) {
228 glTexCoord2f(0, 0);
229 glVertex2f(-1, -1);
230 glTexCoord2f(1, 0);
231 glVertex2f(1, -1);
232 glColor3f(1.0, 1.0, 1.0);
233 glTexCoord2f(1, 1);
234 glVertex2f(1, 1);
235 glTexCoord2f(0, 1);
236 glVertex2f(-1, 1);
238 else {
239 assert(TexTarget == GL_TEXTURE_RECTANGLE_ARB);
240 glTexCoord2f(0, 0);
241 glVertex2f(-1, -1);
242 glTexCoord2f(TexWidth, 0);
243 glVertex2f(1, -1);
244 glColor3f(1.0, 1.0, 1.0);
245 glTexCoord2f(TexWidth, TexHeight);
246 glVertex2f(1, 1);
247 glTexCoord2f(0, TexHeight);
248 glVertex2f(-1, 1);
250 glEnd();
251 glPopMatrix();
252 glDisable(TexTarget);
253 #endif
255 glutSwapBuffers();
256 CheckError(__LINE__);
260 static void
261 Reshape(int width, int height)
263 glViewport(0, 0, width, height);
264 Width = width;
265 Height = height;
269 static void
270 CleanUp(void)
272 #if DEPTH
273 glDeleteRenderbuffers_func(1, &DepthRB);
274 #endif
275 #if STENCIL
276 glDeleteRenderbuffers_func(1, &StencilRB);
277 #endif
278 glDeleteFramebuffers_func(1, &MyFB);
280 glDeleteTextures(1, &TexObj);
282 glutDestroyWindow(Win);
284 exit(0);
288 static void
289 Key(unsigned char key, int x, int y)
291 (void) x;
292 (void) y;
293 switch (key) {
294 case 'a':
295 Anim = !Anim;
296 if (Anim)
297 glutIdleFunc(Idle);
298 else
299 glutIdleFunc(NULL);
300 break;
301 case 'c':
302 Cull = !Cull;
303 break;
304 case 'w':
305 Wireframe = !Wireframe;
306 break;
307 case 's':
308 Rot += 2.0;
309 break;
310 case 'S':
311 Rot -= 2.0;
312 break;
313 case 27:
314 CleanUp();
315 break;
317 glutPostRedisplay();
322 * Attach depth and stencil renderbuffer(s) to the given framebuffer object.
323 * \param tryDepthStencil if true, try to use a combined depth+stencil buffer
324 * \param bindDepthStencil if true, and tryDepthStencil is true, bind with
325 * the GL_DEPTH_STENCIL_ATTACHMENT target.
326 * \return GL_TRUE for success, GL_FALSE for failure
328 static GLboolean
329 AttachDepthAndStencilBuffers(GLuint fbo,
330 GLsizei width, GLsizei height,
331 GLboolean tryDepthStencil,
332 GLboolean bindDepthStencil,
333 GLuint *depthRbOut, GLuint *stencilRbOut)
335 GLenum status;
337 *depthRbOut = *stencilRbOut = 0;
339 glBindFramebuffer_func(GL_FRAMEBUFFER_EXT, fbo);
341 if (tryDepthStencil) {
342 GLuint rb;
344 glGenRenderbuffers_func(1, &rb);
345 glBindRenderbuffer_func(GL_RENDERBUFFER_EXT, rb);
346 glRenderbufferStorage_func(GL_RENDERBUFFER_EXT,
347 GL_DEPTH24_STENCIL8_EXT,
348 width, height);
349 if (glGetError())
350 return GL_FALSE;
352 if (bindDepthStencil) {
353 /* attach to both depth and stencil at once */
354 glFramebufferRenderbuffer_func(GL_FRAMEBUFFER_EXT,
355 GL_DEPTH_STENCIL_ATTACHMENT,
356 GL_RENDERBUFFER_EXT, rb);
357 if (glGetError())
358 return GL_FALSE;
360 else {
361 /* attach to depth attachment point */
362 glFramebufferRenderbuffer_func(GL_FRAMEBUFFER_EXT,
363 GL_DEPTH_ATTACHMENT_EXT,
364 GL_RENDERBUFFER_EXT, rb);
365 if (glGetError())
366 return GL_FALSE;
368 /* and attach to stencil attachment point */
369 glFramebufferRenderbuffer_func(GL_FRAMEBUFFER_EXT,
370 GL_STENCIL_ATTACHMENT_EXT,
371 GL_RENDERBUFFER_EXT, rb);
372 if (glGetError())
373 return GL_FALSE;
376 status = glCheckFramebufferStatus_func(GL_FRAMEBUFFER_EXT);
377 if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
378 return GL_FALSE;
380 *depthRbOut = *stencilRbOut = rb;
381 return GL_TRUE;
384 /* just depth renderbuffer */
386 GLuint rb;
388 glGenRenderbuffers_func(1, &rb);
389 glBindRenderbuffer_func(GL_RENDERBUFFER_EXT, rb);
390 glRenderbufferStorage_func(GL_RENDERBUFFER_EXT,
391 GL_DEPTH_COMPONENT,
392 width, height);
393 if (glGetError())
394 return GL_FALSE;
396 /* attach to depth attachment point */
397 glFramebufferRenderbuffer_func(GL_FRAMEBUFFER_EXT,
398 GL_DEPTH_ATTACHMENT_EXT,
399 GL_RENDERBUFFER_EXT, rb);
400 if (glGetError())
401 return GL_FALSE;
403 status = glCheckFramebufferStatus_func(GL_FRAMEBUFFER_EXT);
404 if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
405 return GL_FALSE;
407 *depthRbOut = rb;
410 /* just stencil renderbuffer */
412 GLuint rb;
414 glGenRenderbuffers_func(1, &rb);
415 glBindRenderbuffer_func(GL_RENDERBUFFER_EXT, rb);
416 glRenderbufferStorage_func(GL_RENDERBUFFER_EXT,
417 GL_STENCIL_INDEX,
418 width, height);
419 if (glGetError())
420 return GL_FALSE;
422 /* attach to depth attachment point */
423 glFramebufferRenderbuffer_func(GL_FRAMEBUFFER_EXT,
424 GL_STENCIL_ATTACHMENT_EXT,
425 GL_RENDERBUFFER_EXT, rb);
426 if (glGetError())
427 return GL_FALSE;
429 status = glCheckFramebufferStatus_func(GL_FRAMEBUFFER_EXT);
430 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
431 glDeleteRenderbuffers_func(1, depthRbOut);
432 *depthRbOut = 0;
433 glDeleteRenderbuffers_func(1, &rb);
434 return GL_FALSE;
437 *stencilRbOut = rb;
440 return GL_TRUE;
444 static void
445 ParseArgs(int argc, char *argv[])
447 GLint i;
448 for (i = 1; i < argc; i++) {
449 if (strcmp(argv[i], "-ds") == 0) {
450 if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) {
451 printf("GL_EXT_packed_depth_stencil not found!\n");
452 exit(0);
454 UsePackedDepthStencil = GL_TRUE;
455 printf("Using GL_EXT_packed_depth_stencil\n");
457 else if (strcmp(argv[i], "-ds2") == 0) {
458 if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) {
459 printf("GL_EXT_packed_depth_stencil not found!\n");
460 exit(0);
462 if (!glutExtensionSupported("GL_ARB_framebuffer_object")) {
463 printf("GL_ARB_framebuffer_object not found!\n");
464 exit(0);
466 UsePackedDepthStencil = GL_TRUE;
467 UsePackedDepthStencilBoth = GL_TRUE;
468 printf("Using GL_EXT_packed_depth_stencil and GL_DEPTH_STENCIL attachment point\n");
470 else if (strcmp(argv[i], "-arb") == 0) {
471 if (!glutExtensionSupported("GL_ARB_framebuffer_object")) {
472 printf("Sorry, GL_ARB_framebuffer object not supported!\n");
474 else {
475 Use_ARB_fbo = GL_TRUE;
478 else {
479 printf("Unknown option: %s\n", argv[i]);
485 static void
486 SetupFunctionPointers(void)
488 if (Use_ARB_fbo) {
489 /* use the ARB functions */
490 glIsRenderbuffer_func = glIsRenderbuffer;
491 glBindRenderbuffer_func = glBindRenderbuffer;
492 glDeleteRenderbuffers_func = glDeleteRenderbuffers;
493 glGenRenderbuffers_func = glGenRenderbuffers;
494 glRenderbufferStorage_func = glRenderbufferStorage;
495 glGetRenderbufferParameteriv_func = glGetRenderbufferParameteriv;
496 glIsFramebuffer_func = glIsFramebuffer;
497 glBindFramebuffer_func = glBindFramebuffer;
498 glDeleteFramebuffers_func = glDeleteFramebuffers;
499 glGenFramebuffers_func = glGenFramebuffers;
500 glCheckFramebufferStatus_func = glCheckFramebufferStatus;
501 glFramebufferTexture1D_func = glFramebufferTexture1D;
502 glFramebufferTexture2D_func = glFramebufferTexture2D;
503 glFramebufferTexture3D_func = glFramebufferTexture3D;
504 glFramebufferRenderbuffer_func = glFramebufferRenderbuffer;
505 glGetFramebufferAttachmentParameteriv_func = glGetFramebufferAttachmentParameteriv;
506 glGenerateMipmap_func = glGenerateMipmap;
508 else {
509 /* use the EXT functions */
510 glIsRenderbuffer_func = glIsRenderbufferEXT;
511 glBindRenderbuffer_func = glBindRenderbufferEXT;
512 glDeleteRenderbuffers_func = glDeleteRenderbuffersEXT;
513 glGenRenderbuffers_func = glGenRenderbuffersEXT;
514 glRenderbufferStorage_func = glRenderbufferStorageEXT;
515 glGetRenderbufferParameteriv_func = glGetRenderbufferParameterivEXT;
516 glIsFramebuffer_func = glIsFramebufferEXT;
517 glBindFramebuffer_func = glBindFramebufferEXT;
518 glDeleteFramebuffers_func = glDeleteFramebuffersEXT;
519 glGenFramebuffers_func = glGenFramebuffersEXT;
520 glCheckFramebufferStatus_func = glCheckFramebufferStatusEXT;
521 glFramebufferTexture1D_func = glFramebufferTexture1DEXT;
522 glFramebufferTexture2D_func = glFramebufferTexture2DEXT;
523 glFramebufferTexture3D_func = glFramebufferTexture3DEXT;
524 glFramebufferRenderbuffer_func = glFramebufferRenderbufferEXT;
525 glGetFramebufferAttachmentParameteriv_func = glGetFramebufferAttachmentParameterivEXT;
526 glGenerateMipmap_func = glGenerateMipmapEXT;
532 * Make FBO to render into given texture.
534 static GLuint
535 MakeFBO_RenderTexture(GLuint texObj)
537 GLuint fb;
538 GLint sizeFudge = 0;
540 glGenFramebuffers_func(1, &fb);
541 glBindFramebuffer_func(GL_FRAMEBUFFER_EXT, fb);
542 /* Render color to texture */
543 glFramebufferTexture2D_func(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
544 TexTarget, texObj, TextureLevel);
546 if (Use_ARB_fbo) {
547 /* use a smaller depth buffer to see what happens */
548 sizeFudge = 90;
551 /* Setup depth and stencil buffers */
553 GLboolean b;
554 b = AttachDepthAndStencilBuffers(fb,
555 TexWidth - sizeFudge,
556 TexHeight - sizeFudge,
557 UsePackedDepthStencil,
558 UsePackedDepthStencilBoth,
559 &DepthRB, &StencilRB);
560 if (!b) {
561 /* try !UsePackedDepthStencil */
562 b = AttachDepthAndStencilBuffers(fb,
563 TexWidth - sizeFudge,
564 TexHeight - sizeFudge,
565 !UsePackedDepthStencil,
566 UsePackedDepthStencilBoth,
567 &DepthRB, &StencilRB);
569 if (!b) {
570 printf("Unable to create/attach depth and stencil renderbuffers "
571 " to FBO!\n");
572 exit(1);
576 /* queries */
578 GLint bits, w, h, name;
580 glBindRenderbuffer_func(GL_RENDERBUFFER_EXT, DepthRB);
581 glGetRenderbufferParameteriv_func(GL_RENDERBUFFER_EXT,
582 GL_RENDERBUFFER_WIDTH_EXT, &w);
583 glGetRenderbufferParameteriv_func(GL_RENDERBUFFER_EXT,
584 GL_RENDERBUFFER_HEIGHT_EXT, &h);
585 printf("Color/Texture size: %d x %d\n", TexWidth, TexHeight);
586 printf("Depth buffer size: %d x %d\n", w, h);
588 glGetRenderbufferParameteriv_func(GL_RENDERBUFFER_EXT,
589 GL_RENDERBUFFER_DEPTH_SIZE_EXT, &bits);
590 printf("Depth renderbuffer size = %d bits\n", bits);
592 glBindRenderbuffer_func(GL_RENDERBUFFER_EXT, StencilRB);
593 glGetRenderbufferParameteriv_func(GL_RENDERBUFFER_EXT,
594 GL_RENDERBUFFER_STENCIL_SIZE_EXT, &bits);
595 printf("Stencil renderbuffer size = %d bits\n", bits);
597 glGetFramebufferAttachmentParameteriv_func(GL_FRAMEBUFFER_EXT,
598 GL_COLOR_ATTACHMENT0,
599 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
600 &name);
601 printf("Render to texture name: %d\n", texObj);
602 printf("Color attachment[0] name: %d\n", name);
603 assert(texObj == name);
605 glGetFramebufferAttachmentParameteriv_func(GL_FRAMEBUFFER_EXT,
606 GL_STENCIL_ATTACHMENT,
607 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
608 &name);
609 printf("Stencil attachment name: %d\n", name);
611 glGetFramebufferAttachmentParameteriv_func(GL_FRAMEBUFFER_EXT,
612 GL_DEPTH_ATTACHMENT,
613 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
614 &name);
615 printf("Depth attachment name: %d\n", name);
618 /* bind the regular framebuffer */
619 glBindFramebuffer_func(GL_FRAMEBUFFER_EXT, 0);
621 return fb;
625 static void
626 Init(void)
628 if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
629 printf("GL_EXT_framebuffer_object not found!\n");
630 exit(0);
633 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
635 SetupFunctionPointers();
637 /* lighting */
639 static const GLfloat mat[4] = { 1.0, 0.5, 0.5, 1.0 };
640 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat);
644 * Make texture object/image (we'll render into this texture)
647 glGenTextures(1, &TexObj);
648 glBindTexture(TexTarget, TexObj);
650 /* make two image levels */
651 glTexImage2D(TexTarget, 0, TexIntFormat, TexWidth, TexHeight, 0,
652 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
653 if (TexTarget == GL_TEXTURE_2D) {
654 glTexImage2D(TexTarget, 1, TexIntFormat, TexWidth/2, TexHeight/2, 0,
655 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
656 TexWidth = TexWidth >> TextureLevel;
657 TexHeight = TexHeight >> TextureLevel;
658 glTexParameteri(TexTarget, GL_TEXTURE_MAX_LEVEL, TextureLevel);
661 glTexParameteri(TexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
662 glTexParameteri(TexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
663 glTexParameteri(TexTarget, GL_TEXTURE_BASE_LEVEL, TextureLevel);
664 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
667 MyFB = MakeFBO_RenderTexture(TexObj);
671 static void
672 Usage(void)
674 printf("Usage:\n");
675 printf(" -ds Use combined depth/stencil renderbuffer\n");
676 printf(" -arb Try GL_ARB_framebuffer_object's mismatched buffer sizes\n");
677 printf(" -ds2 Try GL_ARB_framebuffer_object's GL_DEPTH_STENCIL_ATTACHMENT\n");
678 printf("Keys:\n");
679 printf(" a Toggle animation\n");
680 printf(" s/s Step/rotate\n");
681 printf(" c Toggle back-face culling\n");
682 printf(" w Toggle wireframe mode (front-face only)\n");
683 printf(" Esc Exit\n");
688 main(int argc, char *argv[])
690 glutInit(&argc, argv);
691 glutInitWindowPosition(0, 0);
692 glutInitWindowSize(Width, Height);
693 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
694 Win = glutCreateWindow(argv[0]);
695 glutReshapeFunc(Reshape);
696 glutKeyboardFunc(Key);
697 glutDisplayFunc(Display);
698 if (Anim)
699 glutIdleFunc(Idle);
701 ParseArgs(argc, argv);
702 glewInit();
703 Init();
704 Usage();
706 glutMainLoop();
707 return 0;