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 <glad/glad.h>
12 #include "glut_wrap.h"
13 
14 #include "readtex.c"
15 
16 
17 #define TEXTURE_FILE DEMOS_DATA_DIR "bw.rgb"
18 
19 unsigned show_fps = 0;
20 unsigned int frame_cnt = 0;
21 void alarmhandler(int);
22 static const char *filename = NULL;
23 
24 static GLuint fragShader;
25 static GLuint vertShader;
26 static GLuint program;
27 
28 
usage(char * name)29 static 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
alarmhandler(int sig)40 void 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 
load_and_compile_shader(GLuint shader,const char * text)56 static 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 
read_shader(GLuint shader,const char * filename)74 static 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 
check_link(GLuint prog)96 static 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 
setup_uniforms(void)108 static 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 
prepare_shaders(void)170 static 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)
203 static int TexWidth = SIZE, TexHeight = SIZE;
204 
205 
206 static void
ResetTextureLevel(int i)207 ResetTextureLevel( 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 
233 static void
ResetTexture(void)234 ResetTexture( void )
235 {
236    int i;
237 
238    for (i = 0; i <= LEVELS; i++)
239    {
240       ResetTextureLevel(i);
241    }
242 }
243 
Init(void)244 static 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 
args(int argc,char * argv[])324 static 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 
Reshape(int width,int height)346 static 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 
CleanUp(void)357 static void CleanUp(void)
358 {
359    glDeleteShader(fragShader);
360    glDeleteShader(vertShader);
361    glDeleteProgram(program);
362 }
363 
Key(unsigned char key,int x,int y)364 static 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 
Display(void)378 static 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 
main(int argc,char ** argv)408 int 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    gladLoadGL();
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