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