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