diff options
author | Roland Scheidegger <rscheidegger@gmx.ch> | 2005-09-10 01:02:25 +0000 |
---|---|---|
committer | Roland Scheidegger <rscheidegger@gmx.ch> | 2005-09-10 01:02:25 +0000 |
commit | 0ca6715ba5c187b687edd544668ef98b9d1b1047 (patch) | |
tree | 812c57ff5d92ecf63694c7352cfb2564cd54788f /progs | |
parent | c53d2d0ca81f4335c3b3bf9870635ba5ec2b3b52 (diff) | |
download | external_mesa3d-0ca6715ba5c187b687edd544668ef98b9d1b1047.zip external_mesa3d-0ca6715ba5c187b687edd544668ef98b9d1b1047.tar.gz external_mesa3d-0ca6715ba5c187b687edd544668ef98b9d1b1047.tar.bz2 |
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.
Diffstat (limited to 'progs')
-rw-r--r-- | progs/tests/Makefile | 5 | ||||
-rw-r--r-- | progs/tests/afsmultiarb.c | 473 |
2 files changed, 478 insertions, 0 deletions
diff --git a/progs/tests/Makefile b/progs/tests/Makefile index 768820c..fc8476a 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 0000000..bd7ed7b --- /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 <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#define GL_GLEXT_PROTOTYPES +#include <GL/glut.h> + +#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; +} |