1/*
2 * Test texture compression.
3 */
4
5
6#include <assert.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <GL/glew.h>
11#include "glut_wrap.h"
12
13#include "texcomp_image.h"
14
15static int ImgWidth = 512;
16static int ImgHeight = 512;
17static GLenum CompFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
18static GLfloat EyeDist = 5.0;
19static GLfloat Rot = 0.0;
20const GLenum Target = GL_TEXTURE_2D;
21
22
23static void
24CheckError(int line)
25{
26   GLenum err = glGetError();
27   if (err) {
28      printf("GL Error %d at line %d\n", (int) err, line);
29   }
30}
31
32static void
33LoadCompressedImage(void)
34{
35   unsigned char ImgDataTemp[ImgSize / 4];
36   unsigned i;
37   const GLenum filter = GL_LINEAR;
38   const int half = ImgSize / 2;
39
40   glTexImage2D(Target, 0, CompFormat, ImgWidth, ImgHeight, 0,
41                GL_RGB, GL_UNSIGNED_BYTE, NULL);
42
43   /* bottom half */
44   glCompressedTexSubImage2DARB(Target, 0,
45                                0, 0, /* pos */
46                                ImgWidth, ImgHeight / 2,
47                                CompFormat, ImgSize / 2, ImgData /*+ ImgSize / 2*/);
48
49   /* top left */
50   for (i = 0; i < ImgHeight / 8; i++) {
51      memcpy(&ImgDataTemp[i * ImgWidth], &ImgData[half + i * 2 * ImgWidth], ImgWidth);
52   }
53   glCompressedTexSubImage2DARB(Target, 0,
54                                0, ImgHeight / 2, /* pos */
55                                ImgWidth / 2, ImgHeight / 2,
56                                CompFormat, ImgSize / 4, ImgDataTemp);
57
58   /* top right */
59   for (i = 0; i < ImgHeight / 8; i++) {
60      memcpy(&ImgDataTemp[i * ImgWidth], &ImgData[half + i * 2 * ImgWidth + ImgWidth], ImgWidth);
61   }
62   glCompressedTexSubImage2DARB(Target, 0,
63                                ImgWidth / 2, ImgHeight / 2, /* pos */
64                                ImgWidth / 2, ImgHeight / 2,
65                                CompFormat, ImgSize / 4, ImgDataTemp);
66
67   glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, filter);
68   glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, filter);
69}
70
71static void
72Init(void)
73{
74   GLint numFormats, formats[100];
75   GLint p;
76
77   if (!glutExtensionSupported("GL_ARB_texture_compression")) {
78      printf("Sorry, GL_ARB_texture_compression is required.\n");
79      exit(1);
80   }
81   if (!glutExtensionSupported("GL_EXT_texture_compression_s3tc")) {
82      printf("Sorry, GL_EXT_texture_compression_s3tc is required.\n");
83      exit(1);
84   }
85
86   printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
87   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
88
89   glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, &numFormats);
90   glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS_ARB, formats);
91   printf("%d supported compression formats: ", numFormats);
92   for (p = 0; p < numFormats; p++)
93      printf("0x%x ", formats[p]);
94   printf("\n");
95
96   glEnable(GL_TEXTURE_2D);
97
98   LoadCompressedImage();
99}
100
101
102static void
103Reshape( int width, int height )
104{
105   glViewport( 0, 0, width, height );
106   glMatrixMode( GL_PROJECTION );
107   glLoadIdentity();
108   glFrustum(-1, 1, -1, 1, 4, 100);
109   glMatrixMode( GL_MODELVIEW );
110   glLoadIdentity();
111}
112
113
114static void
115Key( unsigned char key, int x, int y )
116{
117   (void) x;
118   (void) y;
119   switch (key) {
120      case 'd':
121         EyeDist -= 1.0;
122         if (EyeDist < 4.0)
123            EyeDist = 4.0;
124         break;
125      case 'D':
126         EyeDist += 1.0;
127         break;
128      case 'z':
129         Rot += 5.0;
130         break;
131      case 'Z':
132         Rot -= 5.0;
133         break;
134      case 27:
135         exit(0);
136         break;
137   }
138   glutPostRedisplay();
139}
140
141
142static void
143Draw( void )
144{
145   glClearColor(0.3, 0.3, .8, 0);
146   glClear(GL_COLOR_BUFFER_BIT);
147
148   CheckError(__LINE__);
149   glPushMatrix();
150   glTranslatef(0, 0, -(EyeDist+0.01));
151   glRotatef(Rot, 0, 0, 1);
152   glBegin(GL_POLYGON);
153   glTexCoord2f(0, 0);  glVertex2f(-1, -1);
154   glTexCoord2f(1, 0);  glVertex2f( 1, -1);
155   glTexCoord2f(1, 1);  glVertex2f( 1,  1);
156   glTexCoord2f(0, 1);  glVertex2f(-1,  1);
157   glEnd();
158   glPopMatrix();
159
160   glutSwapBuffers();
161}
162
163
164int
165main( int argc, char *argv[] )
166{
167   glutInit( &argc, argv );
168   glutInitWindowSize( 600, 600 );
169
170   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE);
171
172   glutCreateWindow(argv[0]);
173   glewInit();
174
175   glutReshapeFunc( Reshape );
176   glutKeyboardFunc( Key );
177   glutDisplayFunc( Draw );
178
179   Init();
180
181   glutMainLoop();
182   return 0;
183}
184