Remove CVS keywords.
[mesa.git] / progs / tests / manytex.c
1
2 /*
3 * test handling of many texture maps
4 * Also tests texture priority and residency.
5 *
6 * Brian Paul
7 * August 2, 2000
8 */
9
10
11 #include <assert.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <math.h>
16 #include <GL/glut.h>
17
18
19 static GLint NumTextures = 20;
20 static GLuint *TextureID = NULL;
21 static GLint *TextureWidth = NULL, *TextureHeight = NULL;
22 static GLboolean *TextureResidency = NULL;
23 static GLint TexWidth = 128, TexHeight = 128;
24 static GLfloat Zrot = 0;
25 static GLboolean Anim = GL_TRUE;
26 static GLint WinWidth = 500, WinHeight = 400;
27 static GLboolean MipMap = GL_FALSE;
28 static GLboolean LinearFilter = GL_FALSE;
29 static GLboolean RandomSize = GL_FALSE;
30 static GLint Rows, Columns;
31 static GLint LowPriorityCount = 0;
32
33
34 static void Idle( void )
35 {
36 Zrot += 1.0;
37 glutPostRedisplay();
38 }
39
40
41 static void Display( void )
42 {
43 GLfloat spacing = WinWidth / Columns;
44 GLfloat size = spacing * 0.4;
45 GLint i;
46
47 /* test residency */
48 if (0)
49 {
50 GLboolean b;
51 GLint i, resident;
52 b = glAreTexturesResident(NumTextures, TextureID, TextureResidency);
53 if (b) {
54 printf("all resident\n");
55 }
56 else {
57 resident = 0;
58 for (i = 0; i < NumTextures; i++) {
59 if (TextureResidency[i]) {
60 resident++;
61 }
62 }
63 printf("%d of %d texture resident\n", resident, NumTextures);
64 }
65 }
66
67 /* render the textured quads */
68 glClear( GL_COLOR_BUFFER_BIT );
69 for (i = 0; i < NumTextures; i++) {
70 GLint row = i / Columns;
71 GLint col = i % Columns;
72 GLfloat x = col * spacing + spacing * 0.5;
73 GLfloat y = row * spacing + spacing * 0.5;
74
75 GLfloat maxDim = (TextureWidth[i] > TextureHeight[i])
76 ? TextureWidth[i] : TextureHeight[i];
77 GLfloat w = TextureWidth[i] / maxDim;
78 GLfloat h = TextureHeight[i] / maxDim;
79
80 glPushMatrix();
81 glTranslatef(x, y, 0.0);
82 glRotatef(Zrot, 0, 0, 1);
83 glScalef(size, size, 1);
84
85 glBindTexture(GL_TEXTURE_2D, TextureID[i]);
86 glBegin(GL_POLYGON);
87 #if 0
88 glTexCoord2f(0, 0); glVertex2f(-1, -1);
89 glTexCoord2f(1, 0); glVertex2f( 1, -1);
90 glTexCoord2f(1, 1); glVertex2f( 1, 1);
91 glTexCoord2f(0, 1); glVertex2f(-1, 1);
92 #else
93 glTexCoord2f(0, 0); glVertex2f(-w, -h);
94 glTexCoord2f(1, 0); glVertex2f( w, -h);
95 glTexCoord2f(1, 1); glVertex2f( w, h);
96 glTexCoord2f(0, 1); glVertex2f(-w, h);
97 #endif
98 glEnd();
99 glPopMatrix();
100 }
101
102 glutSwapBuffers();
103 }
104
105
106 static void Reshape( int width, int height )
107 {
108 WinWidth = width;
109 WinHeight = height;
110 glViewport( 0, 0, width, height );
111 glMatrixMode( GL_PROJECTION );
112 glLoadIdentity();
113 glOrtho(0, width, 0, height, -1, 1);
114 glMatrixMode( GL_MODELVIEW );
115 glLoadIdentity();
116 }
117
118
119 /*
120 * Return a random int in [min, max].
121 */
122 static int RandomInt(int min, int max)
123 {
124 int i = rand();
125 int j = i % (max - min + 1);
126 return min + j;
127 }
128
129
130
131 static void Init( void )
132 {
133 GLint i;
134
135 if (RandomSize) {
136 printf("Creating %d %s random-size textures, ", NumTextures,
137 MipMap ? "Mipmapped" : "non-Mipmapped");
138 }
139 else {
140 printf("Creating %d %s %d x %d textures, ", NumTextures,
141 MipMap ? "Mipmapped" : "non-Mipmapped",
142 TexWidth, TexHeight);
143 }
144
145 if (LinearFilter) {
146 printf("bilinear filtering\n");
147 }
148 else {
149 printf("nearest filtering\n");
150 }
151
152
153 /* compute number of rows and columns of rects */
154 {
155 GLfloat area = (GLfloat) (WinWidth * WinHeight) / (GLfloat) NumTextures;
156 GLfloat edgeLen = sqrt(area);
157
158 Columns = WinWidth / edgeLen;
159 Rows = (NumTextures + Columns - 1) / Columns;
160 printf("Rows: %d Cols: %d\n", Rows, Columns);
161 }
162
163
164 if (!TextureID) {
165 TextureID = (GLuint *) malloc(sizeof(GLuint) * NumTextures);
166 assert(TextureID);
167 glGenTextures(NumTextures, TextureID);
168 }
169
170 if (!TextureResidency) {
171 TextureResidency = (GLboolean *) malloc(sizeof(GLboolean) * NumTextures);
172 assert(TextureResidency);
173 }
174
175 if (!TextureWidth) {
176 TextureWidth = (GLint *) malloc(sizeof(GLint) * NumTextures);
177 assert(TextureWidth);
178 }
179 if (!TextureHeight) {
180 TextureHeight = (GLint *) malloc(sizeof(GLint) * NumTextures);
181 assert(TextureHeight);
182 }
183
184 for (i = 0; i < NumTextures; i++) {
185 GLubyte color[4];
186 GLubyte *texImage;
187 GLint j, row, col;
188
189 row = i / Columns;
190 col = i % Columns;
191
192 glBindTexture(GL_TEXTURE_2D, TextureID[i]);
193
194 if (i < LowPriorityCount)
195 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.5F);
196
197 if (RandomSize) {
198 #if 0
199 int k = (glutGet(GLUT_ELAPSED_TIME) % 7) + 2;
200 TexWidth = 1 << k;
201 TexHeight = 1 << k;
202 #else
203 TexWidth = 1 << RandomInt(2, 7);
204 TexHeight = 1 << RandomInt(2, 7);
205 printf("Random size of %3d: %d x %d\n", i, TexWidth, TexHeight);
206 #endif
207 }
208
209 TextureWidth[i] = TexWidth;
210 TextureHeight[i] = TexHeight;
211
212 texImage = (GLubyte*) malloc(4 * TexWidth * TexHeight * sizeof(GLubyte));
213 assert(texImage);
214
215 /* determine texture color */
216 color[0] = (GLint) (255.0 * ((float) col / (Columns - 1)));
217 color[1] = 127;
218 color[2] = (GLint) (255.0 * ((float) row / (Rows - 1)));
219 color[3] = 255;
220
221 /* fill in solid-colored teximage */
222 for (j = 0; j < TexWidth * TexHeight; j++) {
223 texImage[j*4+0] = color[0];
224 texImage[j*4+1] = color[1];
225 texImage[j*4+2] = color[2];
226 texImage[j*4+3] = color[3];
227 }
228
229 if (MipMap) {
230 GLint level = 0;
231 GLint w = TexWidth, h = TexHeight;
232 while (1) {
233 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0,
234 GL_RGBA, GL_UNSIGNED_BYTE, texImage);
235 if (w == 1 && h == 1)
236 break;
237 if (w > 1)
238 w /= 2;
239 if (h > 1)
240 h /= 2;
241 level++;
242 /*printf("%d: %d x %d\n", level, w, h);*/
243 }
244 if (LinearFilter) {
245 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
246 GL_LINEAR_MIPMAP_LINEAR);
247 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
248 }
249 else {
250 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
251 GL_NEAREST_MIPMAP_NEAREST);
252 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
253 }
254 }
255 else {
256 /* Set corners to white */
257 int k = 0;
258 texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
259 k = (TexWidth - 1) * 4;
260 texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
261 k = (TexWidth * TexHeight - TexWidth) * 4;
262 texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
263 k = (TexWidth * TexHeight - 1) * 4;
264 texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255;
265
266 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TexWidth, TexHeight, 0,
267 GL_RGBA, GL_UNSIGNED_BYTE, texImage);
268 if (LinearFilter) {
269 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
270 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
271 }
272 else {
273 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
274 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
275 }
276 }
277
278 free(texImage);
279 }
280
281 glEnable(GL_TEXTURE_2D);
282 }
283
284
285 static void Key( unsigned char key, int x, int y )
286 {
287 const GLfloat step = 3.0;
288 (void) x;
289 (void) y;
290 switch (key) {
291 case 'a':
292 Anim = !Anim;
293 if (Anim)
294 glutIdleFunc(Idle);
295 else
296 glutIdleFunc(NULL);
297 break;
298 case 's':
299 Idle();
300 break;
301 case 'z':
302 Zrot -= step;
303 break;
304 case 'Z':
305 Zrot += step;
306 break;
307 case ' ':
308 Init();
309 break;
310 case 27:
311 exit(0);
312 break;
313 }
314 glutPostRedisplay();
315 }
316
317
318 int main( int argc, char *argv[] )
319 {
320 GLint i;
321
322 glutInit( &argc, argv );
323 glutInitWindowPosition( 0, 0 );
324 glutInitWindowSize( WinWidth, WinHeight );
325 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
326 glutCreateWindow(argv[0]);
327 glutReshapeFunc( Reshape );
328 glutKeyboardFunc( Key );
329 glutDisplayFunc( Display );
330 if (Anim)
331 glutIdleFunc(Idle);
332
333 for (i = 1; i < argc; i++) {
334 if (strcmp(argv[i], "-n") == 0) {
335 NumTextures = atoi(argv[i+1]);
336 if (NumTextures <= 0) {
337 printf("Error, bad number of textures\n");
338 return 1;
339 }
340 i++;
341 }
342 else if (strcmp(argv[i], "-mipmap") == 0) {
343 MipMap = GL_TRUE;
344 }
345 else if (strcmp(argv[i], "-linear") == 0) {
346 LinearFilter = GL_TRUE;
347 }
348 else if (strcmp(argv[i], "-size") == 0) {
349 TexWidth = atoi(argv[i+1]);
350 TexHeight = atoi(argv[i+2]);
351 assert(TexWidth >= 1);
352 assert(TexHeight >= 1);
353 i += 2;
354 }
355 else if (strcmp(argv[i], "-randomsize") == 0) {
356 RandomSize = GL_TRUE;
357 }
358 else if (strcmp(argv[i], "-lowpri") == 0) {
359 LowPriorityCount = atoi(argv[i+1]);
360 i++;
361 }
362 else {
363 printf("Usage:\n");
364 printf(" manytex [options]\n");
365 printf("Options:\n");
366 printf(" -n <number of texture objects>\n");
367 printf(" -size <width> <height> - specify texture size\n");
368 printf(" -randomsize - use random size textures\n");
369 printf(" -mipmap - generate mipmaps\n");
370 printf(" -linear - use linear filtering instead of nearest\n");
371 printf(" -lowpri <n> - Set lower priority on <n> textures\n");
372 return 0;
373 }
374 }
375
376 Init();
377
378 glutMainLoop();
379
380 return 0;
381 }