refmod_test

view refmod_test.c @ 0:b469e6a72636

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 18 Feb 2016 23:15:43 +0200
parents
children 7e911c994ef2
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <GL/glut.h>
5 #include "sdr.h"
7 #ifdef FREEGLUT
8 #include <GL/freeglut_ext.h>
9 #define MOUSEWHEEL
10 #endif
12 void redraw(void);
13 void set_material_color(float r, float g, float b, float a);
14 void setup_lights(void);
15 void key_handler(unsigned char key, int x, int y);
16 void key_up_handler(unsigned char key, int x, int y);
17 void skey_handler(int key, int x, int y);
18 void button_handler(int bn, int state, int x, int y);
19 void mouse_handler(int x, int y);
20 void reshape(int x, int y);
21 #ifdef MOUSEWHEEL
22 void wheel_handler(int unk, int dir, int x, int y);
23 #endif
24 void menu_handler(int val);
25 void init_sdr(void);
27 int xres, yres;
29 float cam_x, cam_y = 0.6, cam_z = 4;
30 float cam_rot, cam_pitch = 35.0;
32 float pan_offs = 0.025;
34 unsigned int prog;
36 float roughness = 0.24;
37 float specularity = 0.86;
38 float ior = 3.2;
39 float spec_pow = 60.0;
41 enum {DSDR_LAMBERT, DSDR_OREN_NAYAR};
42 enum {SSDR_PHONG, SSDR_BLINN, SSDR_COOK_TORR};
44 int dif_sdr = DSDR_OREN_NAYAR;
45 int spec_sdr = SSDR_COOK_TORR;
47 int main(int argc, char **argv)
48 {
49 unsigned int vs, ps, pslib;
50 int dif_menu, spec_menu, i;
52 for(i=1; i<argc; i++) {
53 if(argv[i][0] == '-' && argv[i][2] == 0) {
54 switch(argv[i][1]) {
55 case 'd':
56 if(strcmp(argv[++i], "lambert") == 0) {
57 dif_sdr = DSDR_LAMBERT;
58 } else if(strcmp(argv[i], "oren-nayar") == 0) {
59 dif_sdr = DSDR_OREN_NAYAR;
60 } else {
61 printf("-d (diffuse model) choices:\n");
62 printf(" lambert \"Photometria sive de mensura de gratibus luminis, colorum et umbrae\", 1760\n");
63 printf(" oren-nayar \"Generalization of Lambert's Reflectance Model\", SIGGRAPH 1994\n");
64 return EXIT_FAILURE;
65 }
66 break;
68 case 's':
69 if(strcmp(argv[++i], "phong") == 0) {
70 spec_sdr = SSDR_PHONG;
71 } else if(strcmp(argv[i], "cook-torrance") == 0) {
72 spec_sdr = SSDR_COOK_TORR;
73 } else {
74 printf("-s (specular model) choices:\n");
75 printf(" phong \"Illumination for Computer Generated Pictures\", CACM 1975\n");
76 printf(" blinn \"Models of Light Reflection for Computer Synthesized Pictures\", SIGGRAPH 1977\n");
77 printf(" cook-torrance \"A Reflectance Model for Computer Graphics\", SIGGRAPH 1981\n");
78 return EXIT_FAILURE;
79 }
80 break;
82 default:
83 fprintf(stderr, "unrecognized argument: %s\n", argv[i]);
84 return EXIT_FAILURE;
85 }
86 }
87 }
89 glutInitWindowSize(800, 600);
90 glutInit(&argc, argv);
91 glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
92 glutCreateWindow("1.roughness 2.specularity 3.ior 4.phong power");
93 xres = glutGet(GLUT_WINDOW_WIDTH);
94 yres = glutGet(GLUT_WINDOW_HEIGHT);
96 glutKeyboardFunc(key_handler);
97 glutKeyboardUpFunc(key_up_handler);
98 glutSpecialFunc(skey_handler);
99 glutMotionFunc(mouse_handler);
100 glutMouseFunc(button_handler);
101 glutReshapeFunc(reshape);
102 glutDisplayFunc(redraw);
103 #ifdef MOUSEWHEEL
104 glutMouseWheelFunc(wheel_handler);
105 #endif
107 /* create the menus */
108 dif_menu = glutCreateMenu(menu_handler);
109 glutAddMenuEntry("lambert", DSDR_LAMBERT);
110 glutAddMenuEntry("oren-nayar", DSDR_OREN_NAYAR);
112 spec_menu = glutCreateMenu(menu_handler);
113 glutAddMenuEntry("phong", SSDR_PHONG + 10);
114 glutAddMenuEntry("blinn", SSDR_BLINN + 10);
115 glutAddMenuEntry("cook-torrance", SSDR_COOK_TORR + 10);
117 glutCreateMenu(menu_handler);
118 glutAddSubMenu("diffuse models", dif_menu);
119 glutAddSubMenu("specular models", spec_menu);
121 glutAttachMenu(GLUT_RIGHT_BUTTON);
124 glEnable(GL_DEPTH_TEST);
125 glEnable(GL_CULL_FACE);
127 glEnable(GL_LIGHTING);
128 glEnable(GL_LIGHT0);
130 glMatrixMode(GL_PROJECTION);
131 gluPerspective(45.0, (float)xres / (float)yres, 1.0, 100.0);
132 glMatrixMode(GL_MODELVIEW);
134 init_sdr();
136 if(!(vs = load_vertex_shader("sdr.vs.glsl"))) {
137 fprintf(stderr, "failed to load vertex shader\n");
138 return EXIT_FAILURE;
139 }
141 if(!(pslib = load_pixel_shader("sdr_ref_models.glsl"))) {
142 fprintf(stderr, "failed to load reflection models shader\n");
143 return EXIT_FAILURE;
144 }
146 if(!(ps = load_pixel_shader("sdr.ps.glsl"))) {
147 fprintf(stderr, "failed to load pixel shader\n");
148 return EXIT_FAILURE;
149 }
151 if(!(prog = create_program())) {
152 fprintf(stderr, "failed to create GPU program\n");
153 return EXIT_FAILURE;
154 }
155 attach_shader(prog, vs);
156 attach_shader(prog, pslib);
157 attach_shader(prog, ps);
159 if(link_program(prog) == -1) {
160 fprintf(stderr, "failed to link GPU program\n");
161 return EXIT_FAILURE;
162 }
164 glutMainLoop();
165 return 0;
166 }
168 void setup_lights(void)
169 {
170 float lpos[] = {-6, 8, 10, 1};
171 glLightfv(GL_LIGHT0, GL_POSITION, lpos);
172 }
174 void redraw(void)
175 {
176 glClearColor(0, 0, 0, 0);
177 glClearDepth(1.0);
179 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
181 glMatrixMode(GL_MODELVIEW);
182 glLoadIdentity();
183 glTranslatef(-cam_x, -cam_y, -cam_z);
184 glRotatef(cam_pitch, 1, 0, 0);
185 glRotatef(cam_rot, 0, 1, 0);
187 setup_lights();
189 glPushMatrix();
190 glTranslatef(0, 0.8, 0);
192 bind_program(prog);
193 set_uniform_float(prog, "rough", roughness);
194 set_uniform_float(prog, "specularity", specularity);
195 set_uniform_float(prog, "ior", ior);
196 set_uniform_float(prog, "dif_sdr", dif_sdr);
197 set_uniform_float(prog, "spec_sdr", spec_sdr);
198 glFrontFace(GL_CW);
199 set_material_color(0.55, 0.20, 0.10, 1.0);
200 /*set_material_color(0.87, 0.72, 0.62, 1.0);*/
201 glutSolidTeapot(1.0);
202 glFrontFace(GL_CCW);
203 bind_program(0);
205 glPopMatrix();
208 glutSwapBuffers();
209 }
211 void set_material_color(float r, float g, float b, float a)
212 {
213 float col[4];
214 col[0] = r;
215 col[1] = g;
216 col[2] = b;
217 col[3] = a;
218 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
219 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, spec_pow);
220 }
222 int mod_rough, mod_spec, mod_ior, mod_spow;
224 void key_handler(unsigned char key, int x, int y)
225 {
226 switch(key) {
227 case 27:
228 exit(0);
230 case '1':
231 mod_rough = 1;
232 break;
234 case '2':
235 mod_spec = 1;
236 break;
238 case '3':
239 mod_ior = 1;
240 break;
242 case '4':
243 mod_spow = 1;
244 break;
246 default:
247 break;
248 }
249 }
251 void key_up_handler(unsigned char key, int x, int y)
252 {
253 switch(key) {
254 case '1':
255 mod_rough = 0;
256 break;
258 case '2':
259 mod_spec = 0;
260 break;
262 case '3':
263 mod_ior = 0;
264 break;
266 case '4':
267 mod_spow = 0;
268 break;
270 default:
271 break;
272 }
273 }
275 void skey_handler(int key, int x, int y)
276 {
277 switch(key) {
278 default:
279 break;
280 }
281 }
283 static int prev_x = -1;
284 static int prev_y = -1;
285 static int pbn;
287 void button_handler(int button, int state, int x, int y)
288 {
289 if(state == GLUT_DOWN) {
290 prev_x = x;
291 prev_y = y;
292 pbn = button;
293 } else {
294 prev_x = -1;
295 prev_y = -1;
296 }
297 }
300 #define MIN(a, b) ((a) < (b) ? (a) : (b))
301 #define MAX(a, b) ((a) > (b) ? (a) : (b))
303 void mouse_handler(int x, int y)
304 {
305 if(pbn == GLUT_LEFT_BUTTON) {
306 if(mod_rough || mod_spec || mod_ior || mod_spow) {
307 float dx = (float)(x - prev_x) / (float)xres;
309 if(mod_rough) {
310 roughness = MAX(0.0, MIN(roughness + dx, 1.0));
311 printf("roughness: %.3f\n", roughness);
312 }
313 if(mod_spec) {
314 specularity = MAX(0.0, MIN(specularity + dx, 1.0));
315 printf("specularity: %.3f\n", specularity);
316 }
317 if(mod_ior) {
318 ior = MAX(ior + dx, 0.0);
319 printf("ior: %.3f\n", ior);
320 }
321 if(mod_spow) {
322 spec_pow = MAX(spec_pow + dx * 50.0, 0.01);
323 printf("specular power: %.3f\n", spec_pow);
324 }
325 } else {
326 /*
327 cam_x += (float)(prev_x - x) * pan_offs;
328 cam_y += (float)(y - prev_y) * pan_offs;
329 */
330 }
332 prev_x = x;
333 prev_y = y;
334 glutPostRedisplay();
336 } else if(pbn == GLUT_MIDDLE_BUTTON) {
337 cam_rot += (float)(x - prev_x) / 2.0f;
338 cam_pitch += (float)(y - prev_y) / 2.0f;
339 if(cam_pitch > 90.0) cam_pitch = 90.0;
340 if(cam_pitch < -90.0) cam_pitch = -90.0;
342 prev_x = x;
343 prev_y = y;
344 glutPostRedisplay();
346 } else if(pbn == GLUT_RIGHT_BUTTON) {
347 /*
348 cam_z -= (float)(prev_y - y) / 2.0f;
349 prev_y = y;
350 glutPostRedisplay();
351 */
352 }
353 }
355 void reshape(int x, int y)
356 {
357 glViewport(0, 0, x, y);
358 xres = x;
359 yres = y;
361 glMatrixMode(GL_PROJECTION);
362 glLoadIdentity();
363 gluPerspective(45.0, (float)xres / (float)yres, 1.0, 100.0);
364 glMatrixMode(GL_MODELVIEW);
365 }
367 #ifdef MOUSEWHEEL
368 void wheel_handler(int unk, int dir, int x, int y)
369 {
370 if(dir > 0) {
371 cam_z -= pan_offs * 5.0;
372 } else {
373 cam_z += pan_offs * 5.0;
374 }
375 glutPostRedisplay();
376 }
377 #endif
379 void menu_handler(int val)
380 {
381 if(val < 10) {
382 dif_sdr = val;
383 } else {
384 spec_sdr = val - 10;
385 }
386 glutPostRedisplay();
387 }