1 /**
2  * Test OpenGL 2.0 dx/dy functions for texcoords.
3  * Brian Paul
4  * 2 May 2007
5  *
6  * NOTE: resize the window to observe how the partial derivatives of
7  * the texcoords change.
8  */
9 
10 
11 #include <assert.h>
12 #include <string.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <math.h>
16 #include <glad/glad.h>
17 #include "glut_wrap.h"
18 #include "shaderutil.h"
19 
20 
21 static char *FragProgFile = NULL;
22 static char *VertProgFile = NULL;
23 static GLuint fragShader;
24 static GLuint vertShader;
25 static GLuint program;
26 static GLuint SphereList, RectList, CurList;
27 static GLint win = 0;
28 static GLboolean anim = GL_TRUE;
29 static GLfloat xRot = 0.0f, yRot = 0.0f;
30 static GLint WinSize[2];
31 static GLint WinSizeUniform = -1;
32 
33 
34 static void
Redisplay(void)35 Redisplay(void)
36 {
37    glUniform2iv(WinSizeUniform, 1, WinSize);
38 
39    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
40 
41    glPushMatrix();
42    glRotatef(xRot, 1.0f, 0.0f, 0.0f);
43    glRotatef(yRot, 0.0f, 1.0f, 0.0f);
44    glCallList(CurList);
45    glPopMatrix();
46 
47    glutSwapBuffers();
48 }
49 
50 
51 static void
Idle(void)52 Idle(void)
53 {
54    yRot = glutGet(GLUT_ELAPSED_TIME) * 0.1;
55    glutPostRedisplay();
56 }
57 
58 
59 static void
Reshape(int width,int height)60 Reshape(int width, int height)
61 {
62    WinSize[0] = width;
63    WinSize[1] = height;
64    glViewport(0, 0, width, height);
65    glMatrixMode(GL_PROJECTION);
66    glLoadIdentity();
67    glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
68    glMatrixMode(GL_MODELVIEW);
69    glLoadIdentity();
70    glTranslatef(0.0f, 0.0f, -15.0f);
71 }
72 
73 
74 static void
CleanUp(void)75 CleanUp(void)
76 {
77    glDeleteShader(fragShader);
78    glDeleteShader(vertShader);
79    glDeleteProgram(program);
80    glutDestroyWindow(win);
81 }
82 
83 
84 static void
Key(unsigned char key,int x,int y)85 Key(unsigned char key, int x, int y)
86 {
87   (void) x;
88   (void) y;
89 
90    switch(key) {
91    case ' ':
92    case 'a':
93       anim = !anim;
94       if (anim)
95          glutIdleFunc(Idle);
96       else
97          glutIdleFunc(NULL);
98       break;
99    case 'o':
100       if (CurList == SphereList)
101          CurList = RectList;
102       else
103          CurList = SphereList;
104       break;
105    case 27:
106       CleanUp();
107       exit(0);
108       break;
109    }
110    glutPostRedisplay();
111 }
112 
113 
114 static void
SpecialKey(int key,int x,int y)115 SpecialKey(int key, int x, int y)
116 {
117    const GLfloat step = 3.0f;
118 
119   (void) x;
120   (void) y;
121 
122    switch(key) {
123    case GLUT_KEY_UP:
124       xRot -= step;
125       break;
126    case GLUT_KEY_DOWN:
127       xRot += step;
128       break;
129    case GLUT_KEY_LEFT:
130       yRot -= step;
131       break;
132    case GLUT_KEY_RIGHT:
133       yRot += step;
134       break;
135    }
136    glutPostRedisplay();
137 }
138 
139 
140 static void
MakeSphere(void)141 MakeSphere(void)
142 {
143    GLUquadricObj *obj = gluNewQuadric();
144    SphereList = glGenLists(1);
145    gluQuadricTexture(obj, GL_TRUE);
146    glNewList(SphereList, GL_COMPILE);
147    gluSphere(obj, 2.0f, 30, 15);
148    glEndList();
149    gluDeleteQuadric(obj);
150 }
151 
152 
153 static void
MakeRect(void)154 MakeRect(void)
155 {
156    RectList = glGenLists(1);
157    glNewList(RectList, GL_COMPILE);
158    glBegin(GL_POLYGON);
159    glTexCoord2f(0, 0);   glVertex2f(-2, -2);
160    glTexCoord2f(1, 0);   glVertex2f( 2, -2);
161    glTexCoord2f(1, 1);   glVertex2f( 2,  2);
162    glTexCoord2f(0, 1);   glVertex2f(-2,  2);
163    glEnd();
164    glEndList();
165 }
166 
167 
168 static void
Init(void)169 Init(void)
170 {
171    static const char *fragShaderText =
172       "uniform ivec2 WinSize; \n"
173       "void main() {\n"
174       "   vec2 d = dFdy(gl_TexCoord[0].xy) * vec2(WinSize); \n"
175       "   gl_FragColor =  vec4(d.x, d.y, 0.0, 1.0);\n"
176       "  // gl_FragColor = gl_TexCoord[0];\n"
177       "}\n";
178    static const char *vertShaderText =
179       "void main() {\n"
180       "   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
181       "   gl_TexCoord[0] = gl_MultiTexCoord0;\n"
182       "}\n";
183 
184    if (!ShadersSupported())
185       exit(1);
186 
187    vertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText);
188    fragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText);
189    program = LinkShaders(vertShader, fragShader);
190 
191    glUseProgram(program);
192    WinSizeUniform = glGetUniformLocation(program, "WinSize");
193 
194    /*assert(glGetError() == 0);*/
195 
196    glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
197    glEnable(GL_DEPTH_TEST);
198 
199    MakeSphere();
200    MakeRect();
201 
202    CurList = SphereList;
203 
204    printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
205 
206    assert(glIsProgram(program));
207    assert(glIsShader(fragShader));
208    assert(glIsShader(vertShader));
209 
210    glColor3f(1, 0, 0);
211 }
212 
213 
214 static void
ParseOptions(int argc,char * argv[])215 ParseOptions(int argc, char *argv[])
216 {
217    int i;
218    for (i = 1; i < argc; i++) {
219       if (strcmp(argv[i], "-fs") == 0) {
220          FragProgFile = argv[i+1];
221       }
222       else if (strcmp(argv[i], "-vs") == 0) {
223          VertProgFile = argv[i+1];
224       }
225    }
226 }
227 
228 
229 int
main(int argc,char * argv[])230 main(int argc, char *argv[])
231 {
232    WinSize[0] = WinSize[1] = 200;
233 
234    glutInit(&argc, argv);
235    glutInitWindowSize(WinSize[0], WinSize[1]);
236    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
237    win = glutCreateWindow(argv[0]);
238    gladLoadGL();
239    glutReshapeFunc(Reshape);
240    glutKeyboardFunc(Key);
241    glutSpecialFunc(SpecialKey);
242    glutDisplayFunc(Redisplay);
243    if (anim)
244       glutIdleFunc(Idle);
245    ParseOptions(argc, argv);
246    Init();
247    glutMainLoop();
248    return 0;
249 }
250