132001f49Smrg/*
232001f49Smrg * GL_ATI_fragment_shader test
332001f49Smrg * Roland Scheidegger
432001f49Smrg *
532001f49Smrg * Command line options:
632001f49Smrg *    -info      print GL implementation information
732001f49Smrg */
832001f49Smrg
932001f49Smrg
1032001f49Smrg#include <math.h>
1132001f49Smrg#include <stdio.h>
1232001f49Smrg#include <stdlib.h>
1332001f49Smrg#include <string.h>
1432001f49Smrg#include <GL/glew.h>
1532001f49Smrg#include "glut_wrap.h"
1632001f49Smrg
1732001f49Smrg#include "readtex.h"
1832001f49Smrg
1932001f49Smrg#define TEXTURE_1_FILE DEMOS_DATA_DIR "girl.rgb"
2032001f49Smrg#define TEXTURE_2_FILE DEMOS_DATA_DIR "reflect.rgb"
2132001f49Smrg
2232001f49Smrg#define TEX0 1
2332001f49Smrg#define TEX7 8
2432001f49Smrg#define ANIMATE 10
2532001f49Smrg#define SHADER 20
2632001f49Smrg#define QUIT 100
2732001f49Smrg
2832001f49Smrgstatic GLboolean Animate = GL_TRUE;
2932001f49Smrgstatic GLint NumUnits = 6;
3032001f49Smrgstatic GLboolean TexEnabled[8];
3132001f49Smrgstatic GLuint boringshaderID = 0;
3232001f49Smrgstatic GLuint boring2passID = 0;
3332001f49Smrgstatic GLboolean Shader = GL_FALSE;
3432001f49Smrg
3532001f49Smrgstatic GLfloat Drift = 0.0;
3632001f49Smrgstatic GLfloat drift_increment = 0.005;
3732001f49Smrgstatic GLfloat Xrot = 20.0, Yrot = 30.0, Zrot = 0.0;
3832001f49Smrgstatic GLfloat shaderconstant[4] = {0.5, 0.0, 0.0, 0.0};
3932001f49Smrg
4032001f49Smrgstatic void Idle( void )
4132001f49Smrg{
4232001f49Smrg   if (Animate) {
4332001f49Smrg      GLint i;
4432001f49Smrg
4532001f49Smrg      Drift += drift_increment;
4632001f49Smrg      if (Drift >= 1.0)
4732001f49Smrg         Drift = 0.0;
4832001f49Smrg
4932001f49Smrg      for (i = 0; i < NumUnits; i++) {
5032001f49Smrg         glActiveTextureARB(GL_TEXTURE0_ARB + i);
5132001f49Smrg         glMatrixMode(GL_TEXTURE);
5232001f49Smrg         glLoadIdentity();
5332001f49Smrg         if (i == 0) {
5432001f49Smrg            glTranslatef(Drift, 0.0, 0.0);
5532001f49Smrg            glScalef(2, 2, 1);
5632001f49Smrg         }
5732001f49Smrg         else if (i == 1) {
5832001f49Smrg            glTranslatef(0.0, Drift, 0.0);
5932001f49Smrg         }
6032001f49Smrg         else {
6132001f49Smrg            glTranslatef(0.5, 0.5, 0.0);
6232001f49Smrg            glRotatef(180.0 * Drift, 0, 0, 1);
6332001f49Smrg            glScalef(1.0/i, 1.0/i, 1.0/i);
6432001f49Smrg            glTranslatef(-0.5, -0.5, 0.0);
6532001f49Smrg         }
6632001f49Smrg      }
6732001f49Smrg      glMatrixMode(GL_MODELVIEW);
6832001f49Smrg
6932001f49Smrg      glutPostRedisplay();
7032001f49Smrg   }
7132001f49Smrg}
7232001f49Smrg
7332001f49Smrg
7432001f49Smrgstatic void DrawObject(void)
7532001f49Smrg{
7632001f49Smrg   GLint i;
7732001f49Smrg   GLint j;
7832001f49Smrg   static const GLfloat   tex_coords[] = {  0.0,  0.0,  1.0,  1.0,  0.0 };
7932001f49Smrg   static const GLfloat   vtx_coords[] = { -1.0, -1.0,  1.0,  1.0, -1.0 };
8032001f49Smrg
8132001f49Smrg   if (!TexEnabled[0] && !TexEnabled[1])
8232001f49Smrg      glColor3f(0.1, 0.1, 0.1);  /* add onto this */
8332001f49Smrg   else
8432001f49Smrg      glColor3f(1, 1, 1);  /* modulate this */
8532001f49Smrg
8632001f49Smrg   glBegin(GL_QUADS);
8732001f49Smrg
8832001f49Smrg   /* Toggle between the vector and scalar entry points.  This is done purely
8932001f49Smrg    * to hit multiple paths in the driver.
9032001f49Smrg    */
9132001f49Smrg   if ( Drift > 0.49 ) {
9232001f49Smrg      for (j = 0; j < 4; j++ ) {
9332001f49Smrg	 for (i = 0; i < NumUnits; i++)
9432001f49Smrg	    glMultiTexCoord2fARB(GL_TEXTURE0_ARB + i,
9532001f49Smrg				 tex_coords[j], tex_coords[j+1]);
9632001f49Smrg	 glVertex2f( vtx_coords[j], vtx_coords[j+1] );
9732001f49Smrg      }
9832001f49Smrg   }
9932001f49Smrg   else {
10032001f49Smrg      for (j = 0; j < 4; j++ ) {
10132001f49Smrg	 for (i = 0; i < NumUnits; i++)
10232001f49Smrg	    glMultiTexCoord2fvARB(GL_TEXTURE0_ARB + i, & tex_coords[j]);
10332001f49Smrg	 glVertex2fv( & vtx_coords[j] );
10432001f49Smrg      }
10532001f49Smrg   }
10632001f49Smrg
10732001f49Smrg   glEnd();
10832001f49Smrg}
10932001f49Smrg
11032001f49Smrg
11132001f49Smrg
11232001f49Smrgstatic void Display( void )
11332001f49Smrg{
11432001f49Smrg   static GLint T0 = 0;
11532001f49Smrg   static GLint Frames = 0;
11632001f49Smrg   GLint t;
11732001f49Smrg
11832001f49Smrg   glClear( GL_COLOR_BUFFER_BIT );
11932001f49Smrg
12032001f49Smrg   glPushMatrix();
12132001f49Smrg      glRotatef(Xrot, 1.0, 0.0, 0.0);
12232001f49Smrg      glRotatef(Yrot, 0.0, 1.0, 0.0);
12332001f49Smrg      glRotatef(Zrot, 0.0, 0.0, 1.0);
12432001f49Smrg      glScalef(5.0, 5.0, 5.0);
12532001f49Smrg      DrawObject();
12632001f49Smrg   glPopMatrix();
12732001f49Smrg
12832001f49Smrg   glutSwapBuffers();
12932001f49Smrg
13032001f49Smrg   Frames++;
13132001f49Smrg
13232001f49Smrg   t = glutGet(GLUT_ELAPSED_TIME);
13332001f49Smrg   if (t - T0 >= 2500) {
13432001f49Smrg      GLfloat seconds = (t - T0) / 1000.0;
13532001f49Smrg      GLfloat fps = Frames / seconds;
13632001f49Smrg      drift_increment = 2.2 * seconds / Frames;
13732001f49Smrg      printf("%d frames in %6.3f seconds = %6.3f FPS\n", Frames, seconds, fps);
13832001f49Smrg      T0 = t;
13932001f49Smrg      Frames = 0;
14032001f49Smrg   }
14132001f49Smrg}
14232001f49Smrg
14332001f49Smrg
14432001f49Smrgstatic void Reshape( int width, int height )
14532001f49Smrg{
14632001f49Smrg   glViewport( 0, 0, width, height );
14732001f49Smrg   glMatrixMode( GL_PROJECTION );
14832001f49Smrg   glLoadIdentity();
14932001f49Smrg   glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 );
15032001f49Smrg   /*glOrtho( -6.0, 6.0, -6.0, 6.0, 10.0, 100.0 );*/
15132001f49Smrg   glMatrixMode( GL_MODELVIEW );
15232001f49Smrg   glLoadIdentity();
15332001f49Smrg   glTranslatef( 0.0, 0.0, -70.0 );
15432001f49Smrg}
15532001f49Smrg
15632001f49Smrg
15732001f49Smrgstatic void ModeMenu(int entry)
15832001f49Smrg{
15932001f49Smrg   if (entry >= TEX0 && entry <= TEX7) {
16032001f49Smrg      /* toggle */
16132001f49Smrg      GLint i = entry - TEX0;
16232001f49Smrg      TexEnabled[i] = !TexEnabled[i];
16332001f49Smrg      glActiveTextureARB(GL_TEXTURE0_ARB + i);
16432001f49Smrg      if (TexEnabled[i])
16532001f49Smrg         glEnable(GL_TEXTURE_2D);
16632001f49Smrg      else
16732001f49Smrg         glDisable(GL_TEXTURE_2D);
16832001f49Smrg      printf("Enabled: ");
16932001f49Smrg      for (i = 0; i < NumUnits; i++)
17032001f49Smrg         printf("%d ", (int) TexEnabled[i]);
17132001f49Smrg      printf("\n");
17232001f49Smrg   }
17332001f49Smrg   else if (entry==ANIMATE) {
17432001f49Smrg      Animate = !Animate;
17532001f49Smrg   }
17632001f49Smrg   else if (entry==SHADER) {
17732001f49Smrg      Shader = !Shader;
17832001f49Smrg      if (Shader) {
17932001f49Smrg	 fprintf(stderr, "using 2-pass shader\n");
18032001f49Smrg	 glBindFragmentShaderATI(boring2passID);
18132001f49Smrg      }
18232001f49Smrg      else {
18332001f49Smrg	 fprintf(stderr, "using 1-pass shader\n");
18432001f49Smrg         glBindFragmentShaderATI(boringshaderID);
18532001f49Smrg      }
18632001f49Smrg   }
18732001f49Smrg   else if (entry==QUIT) {
18832001f49Smrg      exit(0);
18932001f49Smrg   }
19032001f49Smrg
19132001f49Smrg   glutPostRedisplay();
19232001f49Smrg}
19332001f49Smrg
19432001f49Smrg
19532001f49Smrgstatic void Key( unsigned char key, int x, int y )
19632001f49Smrg{
19732001f49Smrg   (void) x;
19832001f49Smrg   (void) y;
19932001f49Smrg   switch (key) {
20032001f49Smrg      case 27:
20132001f49Smrg         exit(0);
20232001f49Smrg         break;
20332001f49Smrg   }
20432001f49Smrg   glutPostRedisplay();
20532001f49Smrg}
20632001f49Smrg
20732001f49Smrg
20832001f49Smrgstatic void SpecialKey( int key, int x, int y )
20932001f49Smrg{
21032001f49Smrg   float step = 3.0;
21132001f49Smrg   (void) x;
21232001f49Smrg   (void) y;
21332001f49Smrg
21432001f49Smrg   switch (key) {
21532001f49Smrg      case GLUT_KEY_UP:
21632001f49Smrg         Xrot += step;
21732001f49Smrg         break;
21832001f49Smrg      case GLUT_KEY_DOWN:
21932001f49Smrg         Xrot -= step;
22032001f49Smrg         break;
22132001f49Smrg      case GLUT_KEY_LEFT:
22232001f49Smrg         Yrot += step;
22332001f49Smrg         break;
22432001f49Smrg      case GLUT_KEY_RIGHT:
22532001f49Smrg         Yrot -= step;
22632001f49Smrg         break;
22732001f49Smrg   }
22832001f49Smrg   glutPostRedisplay();
22932001f49Smrg}
23032001f49Smrg
23132001f49Smrg
23232001f49Smrgstatic void Init( int argc, char *argv[] )
23332001f49Smrg{
23432001f49Smrg   GLuint texObj[8];
23532001f49Smrg   GLint size, i;
23632001f49Smrg
23732001f49Smrg   const char *exten = (const char *) glGetString(GL_EXTENSIONS);
23832001f49Smrg   if (!strstr(exten, "GL_ATI_fragment_shader")) {
23932001f49Smrg      printf("Sorry, GL_ATI_fragment_shader not supported by this renderer.\n");
24032001f49Smrg      exit(1);
24132001f49Smrg   }
24232001f49Smrg
24332001f49Smrg
24432001f49Smrg   glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size);
24532001f49Smrg   printf("%d x %d max texture size\n", size, size);
24632001f49Smrg
24732001f49Smrg   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
24832001f49Smrg
24932001f49Smrg   for (i = 0; i < NumUnits; i++) {
25032001f49Smrg      if (i < 6)
25132001f49Smrg         TexEnabled[i] = GL_TRUE;
25232001f49Smrg      else
25332001f49Smrg         TexEnabled[i] = GL_FALSE;
25432001f49Smrg   }
25532001f49Smrg
25632001f49Smrg   /* allocate two texture objects */
25732001f49Smrg   glGenTextures(NumUnits, texObj);
25832001f49Smrg
25932001f49Smrg   /* setup the texture objects */
26032001f49Smrg   for (i = 0; i < NumUnits; i++) {
26132001f49Smrg
26232001f49Smrg      glActiveTextureARB(GL_TEXTURE0_ARB + i);
26332001f49Smrg      glBindTexture(GL_TEXTURE_2D, texObj[i]);
26432001f49Smrg
26532001f49Smrg      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
26632001f49Smrg      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
26732001f49Smrg
26832001f49Smrg      if (i == 0) {
26932001f49Smrg         if (!LoadRGBMipmaps(TEXTURE_1_FILE, GL_RGB)) {
27032001f49Smrg            printf("Error: couldn't load texture image\n");
27132001f49Smrg            exit(1);
27232001f49Smrg         }
27332001f49Smrg      }
27432001f49Smrg      else if (i == 1) {
27532001f49Smrg         if (!LoadRGBMipmaps(TEXTURE_2_FILE, GL_RGB)) {
27632001f49Smrg            printf("Error: couldn't load texture image\n");
27732001f49Smrg            exit(1);
27832001f49Smrg         }
27932001f49Smrg      }
28032001f49Smrg      else {
28132001f49Smrg         /* checker */
28232001f49Smrg         GLubyte image[8][8][3];
28332001f49Smrg         GLint i, j;
28432001f49Smrg         for (i = 0; i < 8; i++) {
28532001f49Smrg            for (j = 0; j < 8; j++) {
28632001f49Smrg               if ((i + j) & 1) {
28732001f49Smrg                  image[i][j][0] = 50;
28832001f49Smrg                  image[i][j][1] = 50;
28932001f49Smrg                  image[i][j][2] = 50;
29032001f49Smrg               }
29132001f49Smrg               else {
29232001f49Smrg                  image[i][j][0] = 25;
29332001f49Smrg                  image[i][j][1] = 25;
29432001f49Smrg                  image[i][j][2] = 25;
29532001f49Smrg               }
29632001f49Smrg            }
29732001f49Smrg         }
29832001f49Smrg         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0,
29932001f49Smrg                      GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *) image);
30032001f49Smrg      }
30132001f49Smrg
30232001f49Smrg      /* Bind texObj[i] to ith texture unit */
30332001f49Smrg/*      if (i < 2)
30432001f49Smrg         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
30532001f49Smrg      else
30632001f49Smrg         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);*/
30732001f49Smrg
30832001f49Smrg      if (TexEnabled[i])
30932001f49Smrg         glEnable(GL_TEXTURE_2D);
31032001f49Smrg   }
31132001f49Smrg
31232001f49Smrg   boringshaderID = glGenFragmentShadersATI(1);
31332001f49Smrg   boring2passID = glGenFragmentShadersATI(1);
31432001f49Smrg   if (boring2passID == 0)
31532001f49Smrg   {
31632001f49Smrg      fprintf(stderr, "couldn't get frag shader id\n");
31732001f49Smrg      exit(1);
31832001f49Smrg   }
31932001f49Smrg   glBindFragmentShaderATI(boringshaderID);
32032001f49Smrg/* maybe not the most creative shader but at least I know how it should look like! */
32132001f49Smrg   glBeginFragmentShaderATI();
32232001f49Smrg   glSampleMapATI(GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI);
32332001f49Smrg   glSampleMapATI(GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI);
32432001f49Smrg   glSampleMapATI(GL_REG_2_ATI, GL_TEXTURE2_ARB, GL_SWIZZLE_STR_ATI);
32532001f49Smrg   glSampleMapATI(GL_REG_3_ATI, GL_TEXTURE3_ARB, GL_SWIZZLE_STR_ATI);
32632001f49Smrg   glSampleMapATI(GL_REG_4_ATI, GL_TEXTURE4_ARB, GL_SWIZZLE_STR_ATI);
32732001f49Smrg   glSampleMapATI(GL_REG_5_ATI, GL_TEXTURE5_ARB, GL_SWIZZLE_STR_ATI);
32832001f49Smrg   glColorFragmentOp2ATI(GL_MUL_ATI,
32932001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
33032001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_NONE,
33132001f49Smrg			 GL_PRIMARY_COLOR, GL_NONE, GL_NONE);
33232001f49Smrg   glAlphaFragmentOp1ATI(GL_MOV_ATI,
33332001f49Smrg			 GL_REG_0_ATI, GL_NONE,
33432001f49Smrg			 GL_PRIMARY_COLOR, GL_NONE, GL_NONE);
33532001f49Smrg   glColorFragmentOp3ATI(GL_MAD_ATI,
33632001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
33732001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_NONE,
33832001f49Smrg			 GL_REG_1_ATI, GL_NONE, GL_NONE,
33932001f49Smrg			 GL_REG_2_ATI, GL_NONE, GL_NONE);
34032001f49Smrg   glColorFragmentOp2ATI(GL_ADD_ATI,
34132001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
34232001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_NONE,
34332001f49Smrg			 GL_REG_3_ATI, GL_NONE, GL_NONE);
34432001f49Smrg   glColorFragmentOp2ATI(GL_ADD_ATI,
34532001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
34632001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_NONE,
34732001f49Smrg			 GL_REG_4_ATI, GL_NONE, GL_NONE);
34832001f49Smrg   glColorFragmentOp2ATI(GL_ADD_ATI,
34932001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
35032001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_NONE,
35132001f49Smrg			 GL_REG_5_ATI, GL_NONE, GL_NONE);
35232001f49Smrg   glEndFragmentShaderATI();
35332001f49Smrg
35432001f49Smrg/* mathematically equivalent to first shader but using 2 passes together with
35532001f49Smrg   some tex coord rerouting */
35632001f49Smrg   glBindFragmentShaderATI(boring2passID);
35732001f49Smrg   glBeginFragmentShaderATI();
35832001f49Smrg   glPassTexCoordATI(GL_REG_1_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI);
35932001f49Smrg   glSampleMapATI(GL_REG_2_ATI, GL_TEXTURE2_ARB, GL_SWIZZLE_STR_ATI);
36032001f49Smrg   glSampleMapATI(GL_REG_3_ATI, GL_TEXTURE3_ARB, GL_SWIZZLE_STR_ATI);
36132001f49Smrg   glSampleMapATI(GL_REG_4_ATI, GL_TEXTURE4_ARB, GL_SWIZZLE_STR_ATI);
36232001f49Smrg   glSampleMapATI(GL_REG_5_ATI, GL_TEXTURE5_ARB, GL_SWIZZLE_STR_ATI);
36332001f49Smrg   glColorFragmentOp2ATI(GL_ADD_ATI,
36432001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
36532001f49Smrg			 GL_REG_2_ATI, GL_NONE, GL_NONE,
36632001f49Smrg			 GL_REG_3_ATI, GL_NONE, GL_NONE);
36732001f49Smrg   glColorFragmentOp2ATI(GL_ADD_ATI,
36832001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
36932001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_NONE,
37032001f49Smrg			 GL_REG_4_ATI, GL_NONE, GL_NONE);
37132001f49Smrg   glColorFragmentOp2ATI(GL_ADD_ATI,
37232001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
37332001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_NONE,
37432001f49Smrg			 GL_REG_5_ATI, GL_NONE, GL_NONE);
37532001f49Smrg   /* not really a dependant read */
37632001f49Smrg   glSampleMapATI(GL_REG_0_ATI, GL_REG_1_ATI, GL_SWIZZLE_STR_ATI);
37732001f49Smrg   glSampleMapATI(GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI);
37832001f49Smrg   glPassTexCoordATI(GL_REG_5_ATI, GL_REG_0_ATI, GL_SWIZZLE_STR_ATI);
37932001f49Smrg   glColorFragmentOp2ATI(GL_MUL_ATI,
38032001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
38132001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_NONE,
38232001f49Smrg			 GL_PRIMARY_COLOR, GL_NONE, GL_NONE);
38332001f49Smrg   glAlphaFragmentOp1ATI(GL_MOV_ATI,
38432001f49Smrg			 GL_REG_0_ATI, GL_NONE,
38532001f49Smrg			 GL_PRIMARY_COLOR, GL_NONE, GL_NONE);
38632001f49Smrg   glColorFragmentOp3ATI(GL_MAD_ATI,
38732001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
38832001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_NONE,
38932001f49Smrg			 GL_REG_1_ATI, GL_NONE, GL_NONE,
39032001f49Smrg			 GL_REG_5_ATI, GL_NONE, GL_NONE);
39132001f49Smrg   /* in principle we're finished here, but to test a bit more
39232001f49Smrg      we do some fun with dot ops, replication et al. */
39332001f49Smrg   glSetFragmentShaderConstantATI(GL_CON_3_ATI, shaderconstant);
39432001f49Smrg   glColorFragmentOp2ATI(GL_DOT4_ATI,
39532001f49Smrg			 GL_REG_3_ATI, GL_GREEN_BIT_ATI, GL_EIGHTH_BIT_ATI,
39632001f49Smrg			 GL_ZERO, GL_NONE, GL_COMP_BIT_ATI | GL_NEGATE_BIT_ATI,
39732001f49Smrg			 GL_CON_3_ATI, GL_RED, GL_2X_BIT_ATI);
39832001f49Smrg   /* those args must get ignored, except dstReg */
39932001f49Smrg   glAlphaFragmentOp2ATI(GL_DOT4_ATI,
40032001f49Smrg			 GL_REG_4_ATI, GL_NONE,
40132001f49Smrg			 GL_ZERO, GL_NONE, GL_NONE,
40232001f49Smrg			 GL_ZERO, GL_NONE, GL_NONE);
40332001f49Smrg   /* -> reg3 g = reg4 alpha = -0.5 */
40432001f49Smrg   glAlphaFragmentOp2ATI(GL_ADD_ATI,
40532001f49Smrg			 GL_REG_5_ATI, GL_NONE,
40632001f49Smrg			 GL_REG_3_ATI, GL_GREEN, GL_NONE,
40732001f49Smrg			 GL_REG_4_ATI, GL_NONE, GL_NONE);
40832001f49Smrg   /* -> reg5 a = -1 */
40932001f49Smrg   glColorFragmentOp3ATI(GL_DOT2_ADD_ATI,
41032001f49Smrg			 GL_REG_4_ATI, GL_BLUE_BIT_ATI, GL_HALF_BIT_ATI,
41132001f49Smrg			 GL_REG_5_ATI, GL_ALPHA, GL_NEGATE_BIT_ATI,
41232001f49Smrg			 GL_ONE, GL_NONE, GL_BIAS_BIT_ATI,
41332001f49Smrg			 GL_ONE, GL_ALPHA, GL_2X_BIT_ATI | GL_NEGATE_BIT_ATI);
41432001f49Smrg   /* -> reg 4 b = -0.5 */
41532001f49Smrg   glColorFragmentOp2ATI(GL_MUL_ATI,
41632001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_NONE,
41732001f49Smrg			 GL_REG_4_ATI, GL_BLUE, GL_NEGATE_BIT_ATI | GL_2X_BIT_ATI,
41832001f49Smrg			 GL_REG_0_ATI, GL_NONE, GL_NONE);
41932001f49Smrg   glEndFragmentShaderATI();
42032001f49Smrg
42132001f49Smrg   glBindFragmentShaderATI(boringshaderID);
42232001f49Smrg   glEnable(GL_FRAGMENT_SHADER_ATI);
42332001f49Smrg
42432001f49Smrg   glShadeModel(GL_FLAT);
42532001f49Smrg   glClearColor(0.3, 0.3, 0.4, 1.0);
42632001f49Smrg
42732001f49Smrg   if (argc > 1 && strcmp(argv[1], "-info")==0) {
42832001f49Smrg      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
42932001f49Smrg      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
43032001f49Smrg      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
43132001f49Smrg      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
43232001f49Smrg   }
43332001f49Smrg   printf("output should be identical with both shaders to multiarb demo when 6 textures are enabled\n");
43432001f49Smrg}
43532001f49Smrg
43632001f49Smrg
43732001f49Smrgint main( int argc, char *argv[] )
43832001f49Smrg{
43932001f49Smrg/*   GLint i;*/
44032001f49Smrg
44132001f49Smrg   glutInit( &argc, argv );
44232001f49Smrg   glutInitWindowSize( 300, 300 );
44332001f49Smrg   glutInitWindowPosition( 0, 0 );
44432001f49Smrg   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
44532001f49Smrg   glutCreateWindow(argv[0] );
44632001f49Smrg   glewInit();
44732001f49Smrg
44832001f49Smrg   Init( argc, argv );
44932001f49Smrg
45032001f49Smrg   glutReshapeFunc( Reshape );
45132001f49Smrg   glutKeyboardFunc( Key );
45232001f49Smrg   glutSpecialFunc( SpecialKey );
45332001f49Smrg   glutDisplayFunc( Display );
45432001f49Smrg   glutIdleFunc( Idle );
45532001f49Smrg
45632001f49Smrg   glutCreateMenu(ModeMenu);
45732001f49Smrg
45832001f49Smrg/*   for (i = 0; i < NumUnits; i++) {
45932001f49Smrg      char s[100];
46032001f49Smrg      sprintf(s, "Toggle Texture %d", i);
46132001f49Smrg      glutAddMenuEntry(s, TEX0 + i);
46232001f49Smrg   }*/
46332001f49Smrg   glutAddMenuEntry("Toggle 1/2 Pass Shader", SHADER);
46432001f49Smrg   glutAddMenuEntry("Toggle Animation", ANIMATE);
46532001f49Smrg   glutAddMenuEntry("Quit", QUIT);
46632001f49Smrg   glutAttachMenu(GLUT_RIGHT_BUTTON);
46732001f49Smrg
46832001f49Smrg   glutMainLoop();
46932001f49Smrg   return 0;
47032001f49Smrg}
471