Use glad instead of GLEW.
[mesa-demos.git] / src / demos / textures.c
blobcc43bda3df29af6f454ee811eb678cde49fb0752
1 /*
2 * Simple test of multiple textures
3 */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <math.h>
9 #include <glad/glad.h>
10 #include "glut_wrap.h"
11 #include "readtex.h"
13 #define TEST_CLAMP 0
14 #define TEST_MIPMAPS 0
15 #define TEST_GEN_COMPRESSED_MIPMAPS 0
17 #define MAX_TEXTURES 8
20 static int Win;
21 static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
22 static GLboolean Anim = GL_TRUE;
23 static GLboolean Blend = GL_FALSE;
24 static GLuint Filter = 0;
25 static GLboolean Clamp = GL_FALSE;
26 static GLfloat Scale = 1.0;
28 static GLuint NumTextures;
29 static GLuint Textures[MAX_TEXTURES];
30 static float TexRot[MAX_TEXTURES][3];
31 static float TexPos[MAX_TEXTURES][3];
32 static float TexAspect[MAX_TEXTURES];
34 static const char *DefaultFiles[] = {
35 DEMOS_DATA_DIR "arch.rgb",
36 DEMOS_DATA_DIR "reflect.rgb",
37 DEMOS_DATA_DIR "tree2.rgba",
38 DEMOS_DATA_DIR "tile.rgb"
42 #define NUM_FILTERS 6
43 static
44 struct filter {
45 GLenum min, mag;
46 const char *name;
47 } FilterModes[NUM_FILTERS] = {
48 { GL_NEAREST, GL_NEAREST, "Nearest,Nearest" },
49 { GL_LINEAR, GL_LINEAR, "Linear,Linear" },
50 { GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST, "NearestMipmapNearest,Nearest" },
51 { GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR, "NearestMipmapNearest,Linear" },
52 { GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR, "LinearMipmapNearest,Linear" },
53 { GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, "LinearMipmapLinear,Linear" }
59 static void
60 Idle(void)
62 Xrot = glutGet(GLUT_ELAPSED_TIME) * 0.02;
63 Yrot = glutGet(GLUT_ELAPSED_TIME) * 0.04;
64 /* Zrot += 2.0; */
65 glutPostRedisplay();
69 static void
70 DrawTextures(void)
72 GLuint i;
74 for (i = 0; i < NumTextures; i++) {
75 GLfloat ar = TexAspect[i];
77 glPushMatrix();
78 glTranslatef(TexPos[i][0], TexPos[i][1], TexPos[i][2]);
79 glRotatef(TexRot[i][0], 1, 0, 0);
80 glRotatef(TexRot[i][1], 0, 1, 0);
81 glRotatef(TexRot[i][2], 0, 0, 1);
83 glBindTexture(GL_TEXTURE_2D, Textures[i]);
84 glBegin(GL_POLYGON);
85 #if TEST_CLAMP
86 glTexCoord2f( -0.5, -0.5 ); glVertex2f( -ar, -1.0 );
87 glTexCoord2f( 1.5, -0.5 ); glVertex2f( ar, -1.0 );
88 glTexCoord2f( 1.5, 1.5 ); glVertex2f( ar, 1.0 );
89 glTexCoord2f( -0.5, 1.5 ); glVertex2f( -ar, 1.0 );
90 #else
91 glTexCoord2f( 0.0, 0.0 ); glVertex2f( -ar, -1.0 );
92 glTexCoord2f( 1.0, 0.0 ); glVertex2f( ar, -1.0 );
93 glTexCoord2f( 1.0, 1.0 ); glVertex2f( ar, 1.0 );
94 glTexCoord2f( 0.0, 1.0 ); glVertex2f( -ar, 1.0 );
95 #endif
96 glEnd();
98 glPopMatrix();
102 static void
103 Draw(void)
105 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
107 if (Blend) {
108 glEnable(GL_BLEND);
109 glDisable(GL_DEPTH_TEST);
111 else {
112 glDisable(GL_BLEND);
113 glEnable(GL_DEPTH_TEST);
116 glPushMatrix();
117 glRotatef(Xrot, 1, 0, 0);
118 glRotatef(Yrot, 0, 1, 0);
119 glRotatef(Zrot, 0, 0, 1);
120 glScalef(Scale, Scale, Scale);
122 DrawTextures();
124 glPopMatrix();
126 glutSwapBuffers();
130 static void
131 Reshape(int width, int height)
133 glViewport(0, 0, width, height);
134 glMatrixMode(GL_PROJECTION);
135 glLoadIdentity();
136 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 50.0);
137 glMatrixMode(GL_MODELVIEW);
138 glLoadIdentity();
139 glTranslatef(0.0, 0.0, -10.0);
143 static GLfloat
144 RandFloat(float min, float max)
146 float x = (float) (rand() % 1000) * 0.001;
147 x = x * (max - min) + min;
148 return x;
152 static void
153 Randomize(void)
155 GLfloat k = 1.0;
156 GLuint i;
158 srand(glutGet(GLUT_ELAPSED_TIME));
160 for (i = 0; i < NumTextures; i++) {
161 TexRot[i][0] = RandFloat(0.0, 360);
162 TexRot[i][1] = RandFloat(0.0, 360);
163 TexRot[i][2] = RandFloat(0.0, 360);
164 TexPos[i][0] = RandFloat(-k, k);
165 TexPos[i][1] = RandFloat(-k, k);
166 TexPos[i][2] = RandFloat(-k, k);
171 static void
172 SetTexParams(void)
174 GLuint i;
175 for (i = 0; i < NumTextures; i++) {
176 glBindTexture(GL_TEXTURE_2D, Textures[i]);
177 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
178 FilterModes[Filter].min);
179 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
180 FilterModes[Filter].mag);
182 if (Clamp) {
183 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
184 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
186 else {
187 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
188 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
194 static void
195 PrintState(void)
197 printf("Blend=%s Filter=%s\n",
198 Blend ? "Y" : "n",
199 FilterModes[Filter].name);
203 static void
204 Key(unsigned char key, int x, int y)
206 const GLfloat step = 3.0;
207 (void) x;
208 (void) y;
209 switch (key) {
210 case 'a':
211 case ' ':
212 Anim = !Anim;
213 if (Anim)
214 glutIdleFunc(Idle);
215 else
216 glutIdleFunc(NULL);
217 break;
218 case 'b':
219 Blend = !Blend;
220 break;
221 case 's':
222 Scale /= 1.1;
223 break;
224 case 'S':
225 Scale *= 1.1;
226 break;
227 case 'f':
228 Filter = (Filter + 1) % NUM_FILTERS;
229 SetTexParams();
230 break;
231 case 'r':
232 Randomize();
233 break;
234 #if TEST_CLAMP
235 case 'c':
236 Clamp = !Clamp;
237 SetTexParams();
238 break;
239 #endif
240 case 'z':
241 Zrot -= step;
242 break;
243 case 'Z':
244 Zrot += step;
245 break;
246 case 27:
247 glutDestroyWindow(Win);
248 exit(0);
249 break;
252 PrintState();
254 glutPostRedisplay();
258 static void
259 SpecialKey(int key, int x, int y)
261 const GLfloat step = 3.0;
262 (void) x;
263 (void) y;
264 switch (key) {
265 case GLUT_KEY_UP:
266 Xrot -= step;
267 break;
268 case GLUT_KEY_DOWN:
269 Xrot += step;
270 break;
271 case GLUT_KEY_LEFT:
272 Yrot -= step;
273 break;
274 case GLUT_KEY_RIGHT:
275 Yrot += step;
276 break;
278 glutPostRedisplay();
282 static void
283 LoadTextures(GLuint n, const char *files[])
285 GLuint i;
287 NumTextures = n < MAX_TEXTURES ? n : MAX_TEXTURES;
289 glGenTextures(n, Textures);
291 SetTexParams();
293 for (i = 0; i < n; i++) {
294 GLint w, h;
295 glBindTexture(GL_TEXTURE_2D, Textures[i]);
296 #if TEST_MIPMAPS
298 static const GLubyte color[9][4] = {
299 {255, 0, 0},
300 {0, 255, 0},
301 {0, 0, 255},
302 {0, 255, 255},
303 {255, 0, 255},
304 {255, 255, 0},
305 {255, 128, 255},
306 {128, 128, 128},
307 {64, 64, 64}
310 GLubyte image[256*256*4];
311 int i, level;
312 w = h = 256;
313 for (level = 0; level <= 8; level++) {
314 for (i = 0; i < w * h; i++) {
315 image[i*4+0] = color[level][0];
316 image[i*4+1] = color[level][1];
317 image[i*4+2] = color[level][2];
318 image[i*4+3] = color[level][3];
320 printf("Load level %d: %d x %d\n", level, w>>level, h>>level);
321 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w>>level, h>>level, 0,
322 GL_RGBA, GL_UNSIGNED_BYTE, image);
325 #elif TEST_GEN_COMPRESSED_MIPMAPS
327 GLenum intFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
328 int f;
329 GLenum format;
330 GLubyte *img = LoadRGBImage(files[i], &w, &h, &format);
331 GLboolean write_compressed = GL_FALSE;
332 GLboolean read_compressed = GL_FALSE;
334 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
335 glTexImage2D(GL_TEXTURE_2D, 0, intFormat, w, h, 0,
336 format, GL_UNSIGNED_BYTE, img);
337 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
338 free(img);
340 glGetTexLevelParameteriv(GL_TEXTURE_2D, i,
341 GL_TEXTURE_INTERNAL_FORMAT, &f);
342 printf("actual internal format 0x%x\n", f);
344 if (write_compressed) {
345 GLint i, sz, w, h;
346 int num_levels = 8;
347 for (i = 0; i < num_levels; i++) {
348 char name[20], *buf;
349 FILE *f;
350 glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, &w);
351 glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_HEIGHT, &h);
352 glGetTexLevelParameteriv(GL_TEXTURE_2D, i,
353 GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &sz);
354 printf("Writing level %d: %d x %d bytes: %d\n", i, w, h, sz);
355 buf = malloc(sz);
356 glGetCompressedTexImageARB(GL_TEXTURE_2D, i, buf);
357 sprintf(name, "comp%d", i);
358 f = fopen(name, "w");
359 fwrite(buf, 1, sz, f);
360 fclose(f);
361 free(buf);
365 if (read_compressed) {
366 GLint i, sz, w, h;
367 int num_levels = 8;
368 for (i = 01; i < num_levels; i++) {
369 char name[20], *buf;
370 FILE *f;
371 glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, &w);
372 glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_HEIGHT, &h);
373 glGetTexLevelParameteriv(GL_TEXTURE_2D, i,
374 GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &sz);
375 buf = malloc(sz);
376 sprintf(name, "comp%d", i);
377 printf("Reading level %d: %d x %d bytes: %d from %s\n",
378 i, w, h, sz, name);
379 f = fopen(name, "r");
380 fread(buf, 1, sz, f);
381 fclose(f);
382 glCompressedTexImage2DARB(GL_TEXTURE_2D, i, intFormat,
383 w, h, 0, sz, buf);
384 free(buf);
388 #else
389 if (!LoadRGBMipmaps2(files[i], GL_TEXTURE_2D, GL_RGB, &w, &h)) {
390 printf("Error: couldn't load %s\n", files[i]);
391 exit(1);
393 #endif
394 TexAspect[i] = (float) w / (float) h;
395 printf("Loaded %s\n", files[i]);
400 static void
401 Init(int argc, const char *argv[])
403 if (argc == 1)
404 LoadTextures(4, DefaultFiles);
405 else
406 LoadTextures(argc - 1, argv + 1);
408 Randomize();
410 glEnable(GL_TEXTURE_2D);
412 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
413 glColor4f(1, 1, 1, 0.5);
415 #if 0
416 /* setup lighting, etc */
417 glEnable(GL_LIGHTING);
418 glEnable(GL_LIGHT0);
419 #endif
423 static void
424 Usage(void)
426 printf("Usage:\n");
427 printf(" textures [file.rgb] ...\n");
428 printf("Keys:\n");
429 printf(" a - toggle animation\n");
430 printf(" b - toggle blending\n");
431 printf(" f - change texture filter mode\n");
432 printf(" r - randomize\n");
433 printf(" ESC - exit\n");
438 main(int argc, char *argv[])
440 glutInitWindowSize(700, 700);
441 glutInit(&argc, argv);
442 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
443 Win = glutCreateWindow(argv[0]);
444 gladLoadGL();
445 glutReshapeFunc(Reshape);
446 glutKeyboardFunc(Key);
447 glutSpecialFunc(SpecialKey);
448 glutDisplayFunc(Draw);
449 if (Anim)
450 glutIdleFunc(Idle);
451 Init(argc, (const char **) argv);
452 Usage();
453 PrintState();
454 glutMainLoop();
455 return 0;