3 * test handling of many texture maps
4 * Also tests texture priority and residency.
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;
35 static void Idle( void )
42 static void Display( void )
44 GLfloat spacing
= WinWidth
/ Columns
;
45 GLfloat size
= spacing
* 0.4;
53 b
= glAreTexturesResident(NumTextures
, TextureID
, TextureResidency
);
55 printf("all resident\n");
59 for (i
= 0; i
< NumTextures
; i
++) {
60 if (TextureResidency
[i
]) {
64 printf("%d of %d texture resident\n", resident
, NumTextures
);
68 /* render the textured quads */
69 glClear( GL_COLOR_BUFFER_BIT
);
70 for (i
= 0; i
< NumTextures
; i
++) {
71 GLint row
= i
/ Columns
;
72 GLint col
= i
% Columns
;
73 GLfloat x
= col
* spacing
+ spacing
* 0.5;
74 GLfloat y
= row
* spacing
+ spacing
* 0.5;
76 GLfloat maxDim
= (TextureWidth
[i
] > TextureHeight
[i
])
77 ? TextureWidth
[i
] : TextureHeight
[i
];
78 GLfloat w
= TextureWidth
[i
] / maxDim
;
79 GLfloat h
= TextureHeight
[i
] / maxDim
;
82 glTranslatef(x
, y
, 0.0);
83 glRotatef(Zrot
, 0, 0, 1);
84 glScalef(size
, size
, 1);
86 glBindTexture(GL_TEXTURE_2D
, TextureID
[i
]);
89 glTexCoord2f(0, 0); glVertex2f(-1, -1);
90 glTexCoord2f(1, 0); glVertex2f( 1, -1);
91 glTexCoord2f(1, 1); glVertex2f( 1, 1);
92 glTexCoord2f(0, 1); glVertex2f(-1, 1);
94 glTexCoord2f(0, 0); glVertex2f(-w
, -h
);
95 glTexCoord2f(1, 0); glVertex2f( w
, -h
);
96 glTexCoord2f(1, 1); glVertex2f( w
, h
);
97 glTexCoord2f(0, 1); glVertex2f(-w
, h
);
107 static void Reshape( int width
, int height
)
111 glViewport( 0, 0, width
, height
);
112 glMatrixMode( GL_PROJECTION
);
114 glOrtho(0, width
, 0, height
, -1, 1);
115 glMatrixMode( GL_MODELVIEW
);
121 * Return a random int in [min, max].
123 static int RandomInt(int min
, int max
)
126 int j
= i
% (max
- min
+ 1);
131 static void DeleteTextures(void)
133 glDeleteTextures(NumTextures
, TextureID
);
140 static void Init( void )
145 printf("Creating %d %s random-size textures, ", NumTextures
,
146 MipMap
? "Mipmapped" : "non-Mipmapped");
149 printf("Creating %d %s %d x %d textures, ", NumTextures
,
150 MipMap
? "Mipmapped" : "non-Mipmapped",
151 TexWidth
, TexHeight
);
155 printf("bilinear filtering\n");
158 printf("nearest filtering\n");
162 /* compute number of rows and columns of rects */
164 GLfloat area
= (GLfloat
) (WinWidth
* WinHeight
) / (GLfloat
) NumTextures
;
165 GLfloat edgeLen
= sqrt(area
);
167 Columns
= WinWidth
/ edgeLen
;
168 Rows
= (NumTextures
+ Columns
- 1) / Columns
;
169 printf("Rows: %d Cols: %d\n", Rows
, Columns
);
174 TextureID
= (GLuint
*) malloc(sizeof(GLuint
) * NumTextures
);
176 glGenTextures(NumTextures
, TextureID
);
179 if (!TextureResidency
) {
180 TextureResidency
= (GLboolean
*) malloc(sizeof(GLboolean
) * NumTextures
);
181 assert(TextureResidency
);
185 TextureWidth
= (GLint
*) malloc(sizeof(GLint
) * NumTextures
);
186 assert(TextureWidth
);
188 if (!TextureHeight
) {
189 TextureHeight
= (GLint
*) malloc(sizeof(GLint
) * NumTextures
);
190 assert(TextureHeight
);
193 for (i
= 0; i
< NumTextures
; i
++) {
201 glBindTexture(GL_TEXTURE_2D
, TextureID
[i
]);
203 if (i
< LowPriorityCount
)
204 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_PRIORITY
, 0.5F
);
208 int k
= (glutGet(GLUT_ELAPSED_TIME
) % 7) + 2;
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
);
218 TextureWidth
[i
] = TexWidth
;
219 TextureHeight
[i
] = TexHeight
;
221 texImage
= (GLubyte
*) malloc(4 * TexWidth
* TexHeight
* sizeof(GLubyte
));
224 /* determine texture color */
225 color
[0] = (GLint
) (255.0 * ((float) col
/ (Columns
- 1)));
227 color
[2] = (GLint
) (255.0 * ((float) row
/ (Rows
- 1)));
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];
240 GLint w
= TexWidth
, h
= TexHeight
;
242 glTexImage2D(GL_TEXTURE_2D
, level
, GL_RGBA
, w
, h
, 0,
243 GL_RGBA
, GL_UNSIGNED_BYTE
, texImage
);
244 if (w
== 1 && h
== 1)
251 /*printf("%d: %d x %d\n", level, w, h);*/
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
);
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
);
265 /* Set corners to white */
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;
275 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, TexWidth
, TexHeight
, 0,
276 GL_RGBA
, GL_UNSIGNED_BYTE
, texImage
);
278 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
279 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
282 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
283 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
290 glEnable(GL_TEXTURE_2D
);
294 static void Key( unsigned char key
, int x
, int y
)
296 const GLfloat step
= 3.0;
322 glutDestroyWindow(Win
);
330 int main( int argc
, char *argv
[] )
334 glutInit( &argc
, argv
);
335 glutInitWindowPosition( 0, 0 );
336 glutInitWindowSize( WinWidth
, WinHeight
);
337 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
);
338 Win
= glutCreateWindow(argv
[0]);
339 glutReshapeFunc( Reshape
);
340 glutKeyboardFunc( Key
);
341 glutDisplayFunc( Display
);
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");
354 else if (strcmp(argv
[i
], "-mipmap") == 0) {
357 else if (strcmp(argv
[i
], "-linear") == 0) {
358 LinearFilter
= GL_TRUE
;
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);
367 else if (strcmp(argv
[i
], "-randomsize") == 0) {
368 RandomSize
= GL_TRUE
;
370 else if (strcmp(argv
[i
], "-lowpri") == 0) {
371 LowPriorityCount
= atoi(argv
[i
+1]);
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");