diff options
-rw-r--r-- | progs/tests/Makefile | 7 | ||||
-rw-r--r-- | progs/tests/texfilt.c | 398 |
2 files changed, 402 insertions, 3 deletions
diff --git a/progs/tests/Makefile b/progs/tests/Makefile index 03bb6c2ad5..3143b2a6c2 100644 --- a/progs/tests/Makefile +++ b/progs/tests/Makefile @@ -47,6 +47,7 @@ SOURCES = antialias.c \ stencilwrap.c \ stencil_wrap.c \ tex1d.c \ + texfilt.c \ texline.c \ texobjshare.c \ texrect.c \ @@ -100,13 +101,13 @@ getproclist.h: $(TOP)/src/mesa/glapi/gl_API.xml getprocaddress.c getprocaddress. python getprocaddress.py > getproclist.h afsmultiarb: afsmultiarb.o readtex.o - $(CC) afsmultiarb.o readtex.o $(LIBS) -o $@ + $(CC) $(CFLAGS) afsmultiarb.o readtex.o $(LIBS) -o $@ afsmultiarb.o: afsmultiarb.c readtex.h $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ texrect: texrect.o readtex.o - $(CC) texrect.o readtex.o $(LIBS) -o $@ + $(CC) $(CFLAGS) texrect.o readtex.o $(LIBS) -o $@ texrect.o: texrect.c readtex.h $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ @@ -118,7 +119,7 @@ bug_3195.o: bug_3195.c readtex.h $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ invert: invert.o readtex.o - $(CC) invert.o readtex.o $(LIBS) -o $@ + $(CC) $(CFLAGS) invert.o readtex.o $(LIBS) -o $@ invert.o: invert.c readtex.h $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ diff --git a/progs/tests/texfilt.c b/progs/tests/texfilt.c new file mode 100644 index 0000000000..6ee4bc4eae --- /dev/null +++ b/progs/tests/texfilt.c @@ -0,0 +1,398 @@ +/* + * (C) Copyright IBM Corporation 2005 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <GL/glut.h> + +const GLenum filter_modes[] = { + GL_NEAREST, + GL_LINEAR, + GL_NEAREST_MIPMAP_NEAREST, + GL_NEAREST_MIPMAP_LINEAR, + GL_LINEAR_MIPMAP_NEAREST, + GL_LINEAR_MIPMAP_LINEAR, +}; + +static GLenum min_filter = GL_LINEAR_MIPMAP_LINEAR; +static GLenum mag_filter = GL_LINEAR; + +static unsigned segments = 64; +static GLfloat * position_data = NULL; +static GLfloat * texcoord_data = NULL; +static GLfloat max_anisotropy = 0.0; +static GLfloat anisotropy = 1.0; + +static void generate_tunnel( unsigned num_segs, GLfloat ** pos_data, + GLfloat ** tex_data ); +static void generate_textures( unsigned mode ); + +#define min(a,b) ( (a) < (b) ) ? (a) : (b) +#define max(a,b) ( (a) > (b) ) ? (a) : (b) + + +static void Display( void ) +{ + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter ); + + if ( max_anisotropy > 0.0 ) { + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, + anisotropy ); + } + + glClear( GL_COLOR_BUFFER_BIT ); + glLoadIdentity(); + glTranslatef( 0.0f, 0.0f, -19.0f ); + + glVertexPointer( 4, GL_FLOAT, 0, position_data ); + glTexCoordPointer( 2, GL_FLOAT, 0, texcoord_data ); + glEnableClientState( GL_VERTEX_ARRAY ); + glEnableClientState( GL_TEXTURE_COORD_ARRAY ); + glDrawArrays( GL_QUADS, 0, 4 * segments ); + glutSwapBuffers(); +} + + +static void Reshape( int width, int height ) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0f, (GLfloat)(width)/(GLfloat)(height), 0.1f, 100.0f); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + + +static void Key( unsigned char key, int x, int y ) +{ + GLfloat new_anisotropy = anisotropy; + + (void) x; + (void) y; + + + switch( key ) { + case 'a': { + new_anisotropy = anisotropy - 1.0; + break; + } + + case 'A': { + new_anisotropy = anisotropy + 1.0; + break; + } + + case 's': { + segments--; + if ( segments < 3 ) { + segments = 3; + } + generate_tunnel( segments, & position_data, & texcoord_data ); + break; + } + + case 'S': { + segments++; + if ( segments > 128 ) { + segments = 128; + } + generate_tunnel( segments, & position_data, & texcoord_data ); + break; + } + case 'q': + case 'Q': + case 27: + exit(0); + break; + } + + new_anisotropy = max( new_anisotropy, 1.0 ); + new_anisotropy = min( new_anisotropy, max_anisotropy ); + if ( new_anisotropy != anisotropy ) { + anisotropy = new_anisotropy; + printf( "Texture anisotropy: %f%s\n", anisotropy, + (anisotropy == 1.0) ? " (disabled)" : "" ); + } + + glutPostRedisplay(); +} + + +static void SpecialKey( int key, int x, int y ) +{ + (void) x; + (void) y; + (void) key; + glutPostRedisplay(); +} + + +static void menu_handler( int selection ) +{ + switch( selection >> 3 ) { + case 0: + glBindTexture( GL_TEXTURE_2D, selection ); + break; + + case 1: + min_filter = filter_modes[ selection & 7 ]; + break; + + case 2: + mag_filter = filter_modes[ selection & 7 ]; + break; + } + + glutPostRedisplay(); +} + + +static void Init( void ) +{ + glDisable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + glClearColor(0.0f, 0.0f, 0.4f, 0.0f); + glShadeModel(GL_SMOOTH); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + + generate_tunnel( segments, & position_data, & texcoord_data ); + + glBindTexture( GL_TEXTURE_2D, 1 ); + generate_textures(1); + + glBindTexture( GL_TEXTURE_2D, 2 ); + generate_textures(2); + + glBindTexture( GL_TEXTURE_2D, 3 ); + generate_textures(3); + + if ( glutExtensionSupported( "GL_EXT_texture_filter_anisotropic" ) ) { + glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, & max_anisotropy ); + } + + printf("Maximum texture anisotropy: %f\n", max_anisotropy ); + + /* Create the menus. */ + + glutCreateMenu( menu_handler ); + glutAddMenuEntry( "Min filter: GL_NEAREST", 8 + 0 ); + glutAddMenuEntry( "Min filter: GL_LINEAR", 8 + 1 ); + glutAddMenuEntry( "Min filter: GL_NEAREST_MIMMAP_NEAREST", 8 + 2 ); + glutAddMenuEntry( "Min filter: GL_NEAREST_MIMMAP_LINEAR", 8 + 3 ); + glutAddMenuEntry( "Min filter: GL_LINEAR_MIMMAP_NEAREST", 8 + 4 ); + glutAddMenuEntry( "Min filter: GL_LINEAR_MIMMAP_LINEAR", 8 + 5 ); + glutAddMenuEntry( "Mag filter: GL_NEAREST", 16 + 0 ); + glutAddMenuEntry( "Mag filter: GL_LINEAR", 16 + 1 ); + glutAddMenuEntry( "Texture: regular mipmaps", 1 ); + glutAddMenuEntry( "Texture: blended mipmaps", 2 ); + glutAddMenuEntry( "Texture: color mipmaps", 3 ); + glutAttachMenu( GLUT_RIGHT_BUTTON ); +} + + +static void generate_tunnel( unsigned num_segs, GLfloat ** pos_data, + GLfloat ** tex_data ) +{ + const GLfloat far = 20.0f; + const GLfloat near = -90.0f; + const GLfloat far_tex = 30.0f; + const GLfloat near_tex = 0.0f; + const GLfloat angle_step = (2 * M_PI) / num_segs; + const GLfloat tex_coord_step = 2.0 / num_segs; + GLfloat angle = 0.0f; + GLfloat tex_coord = 0.0f; + unsigned i; + GLfloat * position; + GLfloat * texture; + + + position = realloc( *pos_data, sizeof( GLfloat ) * num_segs * 4 * 4 ); + texture = realloc( *tex_data, sizeof( GLfloat ) * num_segs * 4 * 2 ); + + *pos_data = position; + *tex_data = texture; + + for ( i = 0 ; i < num_segs ; i++ ) { + position[0] = 2.5 * sinf( angle ); + position[1] = 2.5 * cosf( angle ); + position[2] = (i & 1) ? far : near; + position[3] = 1.0f; + + position[4] = position[0]; + position[5] = position[1]; + position[6] = (i & 1) ? near : far; + position[7] = 1.0f; + + position += 8; + + texture[0] = tex_coord; + texture[1] = (i & 1) ? far_tex : near_tex; + texture += 2; + + texture[0] = tex_coord; + texture[1] = (i & 1) ? near_tex : far_tex; + texture += 2; + + angle += angle_step; + tex_coord += tex_coord_step; + + position[0] = 2.5 * sinf( angle ); + position[1] = 2.5 * cosf( angle ); + position[2] = (i & 1) ? near : far; + position[3] = 1.0f; + + position[4] = position[0]; + position[5] = position[1]; + position[6] = (i & 1) ? far : near; + position[7] = 1.0f; + + position += 8; + + texture[0] = tex_coord; + texture[1] = (i & 1) ? near_tex : far_tex; + texture += 2; + + texture[0] = tex_coord; + texture[1] = (i & 1) ? far_tex : near_tex; + texture += 2; + } +} + + +static void generate_textures( unsigned mode ) +{ +#define LEVEL_COLORS 6 + const GLfloat colors[LEVEL_COLORS][3] = { + { 1.0, 0.0, 0.0 }, /* 32 x 32 */ + { 0.0, 1.0, 0.0 }, /* 16 x 16 */ + { 0.0, 0.0, 1.0 }, /* 8 x 8 */ + { 1.0, 0.0, 1.0 }, /* 4 x 4 */ + { 1.0, 1.0, 1.0 }, /* 2 x 2 */ + { 1.0, 1.0, 0.0 } /* 1 x 1 */ + }; + const unsigned checkers_per_level = 2; + GLfloat * tex; + unsigned level; + unsigned size; + GLint max_size; + + + glGetIntegerv( GL_MAX_TEXTURE_SIZE, & max_size ); + if ( max_size > 512 ) { + max_size = 512; + } + + tex = malloc( sizeof( GLfloat ) * 3 * max_size * max_size ); + + level = 0; + for ( size = max_size ; size > 0 ; size >>= 1 ) { + unsigned divisor = size / checkers_per_level; + unsigned i; + unsigned j; + GLfloat checkers[2][3]; + + + if ((level == 0) || (mode == 1)) { + checkers[0][0] = 1.0; + checkers[0][1] = 1.0; + checkers[0][2] = 1.0; + checkers[1][0] = 0.0; + checkers[1][1] = 0.0; + checkers[1][2] = 0.0; + } + else if (mode == 2) { + checkers[0][0] = colors[level % LEVEL_COLORS][0]; + checkers[0][1] = colors[level % LEVEL_COLORS][1]; + checkers[0][2] = colors[level % LEVEL_COLORS][2]; + checkers[1][0] = colors[level % LEVEL_COLORS][0] * 0.5; + checkers[1][1] = colors[level % LEVEL_COLORS][1] * 0.5; + checkers[1][2] = colors[level % LEVEL_COLORS][2] * 0.5; + } + else { + checkers[0][0] = colors[level % LEVEL_COLORS][0]; + checkers[0][1] = colors[level % LEVEL_COLORS][1]; + checkers[0][2] = colors[level % LEVEL_COLORS][2]; + checkers[1][0] = colors[level % LEVEL_COLORS][0]; + checkers[1][1] = colors[level % LEVEL_COLORS][1]; + checkers[1][2] = colors[level % LEVEL_COLORS][2]; + } + + if ( divisor == 0 ) { + divisor = 1; + + checkers[0][0] = (checkers[0][0] + checkers[1][0]) / 2; + checkers[0][1] = (checkers[0][0] + checkers[1][0]) / 2; + checkers[0][2] = (checkers[0][0] + checkers[1][0]) / 2; + checkers[1][0] = checkers[0][0]; + checkers[1][1] = checkers[0][1]; + checkers[1][2] = checkers[0][2]; + } + + + for ( i = 0 ; i < size ; i++ ) { + for ( j = 0 ; j < size ; j++ ) { + const unsigned idx = ((i ^ j) / divisor) & 1; + + tex[ ((i * size) + j) * 3 + 0] = checkers[ idx ][0]; + tex[ ((i * size) + j) * 3 + 1] = checkers[ idx ][1]; + tex[ ((i * size) + j) * 3 + 2] = checkers[ idx ][2]; + } + } + + glTexImage2D( GL_TEXTURE_2D, level, GL_RGB, size, size, 0, + GL_RGB, GL_FLOAT, tex ); + level++; + } + + free( tex ); +} + + +int main( int argc, char ** argv ) +{ + glutInit( &argc, argv ); + glutInitWindowPosition( 0, 0 ); + glutInitWindowSize( 800, 600 ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); + glutCreateWindow( "Texture Filter Test" ); + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutSpecialFunc( SpecialKey ); + glutDisplayFunc( Display ); + + Init(); + + printf("\nUse the right-button menu to select the texture and filter mode.\n"); + printf("Use 'A' and 'a' to increase and decrease the aniotropy.\n"); + printf("Use 'S' and 's' to increase and decrease the number of cylinder segments.\n"); + printf("Use 'q' to exit.\n\n"); + + glutMainLoop(); + return 0; +} |