2 * GL_ATI_fragment_shader test
5 * Command line options:
6 * -info print GL implementation information
19 #define TEXTURE_1_FILE "../images/girl.rgb"
20 #define TEXTURE_2_FILE "../images/reflect.rgb"
28 static GLboolean Animate
= GL_TRUE
;
29 static GLint NumUnits
= 6;
30 static GLboolean TexEnabled
[8];
31 static GLuint boringshaderID
= 0;
32 static GLuint boring2passID
= 0;
33 static GLboolean Shader
= GL_FALSE
;
35 static GLfloat Drift
= 0.0;
36 static GLfloat drift_increment
= 0.005;
37 static GLfloat Xrot
= 20.0, Yrot
= 30.0, Zrot
= 0.0;
38 static GLfloat shaderconstant
[4] = {0.5, 0.0, 0.0, 0.0};
40 static void Idle( void )
45 Drift
+= drift_increment
;
49 for (i
= 0; i
< NumUnits
; i
++) {
50 glActiveTextureARB(GL_TEXTURE0_ARB
+ i
);
51 glMatrixMode(GL_TEXTURE
);
54 glTranslatef(Drift
, 0.0, 0.0);
58 glTranslatef(0.0, Drift
, 0.0);
61 glTranslatef(0.5, 0.5, 0.0);
62 glRotatef(180.0 * Drift
, 0, 0, 1);
63 glScalef(1.0/i
, 1.0/i
, 1.0/i
);
64 glTranslatef(-0.5, -0.5, 0.0);
67 glMatrixMode(GL_MODELVIEW
);
74 static void DrawObject(void)
78 static const GLfloat tex_coords
[] = { 0.0, 0.0, 1.0, 1.0, 0.0 };
79 static const GLfloat vtx_coords
[] = { -1.0, -1.0, 1.0, 1.0, -1.0 };
81 if (!TexEnabled
[0] && !TexEnabled
[1])
82 glColor3f(0.1, 0.1, 0.1); /* add onto this */
84 glColor3f(1, 1, 1); /* modulate this */
88 /* Toggle between the vector and scalar entry points. This is done purely
89 * to hit multiple paths in the driver.
92 for (j
= 0; j
< 4; j
++ ) {
93 for (i
= 0; i
< NumUnits
; i
++)
94 glMultiTexCoord2fARB(GL_TEXTURE0_ARB
+ i
,
95 tex_coords
[j
], tex_coords
[j
+1]);
96 glVertex2f( vtx_coords
[j
], vtx_coords
[j
+1] );
100 for (j
= 0; j
< 4; j
++ ) {
101 for (i
= 0; i
< NumUnits
; i
++)
102 glMultiTexCoord2fvARB(GL_TEXTURE0_ARB
+ i
, & tex_coords
[j
]);
103 glVertex2fv( & vtx_coords
[j
] );
112 static void Display( void )
115 static GLint Frames
= 0;
118 glClear( GL_COLOR_BUFFER_BIT
);
121 glRotatef(Xrot
, 1.0, 0.0, 0.0);
122 glRotatef(Yrot
, 0.0, 1.0, 0.0);
123 glRotatef(Zrot
, 0.0, 0.0, 1.0);
124 glScalef(5.0, 5.0, 5.0);
132 t
= glutGet(GLUT_ELAPSED_TIME
);
133 if (t
- T0
>= 2500) {
134 GLfloat seconds
= (t
- T0
) / 1000.0;
135 GLfloat fps
= Frames
/ seconds
;
136 drift_increment
= 2.2 * seconds
/ Frames
;
137 printf("%d frames in %6.3f seconds = %6.3f FPS\n", Frames
, seconds
, fps
);
144 static void Reshape( int width
, int height
)
146 glViewport( 0, 0, width
, height
);
147 glMatrixMode( GL_PROJECTION
);
149 glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 );
150 /*glOrtho( -6.0, 6.0, -6.0, 6.0, 10.0, 100.0 );*/
151 glMatrixMode( GL_MODELVIEW
);
153 glTranslatef( 0.0, 0.0, -70.0 );
157 static void ModeMenu(int entry
)
159 if (entry
>= TEX0
&& entry
<= TEX7
) {
161 GLint i
= entry
- TEX0
;
162 TexEnabled
[i
] = !TexEnabled
[i
];
163 glActiveTextureARB(GL_TEXTURE0_ARB
+ i
);
165 glEnable(GL_TEXTURE_2D
);
167 glDisable(GL_TEXTURE_2D
);
169 for (i
= 0; i
< NumUnits
; i
++)
170 printf("%d ", (int) TexEnabled
[i
]);
173 else if (entry
==ANIMATE
) {
176 else if (entry
==SHADER
) {
179 fprintf(stderr
, "using 2-pass shader\n");
180 glBindFragmentShaderATI(boring2passID
);
183 fprintf(stderr
, "using 1-pass shader\n");
184 glBindFragmentShaderATI(boringshaderID
);
187 else if (entry
==QUIT
) {
195 static void Key( unsigned char key
, int x
, int y
)
208 static void SpecialKey( int key
, int x
, int y
)
232 static void Init( int argc
, char *argv
[] )
237 const char *exten
= (const char *) glGetString(GL_EXTENSIONS
);
238 if (!strstr(exten
, "GL_ATI_fragment_shader")) {
239 printf("Sorry, GL_ATI_fragment_shader not supported by this renderer.\n");
244 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &size
);
245 printf("%d x %d max texture size\n", size
, size
);
247 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
249 for (i
= 0; i
< NumUnits
; i
++) {
251 TexEnabled
[i
] = GL_TRUE
;
253 TexEnabled
[i
] = GL_FALSE
;
256 /* allocate two texture objects */
257 glGenTextures(NumUnits
, texObj
);
259 /* setup the texture objects */
260 for (i
= 0; i
< NumUnits
; i
++) {
262 glActiveTextureARB(GL_TEXTURE0_ARB
+ i
);
263 glBindTexture(GL_TEXTURE_2D
, texObj
[i
]);
265 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
266 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
269 if (!LoadRGBMipmaps(TEXTURE_1_FILE
, GL_RGB
)) {
270 printf("Error: couldn't load texture image\n");
275 if (!LoadRGBMipmaps(TEXTURE_2_FILE
, GL_RGB
)) {
276 printf("Error: couldn't load texture image\n");
282 GLubyte image
[8][8][3];
284 for (i
= 0; i
< 8; i
++) {
285 for (j
= 0; j
< 8; j
++) {
298 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGB
, 8, 8, 0,
299 GL_RGB
, GL_UNSIGNED_BYTE
, (GLvoid
*) image
);
302 /* Bind texObj[i] to ith texture unit */
304 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
306 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);*/
309 glEnable(GL_TEXTURE_2D
);
312 boringshaderID
= glGenFragmentShadersATI(1);
313 boring2passID
= glGenFragmentShadersATI(1);
314 if (boring2passID
== 0)
316 fprintf(stderr
, "couldn't get frag shader id\n");
319 glBindFragmentShaderATI(boringshaderID
);
320 /* maybe not the most creative shader but at least I know how it should look like! */
321 glBeginFragmentShaderATI();
322 glSampleMapATI(GL_REG_0_ATI
, GL_TEXTURE0_ARB
, GL_SWIZZLE_STR_ATI
);
323 glSampleMapATI(GL_REG_1_ATI
, GL_TEXTURE1_ARB
, GL_SWIZZLE_STR_ATI
);
324 glSampleMapATI(GL_REG_2_ATI
, GL_TEXTURE2_ARB
, GL_SWIZZLE_STR_ATI
);
325 glSampleMapATI(GL_REG_3_ATI
, GL_TEXTURE3_ARB
, GL_SWIZZLE_STR_ATI
);
326 glSampleMapATI(GL_REG_4_ATI
, GL_TEXTURE4_ARB
, GL_SWIZZLE_STR_ATI
);
327 glSampleMapATI(GL_REG_5_ATI
, GL_TEXTURE5_ARB
, GL_SWIZZLE_STR_ATI
);
328 glColorFragmentOp2ATI(GL_MUL_ATI
,
329 GL_REG_0_ATI
, GL_NONE
, GL_SATURATE_BIT_ATI
,
330 GL_REG_0_ATI
, GL_NONE
, GL_NONE
,
331 GL_PRIMARY_COLOR
, GL_NONE
, GL_NONE
);
332 glAlphaFragmentOp1ATI(GL_MOV_ATI
,
333 GL_REG_0_ATI
, GL_NONE
,
334 GL_PRIMARY_COLOR
, GL_NONE
, GL_NONE
);
335 glColorFragmentOp3ATI(GL_MAD_ATI
,
336 GL_REG_0_ATI
, GL_NONE
, GL_SATURATE_BIT_ATI
,
337 GL_REG_0_ATI
, GL_NONE
, GL_NONE
,
338 GL_REG_1_ATI
, GL_NONE
, GL_NONE
,
339 GL_REG_2_ATI
, GL_NONE
, GL_NONE
);
340 glColorFragmentOp2ATI(GL_ADD_ATI
,
341 GL_REG_0_ATI
, GL_NONE
, GL_SATURATE_BIT_ATI
,
342 GL_REG_0_ATI
, GL_NONE
, GL_NONE
,
343 GL_REG_3_ATI
, GL_NONE
, GL_NONE
);
344 glColorFragmentOp2ATI(GL_ADD_ATI
,
345 GL_REG_0_ATI
, GL_NONE
, GL_SATURATE_BIT_ATI
,
346 GL_REG_0_ATI
, GL_NONE
, GL_NONE
,
347 GL_REG_4_ATI
, GL_NONE
, GL_NONE
);
348 glColorFragmentOp2ATI(GL_ADD_ATI
,
349 GL_REG_0_ATI
, GL_NONE
, GL_SATURATE_BIT_ATI
,
350 GL_REG_0_ATI
, GL_NONE
, GL_NONE
,
351 GL_REG_5_ATI
, GL_NONE
, GL_NONE
);
352 glEndFragmentShaderATI();
354 /* mathematically equivalent to first shader but using 2 passes together with
355 some tex coord rerouting */
356 glBindFragmentShaderATI(boring2passID
);
357 glBeginFragmentShaderATI();
358 glPassTexCoordATI(GL_REG_1_ATI
, GL_TEXTURE0_ARB
, GL_SWIZZLE_STR_ATI
);
359 glSampleMapATI(GL_REG_2_ATI
, GL_TEXTURE2_ARB
, GL_SWIZZLE_STR_ATI
);
360 glSampleMapATI(GL_REG_3_ATI
, GL_TEXTURE3_ARB
, GL_SWIZZLE_STR_ATI
);
361 glSampleMapATI(GL_REG_4_ATI
, GL_TEXTURE4_ARB
, GL_SWIZZLE_STR_ATI
);
362 glSampleMapATI(GL_REG_5_ATI
, GL_TEXTURE5_ARB
, GL_SWIZZLE_STR_ATI
);
363 glColorFragmentOp2ATI(GL_ADD_ATI
,
364 GL_REG_0_ATI
, GL_NONE
, GL_SATURATE_BIT_ATI
,
365 GL_REG_2_ATI
, GL_NONE
, GL_NONE
,
366 GL_REG_3_ATI
, GL_NONE
, GL_NONE
);
367 glColorFragmentOp2ATI(GL_ADD_ATI
,
368 GL_REG_0_ATI
, GL_NONE
, GL_SATURATE_BIT_ATI
,
369 GL_REG_0_ATI
, GL_NONE
, GL_NONE
,
370 GL_REG_4_ATI
, GL_NONE
, GL_NONE
);
371 glColorFragmentOp2ATI(GL_ADD_ATI
,
372 GL_REG_0_ATI
, GL_NONE
, GL_SATURATE_BIT_ATI
,
373 GL_REG_0_ATI
, GL_NONE
, GL_NONE
,
374 GL_REG_5_ATI
, GL_NONE
, GL_NONE
);
375 /* not really a dependant read */
376 glSampleMapATI(GL_REG_0_ATI
, GL_REG_1_ATI
, GL_SWIZZLE_STR_ATI
);
377 glSampleMapATI(GL_REG_1_ATI
, GL_TEXTURE1_ARB
, GL_SWIZZLE_STR_ATI
);
378 glPassTexCoordATI(GL_REG_5_ATI
, GL_REG_0_ATI
, GL_SWIZZLE_STR_ATI
);
379 glColorFragmentOp2ATI(GL_MUL_ATI
,
380 GL_REG_0_ATI
, GL_NONE
, GL_SATURATE_BIT_ATI
,
381 GL_REG_0_ATI
, GL_NONE
, GL_NONE
,
382 GL_PRIMARY_COLOR
, GL_NONE
, GL_NONE
);
383 glAlphaFragmentOp1ATI(GL_MOV_ATI
,
384 GL_REG_0_ATI
, GL_NONE
,
385 GL_PRIMARY_COLOR
, GL_NONE
, GL_NONE
);
386 glColorFragmentOp3ATI(GL_MAD_ATI
,
387 GL_REG_0_ATI
, GL_NONE
, GL_SATURATE_BIT_ATI
,
388 GL_REG_0_ATI
, GL_NONE
, GL_NONE
,
389 GL_REG_1_ATI
, GL_NONE
, GL_NONE
,
390 GL_REG_5_ATI
, GL_NONE
, GL_NONE
);
391 /* in principle we're finished here, but to test a bit more
392 we do some fun with dot ops, replication et al. */
393 glSetFragmentShaderConstantATI(GL_CON_3_ATI
, shaderconstant
);
394 glColorFragmentOp2ATI(GL_DOT4_ATI
,
395 GL_REG_3_ATI
, GL_GREEN_BIT_ATI
, GL_EIGHTH_BIT_ATI
,
396 GL_ZERO
, GL_NONE
, GL_COMP_BIT_ATI
| GL_NEGATE_BIT_ATI
,
397 GL_CON_3_ATI
, GL_RED
, GL_2X_BIT_ATI
);
398 /* those args must get ignored, except dstReg */
399 glAlphaFragmentOp2ATI(GL_DOT4_ATI
,
400 GL_REG_4_ATI
, GL_NONE
,
401 GL_ZERO
, GL_NONE
, GL_NONE
,
402 GL_ZERO
, GL_NONE
, GL_NONE
);
403 /* -> reg3 g = reg4 alpha = -0.5 */
404 glAlphaFragmentOp2ATI(GL_ADD_ATI
,
405 GL_REG_5_ATI
, GL_NONE
,
406 GL_REG_3_ATI
, GL_GREEN
, GL_NONE
,
407 GL_REG_4_ATI
, GL_NONE
, GL_NONE
);
409 glColorFragmentOp3ATI(GL_DOT2_ADD_ATI
,
410 GL_REG_4_ATI
, GL_BLUE_BIT_ATI
, GL_HALF_BIT_ATI
,
411 GL_REG_5_ATI
, GL_ALPHA
, GL_NEGATE_BIT_ATI
,
412 GL_ONE
, GL_NONE
, GL_BIAS_BIT_ATI
,
413 GL_ONE
, GL_ALPHA
, GL_2X_BIT_ATI
| GL_NEGATE_BIT_ATI
);
414 /* -> reg 4 b = -0.5 */
415 glColorFragmentOp2ATI(GL_MUL_ATI
,
416 GL_REG_0_ATI
, GL_NONE
, GL_NONE
,
417 GL_REG_4_ATI
, GL_BLUE
, GL_NEGATE_BIT_ATI
| GL_2X_BIT_ATI
,
418 GL_REG_0_ATI
, GL_NONE
, GL_NONE
);
419 glEndFragmentShaderATI();
421 glBindFragmentShaderATI(boringshaderID
);
422 glEnable(GL_FRAGMENT_SHADER_ATI
);
424 glShadeModel(GL_FLAT
);
425 glClearColor(0.3, 0.3, 0.4, 1.0);
427 if (argc
> 1 && strcmp(argv
[1], "-info")==0) {
428 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
429 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION
));
430 printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR
));
431 printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS
));
433 printf("output should be identical with both shaders to multiarb demo when 6 textures are enabled\n");
437 int main( int argc
, char *argv
[] )
441 glutInit( &argc
, argv
);
442 glutInitWindowSize( 300, 300 );
443 glutInitWindowPosition( 0, 0 );
444 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
);
445 glutCreateWindow(argv
[0] );
450 glutReshapeFunc( Reshape
);
451 glutKeyboardFunc( Key
);
452 glutSpecialFunc( SpecialKey
);
453 glutDisplayFunc( Display
);
454 glutIdleFunc( Idle
);
456 glutCreateMenu(ModeMenu
);
458 /* for (i = 0; i < NumUnits; i++) {
460 sprintf(s, "Toggle Texture %d", i);
461 glutAddMenuEntry(s, TEX0 + i);
463 glutAddMenuEntry("Toggle 1/2 Pass Shader", SHADER
);
464 glutAddMenuEntry("Toggle Animation", ANIMATE
);
465 glutAddMenuEntry("Quit", QUIT
);
466 glutAttachMenu(GLUT_RIGHT_BUTTON
);