Add more structure constructor tests.
[piglit/hramrach.git] / tests / glean / tfbo.cpp
blob5f81d43cd0d4570f7192cb1ab0344ff5b28e7961
1 // BEGIN_COPYRIGHT -*- glean -*-
2 //
3 // Copyrigth (C) 2007 Intel Corporation
4 // Copyright (C) 1999 Allen Akin All Rights Reserved.
5 //
6 // Permission is hereby granted, free of charge, to any person
7 // obtaining a copy of this software and associated documentation
8 // files (the "Software"), to deal in the Software without
9 // restriction, including without limitation the rights to use,
10 // copy, modify, merge, publish, distribute, sublicense, and/or
11 // sell copies of the Software, and to permit persons to whom the
12 // Software is furnished to do so, subject to the following
13 // conditions:
14 //
15 // The above copyright notice and this permission notice shall be
16 // included in all copies or substantial portions of the
17 // Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
20 // KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
21 // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
22 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ALLEN AKIN BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
24 // AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
25 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 // DEALINGS IN THE SOFTWARE.
27 //
28 // END_COPYRIGHT
30 // Authors:
31 // Shuang He <shuang.he@intel.com>
33 // tfbo.cpp: Test OpenGL Extension GL_EXT_framebuffer_object
36 #define GL_GLEXT_PROTOTYPES
38 #include "tfbo.h"
39 #include <cassert>
40 #include <math.h>
41 #include <cstring>
42 #include "timer.h"
44 namespace GLEAN
47 // GL_VERSION_1_2
48 static PFNGLTEXIMAGE3DPROC glTexImage3D_func = NULL;
49 static PFNGLCOPYTEXSUBIMAGE3DPROC glCopyTexSubImage3D_func = NULL;
51 // GL_VERSION_1_3
52 static PFNGLACTIVETEXTUREPROC glActiveTexture_func = NULL;
53 static PFNGLMULTITEXCOORD2FPROC glMultiTexCoord2f_func = NULL;
55 // GL_EXT_framebuffer_object
56 static PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT_func = NULL;
57 static PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT_func = NULL;
58 static PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT_func = NULL;
59 static PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT_func = NULL;
60 static PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT_func = NULL;
61 static PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glGetRenderbufferParameterivEXT_func = NULL;
62 static PFNGLISFRAMEBUFFEREXTPROC glIsFramebufferEXT_func = NULL;
63 static PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT_func = NULL;
64 static PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT_func = NULL;
65 static PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT_func = NULL;
66 static PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT_func = NULL;
67 static PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glFramebufferTexture1DEXT_func = NULL;
68 static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT_func = NULL;
69 static PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT_func = NULL;
70 static PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT_func = NULL;
71 static PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT_func = NULL;
73 static int useFramebuffer;
75 bool
76 FBOTest::setup(void)
78 // setup vertex transform (we'll draw a quad in middle of window)
79 glMatrixMode(GL_PROJECTION);
81 glLoadIdentity();
82 gluOrtho2D(0, 100, 0, 100);
83 glMatrixMode(GL_MODELVIEW);
84 glLoadIdentity();
85 glDrawBuffer(GL_FRONT);
86 glReadBuffer(GL_FRONT);
88 glDisable(GL_DITHER);
90 // compute error tolerances (may need fine-tuning)
91 int bufferBits[5];
93 glGetIntegerv(GL_RED_BITS, &bufferBits[0]);
94 glGetIntegerv(GL_GREEN_BITS, &bufferBits[1]);
95 glGetIntegerv(GL_BLUE_BITS, &bufferBits[2]);
96 glGetIntegerv(GL_ALPHA_BITS, &bufferBits[3]);
97 glGetIntegerv(GL_DEPTH_BITS, &bufferBits[4]);
99 tolerance[0] = 3.0 / (1 << bufferBits[0]);
100 tolerance[1] = 3.0 / (1 << bufferBits[1]);
101 tolerance[2] = 3.0 / (1 << bufferBits[2]);
102 if (bufferBits[3])
103 tolerance[3] = 3.0 / (1 << bufferBits[3]);
104 else
105 tolerance[3] = 1.0;
106 if (bufferBits[4])
107 tolerance[4] = 16.0 / (1 << bufferBits[4]);
108 else
109 tolerance[4] = 1.0;
111 // Check if GL_EXT_framebuffer_object is supported
112 if (GLUtils::haveExtension("GL_EXT_framebuffer_object")) {
113 printf("GL_EXT_framebuffer_object is supported\n");
114 useFramebuffer = 1;
116 else {
117 printf("GL_EXT_framebuffer_object is not supported\n");
118 useFramebuffer = 0;
119 return false;
122 haveARBfbo = GLUtils::haveExtension("GL_ARB_framebuffer_object");
123 if (haveARBfbo)
124 printf("GL_ARB_framebuffer_object is supported\n");
125 else
126 printf("GL_ARB_framebuffer_object is not supported\n");
128 glTexImage3D_func = (PFNGLTEXIMAGE3DPROC) GLUtils::getProcAddress("glTexImage3D");
129 assert(glTexImage3D_func);
130 glCopyTexSubImage3D_func = (PFNGLCOPYTEXSUBIMAGE3DPROC) GLUtils::getProcAddress("glCopyTexSubImage3D");
131 assert(glCopyTexSubImage3D_func);
133 glActiveTexture_func = (PFNGLACTIVETEXTUREPROC) GLUtils::getProcAddress("glActiveTexture");
134 assert(glActiveTexture_func);
135 glMultiTexCoord2f_func = (PFNGLMULTITEXCOORD2FPROC) GLUtils::getProcAddress("glMultiTexCoord2f");
136 assert(glMultiTexCoord2f_func);
138 glIsRenderbufferEXT_func = (PFNGLISRENDERBUFFEREXTPROC) GLUtils::getProcAddress("glIsRenderbufferEXT");
139 assert(glIsRenderbufferEXT_func);
140 glBindRenderbufferEXT_func = (PFNGLBINDRENDERBUFFEREXTPROC) GLUtils::getProcAddress("glBindRenderbufferEXT");
141 assert(glBindRenderbufferEXT_func);
142 glDeleteRenderbuffersEXT_func = (PFNGLDELETERENDERBUFFERSEXTPROC) GLUtils::getProcAddress("glDeleteRenderbuffersEXT");
143 assert(glDeleteRenderbuffersEXT_func);
144 glGenRenderbuffersEXT_func = (PFNGLGENRENDERBUFFERSEXTPROC) GLUtils::getProcAddress("glGenRenderbuffersEXT");
145 assert(glGenRenderbuffersEXT_func);
146 glRenderbufferStorageEXT_func = (PFNGLRENDERBUFFERSTORAGEEXTPROC) GLUtils::getProcAddress("glRenderbufferStorageEXT");
147 assert(glRenderbufferStorageEXT_func);
148 glGetRenderbufferParameterivEXT_func = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) GLUtils::getProcAddress("glGetRenderbufferParameterivEXT");
149 assert(glGetRenderbufferParameterivEXT_func);
150 glIsFramebufferEXT_func = (PFNGLISFRAMEBUFFEREXTPROC) GLUtils::getProcAddress("glIsFramebufferEXT");
151 assert(glIsFramebufferEXT_func);
152 glBindFramebufferEXT_func = (PFNGLBINDFRAMEBUFFEREXTPROC) GLUtils::getProcAddress("glBindFramebufferEXT");
153 assert(glBindFramebufferEXT_func);
154 glDeleteFramebuffersEXT_func = (PFNGLDELETEFRAMEBUFFERSEXTPROC) GLUtils::getProcAddress("glDeleteFramebuffersEXT");
155 assert(glDeleteFramebuffersEXT_func);
156 glGenFramebuffersEXT_func = (PFNGLGENFRAMEBUFFERSEXTPROC) GLUtils::getProcAddress("glGenFramebuffersEXT");
157 assert(glGenFramebuffersEXT_func);
158 glCheckFramebufferStatusEXT_func = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) GLUtils::getProcAddress("glCheckFramebufferStatusEXT");
159 assert(glCheckFramebufferStatusEXT_func);
160 glFramebufferTexture1DEXT_func = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) GLUtils::getProcAddress("glFramebufferTexture1DEXT");
161 assert(glFramebufferTexture1DEXT_func);
162 glFramebufferTexture2DEXT_func = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) GLUtils::getProcAddress("glFramebufferTexture2DEXT");
163 assert(glFramebufferTexture2DEXT_func);
164 glFramebufferTexture3DEXT_func = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) GLUtils::getProcAddress("glFramebufferTexture3DEXT");
165 assert(glFramebufferTexture3DEXT_func);
166 glFramebufferRenderbufferEXT_func = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) GLUtils::getProcAddress("glFramebufferRenderbufferEXT");
167 assert(glFramebufferRenderbufferEXT_func);
168 glGetFramebufferAttachmentParameterivEXT_func = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) GLUtils::getProcAddress("glGetFramebufferAttachmentParameterivEXT");
169 assert(glGetFramebufferAttachmentParameterivEXT_func);
171 return true;
175 void
176 FBOTest::reportFailure(const char *msg, const int line) const
178 env->log << "FAILURE: " << msg << " (at tfbo.cpp:" << line
179 << ")\n";
182 void
183 FBOTest::reportFailure(const char *msg, const GLenum target, const int line) const
185 env->log << "FAILURE: " << msg;
186 if (target == GL_FRAGMENT_SHADER)
187 env->log << " (fragment)";
188 else
189 env->log << " (vertex)";
190 env->log << " (at tfbo.cpp:" << line << ")\n";
193 #define REPORT_FAILURE(MSG) reportFailure(MSG, __LINE__)
194 #define REPORT_FAILURE_T(MSG, TARGET) reportFailure(MSG, TARGET, __LINE__)
195 // Compare actual and expected colors
196 bool
197 FBOTest::equalColors(const GLfloat act[3], const GLfloat exp[3]) const
199 if ((fabsf(act[0] - exp[0]) > tolerance[0])
200 || (fabsf(act[1] - exp[1]) > tolerance[1])
201 || (fabsf(act[2] - exp[2]) > tolerance[2])) {
202 return false;
204 else
205 return true;
209 #define TEXSIZE 64
212 |--------------------|
213 |---depth---|
214 |---stencil---|
216 bool
217 FBOTest::checkResult(const GLfloat color[4], const int depth,
218 const int stencil) const
220 GLfloat buf[TEXSIZE * TEXSIZE * 3];
221 int i, j;
222 const GLfloat black[4] = { 0.0, 0.0, 0.0, 0.0 };
223 const GLfloat *exp;
225 glReadPixels(0, 0, TEXSIZE, TEXSIZE, GL_RGB, GL_FLOAT, buf);
227 for (j = 0; j < TEXSIZE; j++) {
228 for (i = 0; i < TEXSIZE; i++) {
229 exp = color;
231 if (i * 4 >= TEXSIZE && i * 8 < TEXSIZE * 5
232 && depth)
233 exp = black;
234 if (i * 2 >= TEXSIZE && i * 8 < TEXSIZE * 7
235 && stencil)
236 exp = black;
239 if (!equalColors(buf + (j * TEXSIZE + i) * 3, exp)) {
240 printf(" depth = %d, stencil = %d\n",
241 depth, stencil);
242 printf(" (%d, %d) = [%f, %f, %f], is expected to be[%f, %f, %f]\n", i, j, buf[(j * TEXSIZE + i) * 3], buf[(j * TEXSIZE + i) * 3 + 1], buf[(j * TEXSIZE + i) * 3 + 2], exp[0], exp[1], exp[2]);
243 return false;
247 return true;
251 // Check FB status, print unexpected results to stdout.
252 static GLenum
253 CheckFramebufferStatus(const char *func, int line)
255 GLenum status;
256 status = glCheckFramebufferStatusEXT_func(GL_FRAMEBUFFER_EXT);
258 switch(status) {
259 case GL_FRAMEBUFFER_COMPLETE_EXT:
260 /*printf(" (%s:%d)GL_FRAMEBUFFER_COMPLETE_EXT\n", func, line);*/
261 break;
262 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
263 printf(" (%s:%d)GL_FRAMEBUFFER_UNSUPPORTED_EXT\n", func, line);
264 /* choose different formats */
265 break;
266 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
267 printf(" (%s:%d)GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\n", func, line);
268 break;
269 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
270 printf(" (%s:%d)GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\n", func, line);
271 break;
272 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
273 printf(" (%s:%d)GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\n", func, line);
274 break;
275 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
276 printf(" (%s:%d)GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n", func, line);
277 break;
278 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
279 printf(" (%s:%d)GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\n", func, line);
280 break;
281 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
282 printf(" (%s:%d)GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\n", func, line);
283 break;
284 default:
285 /* programming error; will fail on all hardware */
286 printf(" (%s:%d)programming error\n", func, line);
287 break;
289 return status;
293 enum
294 { BLACK, RED, GREEN, BLUE, WHITE };
296 GLfloat colors[][4] = {
297 {0.0, 0.0, 0.0, 0.0},
298 {1.0, 0.0, 0.0, 1.0},
299 {0.0, 1.0, 0.0, 1.0},
300 {0.0, 0.0, 1.0, 1.0},
301 {1.0, 1.0, 1.0, 1.0}
306 bool
307 FBOTest::testSanity(void)
309 GLuint fbs[2];
310 GLuint maxColorAttachment;
311 GLuint fb_binding;
313 if (!useFramebuffer)
314 return true;
316 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT,
317 (GLint *) & maxColorAttachment);
318 if (maxColorAttachment < 1) {
319 REPORT_FAILURE
320 ("Failed to get max color attachment points");
321 return false;
325 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, (GLint *) & fb_binding);
326 if (fb_binding != 0) {
327 printf(" fb_binding = %d\n", fb_binding);
328 REPORT_FAILURE
329 ("The default framebuffer binding should be 0");
330 return false;
333 glGenFramebuffersEXT_func(1, fbs);
336 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, fbs[0]);
337 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, (GLint *) & fb_binding);
338 if (fb_binding != fbs[0]) {
339 printf(" fb_binding = %d\n", fb_binding);
340 REPORT_FAILURE("Binding framebuffer failed");
341 return false;
343 if (glIsFramebufferEXT_func(fbs[0]) != GL_TRUE)
345 REPORT_FAILURE("Call glIsFramebufferEXT failed");
346 return false;
349 glDeleteFramebuffersEXT_func(1, fbs);
351 GLint maxRenderbufferSize;
353 glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &maxRenderbufferSize);
354 if (maxRenderbufferSize < 1) {
355 printf(" maxRenderbufferSize = %d\n",
356 maxRenderbufferSize);
357 REPORT_FAILURE("Get max Renderbuffer Size failed");
358 return false;
361 return true;
365 void
366 FBOTest::reset(void)
368 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, 0);
369 glDisable(GL_DEPTH_TEST);
370 glDisable(GL_STENCIL_TEST);
373 GLenum textureModes[] = { GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D,
374 GL_TEXTURE_CUBE_MAP};
376 bool
377 FBOTest::testRender2SingleTexture(void)
379 GLint depthBuffer = 0;
380 GLint stencilBuffer = 0;
381 GLuint fbs[1];
382 GLuint depth_rb[1];
383 GLuint stencil_rb[1];
384 GLuint textures[1];
385 int mode;
386 int maxzoffset = -1;
387 GLenum status;
389 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &maxzoffset);
390 if (maxzoffset > 16)
391 maxzoffset = 16;
393 for (depthBuffer = 0; depthBuffer < 2; depthBuffer++) {
394 for (stencilBuffer = 0; stencilBuffer < 2; stencilBuffer++) {
395 for (mode = 0; mode < 4; mode++) {
398 // Setup state to test
400 if (mode == 2 && maxzoffset <= 0)
401 continue;
403 if (useFramebuffer)
404 glGenFramebuffersEXT_func(1, fbs);
405 glGenTextures(1, textures);
407 glBindTexture(textureModes[mode],
408 textures[0]);
409 glTexParameteri(textureModes[mode],
410 GL_TEXTURE_MIN_FILTER,
411 GL_NEAREST);
412 glTexParameteri(textureModes[mode],
413 GL_TEXTURE_MAG_FILTER,
414 GL_NEAREST);
416 switch (textureModes[mode]) {
417 case GL_TEXTURE_1D:
418 glTexImage1D(GL_TEXTURE_1D,
419 0, GL_RGB,
420 TEXSIZE, 0,
421 GL_RGB, GL_INT, NULL);
422 break;
423 case GL_TEXTURE_2D:
424 glTexImage2D(GL_TEXTURE_2D,
425 0, GL_RGB,
426 TEXSIZE,
427 TEXSIZE, 0,
428 GL_RGB, GL_INT, NULL);
429 break;
430 case GL_TEXTURE_3D:
431 glTexImage3D_func(GL_TEXTURE_3D,
432 0, GL_RGB,
433 TEXSIZE,
434 TEXSIZE,
435 maxzoffset, 0,
436 GL_RGB, GL_INT, NULL);
437 break;
438 case GL_TEXTURE_CUBE_MAP:
439 glTexImage2D
440 (GL_TEXTURE_CUBE_MAP_POSITIVE_X,
441 0, GL_RGB,
442 TEXSIZE, TEXSIZE,
443 0, GL_RGB, GL_INT, NULL);
444 glTexImage2D
445 (GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
446 0, GL_RGB,
447 TEXSIZE, TEXSIZE,
448 0, GL_RGB, GL_INT, NULL);
449 glTexImage2D
450 (GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
451 0, GL_RGB,
452 TEXSIZE, TEXSIZE,
453 0, GL_RGB, GL_INT, NULL);
454 glTexImage2D
455 (GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
456 0, GL_RGB,
457 TEXSIZE, TEXSIZE,
458 0, GL_RGB, GL_INT, NULL);
459 glTexImage2D
460 (GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
461 0, GL_RGB,
462 TEXSIZE, TEXSIZE,
463 0, GL_RGB, GL_INT, NULL);
464 glTexImage2D
465 (GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
466 0, GL_RGB,
467 TEXSIZE, TEXSIZE,
468 0, GL_RGB, GL_INT, NULL);
469 break;
473 if (useFramebuffer) {
474 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, fbs[0]);
475 int height = TEXSIZE;
477 if (textureModes[mode] == GL_TEXTURE_1D)
478 height = 1;
480 if (depthBuffer) {
481 int params;
483 glGenRenderbuffersEXT_func(1, depth_rb);
486 glBindRenderbufferEXT_func
487 (GL_RENDERBUFFER_EXT,
488 depth_rb[0]);
489 if (glIsRenderbufferEXT_func(depth_rb[0]) != GL_TRUE)
491 REPORT_FAILURE("Call glIsRenderbufferEXT failed\n");
492 return false;
495 glRenderbufferStorageEXT_func
496 (GL_RENDERBUFFER_EXT,
497 GL_DEPTH_COMPONENT,
498 TEXSIZE, height);
499 glFramebufferRenderbufferEXT_func
500 (GL_FRAMEBUFFER_EXT,
501 GL_DEPTH_ATTACHMENT_EXT,
502 GL_RENDERBUFFER_EXT,
503 depth_rb[0]);
504 glGetRenderbufferParameterivEXT_func
505 (GL_RENDERBUFFER_EXT,
506 GL_RENDERBUFFER_WIDTH_EXT,
507 &params);
508 if (params != TEXSIZE) {
509 REPORT_FAILURE("Get Renderbuffer width failed");
510 printf("glGetRenderbufferParameterivEXT: %s\n", gluErrorString(glGetError()));
511 printf("width = %d\n", params);
512 return false;
514 glGetRenderbufferParameterivEXT_func
515 (GL_RENDERBUFFER_EXT,
516 GL_RENDERBUFFER_HEIGHT_EXT,
517 &params);
518 if (params != height) {
519 REPORT_FAILURE("Get Renderbuffer height failed");
520 printf("glGetRenderbufferParameterivEXT: %s\n", gluErrorString(glGetError()));
521 return false;
525 if (stencilBuffer) {
526 int type;
528 type = -1;
529 glGenRenderbuffersEXT_func(1, stencil_rb);
530 glBindRenderbufferEXT_func(GL_RENDERBUFFER_EXT, stencil_rb[0]);
531 glRenderbufferStorageEXT_func
532 (GL_RENDERBUFFER_EXT,
533 GL_STENCIL_INDEX,
534 TEXSIZE, height);
535 glFramebufferRenderbufferEXT_func
536 (GL_FRAMEBUFFER_EXT,
537 GL_STENCIL_ATTACHMENT_EXT,
538 GL_RENDERBUFFER_EXT,
539 stencil_rb[0]);
540 glGetFramebufferAttachmentParameterivEXT_func
541 (GL_FRAMEBUFFER_EXT,
542 GL_STENCIL_ATTACHMENT_EXT,
543 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,
544 &type);
545 if (type != GL_RENDERBUFFER_EXT) {
546 REPORT_FAILURE("Get Framebuffer attached object type failed");
547 printf("glGetFramebufferParameterivEXT: %s\n", gluErrorString(glGetError()));
548 printf("type = %d\n", type);
549 return false;
553 switch (textureModes[mode]) {
554 case GL_TEXTURE_1D:
555 int name;
557 name = -1;
558 glFramebufferTexture1DEXT_func
559 (GL_FRAMEBUFFER_EXT,
560 GL_COLOR_ATTACHMENT0_EXT,
561 GL_TEXTURE_1D,
562 textures[0], 0);
563 glGetFramebufferAttachmentParameterivEXT_func
564 (GL_FRAMEBUFFER_EXT,
565 GL_COLOR_ATTACHMENT0_EXT,
566 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
567 &name);
568 if ((GLuint)name != textures[0]) {
569 REPORT_FAILURE("Get Framebuffer attached texture name failed");
570 printf("glGetFramebufferParameterivEXT: %s\n", gluErrorString(glGetError()));
571 printf("name = %d\n", name);
572 return false;
575 break;
576 case GL_TEXTURE_2D:
577 int level;
579 level = -1;
580 glFramebufferTexture2DEXT_func
581 (GL_FRAMEBUFFER_EXT,
582 GL_COLOR_ATTACHMENT0_EXT,
583 GL_TEXTURE_2D,
584 textures[0], 0);
585 glGetFramebufferAttachmentParameterivEXT_func
586 (GL_FRAMEBUFFER_EXT,
587 GL_COLOR_ATTACHMENT0_EXT,
588 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT,
589 &level);
590 if (level != 0) {
591 REPORT_FAILURE("Get Framebuffer attached texture level failed");
592 printf("glGetFramebufferParameterivEXT: %s\n", gluErrorString(glGetError()));
593 printf("level = %d\n", level);
594 return false;
597 break;
598 case GL_TEXTURE_3D:
599 int zoffset;
601 zoffset = -1;
602 glFramebufferTexture3DEXT_func
603 (GL_FRAMEBUFFER_EXT,
604 GL_COLOR_ATTACHMENT0_EXT,
605 GL_TEXTURE_3D,
606 textures[0],
608 maxzoffset-1);
610 glGetFramebufferAttachmentParameterivEXT_func
611 (GL_FRAMEBUFFER_EXT,
612 GL_COLOR_ATTACHMENT0_EXT,
613 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT,
614 &zoffset);
616 if (zoffset != maxzoffset-1) {
617 REPORT_FAILURE("Get Framebuffer attached 3D texture z-offset failed");
618 printf("glGetFramebufferParameterivEXT: %s\n", gluErrorString(glGetError()));
619 printf("zoffset = %d\n", zoffset);
620 return false;
622 break;
623 case GL_TEXTURE_CUBE_MAP:
624 int face = 0;
626 glFramebufferTexture2DEXT_func
627 (GL_FRAMEBUFFER_EXT,
628 GL_COLOR_ATTACHMENT0_EXT,
629 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
630 textures[0], 0);
631 glGetFramebufferAttachmentParameterivEXT_func
632 (GL_FRAMEBUFFER_EXT,
633 GL_COLOR_ATTACHMENT0_EXT,
634 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT,
635 &face);
636 if (face !=
637 GL_TEXTURE_CUBE_MAP_POSITIVE_Z)
639 REPORT_FAILURE("Get Framebuffer attached cube map face failed");
640 printf("glGetFramebufferParameterivEXT: %s\n", gluErrorString(glGetError()));
641 printf("face = %d\n", face);
642 return false;
645 break;
648 status = CheckFramebufferStatus("FBOTest::testRender2SingleTexture", __LINE__);
650 else {
651 status = GL_FRAMEBUFFER_COMPLETE_EXT;
655 if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
656 continue;
660 // Render, test the results
663 if (depthBuffer) {
664 glClear(GL_DEPTH_BUFFER_BIT);
665 // Init depth buffer
666 glEnable(GL_DEPTH_TEST);
667 glDepthFunc(GL_ALWAYS);
668 switch (textureModes[mode]) {
669 case GL_TEXTURE_1D:
670 glBegin(GL_LINES);
671 glVertex3f(TEXSIZE / 4, 0, 0.3);
672 glVertex3f(TEXSIZE * 5 / 8, 0, 0.3);
673 glEnd();
674 break;
675 case GL_TEXTURE_2D:
676 case GL_TEXTURE_3D:
677 case GL_TEXTURE_CUBE_MAP:
678 glBegin(GL_POLYGON);
679 glVertex3f(TEXSIZE / 4, 0, 0.3);
680 glVertex3f(TEXSIZE * 5 / 8, 0, 0.3);
681 glVertex3f(TEXSIZE * 5 / 8, TEXSIZE, 0.3);
682 glVertex3f(TEXSIZE / 4, TEXSIZE, 0.3);
683 glEnd();
684 break;
685 default:
686 break;
688 glDepthFunc(GL_LESS);
691 if (stencilBuffer) {
692 glClear(GL_STENCIL_BUFFER_BIT);
693 // Init stencil buffer
694 glEnable(GL_STENCIL_TEST);
695 glStencilFunc(GL_ALWAYS, 0x1, 0x1);
696 glStencilOp(GL_KEEP,
697 GL_KEEP, GL_REPLACE);
698 switch (textureModes[mode]) {
699 case GL_TEXTURE_1D:
700 glBegin(GL_LINES);
701 glVertex3f(TEXSIZE / 2, 0, 0.3);
702 glVertex3f(TEXSIZE * 7 / 8, 0, 0.3);
703 glEnd();
704 break;
705 case GL_TEXTURE_2D:
706 case GL_TEXTURE_3D:
707 case GL_TEXTURE_CUBE_MAP:
708 glBegin(GL_POLYGON);
709 glVertex3f(TEXSIZE / 2, 0, 0.3);
710 glVertex3f(TEXSIZE * 7 / 8, 0, 0.3);
711 glVertex3f(TEXSIZE * 7 / 8, TEXSIZE, 0.3);
712 glVertex3f(TEXSIZE / 2, TEXSIZE, 0.3);
713 glEnd();
714 break;
715 default:
716 break;
719 glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);
722 // Render to the texture
723 glBindTexture(textureModes[mode], 0);
724 glDisable(textureModes[mode]);
725 glColor4fv(colors[RED]);
726 glClearColor(0.0, 0.0, 0.0, 0.0);
727 glClear(GL_COLOR_BUFFER_BIT);
729 switch (textureModes[mode]) {
730 case GL_TEXTURE_1D:
731 glBegin(GL_LINES);
732 glVertex3f(0, 0, 0.2);
733 glVertex3f(TEXSIZE, 0, 0.2);
734 glEnd();
735 break;
736 case GL_TEXTURE_2D:
737 case GL_TEXTURE_3D:
738 case GL_TEXTURE_CUBE_MAP:
739 glBegin(GL_POLYGON);
740 glVertex3f(0, 0, 0.2);
741 glVertex3f(TEXSIZE, 0, 0.2);
742 glVertex3f(TEXSIZE, TEXSIZE, 0.2);
743 glVertex3f(0, TEXSIZE, 0.2);
744 glEnd();
745 break;
748 // Render to the window
749 glEnable(textureModes[mode]);
750 glBindTexture(textureModes[mode],
751 textures[0]);
752 if (useFramebuffer) {
753 glBindFramebufferEXT_func
754 (GL_FRAMEBUFFER_EXT, 0);
755 glBindTexture(textureModes
756 [mode], textures[0]);
758 else {
759 switch (textureModes[mode]) {
760 case GL_TEXTURE_1D:
761 glCopyTexImage1D
762 (GL_TEXTURE_1D,
763 0, GL_RGB,
764 0, 0, TEXSIZE, 0);
765 break;
766 case GL_TEXTURE_2D:
767 glCopyTexImage2D
768 (GL_TEXTURE_2D,
769 0, GL_RGB,
770 0, 0,
771 TEXSIZE,
772 TEXSIZE, 0);
773 break;
774 case GL_TEXTURE_3D:
775 glCopyTexSubImage3D_func
776 (GL_TEXTURE_3D,
777 0, 0, 0,
778 0, 0, 0,
779 TEXSIZE, TEXSIZE);
780 break;
781 case GL_TEXTURE_CUBE_MAP:
782 glCopyTexImage2D
783 (GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
784 0, GL_RGB,
785 0, 0,
786 TEXSIZE,
787 TEXSIZE, 0);
788 default:
789 break;
792 if (depthBuffer)
793 glDisable(GL_DEPTH_TEST);
794 if (stencilBuffer)
795 glDisable(GL_STENCIL_TEST);
797 glEnable(textureModes[mode]);
798 glColor4fv(colors[WHITE]);
799 glClearColor(0.0, 0.0, 0.0, 0.0);
800 glClear(GL_COLOR_BUFFER_BIT);
802 glTexParameteri (textureModes[mode], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
803 glTexParameteri (textureModes[mode], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
804 glTexParameteri (textureModes[mode], GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
806 if (textureModes[mode] !=
807 GL_TEXTURE_CUBE_MAP) {
808 GLfloat depth = 0.99+0.01;
809 glBegin(GL_POLYGON);
810 glTexCoord3f(0.0, 0.0, depth);
811 glVertex2f(0, 0);
812 glTexCoord3f(1.0, 0.0, depth);
813 glVertex2f(TEXSIZE, 0);
814 glTexCoord3f(1.0, 1.0, depth);
815 glVertex2f(TEXSIZE, TEXSIZE);
816 glTexCoord3f(0.0, 1.0, depth);
817 glVertex2f(0, TEXSIZE);
818 glEnd();
820 else {
821 glBegin(GL_POLYGON);
822 glTexCoord3f(-1.0, 1.0, 1.0);
823 glVertex2f(0, 0);
824 glTexCoord3f(1.0, 1.0, 1.0);
825 glVertex2f(TEXSIZE, 0);
826 glTexCoord3f(1.0, -1.0, 1.0);
827 glVertex2f(TEXSIZE, TEXSIZE);
828 glTexCoord3f(-1.0, -1.0, 1.0);
829 glVertex2f(0, TEXSIZE);
830 glEnd();
833 glDeleteTextures(1, textures);
834 if (useFramebuffer)
835 glDeleteFramebuffersEXT_func(1, fbs);
836 if (depthBuffer)
837 glDeleteRenderbuffersEXT_func(1, depth_rb);
838 if (stencilBuffer)
839 glDeleteRenderbuffersEXT_func(1, stencil_rb);
841 // getchar();
842 if (checkResult(colors[RED], depthBuffer, stencilBuffer) == false) {
843 REPORT_FAILURE("Render to single texture failed");
844 printf(" mode = %d\n", mode);
845 return false;
851 return true;
855 bool
856 FBOTest::testRender2MultiTexture(void)
858 int i;
859 GLuint fbs[8];
860 GLuint textures[8];
861 GLint maxColorAttachment = 8;
864 enum { MULTI_FBO, SINGLE_COLOR_ATTACH, MULTI_COLOR_ATTACH };
865 int numRender;
866 int numFBO;
867 int numColorAttach;
868 int mode;
870 reset();
871 for (mode = MULTI_FBO; mode < MULTI_COLOR_ATTACH + 1; mode++) {
872 if (useFramebuffer) {
873 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT,
874 &maxColorAttachment);
875 if (maxColorAttachment < 1) {
876 REPORT_FAILURE("Failed to get max color attachment points");
877 return false;
881 numRender = maxColorAttachment;
882 numColorAttach = maxColorAttachment;
883 if (mode == MULTI_FBO)
884 numFBO = maxColorAttachment;
885 else
886 numFBO = 1;
888 if (useFramebuffer)
889 glGenFramebuffersEXT_func(numFBO, fbs);
891 GLint maxTexUnits;
893 glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxTexUnits);
894 glGenTextures(maxTexUnits, textures);
897 for (i = 0; i < numColorAttach; i++) {
898 int idx;
900 if (i > maxTexUnits - 1)
901 idx = maxTexUnits - 1;
902 else
903 idx = i;
905 glActiveTexture_func(GL_TEXTURE0 + idx);
906 glBindTexture(GL_TEXTURE_2D, textures[idx]);
907 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
908 TEXSIZE, TEXSIZE, 0, GL_RGB,
909 GL_INT, NULL);
911 if (useFramebuffer) {
912 if (mode == MULTI_FBO)
913 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, fbs[i]);
914 else
915 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, fbs[0]);
917 if (mode != SINGLE_COLOR_ATTACH)
918 glFramebufferTexture2DEXT_func
919 (GL_FRAMEBUFFER_EXT,
920 GL_COLOR_ATTACHMENT0_EXT + i,
921 GL_TEXTURE_2D,
922 textures[idx], 0);
923 else
924 glFramebufferTexture2DEXT_func
925 (GL_FRAMEBUFFER_EXT,
926 GL_COLOR_ATTACHMENT0_EXT,
927 GL_TEXTURE_2D,
928 textures[idx], 0);
929 if (mode != SINGLE_COLOR_ATTACH) {
930 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + i);
931 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + i);
933 else {
934 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
935 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
937 CheckFramebufferStatus("FBOTest::testRender2MultiTexture", __LINE__);
943 for (i = 0; i < numRender; i++) {
944 int idx;
946 if (i > maxTexUnits - 1)
947 idx = maxTexUnits - 1;
948 else
949 idx = i;
952 if (useFramebuffer) {
953 if (mode == MULTI_FBO)
954 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, fbs[i]);
955 else
956 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, fbs[0]);
958 if (mode == MULTI_COLOR_ATTACH) {
959 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + idx);
960 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + idx);
963 CheckFramebufferStatus("FBOTest::testRender2MultiTexture", __LINE__);
964 if (mode == SINGLE_COLOR_ATTACH) {
965 glFramebufferTexture2DEXT_func
966 (GL_FRAMEBUFFER_EXT,
967 GL_COLOR_ATTACHMENT0_EXT,
968 GL_TEXTURE_2D,
969 textures[idx], 0);
973 glDisable(GL_TEXTURE_2D);
975 // Render to the texture
976 glColor4fv(colors[RED + i % (WHITE - RED)]);
978 glClearColor(0.0, 0.0, 0.0, 0.0);
979 glClear(GL_COLOR_BUFFER_BIT);
981 glBegin(GL_POLYGON);
982 glVertex3f(0, 0, 1);
983 glVertex3f(TEXSIZE, 0, 1);
984 glVertex3f(TEXSIZE, TEXSIZE, 1);
985 glVertex3f(0, TEXSIZE, 1);
986 glEnd();
989 glEnable(GL_TEXTURE_2D);
990 if (useFramebuffer) {
991 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, 0);
992 glBindTexture(GL_TEXTURE_2D, textures[idx]);
994 else {
995 glBindTexture(GL_TEXTURE_2D, textures[idx]);
996 glCopyTexImage2D(GL_TEXTURE_2D, 0,
997 GL_RGB, 0, 0,
998 TEXSIZE, TEXSIZE, 0);
1002 // Clean up
1003 if (useFramebuffer)
1004 glDeleteFramebuffersEXT_func(numFBO, fbs);
1007 // Render to the window
1008 for (i = 0; i < numRender; i++) {
1009 int idx;
1011 if (i > maxTexUnits - 1)
1012 idx = maxTexUnits - 1;
1013 else
1014 idx = i;
1016 glActiveTexture_func(GL_TEXTURE0 + idx);
1017 glEnable(GL_TEXTURE_2D);
1018 glTexParameteri(GL_TEXTURE_2D,
1019 GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1020 glTexParameteri(GL_TEXTURE_2D,
1021 GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1022 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1023 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1025 glColor4fv(colors[WHITE]);
1026 glClearColor(0.0, 0.0, 0.0, 0.0);
1027 glClear(GL_COLOR_BUFFER_BIT);
1028 glBegin(GL_POLYGON);
1029 glMultiTexCoord2f_func(GL_TEXTURE0 + idx, 0, 0);
1030 glVertex3f(0, 0, 1);
1031 glMultiTexCoord2f_func(GL_TEXTURE0 + idx, 1, 0);
1032 glVertex3f(TEXSIZE, 0, 1);
1033 glMultiTexCoord2f_func(GL_TEXTURE0 + idx, 1, 1);
1034 glVertex3f(TEXSIZE, TEXSIZE, 1);
1035 glMultiTexCoord2f_func(GL_TEXTURE0 + idx, 0, 1);
1036 glVertex3f(0, TEXSIZE, 1);
1037 glEnd();
1039 //Check result
1040 int exp = (i >= maxTexUnits - 1) ? maxColorAttachment - 1 : i;
1042 if (checkResult(colors[RED + (exp % (WHITE - RED))], 0, 0) == false) {
1043 glDeleteTextures(maxTexUnits, textures);
1045 REPORT_FAILURE("Render to multi texture failed");
1046 return false;
1049 glDisable(GL_TEXTURE_2D);
1050 glActiveTexture_func(GL_TEXTURE0);
1053 glDeleteTextures(maxTexUnits, textures);
1056 return true;
1060 bool
1061 FBOTest::testRender2depthTexture(void)
1063 GLuint fbs[2];
1064 GLuint textures[8];
1066 reset();
1067 if (useFramebuffer)
1068 glGenFramebuffersEXT_func(1, fbs);
1070 glGenTextures(1, textures);
1071 glBindTexture(GL_TEXTURE_2D, textures[0]);
1072 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, TEXSIZE,
1073 TEXSIZE, 0, GL_DEPTH_COMPONENT, GL_INT, NULL);
1075 if (useFramebuffer) {
1076 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, fbs[0]);
1077 glFramebufferTexture2DEXT_func(GL_FRAMEBUFFER_EXT,
1078 GL_DEPTH_ATTACHMENT_EXT,
1079 GL_TEXTURE_2D, textures[0], 0);
1080 glDrawBuffer(GL_NONE);
1081 glReadBuffer(GL_NONE);
1083 CheckFramebufferStatus("FBOTest::testRender2depthTexture", __LINE__);
1085 glClear(GL_DEPTH_BUFFER_BIT);
1086 glEnable(GL_DEPTH_TEST);
1088 glDisable(GL_TEXTURE_2D);
1090 // Render to the texture
1091 glColor4fv(colors[RED]);
1092 glClearColor(0.0, 0.0, 0.0, 0.0);
1093 glClear(GL_COLOR_BUFFER_BIT);
1094 glBegin(GL_POLYGON);
1095 glVertex3f(TEXSIZE / 4, 0, 0.5);
1096 glVertex3f(TEXSIZE * 5 / 8, 0, 0.5);
1097 glVertex3f(TEXSIZE * 5 / 8, TEXSIZE, 0.5);
1098 glVertex3f(TEXSIZE / 4, TEXSIZE, 0.5);
1099 glEnd();
1101 if (useFramebuffer) {
1102 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, 0);
1103 glBindTexture(GL_TEXTURE_2D, textures[0]);
1105 else {
1106 glBindTexture(GL_TEXTURE_2D, textures[0]);
1107 glCopyTexImage2D(GL_TEXTURE_2D, 0,
1108 GL_DEPTH_COMPONENT, 0, 0, TEXSIZE,
1109 TEXSIZE, 0);
1112 glClear(GL_DEPTH_BUFFER_BIT);
1114 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1115 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1116 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1117 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
1118 GL_COMPARE_R_TO_TEXTURE);
1119 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
1120 glTexParameterf(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE,
1121 GL_LUMINANCE);
1122 glEnable(GL_TEXTURE_2D);
1123 glDisable(GL_DEPTH_TEST);
1125 // Render to the window
1126 glColor4fv(colors[GREEN]);
1127 glClearColor(0.0, 0.0, 0.0, 0.0);
1128 glClear(GL_COLOR_BUFFER_BIT);
1129 glBegin(GL_POLYGON);
1130 glTexCoord3f(0, 0, 0.75);
1131 glVertex2f(0, 0);
1132 glTexCoord3f(1, 0, 0.75);
1133 glVertex2f(TEXSIZE, 0);
1134 glTexCoord3f(1, 1, 0.75);
1135 glVertex2f(TEXSIZE, TEXSIZE);
1136 glTexCoord3f(0, 1, 0.75);
1137 glVertex2f(0, TEXSIZE);
1138 glEnd();
1139 glFlush();
1141 // Clean up
1142 if (useFramebuffer)
1143 glDeleteFramebuffersEXT_func(1, fbs);
1144 glDeleteTextures(1, textures);
1146 // Check result
1147 if (checkResult(colors[WHITE], 1, 0) == false) {
1148 REPORT_FAILURE("Render to depth texture failed");
1149 return false;
1154 return true;
1158 bool
1159 FBOTest::testRender2MipmapTexture(void)
1161 int i;
1162 GLuint fbs[1];
1163 GLuint textures[1];
1165 reset();
1166 if (useFramebuffer)
1167 glGenFramebuffersEXT_func(1, fbs);
1169 glGenTextures(1, textures);
1170 glBindTexture(GL_TEXTURE_2D, textures[0]);
1172 if (useFramebuffer)
1173 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, fbs[0]);
1175 glDisable(GL_TEXTURE_2D);
1177 GLint level = 0;
1179 for (i = TEXSIZE; i > 0; i /= 2, level++) {
1180 if (useFramebuffer) {
1181 glTexImage2D(GL_TEXTURE_2D, level, GL_RGB,
1182 i, i, 0, GL_RGB, GL_INT, NULL);
1183 glFramebufferTexture2DEXT_func
1184 (GL_FRAMEBUFFER_EXT,
1185 GL_COLOR_ATTACHMENT0_EXT,
1186 GL_TEXTURE_2D, textures[0], level);
1187 CheckFramebufferStatus("FBOTest::testRender2MipmapTexture", __LINE__);
1189 glColor4fv(colors[RED + (level % (WHITE - RED))]);
1190 glClearColor(0.0, 0.0, 0.0, 0.0);
1191 glClear(GL_COLOR_BUFFER_BIT);
1193 glBegin(GL_POLYGON);
1194 glVertex3f(0, 0, 1);
1195 glVertex3f(TEXSIZE, 0, 1);
1196 glVertex3f(TEXSIZE, TEXSIZE, 1);
1197 glVertex3f(0, TEXSIZE, 1);
1198 glEnd();
1200 else {
1201 glColor4fv(colors[RED + (level % (WHITE - RED))]);
1202 glClearColor(0.0, 0.0, 0.0, 0.0);
1203 glClear(GL_COLOR_BUFFER_BIT);
1205 glBegin(GL_POLYGON);
1206 glVertex3f(0, 0, 1);
1207 glVertex3f(TEXSIZE, 0, 1);
1208 glVertex3f(TEXSIZE, TEXSIZE, 1);
1209 glVertex3f(0, TEXSIZE, 1);
1210 glEnd();
1213 glTexImage2D(GL_TEXTURE_2D, level, GL_RGB,
1214 i, i, 0, GL_RGB, GL_INT, NULL);
1215 glCopyTexImage2D(GL_TEXTURE_2D, level,
1216 GL_RGB, 0, 0, i, i, 0);
1220 if (useFramebuffer) {
1221 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, 0);
1222 glBindTexture(GL_TEXTURE_2D, textures[0]);
1224 glEnable(GL_TEXTURE_2D);
1226 // Render to the window
1227 glColor4fv(colors[GREEN]);
1228 glClearColor(0.0, 0.0, 0.0, 0.0);
1229 glClear(GL_COLOR_BUFFER_BIT);
1230 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1231 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
1232 GL_NEAREST_MIPMAP_NEAREST);
1233 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1235 for (i = TEXSIZE; i > 0; i /= 2) {
1236 glBegin(GL_POLYGON);
1237 glTexCoord2f(0, 0);
1238 glVertex3f(windowSize / 2 - i / 2,
1239 windowSize / 2 - i / 2, 1);
1240 glTexCoord2f(1, 0);
1241 glVertex3f(windowSize / 2 + i / 2,
1242 windowSize / 2 - i / 2, 1);
1243 glTexCoord2f(1, 1);
1244 glVertex3f(windowSize / 2 + i / 2,
1245 windowSize / 2 + i / 2, 1);
1246 glTexCoord2f(0, 1);
1247 glVertex3f(windowSize / 2 - i / 2,
1248 windowSize / 2 + i / 2, 1);
1249 glEnd();
1251 glFlush();
1253 // Clean up
1254 if (useFramebuffer)
1255 glDeleteFramebuffersEXT_func(1, fbs);
1256 glDeleteTextures(1, textures);
1258 // Check result
1259 level = 0;
1260 for (i = TEXSIZE; i > 1; i /= 2, level++) {
1261 GLfloat pixel[3];
1263 glReadPixels(windowSize / 2 - i / 2,
1264 windowSize / 2 - i / 2, 1, 1, GL_RGB,
1265 GL_FLOAT, pixel);
1266 if (!equalColors
1267 (pixel, colors[RED + (level % (WHITE - RED))])) {
1268 REPORT_FAILURE("Render to mipmap texture failed");
1269 printf(" level = %d\n", level);
1270 return false;
1275 return true;
1279 bool
1280 FBOTest::testErrorHandling(void)
1282 GLuint fbs[1];
1283 GLuint textures[2];
1284 GLenum status;
1286 if (useFramebuffer) {
1287 GLuint maxColorAttachment;
1289 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, (GLint *) & maxColorAttachment);
1290 if (maxColorAttachment < 1) {
1291 REPORT_FAILURE("Failed to get max color attachment points");
1292 return false;
1296 // At least one image attached to the framebuffer
1297 glGenFramebuffersEXT_func(1, fbs);
1298 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, fbs[0]);
1299 glDrawBuffer(GL_NONE);
1300 glReadBuffer(GL_NONE);
1301 status = glCheckFramebufferStatusEXT_func(GL_FRAMEBUFFER_EXT);
1302 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, 0);
1303 glDeleteFramebuffersEXT_func(1, fbs);
1304 if (status !=
1305 GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT) {
1306 REPORT_FAILURE
1307 ("If no image is attached to framebuffer, status should be GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT");
1308 return false;
1311 // All attached images have the same width and height,
1312 // unless GL_ARB_framebuffer object is supported.
1313 glGenFramebuffersEXT_func(1, fbs);
1314 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, fbs[0]);
1315 glGenTextures(2, textures);
1316 glBindTexture(GL_TEXTURE_2D, textures[0]);
1317 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TEXSIZE,
1318 TEXSIZE, 0, GL_RGB, GL_INT, NULL);
1319 glFramebufferTexture2DEXT_func(GL_FRAMEBUFFER_EXT,
1320 GL_COLOR_ATTACHMENT0_EXT,
1321 GL_TEXTURE_2D, textures[0], 0);
1322 glBindTexture(GL_TEXTURE_2D, textures[1]);
1323 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TEXSIZE / 2,
1324 TEXSIZE / 2, 0, GL_RGB, GL_INT, NULL);
1325 glFramebufferTexture2DEXT_func(GL_FRAMEBUFFER_EXT,
1326 GL_COLOR_ATTACHMENT0_EXT
1327 + maxColorAttachment - 1,
1328 GL_TEXTURE_2D, textures[1], 0);
1329 status = glCheckFramebufferStatusEXT_func(GL_FRAMEBUFFER_EXT);
1330 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, 0);
1331 glDeleteFramebuffersEXT_func(1, fbs);
1332 glDeleteTextures(2, textures);
1333 if (!haveARBfbo &&
1334 status != GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT) {
1335 REPORT_FAILURE
1336 ("If renderbuffer sizes don't all match, status should be GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT");
1337 return false;
1340 // All images attached to the attachment points
1341 // COLOR_ATTACHMENT0_EXT through COLOR_ATTACHMENTn_EXT must
1342 // have the same internal format, unless ARB_fbo is supported.
1343 glGenFramebuffersEXT_func(1, fbs);
1344 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, fbs[0]);
1345 glGenTextures(2, textures);
1346 glBindTexture(GL_TEXTURE_2D, textures[0]);
1347 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TEXSIZE,
1348 TEXSIZE, 0, GL_RGB, GL_INT, NULL);
1349 glFramebufferTexture2DEXT_func(GL_FRAMEBUFFER_EXT,
1350 GL_COLOR_ATTACHMENT0_EXT,
1351 GL_TEXTURE_2D, textures[0], 0);
1352 glBindTexture(GL_TEXTURE_2D, textures[1]);
1353 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEXSIZE,
1354 TEXSIZE, 0, GL_RGBA, GL_INT, NULL);
1355 glFramebufferTexture2DEXT_func(GL_FRAMEBUFFER_EXT,
1356 GL_COLOR_ATTACHMENT0_EXT
1357 + maxColorAttachment - 1,
1358 GL_TEXTURE_2D, textures[1], 0);
1359 status = glCheckFramebufferStatusEXT_func(GL_FRAMEBUFFER_EXT);
1360 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, 0);
1361 glDeleteFramebuffersEXT_func(1, fbs);
1362 glDeleteTextures(2, textures);
1363 if (!haveARBfbo &&
1364 status != GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT) {
1365 REPORT_FAILURE
1366 ("All color renderbuffers must be of same format, status should be GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT");
1367 return false;
1371 // The value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT must not
1372 // be NONE for any color attachment point(s) named by
1373 // DRAW_BUFFERi.
1374 glGenFramebuffersEXT_func(1, fbs);
1375 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, fbs[0]);
1376 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT +
1377 maxColorAttachment - 1);
1378 status = glCheckFramebufferStatusEXT_func(GL_FRAMEBUFFER_EXT);
1379 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, 0);
1380 glDeleteFramebuffersEXT_func(1, fbs);
1381 if (status != GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT) {
1382 REPORT_FAILURE
1383 ("All any buffer named by glDrawBuffers is missing, status should be GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT");
1384 return false;
1387 // If READ_BUFFER is not NONE, then the value of
1388 // FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT must not be NONE for
1389 // the color attachment point named by READ_BUFFER.
1390 glGenFramebuffersEXT_func(1, fbs);
1391 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, fbs[0]);
1392 glDrawBuffer(GL_NONE);
1393 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT +
1394 maxColorAttachment - 1);
1395 status = glCheckFramebufferStatusEXT_func(GL_FRAMEBUFFER_EXT);
1396 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, 0);
1397 glDeleteFramebuffersEXT_func(1, fbs);
1398 if (status != GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT) {
1399 REPORT_FAILURE
1400 ("If buffer named by glReadBuffers is missing, status should be GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT");
1401 return false;
1404 return true;
1407 bool
1408 FBOTest::testFunctionality(MultiTestResult & r)
1410 static SubTestFunc funcs[] = {
1411 &GLEAN::FBOTest::testSanity,
1412 &GLEAN::FBOTest::testRender2SingleTexture,
1413 &GLEAN::FBOTest::testRender2MultiTexture,
1414 &GLEAN::FBOTest::testRender2depthTexture,
1415 &GLEAN::FBOTest::testRender2MipmapTexture,
1416 &GLEAN::FBOTest::testErrorHandling,
1417 NULL
1420 for (int i = 0; funcs[i]; i++)
1421 if ((this->*funcs[i]) ())
1422 r.numPassed++;
1423 else
1424 r.numFailed++;
1425 return true;
1429 bool
1430 FBOTest::testPerformance(MultiTestResult & r)
1432 GLuint fbs[1];
1433 GLuint textures[1];
1434 int mode;
1436 Timer t;
1437 double t0, t1, perf[2];
1439 (void) r;
1441 for (mode = 0; mode < useFramebuffer + 1; mode++) {
1442 t0 = t.getClock();
1443 glClearColor(0.0, 0.0, 0.0, 1.0);
1444 glClear(GL_COLOR_BUFFER_BIT);
1445 if (mode)
1446 glGenFramebuffersEXT_func(1, fbs);
1447 glGenTextures(1, textures);
1449 glBindTexture(GL_TEXTURE_2D, textures[0]);
1450 glTexParameteri(GL_TEXTURE_2D,
1451 GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1452 glTexParameteri(GL_TEXTURE_2D,
1453 GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1455 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TEXSIZE,
1456 TEXSIZE, 0, GL_RGB, GL_INT, NULL);
1458 if (mode) {
1459 glBindFramebufferEXT_func(GL_FRAMEBUFFER_EXT, fbs[0]);
1460 glFramebufferTexture2DEXT_func
1461 (GL_FRAMEBUFFER_EXT,
1462 GL_COLOR_ATTACHMENT0_EXT,
1463 GL_TEXTURE_2D, textures[0], 0);
1464 CheckFramebufferStatus("FBOTest::testPerformance", __LINE__);
1467 int i;
1469 for (i = 0; i < 1024; i++) {
1470 if (mode)
1471 glBindFramebufferEXT_func
1472 (GL_FRAMEBUFFER_EXT, fbs[0]);
1474 // Render to the texture
1475 glBindTexture(GL_TEXTURE_2D, 0);
1476 glDisable(GL_TEXTURE_2D);
1477 glColor4fv(colors[RED + (i % (WHITE - RED))]);
1478 glClearColor(0.0, 0.0, 0.0, 0.0);
1479 glClear(GL_COLOR_BUFFER_BIT);
1482 glBegin(GL_POLYGON);
1483 glVertex3f(0, 0, 0.2);
1484 glVertex3f(TEXSIZE, 0, 0.2);
1485 glVertex3f(TEXSIZE, TEXSIZE, 0.2);
1486 glVertex3f(0, TEXSIZE, 0.2);
1487 glEnd();
1489 // Render to the window
1490 if (mode) {
1491 glBindFramebufferEXT_func
1492 (GL_FRAMEBUFFER_EXT, 0);
1493 glBindTexture(GL_TEXTURE_2D, textures[0]);
1495 else {
1496 glBindTexture(GL_TEXTURE_2D, textures[0]);
1497 glCopyTexImage2D(GL_TEXTURE_2D, 0,
1498 GL_RGB, 0, 0,
1499 TEXSIZE, TEXSIZE, 0);
1501 glEnable(GL_TEXTURE_2D);
1502 glColor4fv(colors[WHITE]);
1503 glClearColor(0.0, 0.0, 0.0, 0.0);
1504 glClear(GL_COLOR_BUFFER_BIT);
1506 glBegin(GL_POLYGON);
1507 glTexCoord3f(0.0, 0.0, 1.0);
1508 glVertex2f(0, 0);
1509 glTexCoord3f(1.0, 0.0, 1.0);
1510 glVertex2f(1, 0);
1511 glTexCoord3f(1.0, 1.0, 1.0);
1512 glVertex2f(1, 1);
1513 glTexCoord3f(0.0, 1.0, 1.0);
1514 glVertex2f(0, 1);
1515 glEnd();
1517 t1 = t.getClock();
1518 glDeleteTextures(1, textures);
1519 if (mode)
1520 glDeleteFramebuffersEXT_func(1, fbs);
1522 perf[mode] =
1523 (double) TEXSIZE *TEXSIZE * 3 / 1024 / (t1 - t0);
1526 if (perf[1] < perf[0] && useFramebuffer) {
1527 env->log << name << ": NOTE "
1528 << "perf[0] = " << perf[0] <<
1529 " MB/s, which is using glCopyTexImage2D" << endl;
1530 env->log << name << ": NOTE " << "perf[1] = " <<
1531 perf[1] << " MB/s, which is using FBO" << endl;
1534 return true;
1537 // Run all the subtests, incrementing numPassed, numFailed
1538 void
1539 FBOTest::runSubTests(MultiTestResult & r)
1541 static TestFunc funcs[] = {
1542 &GLEAN::FBOTest::testFunctionality,
1543 &GLEAN::FBOTest::testPerformance,
1544 NULL
1547 for (int i = 0; funcs[i]; i++)
1548 if ((this->*funcs[i]) (r))
1549 r.numPassed++;
1550 else
1551 r.numFailed++;
1555 void
1556 FBOTest::runOne(MultiTestResult & r, Window & w)
1558 (void) w;
1560 if (!setup()) {
1561 r.pass = false;
1562 return;
1565 runSubTests(r);
1567 r.pass = (r.numFailed == 0);
1571 // The test object itself:
1572 FBOTest fboTest("fbo", "window, rgb, z", "", // no extension filter
1573 "fbo test: Test OpenGL Extension GL_EXT_framebuffer_object\n");
1577 } // namespace GLEAN