From 0ca6715ba5c187b687edd544668ef98b9d1b1047 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Sat, 10 Sep 2005 01:02:25 +0000 Subject: [PATCH] new demo to test ATI_fragment_shader, not very creative but easy to know if the output is correct. Tests single-pass as well as multi-pass shader (only pseudo-dependant texture read though, and no tex coord swizzling), src and dst modifiers, src repetition, dst masks, constants, and some ops. Both shaders run succesfully with swrast as well as r200. --- progs/tests/Makefile | 5 + progs/tests/afsmultiarb.c | 473 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 478 insertions(+) create mode 100644 progs/tests/afsmultiarb.c diff --git a/progs/tests/Makefile b/progs/tests/Makefile index 768820cf3df..fc8476a27a7 100644 --- a/progs/tests/Makefile +++ b/progs/tests/Makefile @@ -98,6 +98,11 @@ getprocaddress: getprocaddress.c getproclist.h getproclist.h: $(TOP)/src/mesa/glapi/gl_API.xml getprocaddress.c getprocaddress.py python getprocaddress.py > getproclist.h +afsmultiarb: afsmultiarb.o readtex.o + $(CC) 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 $@ diff --git a/progs/tests/afsmultiarb.c b/progs/tests/afsmultiarb.c new file mode 100644 index 00000000000..bd7ed7bff46 --- /dev/null +++ b/progs/tests/afsmultiarb.c @@ -0,0 +1,473 @@ + +/* + * GL_ARB_multitexture demo + * + * Command line options: + * -info print GL implementation information + * + * + * Brian Paul November 1998 This program is in the public domain. + * Modified on 12 Feb 2002 for > 2 texture units. + */ + + +#include +#include +#include +#include +#define GL_GLEXT_PROTOTYPES +#include + +#include "readtex.h" + +#define TEXTURE_1_FILE "../images/girl.rgb" +#define TEXTURE_2_FILE "../images/reflect.rgb" + +#define TEX0 1 +#define TEX7 8 +#define ANIMATE 10 +#define SHADER 20 +#define QUIT 100 + +static GLboolean Animate = GL_TRUE; +static GLint NumUnits = 6; +static GLboolean TexEnabled[8]; +static GLuint boringshaderID = 0; +static GLuint boring2passID = 0; +static GLboolean Shader = GL_FALSE; + +static GLfloat Drift = 0.0; +static GLfloat drift_increment = 0.005; +static GLfloat Xrot = 20.0, Yrot = 30.0, Zrot = 0.0; +static GLfloat shaderconstant[4] = {0.5, 0.0, 0.0, 0.0}; + +static void Idle( void ) +{ + if (Animate) { + GLint i; + + Drift += drift_increment; + if (Drift >= 1.0) + Drift = 0.0; + + for (i = 0; i < NumUnits; i++) { + glActiveTextureARB(GL_TEXTURE0_ARB + i); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + if (i == 0) { + glTranslatef(Drift, 0.0, 0.0); + glScalef(2, 2, 1); + } + else if (i == 1) { + glTranslatef(0.0, Drift, 0.0); + } + else { + glTranslatef(0.5, 0.5, 0.0); + glRotatef(180.0 * Drift, 0, 0, 1); + glScalef(1.0/i, 1.0/i, 1.0/i); + glTranslatef(-0.5, -0.5, 0.0); + } + } + glMatrixMode(GL_MODELVIEW); + + glutPostRedisplay(); + } +} + + +static void DrawObject(void) +{ + GLint i; + GLint j; + static const GLfloat tex_coords[] = { 0.0, 0.0, 1.0, 1.0, 0.0 }; + static const GLfloat vtx_coords[] = { -1.0, -1.0, 1.0, 1.0, -1.0 }; + + if (!TexEnabled[0] && !TexEnabled[1]) + glColor3f(0.1, 0.1, 0.1); /* add onto this */ + else + glColor3f(1, 1, 1); /* modulate this */ + + glBegin(GL_QUADS); + + /* Toggle between the vector and scalar entry points. This is done purely + * to hit multiple paths in the driver. + */ + if ( Drift > 0.49 ) { + for (j = 0; j < 4; j++ ) { + for (i = 0; i < NumUnits; i++) + glMultiTexCoord2fARB(GL_TEXTURE0_ARB + i, + tex_coords[j], tex_coords[j+1]); + glVertex2f( vtx_coords[j], vtx_coords[j+1] ); + } + } + else { + for (j = 0; j < 4; j++ ) { + for (i = 0; i < NumUnits; i++) + glMultiTexCoord2fvARB(GL_TEXTURE0_ARB + i, & tex_coords[j]); + glVertex2fv( & vtx_coords[j] ); + } + } + + glEnd(); +} + + + +static void Display( void ) +{ + static GLint T0 = 0; + static GLint Frames = 0; + GLint t; + + glClear( GL_COLOR_BUFFER_BIT ); + + glPushMatrix(); + glRotatef(Xrot, 1.0, 0.0, 0.0); + glRotatef(Yrot, 0.0, 1.0, 0.0); + glRotatef(Zrot, 0.0, 0.0, 1.0); + glScalef(5.0, 5.0, 5.0); + DrawObject(); + glPopMatrix(); + + glutSwapBuffers(); + + Frames++; + + t = glutGet(GLUT_ELAPSED_TIME); + if (t - T0 >= 2500) { + GLfloat seconds = (t - T0) / 1000.0; + GLfloat fps = Frames / seconds; + drift_increment = 2.2 * seconds / Frames; + printf("%d frames in %6.3f seconds = %6.3f FPS\n", Frames, seconds, fps); + T0 = t; + Frames = 0; + } +} + + +static void Reshape( int width, int height ) +{ + glViewport( 0, 0, width, height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 ); + /*glOrtho( -6.0, 6.0, -6.0, 6.0, 10.0, 100.0 );*/ + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslatef( 0.0, 0.0, -70.0 ); +} + + +static void ModeMenu(int entry) +{ + if (entry >= TEX0 && entry <= TEX7) { + /* toggle */ + GLint i = entry - TEX0; + TexEnabled[i] = !TexEnabled[i]; + glActiveTextureARB(GL_TEXTURE0_ARB + i); + if (TexEnabled[i]) + glEnable(GL_TEXTURE_2D); + else + glDisable(GL_TEXTURE_2D); + printf("Enabled: "); + for (i = 0; i < NumUnits; i++) + printf("%d ", (int) TexEnabled[i]); + printf("\n"); + } + else if (entry==ANIMATE) { + Animate = !Animate; + } + else if (entry==SHADER) { + Shader = !Shader; + if (Shader) { + fprintf(stderr, "using 2-pass shader\n"); + glBindFragmentShaderATI(boring2passID); + } + else { + fprintf(stderr, "using 1-pass shader\n"); + glBindFragmentShaderATI(boringshaderID); + } + } + else if (entry==QUIT) { + exit(0); + } + + glutPostRedisplay(); +} + + +static void Key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void SpecialKey( int key, int x, int y ) +{ + float step = 3.0; + (void) x; + (void) y; + + switch (key) { + case GLUT_KEY_UP: + Xrot += step; + break; + case GLUT_KEY_DOWN: + Xrot -= step; + break; + case GLUT_KEY_LEFT: + Yrot += step; + break; + case GLUT_KEY_RIGHT: + Yrot -= step; + break; + } + glutPostRedisplay(); +} + + +static void Init( int argc, char *argv[] ) +{ + GLuint texObj[8]; + GLint size, i; + + const char *exten = (const char *) glGetString(GL_EXTENSIONS); + if (!strstr(exten, "GL_ATI_fragment_shader")) { + printf("Sorry, GL_ATI_fragment_shader not supported by this renderer.\n"); + exit(1); + } + + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size); + printf("%d x %d max texture size\n", size, size); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + for (i = 0; i < NumUnits; i++) { + if (i < 6) + TexEnabled[i] = GL_TRUE; + else + TexEnabled[i] = GL_FALSE; + } + + /* allocate two texture objects */ + glGenTextures(NumUnits, texObj); + + /* setup the texture objects */ + for (i = 0; i < NumUnits; i++) { + + glActiveTextureARB(GL_TEXTURE0_ARB + i); + glBindTexture(GL_TEXTURE_2D, texObj[i]); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + if (i == 0) { + if (!LoadRGBMipmaps(TEXTURE_1_FILE, GL_RGB)) { + printf("Error: couldn't load texture image\n"); + exit(1); + } + } + else if (i == 1) { + if (!LoadRGBMipmaps(TEXTURE_2_FILE, GL_RGB)) { + printf("Error: couldn't load texture image\n"); + exit(1); + } + } + else { + /* checker */ + GLubyte image[8][8][3]; + GLint i, j; + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++) { + if ((i + j) & 1) { + image[i][j][0] = 50; + image[i][j][1] = 50; + image[i][j][2] = 50; + } + else { + image[i][j][0] = 25; + image[i][j][1] = 25; + image[i][j][2] = 25; + } + } + } + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, + GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *) image); + } + + /* Bind texObj[i] to ith texture unit */ +/* if (i < 2) + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + else + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);*/ + + if (TexEnabled[i]) + glEnable(GL_TEXTURE_2D); + } + + boringshaderID = glGenFragmentShadersATI(1); + boring2passID = glGenFragmentShadersATI(1); + if (boring2passID == 0) + { + fprintf(stderr, "couldn't get frag shader id\n"); + exit(1); + } + glBindFragmentShaderATI(boringshaderID); +/* maybe not the most creative shader but at least I know how it should look like! */ + glBeginFragmentShaderATI(); + glSampleMapATI(GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI); + glSampleMapATI(GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI); + glSampleMapATI(GL_REG_2_ATI, GL_TEXTURE2_ARB, GL_SWIZZLE_STR_ATI); + glSampleMapATI(GL_REG_3_ATI, GL_TEXTURE3_ARB, GL_SWIZZLE_STR_ATI); + glSampleMapATI(GL_REG_4_ATI, GL_TEXTURE4_ARB, GL_SWIZZLE_STR_ATI); + glSampleMapATI(GL_REG_5_ATI, GL_TEXTURE5_ARB, GL_SWIZZLE_STR_ATI); + glColorFragmentOp2ATI(GL_MUL_ATI, + GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI, + GL_REG_0_ATI, GL_NONE, GL_NONE, + GL_PRIMARY_COLOR, GL_NONE, GL_NONE); + glAlphaFragmentOp1ATI(GL_MOV_ATI, + GL_REG_0_ATI, GL_NONE, + GL_PRIMARY_COLOR, GL_NONE, GL_NONE); + glColorFragmentOp3ATI(GL_MAD_ATI, + GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI, + GL_REG_0_ATI, GL_NONE, GL_NONE, + GL_REG_1_ATI, GL_NONE, GL_NONE, + GL_REG_2_ATI, GL_NONE, GL_NONE); + glColorFragmentOp2ATI(GL_ADD_ATI, + GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI, + GL_REG_0_ATI, GL_NONE, GL_NONE, + GL_REG_3_ATI, GL_NONE, GL_NONE); + glColorFragmentOp2ATI(GL_ADD_ATI, + GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI, + GL_REG_0_ATI, GL_NONE, GL_NONE, + GL_REG_4_ATI, GL_NONE, GL_NONE); + glColorFragmentOp2ATI(GL_ADD_ATI, + GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI, + GL_REG_0_ATI, GL_NONE, GL_NONE, + GL_REG_5_ATI, GL_NONE, GL_NONE); + glEndFragmentShaderATI(); + +/* mathematically equivalent to first shader but using 2 passes together with + some tex coord rerouting */ + glBindFragmentShaderATI(boring2passID); + glBeginFragmentShaderATI(); + glPassTexCoordATI(GL_REG_1_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI); + glSampleMapATI(GL_REG_2_ATI, GL_TEXTURE2_ARB, GL_SWIZZLE_STR_ATI); + glSampleMapATI(GL_REG_3_ATI, GL_TEXTURE3_ARB, GL_SWIZZLE_STR_ATI); + glSampleMapATI(GL_REG_4_ATI, GL_TEXTURE4_ARB, GL_SWIZZLE_STR_ATI); + glSampleMapATI(GL_REG_5_ATI, GL_TEXTURE5_ARB, GL_SWIZZLE_STR_ATI); + glColorFragmentOp2ATI(GL_ADD_ATI, + GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI, + GL_REG_2_ATI, GL_NONE, GL_NONE, + GL_REG_3_ATI, GL_NONE, GL_NONE); + glColorFragmentOp2ATI(GL_ADD_ATI, + GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI, + GL_REG_0_ATI, GL_NONE, GL_NONE, + GL_REG_4_ATI, GL_NONE, GL_NONE); + glColorFragmentOp2ATI(GL_ADD_ATI, + GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI, + GL_REG_0_ATI, GL_NONE, GL_NONE, + GL_REG_5_ATI, GL_NONE, GL_NONE); + /* not really a dependant read */ + glSampleMapATI(GL_REG_0_ATI, GL_REG_1_ATI, GL_SWIZZLE_STR_ATI); + glSampleMapATI(GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI); + glPassTexCoordATI(GL_REG_5_ATI, GL_REG_0_ATI, GL_SWIZZLE_STR_ATI); + glColorFragmentOp2ATI(GL_MUL_ATI, + GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI, + GL_REG_0_ATI, GL_NONE, GL_NONE, + GL_PRIMARY_COLOR, GL_NONE, GL_NONE); + glAlphaFragmentOp1ATI(GL_MOV_ATI, + GL_REG_0_ATI, GL_NONE, + GL_PRIMARY_COLOR, GL_NONE, GL_NONE); + glColorFragmentOp3ATI(GL_MAD_ATI, + GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI, + GL_REG_0_ATI, GL_NONE, GL_NONE, + GL_REG_1_ATI, GL_NONE, GL_NONE, + GL_REG_5_ATI, GL_NONE, GL_NONE); + /* in principle we're finished here, but to test a bit more + we do some fun with dot ops, replication et al. */ + glSetFragmentShaderConstantATI(GL_CON_3_ATI, shaderconstant); + glColorFragmentOp2ATI(GL_DOT4_ATI, + GL_REG_3_ATI, GL_GREEN_BIT_ATI, GL_EIGHTH_BIT_ATI, + GL_ZERO, GL_NONE, GL_COMP_BIT_ATI | GL_NEGATE_BIT_ATI, + GL_CON_3_ATI, GL_RED, GL_2X_BIT_ATI); + /* those args must get ignored, except dstReg */ + glAlphaFragmentOp2ATI(GL_DOT4_ATI, + GL_REG_4_ATI, GL_NONE, + GL_ZERO, GL_NONE, GL_NONE, + GL_ZERO, GL_NONE, GL_NONE); + /* -> reg3 g = reg4 alpha = -0.5 */ + glAlphaFragmentOp2ATI(GL_ADD_ATI, + GL_REG_5_ATI, GL_NONE, + GL_REG_3_ATI, GL_GREEN, GL_NONE, + GL_REG_4_ATI, GL_NONE, GL_NONE); + /* -> reg5 a = -1 */ + glColorFragmentOp3ATI(GL_DOT2_ADD_ATI, + GL_REG_4_ATI, GL_BLUE_BIT_ATI, GL_HALF_BIT_ATI, + GL_REG_5_ATI, GL_ALPHA, GL_NEGATE_BIT_ATI, + GL_ONE, GL_NONE, GL_BIAS_BIT_ATI, + GL_ONE, GL_ALPHA, GL_2X_BIT_ATI | GL_NEGATE_BIT_ATI); + /* -> reg 4 b = -0.5 */ + glColorFragmentOp2ATI(GL_MUL_ATI, + GL_REG_0_ATI, GL_NONE, GL_NONE, + GL_REG_4_ATI, GL_BLUE, GL_NEGATE_BIT_ATI | GL_2X_BIT_ATI, + GL_REG_0_ATI, GL_NONE, GL_NONE); + glEndFragmentShaderATI(); + + glBindFragmentShaderATI(boringshaderID); + glEnable(GL_FRAGMENT_SHADER_ATI); + + glShadeModel(GL_FLAT); + glClearColor(0.3, 0.3, 0.4, 1.0); + + if (argc > 1 && strcmp(argv[1], "-info")==0) { + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); + } + printf("output should be identical with both shaders to multiarb demo when 6 textures are enabled\n"); +} + + +int main( int argc, char *argv[] ) +{ +/* GLint i;*/ + + glutInit( &argc, argv ); + glutInitWindowSize( 300, 300 ); + glutInitWindowPosition( 0, 0 ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); + glutCreateWindow(argv[0] ); + + Init( argc, argv ); + + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutSpecialFunc( SpecialKey ); + glutDisplayFunc( Display ); + glutIdleFunc( Idle ); + + glutCreateMenu(ModeMenu); + +/* for (i = 0; i < NumUnits; i++) { + char s[100]; + sprintf(s, "Toggle Texture %d", i); + glutAddMenuEntry(s, TEX0 + i); + }*/ + glutAddMenuEntry("Toggle 1/2 Pass Shader", SHADER); + glutAddMenuEntry("Toggle Animation", ANIMATE); + glutAddMenuEntry("Quit", QUIT); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glutMainLoop(); + return 0; +} -- 2.30.2