Merge commit 'origin/master' into gallium-0.2
[mesa.git] / progs / demos / textures.c
1 /*
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
12 #define MAX_TEXTURES 8
13
14
15 static int Win;
16 static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
17 static GLboolean Anim = GL_TRUE;
18 static GLboolean Blend = GL_FALSE;
19 static GLboolean MipMap = 1+GL_FALSE;
20
21 static GLuint NumTextures;
22 static GLuint Textures[MAX_TEXTURES];
23 static float TexRot[MAX_TEXTURES][3];
24 static float TexPos[MAX_TEXTURES][3];
25 static float TexAspect[MAX_TEXTURES];
26
27 static const char *DefaultFiles[] = {
28 "../images/arch.rgb",
29 "../images/reflect.rgb",
30 "../images/tree2.rgba",
31 "../images/tile.rgb"
32 };
33
34
35 static void
36 Idle(void)
37 {
38 Xrot = glutGet(GLUT_ELAPSED_TIME) * 0.02;
39 Yrot = glutGet(GLUT_ELAPSED_TIME) * 0.04;
40 //Zrot += 2.0;
41 glutPostRedisplay();
42 }
43
44
45 static void
46 DrawTextures(void)
47 {
48 GLuint i;
49
50 for (i = 0; i < NumTextures; i++) {
51 GLfloat ar = TexAspect[i];
52
53 glPushMatrix();
54 glTranslatef(TexPos[i][0], TexPos[i][1], TexPos[i][2]);
55 glRotatef(TexRot[i][0], 1, 0, 0);
56 glRotatef(TexRot[i][1], 0, 1, 0);
57 glRotatef(TexRot[i][2], 0, 0, 1);
58
59 glBindTexture(GL_TEXTURE_2D, Textures[i]);
60 glBegin(GL_POLYGON);
61 glTexCoord2f( 0.0, 0.0 ); glVertex2f( -ar, -1.0 );
62 glTexCoord2f( 1.0, 0.0 ); glVertex2f( ar, -1.0 );
63 glTexCoord2f( 1.0, 1.0 ); glVertex2f( ar, 1.0 );
64 glTexCoord2f( 0.0, 1.0 ); glVertex2f( -ar, 1.0 );
65 glEnd();
66
67 glPopMatrix();
68 }
69 }
70
71 static void
72 Draw(void)
73 {
74 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
75
76 if (Blend) {
77 glEnable(GL_BLEND);
78 glDisable(GL_DEPTH_TEST);
79 }
80 else {
81 glDisable(GL_BLEND);
82 glEnable(GL_DEPTH_TEST);
83 }
84
85 glPushMatrix();
86 glRotatef(Xrot, 1, 0, 0);
87 glRotatef(Yrot, 0, 1, 0);
88 glRotatef(Zrot, 0, 0, 1);
89
90 DrawTextures();
91
92 glPopMatrix();
93
94 glutSwapBuffers();
95 }
96
97
98 static void
99 Reshape(int width, int height)
100 {
101 glViewport(0, 0, width, height);
102 glMatrixMode(GL_PROJECTION);
103 glLoadIdentity();
104 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 50.0);
105 glMatrixMode(GL_MODELVIEW);
106 glLoadIdentity();
107 glTranslatef(0.0, 0.0, -10.0);
108 }
109
110
111 static GLfloat
112 RandFloat(float min, float max)
113 {
114 float x = (float) (rand() % 1000) * 0.001;
115 x = x * (max - min) + min;
116 return x;
117 }
118
119
120 static void
121 Randomize(void)
122 {
123 GLfloat k = 1.0;
124 GLuint i;
125
126 srand(glutGet(GLUT_ELAPSED_TIME));
127
128 for (i = 0; i < NumTextures; i++) {
129 TexRot[i][0] = RandFloat(0.0, 360);
130 TexRot[i][1] = RandFloat(0.0, 360);
131 TexRot[i][2] = RandFloat(0.0, 360);
132 TexPos[i][0] = RandFloat(-k, k);
133 TexPos[i][1] = RandFloat(-k, k);
134 TexPos[i][2] = RandFloat(-k, k);
135 }
136 }
137
138
139 static void
140 SetTexFilters(void)
141 {
142 GLuint i;
143 for (i = 0; i < NumTextures; i++) {
144 glBindTexture(GL_TEXTURE_2D, Textures[i]);
145 if (MipMap) {
146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
147 GL_LINEAR_MIPMAP_LINEAR);
148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
149 }
150 else {
151 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
152 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
153 }
154 }
155 }
156
157
158 static void
159 Key(unsigned char key, int x, int y)
160 {
161 const GLfloat step = 3.0;
162 (void) x;
163 (void) y;
164 switch (key) {
165 case 'a':
166 Anim = !Anim;
167 if (Anim)
168 glutIdleFunc(Idle);
169 else
170 glutIdleFunc(NULL);
171 break;
172 case 'b':
173 Blend = !Blend;
174 break;
175 case 'm':
176 MipMap = !MipMap;
177 SetTexFilters();
178 break;
179 case 'r':
180 Randomize();
181 case 'z':
182 Zrot -= step;
183 break;
184 case 'Z':
185 Zrot += step;
186 break;
187 case 27:
188 glutDestroyWindow(Win);
189 exit(0);
190 break;
191 }
192
193 printf("Blend=%s MipMap=%s\n",
194 Blend ? "Y" : "n",
195 MipMap ? "Y" : "n");
196
197 glutPostRedisplay();
198 }
199
200
201 static void
202 SpecialKey(int key, int x, int y)
203 {
204 const GLfloat step = 3.0;
205 (void) x;
206 (void) y;
207 switch (key) {
208 case GLUT_KEY_UP:
209 Xrot -= step;
210 break;
211 case GLUT_KEY_DOWN:
212 Xrot += step;
213 break;
214 case GLUT_KEY_LEFT:
215 Yrot -= step;
216 break;
217 case GLUT_KEY_RIGHT:
218 Yrot += step;
219 break;
220 }
221 glutPostRedisplay();
222 }
223
224
225 static void
226 LoadTextures(GLuint n, const char *files[])
227 {
228 GLuint i;
229
230 NumTextures = n < MAX_TEXTURES ? n : MAX_TEXTURES;
231
232 glGenTextures(n, Textures);
233
234 for (i = 0; i < n; i++) {
235 GLint w, h;
236 glBindTexture(GL_TEXTURE_2D, Textures[i]);
237 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
238 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
239 if (!LoadRGBMipmaps2(files[i], GL_TEXTURE_2D, GL_RGB, &w, &h)) {
240 printf("Error: couldn't load %s\n", files[i]);
241 exit(1);
242 }
243 TexAspect[i] = (float) w / (float) h;
244 printf("Loaded %s\n", files[i]);
245 }
246 }
247
248
249 static void
250 Init(int argc, const char *argv[])
251 {
252 if (argc == 1)
253 LoadTextures(4, DefaultFiles);
254 else
255 LoadTextures(argc - 1, argv + 1);
256
257 Randomize();
258
259 glEnable(GL_TEXTURE_2D);
260
261 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
262 glColor4f(1, 1, 1, 0.5);
263
264 #if 0
265 /* setup lighting, etc */
266 glEnable(GL_LIGHTING);
267 glEnable(GL_LIGHT0);
268 #endif
269 }
270
271
272 static void
273 Usage(void)
274 {
275 printf("Usage:\n");
276 printf(" textures [file.rgb] ...\n");
277 printf("Keys:\n");
278 printf(" a - toggle animation\n");
279 printf(" b - toggle blending\n");
280 printf(" m - toggle mipmapping\n");
281 printf(" r - randomize\n");
282 printf(" ESC - exit\n");
283 }
284
285
286 int
287 main(int argc, char *argv[])
288 {
289 glutInit(&argc, argv);
290 glutInitWindowPosition(0, 0);
291 glutInitWindowSize(400, 400);
292 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
293 Win = glutCreateWindow(argv[0]);
294 glutReshapeFunc(Reshape);
295 glutKeyboardFunc(Key);
296 glutSpecialFunc(SpecialKey);
297 glutDisplayFunc(Draw);
298 if (Anim)
299 glutIdleFunc(Idle);
300 Init(argc, (const char **) argv);
301 Usage();
302 glutMainLoop();
303 return 0;
304 }