blob: a2a19915297d15cf1465b78afaabc614bf8e90fb [file] [log] [blame]
Stephane Marchesin4ccbee22008-10-07 21:21:20 +02001/**
2 * Test very basic glsl functionality (identity vertex and fragment shaders).
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
22static char *FragProgFile = NULL;
23static char *VertProgFile = NULL;
24static GLuint fragShader;
25static GLuint vertShader;
26static GLuint program;
27static GLint win = 0;
28static GLboolean anim = GL_TRUE;
29static GLfloat xRot = 0.0f, yRot = 0.0f;
30static int w,h;
31
32static void
33Redisplay(void)
34{
35 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
36
37 glBegin(GL_TRIANGLES);
38 glColor3f(.8,0,0);
39 glVertex3f(-0.9, -0.9, 0.0);
40 glColor3f(0,.9,0);
41 glVertex3f( 0.9, -0.9, 0.0);
42 glColor3f(0,0,.7);
43 glVertex3f( 0.0, 0.9, 0.0);
44 glEnd();
45
46 glutSwapBuffers();
47}
48
49
50static void
51Idle(void)
52{
53 yRot = glutGet(GLUT_ELAPSED_TIME) * 0.1;
54 glutPostRedisplay();
55}
56
57
58static void
59Reshape(int width, int height)
60{
61 glViewport(0, 0, width, height);
62 glMatrixMode(GL_PROJECTION);
63 glLoadIdentity();
64 glMatrixMode(GL_MODELVIEW);
65 glLoadIdentity();
66 w = width;
67 h = height;
68}
69
70
71static void
72CleanUp(void)
73{
74 glDeleteShader_func(fragShader);
75 glDeleteShader_func(vertShader);
76 glDeleteProgram_func(program);
77 glutDestroyWindow(win);
78}
79
80
81static void
82Key(unsigned char key, int x, int y)
83{
84 (void) x;
85 (void) y;
86
87 switch(key) {
88 case ' ':
89 case 'a':
90 anim = !anim;
91 if (anim)
92 glutIdleFunc(Idle);
93 else
94 glutIdleFunc(NULL);
95 break;
96 case 27:
97 CleanUp();
98 exit(0);
99 break;
100 }
101 glutPostRedisplay();
102}
103
104
105static void
106SpecialKey(int key, int x, int y)
107{
108 const GLfloat step = 3.0f;
109
110 (void) x;
111 (void) y;
112
113 switch(key) {
114 case GLUT_KEY_UP:
115 xRot -= step;
116 break;
117 case GLUT_KEY_DOWN:
118 xRot += step;
119 break;
120 case GLUT_KEY_LEFT:
121 yRot -= step;
122 break;
123 case GLUT_KEY_RIGHT:
124 yRot += step;
125 break;
126 }
127 glutPostRedisplay();
128}
129
130
131
132
133static void
134LoadAndCompileShader(GLuint shader, const char *text)
135{
136 GLint stat;
137
138 glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
139
140 glCompileShader_func(shader);
141
142 glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
143 if (!stat) {
144 GLchar log[1000];
145 GLsizei len;
146 glGetShaderInfoLog_func(shader, 1000, &len, log);
147 fprintf(stderr, "fslight: problem compiling shader:\n%s\n", log);
148 exit(1);
149 }
150}
151
152
153/**
154 * Read a shader from a file.
155 */
156static void
157ReadShader(GLuint shader, const char *filename)
158{
159 const int max = 100*1000;
160 int n;
161 char *buffer = (char*) malloc(max);
162 FILE *f = fopen(filename, "r");
163 if (!f) {
164 fprintf(stderr, "fslight: Unable to open shader file %s\n", filename);
165 exit(1);
166 }
167
168 n = fread(buffer, 1, max, f);
169 printf("fslight: read %d bytes from shader file %s\n", n, filename);
170 if (n > 0) {
171 buffer[n] = 0;
172 LoadAndCompileShader(shader, buffer);
173 }
174
175 fclose(f);
176 free(buffer);
177}
178
179
180static void
181CheckLink(GLuint prog)
182{
183 GLint stat;
184 glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
185 if (!stat) {
186 GLchar log[1000];
187 GLsizei len;
188 glGetProgramInfoLog_func(prog, 1000, &len, log);
189 fprintf(stderr, "Linker error:\n%s\n", log);
190 }
191}
192
193
194static void
195Init(void)
196{
197 static const char *fragShaderText =
198 "void main() {\n"
199 " gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n"
200 "}\n";
201 static const char *vertShaderText =
202 "void main() {\n"
203 " gl_Position = gl_Vertex;\n"
204 "}\n";
205 const char *version;
206
207 version = (const char *) glGetString(GL_VERSION);
208 if (version[0] != '2' || version[1] != '.') {
209 printf("This program requires OpenGL 2.x, found %s\n", version);
210 exit(1);
211 }
212
213 GetExtensionFuncs();
214
215 fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
216 if (FragProgFile)
217 ReadShader(fragShader, FragProgFile);
218 else
219 LoadAndCompileShader(fragShader, fragShaderText);
220
221 vertShader = glCreateShader_func(GL_VERTEX_SHADER);
222 if (VertProgFile)
223 ReadShader(vertShader, VertProgFile);
224 else
225 LoadAndCompileShader(vertShader, vertShaderText);
226
227 program = glCreateProgram_func();
228 glAttachShader_func(program, fragShader);
229 glAttachShader_func(program, vertShader);
230 glLinkProgram_func(program);
231 CheckLink(program);
232 glUseProgram_func(program);
233
234 /*assert(glGetError() == 0);*/
235
236 glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
237 glEnable(GL_DEPTH_TEST);
238
239 printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
240
241 assert(glIsProgram_func(program));
242 assert(glIsShader_func(fragShader));
243 assert(glIsShader_func(vertShader));
244
245 glColor3f(1, 0, 0);
246}
247
248
249static void
250ParseOptions(int argc, char *argv[])
251{
252 int i;
253 for (i = 1; i < argc; i++) {
254 if (strcmp(argv[i], "-fs") == 0) {
255 FragProgFile = argv[i+1];
256 }
257 else if (strcmp(argv[i], "-vs") == 0) {
258 VertProgFile = argv[i+1];
259 }
260 }
261}
262
263
264int
265main(int argc, char *argv[])
266{
267 glutInit(&argc, argv);
268 glutInitWindowPosition( 0, 0);
269 glutInitWindowSize(200, 200);
270 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
271 win = glutCreateWindow(argv[0]);
272 glutReshapeFunc(Reshape);
273 glutKeyboardFunc(Key);
274 glutSpecialFunc(SpecialKey);
275 glutDisplayFunc(Redisplay);
276 if (anim)
277 glutIdleFunc(Idle);
278 ParseOptions(argc, argv);
279 Init();
280 glutMainLoop();
281 return 0;
282}