diff options
Diffstat (limited to 'progs/miniglx/manytex.c')
-rw-r--r-- | progs/miniglx/manytex.c | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/progs/miniglx/manytex.c b/progs/miniglx/manytex.c new file mode 100644 index 0000000000..3801963f9d --- /dev/null +++ b/progs/miniglx/manytex.c @@ -0,0 +1,381 @@ +/* $Id: manytex.c,v 1.1 2003/08/06 17:47:15 keithw Exp $ */ + +/* + * test handling of many texture maps + * Also tests texture priority and residency. + * + * Brian Paul + * August 2, 2000 + */ + + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glut.h> + + +static GLint NumTextures = 20; +static GLuint *TextureID = NULL; +static GLint *TextureWidth = NULL, *TextureHeight = NULL; +static GLboolean *TextureResidency = NULL; +static GLint TexWidth = 128, TexHeight = 128; +static GLfloat Zrot = 0; +static GLboolean Anim = GL_TRUE; +static GLint WinWidth = 500, WinHeight = 400; +static GLboolean MipMap = GL_FALSE; +static GLboolean LinearFilter = GL_FALSE; +static GLboolean RandomSize = GL_FALSE; +static GLint Rows, Columns; +static GLint LowPriorityCount = 0; + + +static void Idle( void ) +{ + Zrot += 1.0; + glutPostRedisplay(); +} + + +static void Display( void ) +{ + GLfloat spacing = WinWidth / Columns; + GLfloat size = spacing * 0.4; + GLint i; + + /* test residency */ + if (0) + { + GLboolean b; + GLint i, resident; + b = glAreTexturesResident(NumTextures, TextureID, TextureResidency); + if (b) { + printf("all resident\n"); + } + else { + resident = 0; + for (i = 0; i < NumTextures; i++) { + if (TextureResidency[i]) { + resident++; + } + } + printf("%d of %d texture resident\n", resident, NumTextures); + } + } + + /* render the textured quads */ + glClear( GL_COLOR_BUFFER_BIT ); + for (i = 0; i < NumTextures; i++) { + GLint row = i / Columns; + GLint col = i % Columns; + GLfloat x = col * spacing + spacing * 0.5; + GLfloat y = row * spacing + spacing * 0.5; + + GLfloat maxDim = (TextureWidth[i] > TextureHeight[i]) + ? TextureWidth[i] : TextureHeight[i]; + GLfloat w = TextureWidth[i] / maxDim; + GLfloat h = TextureHeight[i] / maxDim; + + glPushMatrix(); + glTranslatef(x, y, 0.0); + glRotatef(Zrot, 0, 0, 1); + glScalef(size, size, 1); + + glBindTexture(GL_TEXTURE_2D, TextureID[i]); + glBegin(GL_POLYGON); +#if 0 + glTexCoord2f(0, 0); glVertex2f(-1, -1); + glTexCoord2f(1, 0); glVertex2f( 1, -1); + glTexCoord2f(1, 1); glVertex2f( 1, 1); + glTexCoord2f(0, 1); glVertex2f(-1, 1); +#else + glTexCoord2f(0, 0); glVertex2f(-w, -h); + glTexCoord2f(1, 0); glVertex2f( w, -h); + glTexCoord2f(1, 1); glVertex2f( w, h); + glTexCoord2f(0, 1); glVertex2f(-w, h); +#endif + glEnd(); + glPopMatrix(); + } + + glutSwapBuffers(); +} + + +static void Reshape( int width, int height ) +{ + WinWidth = width; + WinHeight = height; + glViewport( 0, 0, width, height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glOrtho(0, width, 0, height, -1, 1); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); +} + + +/* + * Return a random int in [min, max]. + */ +static int RandomInt(int min, int max) +{ + int i = rand(); + int j = i % (max - min + 1); + return min + j; +} + + + +static void Init( void ) +{ + GLint i; + + if (RandomSize) { + printf("Creating %d %s random-size textures, ", NumTextures, + MipMap ? "Mipmapped" : "non-Mipmapped"); + } + else { + printf("Creating %d %s %d x %d textures, ", NumTextures, + MipMap ? "Mipmapped" : "non-Mipmapped", + TexWidth, TexHeight); + } + + if (LinearFilter) { + printf("bilinear filtering\n"); + } + else { + printf("nearest filtering\n"); + } + + + /* compute number of rows and columns of rects */ + { + GLfloat area = (GLfloat) (WinWidth * WinHeight) / (GLfloat) NumTextures; + GLfloat edgeLen = sqrt(area); + + Columns = WinWidth / edgeLen; + Rows = (NumTextures + Columns - 1) / Columns; + printf("Rows: %d Cols: %d\n", Rows, Columns); + } + + + if (!TextureID) { + TextureID = (GLuint *) malloc(sizeof(GLuint) * NumTextures); + assert(TextureID); + glGenTextures(NumTextures, TextureID); + } + + if (!TextureResidency) { + TextureResidency = (GLboolean *) malloc(sizeof(GLboolean) * NumTextures); + assert(TextureResidency); + } + + if (!TextureWidth) { + TextureWidth = (GLint *) malloc(sizeof(GLint) * NumTextures); + assert(TextureWidth); + } + if (!TextureHeight) { + TextureHeight = (GLint *) malloc(sizeof(GLint) * NumTextures); + assert(TextureHeight); + } + + for (i = 0; i < NumTextures; i++) { + GLubyte color[4]; + GLubyte *texImage; + GLint j, row, col; + + row = i / Columns; + col = i % Columns; + + glBindTexture(GL_TEXTURE_2D, TextureID[i]); + + if (i < LowPriorityCount) + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.5F); + + if (RandomSize) { +#if 0 + int k = (glutGet(GLUT_ELAPSED_TIME) % 7) + 2; + TexWidth = 1 << k; + TexHeight = 1 << k; +#else + TexWidth = 1 << RandomInt(2, 7); + TexHeight = 1 << RandomInt(2, 7); + printf("Random size of %3d: %d x %d\n", i, TexWidth, TexHeight); +#endif + } + + TextureWidth[i] = TexWidth; + TextureHeight[i] = TexHeight; + + texImage = (GLubyte*) malloc(4 * TexWidth * TexHeight * sizeof(GLubyte)); + assert(texImage); + + /* determine texture color */ + color[0] = (GLint) (255.0 * ((float) col / (Columns - 1))); + color[1] = 127; + color[2] = (GLint) (255.0 * ((float) row / (Rows - 1))); + color[3] = 255; + + /* fill in solid-colored teximage */ + for (j = 0; j < TexWidth * TexHeight; j++) { + texImage[j*4+0] = color[0]; + texImage[j*4+1] = color[1]; + texImage[j*4+2] = color[2]; + texImage[j*4+3] = color[3]; + } + + if (MipMap) { + GLint level = 0; + GLint w = TexWidth, h = TexHeight; + while (1) { + glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w, h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texImage); + if (w == 1 && h == 1) + break; + if (w > 1) + w /= 2; + if (h > 1) + h /= 2; + level++; + /*printf("%d: %d x %d\n", level, w, h);*/ + } + if (LinearFilter) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_NEAREST_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + } + else { + /* Set corners to white */ + int k = 0; + texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255; + k = (TexWidth - 1) * 4; + texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255; + k = (TexWidth * TexHeight - TexWidth) * 4; + texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255; + k = (TexWidth * TexHeight - 1) * 4; + texImage[k+0] = texImage[k+1] = texImage[k+2] = texImage[k+3] = 255; + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TexWidth, TexHeight, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texImage); + if (LinearFilter) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + } + + free(texImage); + } + + glEnable(GL_TEXTURE_2D); +} + + +static void Key( unsigned char key, int x, int y ) +{ + const GLfloat step = 3.0; + (void) x; + (void) y; + switch (key) { + case 'a': + Anim = !Anim; + if (Anim) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); + break; + case 's': + Idle(); + break; + case 'z': + Zrot -= step; + break; + case 'Z': + Zrot += step; + break; + case ' ': + Init(); + break; + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +int main( int argc, char *argv[] ) +{ + GLint i; + + glutInit( &argc, argv ); + glutInitWindowPosition( 0, 0 ); + glutInitWindowSize( WinWidth, WinHeight ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); + glutCreateWindow(argv[0]); + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutDisplayFunc( Display ); + if (Anim) + glutIdleFunc(Idle); + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-n") == 0) { + NumTextures = atoi(argv[i+1]); + if (NumTextures <= 0) { + printf("Error, bad number of textures\n"); + return 1; + } + i++; + } + else if (strcmp(argv[i], "-mipmap") == 0) { + MipMap = GL_TRUE; + } + else if (strcmp(argv[i], "-linear") == 0) { + LinearFilter = GL_TRUE; + } + else if (strcmp(argv[i], "-size") == 0) { + TexWidth = atoi(argv[i+1]); + TexHeight = atoi(argv[i+2]); + assert(TexWidth >= 1); + assert(TexHeight >= 1); + i += 2; + } + else if (strcmp(argv[i], "-randomsize") == 0) { + RandomSize = GL_TRUE; + } + else if (strcmp(argv[i], "-lowpri") == 0) { + LowPriorityCount = atoi(argv[i+1]); + i++; + } + else { + printf("Usage:\n"); + printf(" manytex [options]\n"); + printf("Options:\n"); + printf(" -n <number of texture objects>\n"); + printf(" -size <width> <height> - specify texture size\n"); + printf(" -randomsize - use random size textures\n"); + printf(" -mipmap - generate mipmaps\n"); + printf(" -linear - use linear filtering instead of nearest\n"); + printf(" -lowpri <n> - Set lower priority on <n> textures\n"); + return 0; + } + } + + Init(); + + glutMainLoop(); + + return 0; +} |