summaryrefslogtreecommitdiff
path: root/progs/miniglx/manytex.c
diff options
context:
space:
mode:
Diffstat (limited to 'progs/miniglx/manytex.c')
-rw-r--r--progs/miniglx/manytex.c381
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;
+}