1/* Test GL_ARB_fragment_program */
2
3#include <assert.h>
4#include <string.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <math.h>
8#include <GL/glew.h>
9#include "glut_wrap.h"
10
11
12
13static void Display( void )
14{
15   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
16
17   glPushMatrix();
18
19   glColor4f(0, 0.5, 0, 1);
20   glColor4f(0, 1, 0, 1);
21   glBegin(GL_POLYGON);
22   glVertex2f(-1, -1);
23   glVertex2f( 1, -1);
24   glVertex2f( 0,  1);
25   glEnd();
26
27   glPopMatrix();
28
29   glutSwapBuffers();
30}
31
32
33static void Reshape( int width, int height )
34{
35   glViewport( 0, 0, width, height );
36   glMatrixMode( GL_PROJECTION );
37   glLoadIdentity();
38   glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
39   glMatrixMode( GL_MODELVIEW );
40   glLoadIdentity();
41   glTranslatef( 0.0, 0.0, -15.0 );
42}
43
44
45static void Key( unsigned char key, int x, int y )
46{
47   (void) x;
48   (void) y;
49   switch (key) {
50      case 27:
51         exit(0);
52         break;
53   }
54   glutPostRedisplay();
55}
56
57static void load_program(const char *prog, GLuint prognum)
58{
59   int a;
60   GLint errorpos, errnum;
61
62   glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prognum);
63   glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
64                        strlen(prog), (const GLubyte *) prog);
65
66   assert(glIsProgramARB(prognum));
67   errnum = glGetError();
68   printf("glGetError = %d\n", errnum);
69   if (errnum != GL_NO_ERROR)
70   {
71      glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorpos);
72      printf("errorpos: %d\n", errorpos);
73      printf("%s\n", (char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB));
74
75      for (a=-10; a<10; a++)
76      {
77         if ((errorpos+a < 0) || (errorpos+a >= strlen(prog))) continue;
78         printf("%c", prog[errorpos+a]);
79      }
80      printf("\n");
81      exit(1);
82   }
83}
84
85static void Init( void )
86{
87   static const char *prog0 =
88      "!!ARBfp1.0\n"
89      "TEMP R0, RC, HC, H0, H1, H2, H3, H30 ;\n"
90      "MUL       result.color, R0, fragment.position; \n"
91      "ADD       result.color, H3, fragment.texcoord; \n"
92      "ADD_SAT   result.color, H3, fragment.texcoord; \n"
93      "MUL       result.color.xy, R0.wzyx, fragment.position; \n"
94      "MUL       result.color, H0, fragment.position; \n"
95      "MUL       result.color, -H0, fragment.position; \n"
96      "MOV       RC, H1; \n"
97      "MOV       HC, H2; \n"
98      "END \n"
99      ;
100   /* masked updates, defines, declarations */
101   static const char *prog1 =
102      "!!ARBfp1.0\n"
103      "PARAM foo = {1., 2., 3., 4.}; \n"
104      "PARAM foo2 = 5.; \n"
105      "PARAM foo3 = {5., 6., 7., 8.}; \n"
106      "PARAM bar = 3.; \n"
107      "TEMP  R0, R1, RC, EQ, NE, bar2; \n"
108      "ALIAS bar3 = bar; \n"
109      "MOV result.color.xy,  R0; \n"
110      "MOV result.color,     R0; \n"
111      "MOV result.color.xyzw, R0; \n"
112      "MOV result.color.xy,  R0; \n"
113      "MOV RC.x, R1.x; \n"
114      "KIL NE; \n"
115      "KIL EQ.xyxy; \n"
116      "END \n"
117      ;
118
119   /* texture instructions */
120   static const char *prog2 =
121      "!!ARBfp1.0\n"
122      "TEMP R0, R1, R2, R3;\n"
123      "TEX R0, fragment.texcoord,    texture[0], 2D; \n"
124      "TEX R1, fragment.texcoord[1], texture[1], CUBE; \n"
125      "TEX R2, fragment.texcoord[2], texture[2], 3D; \n"
126      "TXP R3, fragment.texcoord[3], texture[3], RECT; \n"
127      "MUL result.color, R0, fragment.color; \n"
128      "END \n"
129      ;
130
131   /* test negation, absolute value */
132   static const char *prog3 =
133      "!!ARBfp1.0\n"
134      "TEMP R0, R1;\n"
135      "MOV R0,  R1; \n"
136      "MOV R0, -R1; \n"
137      "MOV result.color, R0; \n"
138      "END \n"
139      ;
140
141   /* literal constant sources */
142   static const char *prog4 =
143      "!!ARBfp1.0\n"
144      "TEMP R0, R1;\n"
145      "PARAM Pi = 3.14159; \n"
146      "MOV R0, {1., -2., +3., 4.}; \n"
147      "MOV R0, 5.; \n"
148      "MOV R0, -5.; \n"
149      "MOV R0, 5.; \n"
150      "MOV R0, Pi; \n"
151      "MOV result.color, R0; \n"
152      "END \n"
153      ;
154
155   /* change the fragment color in a simple way */
156   static const char *prog10 =
157      "!!ARBfp1.0\n"
158      "PARAM blue = {0., 0., 1., 0.};\n"
159      "PARAM color = {1., 0., 0., 1.};\n"
160      "TEMP R0; \n"
161      "MOV R0, fragment.color; \n"
162      "#ADD result.color, R0, fragment.color; \n"
163      "#ADD result.color, blue, fragment.color; \n"
164      "#ADD result.color, {1., 0., 0., 0.}, fragment.color; \n"
165      "ADD result.color, color, fragment.color; \n"
166      "END \n"
167      ;
168
169   GLuint progs[20];
170
171   glGenProgramsARB(20, progs);
172   assert(progs[0]);
173   assert(progs[1]);
174   assert(progs[0] != progs[1]);
175
176
177   printf("program 0:\n");
178	load_program(prog0, progs[0]);
179   printf("program 1:\n");
180	load_program(prog1, progs[1]);
181   printf("program 2:\n");
182	load_program(prog2, progs[2]);
183   printf("program 3:\n");
184	load_program(prog3, progs[3]);
185	printf("program 4:\n");
186	load_program(prog4, progs[4]);
187	printf("program 10:\n");
188	load_program(prog10, progs[5]);
189
190
191   glEnable(GL_FRAGMENT_PROGRAM_ARB);
192   glEnable(GL_ALPHA_TEST);
193   glAlphaFunc(GL_ALWAYS, 0.0);
194}
195
196
197int main( int argc, char *argv[] )
198{
199   glutInit( &argc, argv );
200   glutInitWindowPosition( 0, 0 );
201   glutInitWindowSize( 250, 250 );
202   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
203   glutCreateWindow(argv[0]);
204   glewInit();
205   glutReshapeFunc( Reshape );
206   glutKeyboardFunc( Key );
207   glutDisplayFunc( Display );
208   Init();
209   glutMainLoop();
210   return 0;
211}
212