blob: 773d7378b197bf7e498e177b365668a755649fcd [file] [log] [blame]
Brian Paulf6e806a2008-10-09 19:45:03 -06001/*
2 * Simple test of multiple textures
3 */
4
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <math.h>
9#include <GL/glut.h>
10#include "readtex.h"
11
Brian Paul22781072008-10-20 17:43:05 -060012#define TEST_CLAMP 0
13#define TEST_MIPMAPS 0
14
Brian Paulf6e806a2008-10-09 19:45:03 -060015#define MAX_TEXTURES 8
16
17
18static int Win;
19static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
20static GLboolean Anim = GL_TRUE;
21static GLboolean Blend = GL_FALSE;
Brian Paul22781072008-10-20 17:43:05 -060022static GLuint Filter = 0;
23static GLboolean Clamp = GL_FALSE;
Brian Paulf6e806a2008-10-09 19:45:03 -060024
25static GLuint NumTextures;
26static GLuint Textures[MAX_TEXTURES];
27static float TexRot[MAX_TEXTURES][3];
28static float TexPos[MAX_TEXTURES][3];
29static float TexAspect[MAX_TEXTURES];
30
31static const char *DefaultFiles[] = {
32 "../images/arch.rgb",
33 "../images/reflect.rgb",
34 "../images/tree2.rgba",
35 "../images/tile.rgb"
36};
37
38
Brian Paul22781072008-10-20 17:43:05 -060039#define NUM_FILTERS 5
40static
41struct filter {
42 GLenum min, mag;
43 const char *name;
44} FilterModes[NUM_FILTERS] = {
45 { GL_NEAREST, GL_NEAREST, "Nearest,Nearest" },
46 { GL_LINEAR, GL_LINEAR, "Linear,Linear" },
47 { GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST, "NearestMipmapNearest,Nearest" },
48 { GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR, "LinearMipmapNearest,Linear" },
49 { GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, "LinearMipmapLinear,Linear" }
50};
51
52
53
54
Brian Paulf6e806a2008-10-09 19:45:03 -060055static void
56Idle(void)
57{
58 Xrot = glutGet(GLUT_ELAPSED_TIME) * 0.02;
59 Yrot = glutGet(GLUT_ELAPSED_TIME) * 0.04;
Brian Paul1888a722009-11-17 16:13:12 -070060 /*Zrot += 2.0;*/
Brian Paulf6e806a2008-10-09 19:45:03 -060061 glutPostRedisplay();
62}
63
64
65static void
66DrawTextures(void)
67{
68 GLuint i;
69
70 for (i = 0; i < NumTextures; i++) {
71 GLfloat ar = TexAspect[i];
72
73 glPushMatrix();
74 glTranslatef(TexPos[i][0], TexPos[i][1], TexPos[i][2]);
75 glRotatef(TexRot[i][0], 1, 0, 0);
76 glRotatef(TexRot[i][1], 0, 1, 0);
77 glRotatef(TexRot[i][2], 0, 0, 1);
78
79 glBindTexture(GL_TEXTURE_2D, Textures[i]);
80 glBegin(GL_POLYGON);
Brian Paul22781072008-10-20 17:43:05 -060081#if TEST_CLAMP
82 glTexCoord2f( -0.5, -0.5 ); glVertex2f( -ar, -1.0 );
83 glTexCoord2f( 1.5, -0.5 ); glVertex2f( ar, -1.0 );
84 glTexCoord2f( 1.5, 1.5 ); glVertex2f( ar, 1.0 );
85 glTexCoord2f( -0.5, 1.5 ); glVertex2f( -ar, 1.0 );
86#else
Brian Paulf6e806a2008-10-09 19:45:03 -060087 glTexCoord2f( 0.0, 0.0 ); glVertex2f( -ar, -1.0 );
88 glTexCoord2f( 1.0, 0.0 ); glVertex2f( ar, -1.0 );
89 glTexCoord2f( 1.0, 1.0 ); glVertex2f( ar, 1.0 );
90 glTexCoord2f( 0.0, 1.0 ); glVertex2f( -ar, 1.0 );
Brian Paul22781072008-10-20 17:43:05 -060091#endif
Brian Paulf6e806a2008-10-09 19:45:03 -060092 glEnd();
93
94 glPopMatrix();
95 }
96}
97
98static void
99Draw(void)
100{
101 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
102
103 if (Blend) {
104 glEnable(GL_BLEND);
105 glDisable(GL_DEPTH_TEST);
106 }
107 else {
108 glDisable(GL_BLEND);
109 glEnable(GL_DEPTH_TEST);
110 }
111
112 glPushMatrix();
113 glRotatef(Xrot, 1, 0, 0);
114 glRotatef(Yrot, 0, 1, 0);
115 glRotatef(Zrot, 0, 0, 1);
116
117 DrawTextures();
118
119 glPopMatrix();
120
121 glutSwapBuffers();
122}
123
124
125static void
126Reshape(int width, int height)
127{
128 glViewport(0, 0, width, height);
129 glMatrixMode(GL_PROJECTION);
130 glLoadIdentity();
131 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 50.0);
132 glMatrixMode(GL_MODELVIEW);
133 glLoadIdentity();
134 glTranslatef(0.0, 0.0, -10.0);
135}
136
137
138static GLfloat
139RandFloat(float min, float max)
140{
141 float x = (float) (rand() % 1000) * 0.001;
142 x = x * (max - min) + min;
143 return x;
144}
145
146
147static void
148Randomize(void)
149{
150 GLfloat k = 1.0;
151 GLuint i;
152
153 srand(glutGet(GLUT_ELAPSED_TIME));
154
155 for (i = 0; i < NumTextures; i++) {
156 TexRot[i][0] = RandFloat(0.0, 360);
157 TexRot[i][1] = RandFloat(0.0, 360);
158 TexRot[i][2] = RandFloat(0.0, 360);
159 TexPos[i][0] = RandFloat(-k, k);
160 TexPos[i][1] = RandFloat(-k, k);
161 TexPos[i][2] = RandFloat(-k, k);
162 }
163}
164
165
166static void
Brian Paul22781072008-10-20 17:43:05 -0600167SetTexParams(void)
Brian Paulf6e806a2008-10-09 19:45:03 -0600168{
169 GLuint i;
170 for (i = 0; i < NumTextures; i++) {
171 glBindTexture(GL_TEXTURE_2D, Textures[i]);
Brian Paul22781072008-10-20 17:43:05 -0600172 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
173 FilterModes[Filter].min);
174 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
175 FilterModes[Filter].mag);
176
177 if (Clamp) {
178 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
179 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Brian Paulf6e806a2008-10-09 19:45:03 -0600180 }
181 else {
Brian Paul22781072008-10-20 17:43:05 -0600182 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
183 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Brian Paulf6e806a2008-10-09 19:45:03 -0600184 }
185 }
186}
187
188
189static void
190Key(unsigned char key, int x, int y)
191{
192 const GLfloat step = 3.0;
193 (void) x;
194 (void) y;
195 switch (key) {
196 case 'a':
Brian Paul22781072008-10-20 17:43:05 -0600197 case ' ':
Brian Paulf6e806a2008-10-09 19:45:03 -0600198 Anim = !Anim;
199 if (Anim)
200 glutIdleFunc(Idle);
201 else
202 glutIdleFunc(NULL);
203 break;
204 case 'b':
205 Blend = !Blend;
206 break;
Brian Paul22781072008-10-20 17:43:05 -0600207 case 'f':
208 Filter = (Filter + 1) % NUM_FILTERS;
209 SetTexParams();
Brian Paulf6e806a2008-10-09 19:45:03 -0600210 break;
211 case 'r':
212 Randomize();
Brian Paul22781072008-10-20 17:43:05 -0600213 break;
214#if TEST_CLAMP
215 case 'c':
216 Clamp = !Clamp;
217 SetTexParams();
218 break;
219#endif
Brian Paulf6e806a2008-10-09 19:45:03 -0600220 case 'z':
221 Zrot -= step;
222 break;
223 case 'Z':
224 Zrot += step;
225 break;
226 case 27:
227 glutDestroyWindow(Win);
228 exit(0);
229 break;
230 }
231
Brian Paul22781072008-10-20 17:43:05 -0600232 printf("Blend=%s Filter=%s\n",
Brian Paulf6e806a2008-10-09 19:45:03 -0600233 Blend ? "Y" : "n",
Brian Paul22781072008-10-20 17:43:05 -0600234 FilterModes[Filter].name);
Brian Paulf6e806a2008-10-09 19:45:03 -0600235
236 glutPostRedisplay();
237}
238
239
240static void
241SpecialKey(int key, int x, int y)
242{
243 const GLfloat step = 3.0;
244 (void) x;
245 (void) y;
246 switch (key) {
247 case GLUT_KEY_UP:
248 Xrot -= step;
249 break;
250 case GLUT_KEY_DOWN:
251 Xrot += step;
252 break;
253 case GLUT_KEY_LEFT:
254 Yrot -= step;
255 break;
256 case GLUT_KEY_RIGHT:
257 Yrot += step;
258 break;
259 }
260 glutPostRedisplay();
261}
262
263
264static void
265LoadTextures(GLuint n, const char *files[])
266{
267 GLuint i;
268
269 NumTextures = n < MAX_TEXTURES ? n : MAX_TEXTURES;
270
271 glGenTextures(n, Textures);
272
Brian Paul22781072008-10-20 17:43:05 -0600273 SetTexParams();
274
Brian Paulf6e806a2008-10-09 19:45:03 -0600275 for (i = 0; i < n; i++) {
276 GLint w, h;
277 glBindTexture(GL_TEXTURE_2D, Textures[i]);
Brian Paul22781072008-10-20 17:43:05 -0600278#if TEST_MIPMAPS
279 {
280 static const GLubyte color[9][4] = {
281 {255, 0, 0},
282 {0, 255, 0},
283 {0, 0, 255},
284 {0, 255, 255},
285 {255, 0, 255},
286 {255, 255, 0},
287 {255, 128, 255},
288 {128, 128, 128},
289 {64, 64, 64}
290 };
291
292 GLubyte image[256*256*4];
293 int i, level;
294 w = h = 256;
295 for (level = 0; level <= 8; level++) {
296 for (i = 0; i < w * h; i++) {
297 image[i*4+0] = color[level][0];
298 image[i*4+1] = color[level][1];
299 image[i*4+2] = color[level][2];
300 image[i*4+3] = color[level][3];
301 }
302 printf("Load level %d: %d x %d\n", level, w>>level, h>>level);
303 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w>>level, h>>level, 0,
304 GL_RGBA, GL_UNSIGNED_BYTE, image);
305 }
306 }
307#else
Brian Paulf6e806a2008-10-09 19:45:03 -0600308 if (!LoadRGBMipmaps2(files[i], GL_TEXTURE_2D, GL_RGB, &w, &h)) {
309 printf("Error: couldn't load %s\n", files[i]);
310 exit(1);
311 }
Brian Paul22781072008-10-20 17:43:05 -0600312#endif
Brian Paulf6e806a2008-10-09 19:45:03 -0600313 TexAspect[i] = (float) w / (float) h;
314 printf("Loaded %s\n", files[i]);
315 }
316}
317
318
319static void
320Init(int argc, const char *argv[])
321{
322 if (argc == 1)
323 LoadTextures(4, DefaultFiles);
324 else
325 LoadTextures(argc - 1, argv + 1);
326
327 Randomize();
328
329 glEnable(GL_TEXTURE_2D);
330
331 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
332 glColor4f(1, 1, 1, 0.5);
333
334#if 0
335 /* setup lighting, etc */
336 glEnable(GL_LIGHTING);
337 glEnable(GL_LIGHT0);
338#endif
339}
340
341
342static void
343Usage(void)
344{
345 printf("Usage:\n");
346 printf(" textures [file.rgb] ...\n");
347 printf("Keys:\n");
348 printf(" a - toggle animation\n");
349 printf(" b - toggle blending\n");
Brian Paul22781072008-10-20 17:43:05 -0600350 printf(" f - change texture filter mode\n");
Brian Paulf6e806a2008-10-09 19:45:03 -0600351 printf(" r - randomize\n");
352 printf(" ESC - exit\n");
353}
354
355
356int
357main(int argc, char *argv[])
358{
Brian Paul22781072008-10-20 17:43:05 -0600359 glutInitWindowSize(700, 700);
Brian Paul263f4322009-12-18 08:12:55 -0700360 glutInit(&argc, argv);
Brian Paulf6e806a2008-10-09 19:45:03 -0600361 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
362 Win = glutCreateWindow(argv[0]);
363 glutReshapeFunc(Reshape);
364 glutKeyboardFunc(Key);
365 glutSpecialFunc(SpecialKey);
366 glutDisplayFunc(Draw);
367 if (Anim)
368 glutIdleFunc(Idle);
369 Init(argc, (const char **) argv);
370 Usage();
371 glutMainLoop();
372 return 0;
373}