fp-tri.c revision 32001f49
1
2#include <stdio.h>
3#include <string.h>
4#include <stdlib.h>
5
6#ifndef WIN32
7#include <unistd.h>
8#include <signal.h>
9#endif
10
11#include <GL/glew.h>
12#include "glut_wrap.h"
13
14#include "readtex.c"
15
16
17#define TEXTURE_FILE DEMOS_DATA_DIR "bw.rgb"
18
19unsigned show_fps = 0;
20unsigned int frame_cnt = 0;
21void alarmhandler(int);
22static const char *filename = NULL;
23
24static GLuint fragShader;
25static GLuint vertShader;
26static GLuint program;
27
28
29static void usage(char *name)
30{
31   fprintf(stderr, "usage: %s [ options ] shader_filename\n", name);
32#ifndef WIN32
33   fprintf(stderr, "\n" );
34   fprintf(stderr, "options:\n");
35   fprintf(stderr, "    -fps  show frames per second\n");
36#endif
37}
38
39#ifndef WIN32
40void alarmhandler (int sig)
41{
42   if (sig == SIGALRM) {
43      printf("%d frames in 5.0 seconds = %.3f FPS\n", frame_cnt,
44             frame_cnt / 5.0);
45
46      frame_cnt = 0;
47   }
48   signal(SIGALRM, alarmhandler);
49   alarm(5);
50}
51#endif
52
53
54
55
56static void load_and_compile_shader(GLuint shader, const char *text)
57{
58   GLint stat;
59
60   glShaderSource(shader, 1, (const GLchar **) &text, NULL);
61
62   glCompileShader(shader);
63
64   glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
65   if (!stat) {
66      GLchar log[1000];
67      GLsizei len;
68      glGetShaderInfoLog(shader, 1000, &len, log);
69      fprintf(stderr, "fp-tri: problem compiling shader:\n%s\n", log);
70      exit(1);
71   }
72}
73
74static void read_shader(GLuint shader, const char *filename)
75{
76   const int max = 100*1000;
77   int n;
78   char *buffer = (char*) malloc(max);
79   FILE *f = fopen(filename, "r");
80   if (!f) {
81      fprintf(stderr, "fp-tri: Unable to open shader file %s\n", filename);
82      exit(1);
83   }
84
85   n = fread(buffer, 1, max, f);
86   printf("fp-tri: read %d bytes from shader file %s\n", n, filename);
87   if (n > 0) {
88      buffer[n] = 0;
89      load_and_compile_shader(shader, buffer);
90   }
91
92   fclose(f);
93   free(buffer);
94}
95
96static void check_link(GLuint prog)
97{
98   GLint stat;
99   glGetProgramiv(prog, GL_LINK_STATUS, &stat);
100   if (!stat) {
101      GLchar log[1000];
102      GLsizei len;
103      glGetProgramInfoLog(prog, 1000, &len, log);
104      fprintf(stderr, "Linker error:\n%s\n", log);
105   }
106}
107
108static void setup_uniforms(void)
109{
110   {
111      GLint loc1f = glGetUniformLocationARB(program, "Offset1f");
112      GLint loc2f = glGetUniformLocationARB(program, "Offset2f");
113      GLint loc4f = glGetUniformLocationARB(program, "Offset4f");
114      GLfloat vecKer[] =
115         { 1.0, 0.0, 0.0,  1.0,
116           0.0, 1.0, 0.0,  1.0,
117           1.0, 0.0, 0.0,  1.0,
118           0.0, 0.0, 0.0,  1.0
119         };
120      if (loc1f >= 0)
121         glUniform1fv(loc1f, 16, vecKer);
122
123      if (loc2f >= 0)
124         glUniform2fv(loc2f, 8, vecKer);
125
126      if (loc4f >= 0)
127         glUniform4fv(loc4f, 4, vecKer);
128
129   }
130
131   {
132      GLint loci = glGetUniformLocationARB(program, "KernelSizeInt");
133      if (loci >= 0)
134         glUniform1i(loci, 4);
135   }
136   {
137      GLint loc1f = glGetUniformLocationARB(program, "KernelValue1f");
138      GLint loc2f = glGetUniformLocationARB(program, "KernelValue2f");
139      GLint loc4f = glGetUniformLocationARB(program, "KernelValue4f");
140      GLfloat vecKer[] =
141         { 1.0, 0.0, 0.0,  0.25,
142           0.0, 1.0, 0.0,  0.25,
143           0.0, 0.0, 1.0,  0.25,
144           0.0, 0.0, 0.0,  0.25,
145           0.5, 0.0, 0.0,  0.35,
146           0.0, 0.5, 0.0,  0.35,
147           0.0, 0.0, 0.5,  0.35,
148           0.0, 0.0, 0.0,  0.35
149         };
150      if (loc1f >= 0)
151         glUniform1fv(loc1f, 16, vecKer);
152
153      if (loc2f >= 0)
154         glUniform2fv(loc2f, 8, vecKer);
155
156      if (loc4f >= 0)
157         glUniform4fv(loc4f, 4, vecKer);
158   }
159
160   {
161      GLint tex1 = glGetUniformLocationARB(program, "tex1");
162      GLint tex2 = glGetUniformLocationARB(program, "tex2");
163      if (tex1 >= 0)
164         glUniform1i(tex1, 0);
165      if (tex2 >= 0)
166         glUniform1i(tex2, 1);
167   }
168}
169
170static void prepare_shaders(void)
171{
172   static const char *fragShaderText =
173      "void main() {\n"
174      "    gl_FragColor = gl_Color;\n"
175      "}\n";
176   static const char *vertShaderText =
177      "void main() {\n"
178      "   gl_FrontColor = gl_Color;\n"
179      "   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
180      "}\n";
181   fragShader = glCreateShader(GL_FRAGMENT_SHADER);
182   if (filename)
183      read_shader(fragShader, filename);
184   else
185      load_and_compile_shader(fragShader, fragShaderText);
186
187
188   vertShader = glCreateShader(GL_VERTEX_SHADER);
189   load_and_compile_shader(vertShader, vertShaderText);
190
191   program = glCreateProgram();
192   glAttachShader(program, fragShader);
193   glAttachShader(program, vertShader);
194   glLinkProgram(program);
195   check_link(program);
196   glUseProgram(program);
197
198   setup_uniforms();
199}
200
201#define LEVELS 8
202#define SIZE (1<<LEVELS)
203static int TexWidth = SIZE, TexHeight = SIZE;
204
205
206static void
207ResetTextureLevel( int i )
208{
209   GLubyte tex2d[SIZE*SIZE][4];
210
211   {
212      GLint Width = TexWidth / (1 << i);
213      GLint Height = TexHeight / (1 << i);
214      GLint s, t;
215
216      for (s = 0; s < Width; s++) {
217         for (t = 0; t < Height; t++) {
218            tex2d[t*Width+s][0] = ((s / 16) % 2) ? 0 : 255;
219            tex2d[t*Width+s][1] = ((t / 16) % 2) ? 0 : 255;
220            tex2d[t*Width+s][2] = 128;
221            tex2d[t*Width+s][3] = 255;
222         }
223      }
224
225      glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
226
227      glTexImage2D(GL_TEXTURE_2D, i, GL_RGB, Width, Height, 0,
228                   GL_RGBA, GL_UNSIGNED_BYTE, tex2d);
229   }
230}
231
232
233static void
234ResetTexture( void )
235{
236   int i;
237
238   for (i = 0; i <= LEVELS; i++)
239   {
240      ResetTextureLevel(i);
241   }
242}
243
244static void Init( void )
245{
246   GLuint Texture;
247
248   /* Setup texture unit 0 */
249   glGenTextures(1, &Texture);
250   glBindTexture(GL_TEXTURE_2D, Texture);
251   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
252   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
253   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
254   if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
255      printf("Error: couldn't load texture image file %s\n", TEXTURE_FILE);
256      exit(1);
257   }
258
259   /* Setup texture unit 1 */
260   glGenTextures(1, &Texture);
261   glActiveTextureARB(GL_TEXTURE0_ARB + 1);
262   glBindTexture(GL_TEXTURE_2D, Texture);
263   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
264   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
265   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
266
267   {
268      GLubyte data[32][32];
269      int width = 32;
270      int height = 32;
271      int i;
272      int j;
273
274      for (i = 0; i < 32; i++)
275         for (j = 0; j < 32; j++)
276	 {
277	    /**
278	     ** +-----------+
279	     ** |     W     |
280	     ** |  +-----+  |
281	     ** |  |     |  |
282	     ** |  |  B  |  |
283	     ** |  |     |  |
284	     ** |  +-----+  |
285	     ** |           |
286	     ** +-----------+
287	     **/
288	    int i2 = i - height / 2;
289	    int j2 = j - width / 2;
290	    int h8 = height / 8;
291	    int w8 = width / 8;
292	    if ( -h8 <= i2 && i2 <= h8 && -w8 <= j2 && j2 <= w8 ) {
293	       data[i][j] = 0x00;
294	    } else if ( -2 * h8 <= i2 && i2 <= 2 * h8 && -2 * w8 <= j2 && j2 <= 2 * w8 ) {
295	       data[i][j] = 0x55;
296	    } else if ( -3 * h8 <= i2 && i2 <= 3 * h8 && -3 * w8 <= j2 && j2 <= 3 * w8 ) {
297	       data[i][j] = 0xaa;
298	    } else {
299	       data[i][j] = 0xff;
300	    }
301	 }
302
303      glTexImage2D( GL_TEXTURE_2D, 0,
304                    GL_ALPHA8,
305                    32, 32, 0,
306                    GL_ALPHA, GL_UNSIGNED_BYTE, data );
307   }
308
309   /* Setup texture unit 2 */
310   glGenTextures(1, &Texture);
311   glActiveTextureARB(GL_TEXTURE0_ARB + 2);
312   glBindTexture(GL_TEXTURE_2D, Texture);
313   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
314   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
315   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
316   ResetTexture();
317
318   glClearColor(.1, .3, .5, 0);
319}
320
321
322
323
324static void args(int argc, char *argv[])
325{
326   GLint i;
327
328   for (i = 1; i < argc; i++) {
329      if (strcmp(argv[i], "-fps") == 0) {
330         show_fps = 1;
331      }
332      else if (i == argc - 1) {
333	 filename = argv[i];
334      }
335      else {
336	 usage(argv[0]);
337	 exit(1);
338      }
339   }
340}
341
342
343
344
345
346static void Reshape(int width, int height)
347{
348
349    glViewport(0, 0, (GLint)width, (GLint)height);
350
351    glMatrixMode(GL_PROJECTION);
352    glLoadIdentity();
353    glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0);
354    glMatrixMode(GL_MODELVIEW);
355}
356
357static void CleanUp(void)
358{
359   glDeleteShader(fragShader);
360   glDeleteShader(vertShader);
361   glDeleteProgram(program);
362}
363
364static void Key(unsigned char key, int x, int y)
365{
366
367   switch (key) {
368   case 27:
369      CleanUp();
370      exit(1);
371   default:
372      break;
373   }
374
375   glutPostRedisplay();
376}
377
378static void Display(void)
379{
380   glClear(GL_COLOR_BUFFER_BIT);
381
382   glUseProgram(program);
383   glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, 1.0, 1.0, 0.0, 0.0);
384   glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 0.0, 0.0, 1.0, 1.0);
385   glBegin(GL_TRIANGLES);
386
387   glColor3f(0,0,1);
388   glTexCoord3f(1,1,0);
389   glVertex3f( 0.9, -0.9, -970.0);
390
391   glColor3f(1,0,0);
392   glTexCoord3f(1,-1,0);
393   glVertex3f( 0.9,  0.9, -30.0);
394
395   glColor3f(0,1,0);
396   glTexCoord3f(-1,0,0);
397   glVertex3f(-0.9,  0.0, -30.0);
398   glEnd();
399
400   glFlush();
401   if (show_fps) {
402      ++frame_cnt;
403      glutPostRedisplay();
404   }
405}
406
407
408int main(int argc, char **argv)
409{
410   glutInit(&argc, argv);
411   glutInitWindowPosition(0, 0);
412   glutInitWindowSize(250, 250);
413   glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH);
414   args(argc, argv);
415   glutCreateWindow(filename ? filename : "fp-tri");
416   glewInit();
417   glutReshapeFunc(Reshape);
418   glutKeyboardFunc(Key);
419   glutDisplayFunc(Display);
420   prepare_shaders();
421   Init();
422#ifndef WIN32
423   if (show_fps) {
424      signal(SIGALRM, alarmhandler);
425      alarm(5);
426   }
427#endif
428   glutMainLoop();
429   return 0;
430}
431