getteximage.c revision 32001f49
132001f49Smrg/**
232001f49Smrg * Test glGetTexImage()
332001f49Smrg * Brian Paul
432001f49Smrg * 9 June 2009
532001f49Smrg */
632001f49Smrg
732001f49Smrg
832001f49Smrg#include <stdio.h>
932001f49Smrg#include <stdlib.h>
1032001f49Smrg#include <math.h>
1132001f49Smrg#include <GL/glew.h>
1232001f49Smrg#include "glut_wrap.h"
1332001f49Smrg
1432001f49Smrgstatic int Win;
1532001f49Smrg
1632001f49Smrg
1732001f49Smrgstatic void
1832001f49SmrgTestGetTexImage(GLboolean npot)
1932001f49Smrg{
2032001f49Smrg   GLuint iter;
2132001f49Smrg   GLubyte *data = (GLubyte *) malloc(1024 * 1024 * 4);
2232001f49Smrg   GLubyte *data2 = (GLubyte *) malloc(1024 * 1024 * 4);
2332001f49Smrg
2432001f49Smrg   glEnable(GL_TEXTURE_2D);
2532001f49Smrg
2632001f49Smrg   printf("glTexImage2D + glGetTexImage:\n");
2732001f49Smrg
2832001f49Smrg   for (iter = 0; iter < 8; iter++) {
2932001f49Smrg      GLint p = (iter % 8) + 3;
3032001f49Smrg      GLint w = npot ? (p * 20) : (1 << p);
3132001f49Smrg      GLint h = npot ? (p * 10) : (1 << p);
3232001f49Smrg      GLuint i;
3332001f49Smrg      GLint level = 0;
3432001f49Smrg
3532001f49Smrg      printf("  Testing %d x %d tex image\n", w, h);
3632001f49Smrg
3732001f49Smrg      /* fill data */
3832001f49Smrg      for (i = 0; i < w * h * 4; i++) {
3932001f49Smrg         data[i] = i & 0xff;
4032001f49Smrg         data2[i] = 0;
4132001f49Smrg      }
4232001f49Smrg
4332001f49Smrg      glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0,
4432001f49Smrg                   GL_RGBA, GL_UNSIGNED_BYTE, data);
4532001f49Smrg
4632001f49Smrg      glBegin(GL_POINTS);
4732001f49Smrg      glVertex2f(0, 0);
4832001f49Smrg      glEnd();
4932001f49Smrg
5032001f49Smrg      /* get */
5132001f49Smrg      glGetTexImage(GL_TEXTURE_2D, level, GL_RGBA, GL_UNSIGNED_BYTE, data2);
5232001f49Smrg
5332001f49Smrg      /* compare */
5432001f49Smrg      for (i = 0; i < w * h * 4; i++) {
5532001f49Smrg         if (data2[i] != data[i]) {
5632001f49Smrg            printf("glTexImage + glGetTexImage failure!\n");
5732001f49Smrg            printf("Expected value %d, found %d\n", data[i], data2[i]);
5832001f49Smrg            abort();
5932001f49Smrg         }
6032001f49Smrg      }
6132001f49Smrg
6232001f49Smrg      /* get as BGRA */
6332001f49Smrg      glGetTexImage(GL_TEXTURE_2D, level, GL_BGRA, GL_UNSIGNED_BYTE, data2);
6432001f49Smrg
6532001f49Smrg      /* compare */
6632001f49Smrg      {
6732001f49Smrg         const GLubyte *rgba = (GLubyte *) data;
6832001f49Smrg         const GLubyte *bgra = (GLubyte *) data2;
6932001f49Smrg         for (i = 0; i < w * h; i += 4) {
7032001f49Smrg            if (rgba[i+0] != bgra[i+2] ||
7132001f49Smrg                rgba[i+1] != bgra[i+1] ||
7232001f49Smrg                rgba[i+2] != bgra[i+0] ||
7332001f49Smrg                rgba[i+3] != bgra[i+3]) {
7432001f49Smrg               printf("glTexImage + glGetTexImage(GL_BGRA) failure!\n");
7532001f49Smrg               printf("Expected value %d, found %d\n", data[i], data2[i]);
7632001f49Smrg               abort();
7732001f49Smrg            }
7832001f49Smrg         }
7932001f49Smrg      }
8032001f49Smrg
8132001f49Smrg   }
8232001f49Smrg
8332001f49Smrg   printf("Passed\n");
8432001f49Smrg   glDisable(GL_TEXTURE_2D);
8532001f49Smrg   free(data);
8632001f49Smrg   free(data2);
8732001f49Smrg}
8832001f49Smrg
8932001f49Smrg
9032001f49Smrgstatic GLboolean
9132001f49SmrgColorsEqual(const GLubyte ref[4], const GLubyte act[4])
9232001f49Smrg{
9332001f49Smrg   if (abs((int) ref[0] - (int) act[0]) > 1 ||
9432001f49Smrg       abs((int) ref[1] - (int) act[1]) > 1 ||
9532001f49Smrg       abs((int) ref[2] - (int) act[2]) > 1 ||
9632001f49Smrg       abs((int) ref[3] - (int) act[3]) > 1) {
9732001f49Smrg      printf("expected %d %d %d %d\n", ref[0], ref[1], ref[2], ref[3]);
9832001f49Smrg      printf("found    %d %d %d %d\n", act[0], act[1], act[2], act[3]);
9932001f49Smrg      return GL_FALSE;
10032001f49Smrg   }
10132001f49Smrg   return GL_TRUE;
10232001f49Smrg}
10332001f49Smrg
10432001f49Smrg
10532001f49Smrgstatic void
10632001f49SmrgTestGetTexImageRTT(GLboolean npot)
10732001f49Smrg{
10832001f49Smrg   GLuint iter;
10932001f49Smrg
11032001f49Smrg   printf("Render to texture + glGetTexImage:\n");
11132001f49Smrg
11232001f49Smrg   for (iter = 0; iter < 8; iter++) {
11332001f49Smrg
11432001f49Smrg      GLuint fb, tex;
11532001f49Smrg      GLint w, h;
11632001f49Smrg      GLint level = 0;
11732001f49Smrg
11832001f49Smrg      if (npot) {
11932001f49Smrg         w = 200 + iter * 40;
12032001f49Smrg         h = 200 + iter * 12;
12132001f49Smrg      }
12232001f49Smrg      else {
12332001f49Smrg         w = 4 << iter;
12432001f49Smrg         h = 4 << iter;
12532001f49Smrg      }
12632001f49Smrg
12732001f49Smrg      glGenTextures(1, &tex);
12832001f49Smrg      glGenFramebuffersEXT(1, &fb);
12932001f49Smrg
13032001f49Smrg      glBindTexture(GL_TEXTURE_2D, tex);
13132001f49Smrg      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13232001f49Smrg      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13332001f49Smrg      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0,
13432001f49Smrg                   GL_RGBA, GL_UNSIGNED_BYTE, NULL);
13532001f49Smrg
13632001f49Smrg      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
13732001f49Smrg      glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
13832001f49Smrg                                GL_TEXTURE_2D, tex, level);
13932001f49Smrg
14032001f49Smrg      glViewport(0, 0, w, h);
14132001f49Smrg
14232001f49Smrg      printf("  Testing %d x %d tex image\n", w, h);
14332001f49Smrg      {
14432001f49Smrg         static const GLubyte blue[4] = {0, 0, 255, 255};
14532001f49Smrg         GLubyte color[4];
14632001f49Smrg         GLubyte *data2 = (GLubyte *) malloc(w * h * 4);
14732001f49Smrg         GLuint i;
14832001f49Smrg
14932001f49Smrg         /* random clear color */
15032001f49Smrg         for (i = 0; i < 4; i++) {
15132001f49Smrg            color[i] = rand() % 256;
15232001f49Smrg         }
15332001f49Smrg
15432001f49Smrg         glClearColor(color[0] / 255.0,
15532001f49Smrg                      color[1] / 255.0,
15632001f49Smrg                      color[2] / 255.0,
15732001f49Smrg                      color[3] / 255.0);
15832001f49Smrg
15932001f49Smrg         glClear(GL_COLOR_BUFFER_BIT);
16032001f49Smrg
16132001f49Smrg         /* draw polygon over top half, in blue */
16232001f49Smrg         glColor4ubv(blue);
16332001f49Smrg         glRectf(0, 0.5, 1.0, 1.0);
16432001f49Smrg
16532001f49Smrg         /* get */
16632001f49Smrg         glGetTexImage(GL_TEXTURE_2D, level, GL_RGBA, GL_UNSIGNED_BYTE, data2);
16732001f49Smrg
16832001f49Smrg         /* compare */
16932001f49Smrg         for (i = 0; i < w * h; i += 4) {
17032001f49Smrg            if (i < w * h / 2) {
17132001f49Smrg               /* lower half */
17232001f49Smrg               if (!ColorsEqual(color, data2 + i * 4)) {
17332001f49Smrg                  printf("Render to texture failure (expected clear color)!\n");
17432001f49Smrg                  abort();
17532001f49Smrg               }
17632001f49Smrg            }
17732001f49Smrg            else {
17832001f49Smrg               /* upper half */
17932001f49Smrg               if (!ColorsEqual(blue, data2 + i * 4)) {
18032001f49Smrg                  printf("Render to texture failure (expected blue)!\n");
18132001f49Smrg                  abort();
18232001f49Smrg               }
18332001f49Smrg            }
18432001f49Smrg         }
18532001f49Smrg
18632001f49Smrg         free(data2);
18732001f49Smrg      }
18832001f49Smrg
18932001f49Smrg      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
19032001f49Smrg      glDeleteFramebuffersEXT(1, &fb);
19132001f49Smrg      glDeleteTextures(1, &tex);
19232001f49Smrg
19332001f49Smrg   }
19432001f49Smrg
19532001f49Smrg   printf("Passed\n");
19632001f49Smrg}
19732001f49Smrg
19832001f49Smrg
19932001f49Smrg
20032001f49Smrg
20132001f49Smrgstatic void
20232001f49SmrgDraw(void)
20332001f49Smrg{
20432001f49Smrg   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
20532001f49Smrg
20632001f49Smrg   TestGetTexImage(GL_FALSE);
20732001f49Smrg   if (glutExtensionSupported("GL_ARB_texture_non_power_of_two"))
20832001f49Smrg      TestGetTexImage(GL_TRUE);
20932001f49Smrg
21032001f49Smrg   if (glutExtensionSupported("GL_EXT_framebuffer_object") ||
21132001f49Smrg       glutExtensionSupported("GL_ARB_framebuffer_object")) {
21232001f49Smrg      TestGetTexImageRTT(GL_FALSE);
21332001f49Smrg      if (glutExtensionSupported("GL_ARB_texture_non_power_of_two"))
21432001f49Smrg         TestGetTexImageRTT(GL_TRUE);
21532001f49Smrg   }
21632001f49Smrg
21732001f49Smrg   glutDestroyWindow(Win);
21832001f49Smrg   exit(0);
21932001f49Smrg
22032001f49Smrg   glutSwapBuffers();
22132001f49Smrg}
22232001f49Smrg
22332001f49Smrg
22432001f49Smrgstatic void
22532001f49SmrgReshape(int width, int height)
22632001f49Smrg{
22732001f49Smrg   glViewport(0, 0, width, height);
22832001f49Smrg   glMatrixMode(GL_PROJECTION);
22932001f49Smrg   glLoadIdentity();
23032001f49Smrg   glOrtho(0, 1, 0, 1, -1, 1);
23132001f49Smrg   glMatrixMode(GL_MODELVIEW);
23232001f49Smrg   glLoadIdentity();
23332001f49Smrg   glTranslatef(0.0, 0.0, 0.0);
23432001f49Smrg}
23532001f49Smrg
23632001f49Smrg
23732001f49Smrgstatic void
23832001f49SmrgKey(unsigned char key, int x, int y)
23932001f49Smrg{
24032001f49Smrg   (void) x;
24132001f49Smrg   (void) y;
24232001f49Smrg   switch (key) {
24332001f49Smrg      case 27:
24432001f49Smrg         glutDestroyWindow(Win);
24532001f49Smrg         exit(0);
24632001f49Smrg         break;
24732001f49Smrg   }
24832001f49Smrg   glutPostRedisplay();
24932001f49Smrg}
25032001f49Smrg
25132001f49Smrg
25232001f49Smrgstatic void
25332001f49SmrgInit(void)
25432001f49Smrg{
25532001f49Smrg}
25632001f49Smrg
25732001f49Smrg
25832001f49Smrgint
25932001f49Smrgmain(int argc, char *argv[])
26032001f49Smrg{
26132001f49Smrg   glutInit(&argc, argv);
26232001f49Smrg   glutInitWindowPosition(0, 0);
26332001f49Smrg   glutInitWindowSize(400, 400);
26432001f49Smrg   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
26532001f49Smrg   Win = glutCreateWindow(argv[0]);
26632001f49Smrg   glewInit();
26732001f49Smrg   glutReshapeFunc(Reshape);
26832001f49Smrg   glutKeyboardFunc(Key);
26932001f49Smrg   glutDisplayFunc(Draw);
27032001f49Smrg   Init();
27132001f49Smrg   glutMainLoop();
27232001f49Smrg   return 0;
27332001f49Smrg}
274