132001f49Smrg/**
232001f49Smrg * Test GLSL gl_FragCoord fragment program attribute.
332001f49Smrg * Color the quad's fragments according to their window position.
432001f49Smrg *
532001f49Smrg * Brian Paul
632001f49Smrg * 20 Nov 2008
732001f49Smrg */
832001f49Smrg
932001f49Smrg
1032001f49Smrg#include <assert.h>
1132001f49Smrg#include <string.h>
1232001f49Smrg#include <stdio.h>
1332001f49Smrg#include <stdlib.h>
1432001f49Smrg#include <math.h>
1532001f49Smrg#include <GL/glew.h>
1632001f49Smrg#include "glut_wrap.h"
1732001f49Smrg#include "shaderutil.h"
1832001f49Smrg
1932001f49Smrg
2032001f49Smrgstatic GLint WinWidth = 200, WinHeight = 200;
2132001f49Smrgstatic char *FragProgFile = NULL;
2232001f49Smrgstatic char *VertProgFile = NULL;
2332001f49Smrgstatic GLuint fragShader;
2432001f49Smrgstatic GLuint vertShader;
2532001f49Smrgstatic GLuint program;
2632001f49Smrgstatic GLint win = 0;
2732001f49Smrgstatic GLboolean Anim = GL_TRUE;
2832001f49Smrgstatic GLfloat PosX = 0.0, PosY = 0.0;
2932001f49Smrg
3032001f49Smrg
3132001f49Smrgstatic void
3232001f49SmrgIdle(void)
3332001f49Smrg{
3432001f49Smrg   float r = (WinWidth < WinHeight) ? WinWidth : WinHeight;
3532001f49Smrg   float a = glutGet(GLUT_ELAPSED_TIME) * 0.001;
3632001f49Smrg   r *= 0.25;
3732001f49Smrg   PosX = WinWidth / 2 + r * cos(a);
3832001f49Smrg   PosY = WinHeight / 2 + r * sin(a);
3932001f49Smrg
4032001f49Smrg   glutPostRedisplay();
4132001f49Smrg}
4232001f49Smrg
4332001f49Smrg
4432001f49Smrgstatic void
4532001f49SmrgRedisplay(void)
4632001f49Smrg{
4732001f49Smrg   glClear(GL_COLOR_BUFFER_BIT);
4832001f49Smrg
4932001f49Smrg   glPushMatrix();
5032001f49Smrg   glTranslatef(PosX, PosY, 0.0);
5132001f49Smrg#if 0
5232001f49Smrg   glBegin(GL_POLYGON);
5332001f49Smrg   glVertex2f(-50, -50);
5432001f49Smrg   glVertex2f( 50, -50);
5532001f49Smrg   glVertex2f( 50,  50);
5632001f49Smrg   glVertex2f(-50,  50);
5732001f49Smrg   glEnd();
5832001f49Smrg#else
5932001f49Smrg   glutSolidSphere(50, 20, 10);
6032001f49Smrg#endif
6132001f49Smrg   glPopMatrix();
6232001f49Smrg
6332001f49Smrg   glutSwapBuffers();
6432001f49Smrg}
6532001f49Smrg
6632001f49Smrg
6732001f49Smrgstatic void
6832001f49SmrgReshape(int width, int height)
6932001f49Smrg{
7032001f49Smrg   glViewport(0, 0, width, height);
7132001f49Smrg   glMatrixMode(GL_PROJECTION);
7232001f49Smrg   glLoadIdentity();
7332001f49Smrg   glOrtho(0, width, 0, height, -55, 55);
7432001f49Smrg
7532001f49Smrg   glMatrixMode(GL_MODELVIEW);
7632001f49Smrg   glLoadIdentity();
7732001f49Smrg
7832001f49Smrg   WinWidth = width;
7932001f49Smrg   WinHeight = height;
8032001f49Smrg}
8132001f49Smrg
8232001f49Smrg
8332001f49Smrgstatic void
8432001f49SmrgCleanUp(void)
8532001f49Smrg{
8632001f49Smrg   glDeleteShader(fragShader);
8732001f49Smrg   glDeleteShader(vertShader);
8832001f49Smrg   glDeleteProgram(program);
8932001f49Smrg   glutDestroyWindow(win);
9032001f49Smrg}
9132001f49Smrg
9232001f49Smrg
9332001f49Smrgstatic void
9432001f49SmrgKey(unsigned char key, int x, int y)
9532001f49Smrg{
9632001f49Smrg  (void) x;
9732001f49Smrg  (void) y;
9832001f49Smrg
9932001f49Smrg   switch(key) {
10032001f49Smrg   case ' ':
10132001f49Smrg   case 'a':
10232001f49Smrg      Anim = !Anim;
10332001f49Smrg      glutIdleFunc(Anim ? Idle : NULL);
10432001f49Smrg      break;
10532001f49Smrg   case 27:
10632001f49Smrg      CleanUp();
10732001f49Smrg      exit(0);
10832001f49Smrg      break;
10932001f49Smrg   }
11032001f49Smrg   glutPostRedisplay();
11132001f49Smrg}
11232001f49Smrg
11332001f49Smrg
11432001f49Smrgstatic void
11532001f49SmrgInit(void)
11632001f49Smrg{
11732001f49Smrg   static const char *fragShaderText =
11832001f49Smrg      "void main() { \n"
11932001f49Smrg      "   vec4 scale = vec4(.005, 0.005, 0.5, 1.0);\n"
12032001f49Smrg      "   gl_FragColor = gl_FragCoord * scale; \n"
12132001f49Smrg      "}\n";
12232001f49Smrg   static const char *vertShaderText =
12332001f49Smrg      "void main() {\n"
12432001f49Smrg      "   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
12532001f49Smrg      "}\n";
12632001f49Smrg
12732001f49Smrg   if (!ShadersSupported())
12832001f49Smrg      exit(1);
12932001f49Smrg
13032001f49Smrg   vertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText);
13132001f49Smrg   fragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText);
13232001f49Smrg   program = LinkShaders(vertShader, fragShader);
13332001f49Smrg
13432001f49Smrg   glUseProgram(program);
13532001f49Smrg
13632001f49Smrg   /*assert(glGetError() == 0);*/
13732001f49Smrg
13832001f49Smrg   glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
13932001f49Smrg
14032001f49Smrg   printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
14132001f49Smrg
14232001f49Smrg   assert(glIsProgram(program));
14332001f49Smrg   assert(glIsShader(fragShader));
14432001f49Smrg   assert(glIsShader(vertShader));
14532001f49Smrg
14632001f49Smrg   glColor3f(1, 0, 0);
14732001f49Smrg}
14832001f49Smrg
14932001f49Smrg
15032001f49Smrgstatic void
15132001f49SmrgParseOptions(int argc, char *argv[])
15232001f49Smrg{
15332001f49Smrg   int i;
15432001f49Smrg   for (i = 1; i < argc; i++) {
15532001f49Smrg      if (strcmp(argv[i], "-fs") == 0) {
15632001f49Smrg         FragProgFile = argv[i+1];
15732001f49Smrg      }
15832001f49Smrg      else if (strcmp(argv[i], "-vs") == 0) {
15932001f49Smrg         VertProgFile = argv[i+1];
16032001f49Smrg      }
16132001f49Smrg   }
16232001f49Smrg}
16332001f49Smrg
16432001f49Smrg
16532001f49Smrgint
16632001f49Smrgmain(int argc, char *argv[])
16732001f49Smrg{
16832001f49Smrg   glutInit(&argc, argv);
16932001f49Smrg   glutInitWindowSize(WinWidth, WinHeight);
17032001f49Smrg   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
17132001f49Smrg   win = glutCreateWindow(argv[0]);
17232001f49Smrg   glewInit();
17332001f49Smrg   glutReshapeFunc(Reshape);
17432001f49Smrg   glutKeyboardFunc(Key);
17532001f49Smrg   glutDisplayFunc(Redisplay);
17632001f49Smrg   ParseOptions(argc, argv);
17732001f49Smrg   Init();
17832001f49Smrg   glutIdleFunc(Anim ? Idle : NULL);
17932001f49Smrg   glutMainLoop();
18032001f49Smrg   return 0;
18132001f49Smrg}
182