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