Merge branch 'master' of git+ssh://znh@git.freedesktop.org/git/mesa/mesa into 965...
[mesa.git] / progs / glsl / deriv.c
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 <GL/gl.h>
17 #include <GL/glut.h>
18 #include <GL/glext.h>
19 #include "extfuncs.h"
20
21
22 static char *FragProgFile = NULL;
23 static char *VertProgFile = NULL;
24 static GLuint fragShader;
25 static GLuint vertShader;
26 static GLuint program;
27 static GLuint SphereList, RectList, CurList;
28 static GLint win = 0;
29 static GLboolean anim = GL_TRUE;
30 static GLfloat xRot = 0.0f, yRot = 0.0f;
31
32
33 static void
34 Redisplay(void)
35 {
36 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
37
38 glPushMatrix();
39 glRotatef(xRot, 1.0f, 0.0f, 0.0f);
40 glRotatef(yRot, 0.0f, 1.0f, 0.0f);
41 glCallList(CurList);
42 glPopMatrix();
43
44 glutSwapBuffers();
45 }
46
47
48 static void
49 Idle(void)
50 {
51 yRot = glutGet(GLUT_ELAPSED_TIME) * 0.1;
52 glutPostRedisplay();
53 }
54
55
56 static void
57 Reshape(int width, int height)
58 {
59 glViewport(0, 0, width, height);
60 glMatrixMode(GL_PROJECTION);
61 glLoadIdentity();
62 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
63 glMatrixMode(GL_MODELVIEW);
64 glLoadIdentity();
65 glTranslatef(0.0f, 0.0f, -15.0f);
66 }
67
68
69 static void
70 CleanUp(void)
71 {
72 glDeleteShader_func(fragShader);
73 glDeleteShader_func(vertShader);
74 glDeleteProgram_func(program);
75 glutDestroyWindow(win);
76 }
77
78
79 static void
80 Key(unsigned char key, int x, int y)
81 {
82 (void) x;
83 (void) y;
84
85 switch(key) {
86 case ' ':
87 case 'a':
88 anim = !anim;
89 if (anim)
90 glutIdleFunc(Idle);
91 else
92 glutIdleFunc(NULL);
93 break;
94 case 'o':
95 if (CurList == SphereList)
96 CurList = RectList;
97 else
98 CurList = SphereList;
99 break;
100 case 27:
101 CleanUp();
102 exit(0);
103 break;
104 }
105 glutPostRedisplay();
106 }
107
108
109 static void
110 SpecialKey(int key, int x, int y)
111 {
112 const GLfloat step = 3.0f;
113
114 (void) x;
115 (void) y;
116
117 switch(key) {
118 case GLUT_KEY_UP:
119 xRot -= step;
120 break;
121 case GLUT_KEY_DOWN:
122 xRot += step;
123 break;
124 case GLUT_KEY_LEFT:
125 yRot -= step;
126 break;
127 case GLUT_KEY_RIGHT:
128 yRot += step;
129 break;
130 }
131 glutPostRedisplay();
132 }
133
134
135 static void
136 MakeSphere(void)
137 {
138 GLUquadricObj *obj = gluNewQuadric();
139 SphereList = glGenLists(1);
140 gluQuadricTexture(obj, GL_TRUE);
141 glNewList(SphereList, GL_COMPILE);
142 gluSphere(obj, 2.0f, 30, 15);
143 glEndList();
144 }
145
146
147 static void
148 MakeRect(void)
149 {
150 RectList = glGenLists(1);
151 glNewList(RectList, GL_COMPILE);
152 glBegin(GL_POLYGON);
153 glTexCoord2f(0, 0); glVertex2f(-2, -2);
154 glTexCoord2f(1, 0); glVertex2f( 2, -2);
155 glTexCoord2f(1, 1); glVertex2f( 2, 2);
156 glTexCoord2f(0, 1); glVertex2f(-2, 2);
157 glEnd();
158 glEndList();
159 }
160
161
162
163 static void
164 LoadAndCompileShader(GLuint shader, const char *text)
165 {
166 GLint stat;
167
168 glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
169
170 glCompileShader_func(shader);
171
172 glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
173 if (!stat) {
174 GLchar log[1000];
175 GLsizei len;
176 glGetShaderInfoLog_func(shader, 1000, &len, log);
177 fprintf(stderr, "fslight: problem compiling shader:\n%s\n", log);
178 exit(1);
179 }
180 }
181
182
183 /**
184 * Read a shader from a file.
185 */
186 static void
187 ReadShader(GLuint shader, const char *filename)
188 {
189 const int max = 100*1000;
190 int n;
191 char *buffer = (char*) malloc(max);
192 FILE *f = fopen(filename, "r");
193 if (!f) {
194 fprintf(stderr, "fslight: Unable to open shader file %s\n", filename);
195 exit(1);
196 }
197
198 n = fread(buffer, 1, max, f);
199 printf("fslight: read %d bytes from shader file %s\n", n, filename);
200 if (n > 0) {
201 buffer[n] = 0;
202 LoadAndCompileShader(shader, buffer);
203 }
204
205 fclose(f);
206 free(buffer);
207 }
208
209
210 static void
211 CheckLink(GLuint prog)
212 {
213 GLint stat;
214 glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
215 if (!stat) {
216 GLchar log[1000];
217 GLsizei len;
218 glGetProgramInfoLog_func(prog, 1000, &len, log);
219 fprintf(stderr, "Linker error:\n%s\n", log);
220 }
221 }
222
223
224 static void
225 Init(void)
226 {
227 static const char *fragShaderText =
228 "void main() {\n"
229 " gl_FragColor = abs(dFdy(gl_TexCoord[0])) * 50.0;\n"
230 " // gl_FragColor = gl_TexCoord[0];\n"
231 "}\n";
232 static const char *vertShaderText =
233 "void main() {\n"
234 " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
235 " gl_TexCoord[0] = gl_MultiTexCoord0;\n"
236 "}\n";
237 const char *version;
238
239 version = (const char *) glGetString(GL_VERSION);
240 if (version[0] != '2' || version[1] != '.') {
241 printf("This program requires OpenGL 2.x, found %s\n", version);
242 exit(1);
243 }
244
245 GetExtensionFuncs();
246
247 fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
248 if (FragProgFile)
249 ReadShader(fragShader, FragProgFile);
250 else
251 LoadAndCompileShader(fragShader, fragShaderText);
252
253 vertShader = glCreateShader_func(GL_VERTEX_SHADER);
254 if (VertProgFile)
255 ReadShader(vertShader, VertProgFile);
256 else
257 LoadAndCompileShader(vertShader, vertShaderText);
258
259 program = glCreateProgram_func();
260 glAttachShader_func(program, fragShader);
261 glAttachShader_func(program, vertShader);
262 glLinkProgram_func(program);
263 CheckLink(program);
264 glUseProgram_func(program);
265
266 /*assert(glGetError() == 0);*/
267
268 glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
269 glEnable(GL_DEPTH_TEST);
270
271 MakeSphere();
272 MakeRect();
273
274 CurList = SphereList;
275
276 printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
277
278 assert(glIsProgram_func(program));
279 assert(glIsShader_func(fragShader));
280 assert(glIsShader_func(vertShader));
281
282 glColor3f(1, 0, 0);
283 }
284
285
286 static void
287 ParseOptions(int argc, char *argv[])
288 {
289 int i;
290 for (i = 1; i < argc; i++) {
291 if (strcmp(argv[i], "-fs") == 0) {
292 FragProgFile = argv[i+1];
293 }
294 else if (strcmp(argv[i], "-vs") == 0) {
295 VertProgFile = argv[i+1];
296 }
297 }
298 }
299
300
301 int
302 main(int argc, char *argv[])
303 {
304 glutInit(&argc, argv);
305 glutInitWindowPosition( 0, 0);
306 glutInitWindowSize(200, 200);
307 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
308 win = glutCreateWindow(argv[0]);
309 glutReshapeFunc(Reshape);
310 glutKeyboardFunc(Key);
311 glutSpecialFunc(SpecialKey);
312 glutDisplayFunc(Redisplay);
313 if (anim)
314 glutIdleFunc(Idle);
315 ParseOptions(argc, argv);
316 Init();
317 glutMainLoop();
318 return 0;
319 }