gpuray_glsl

view src/main.cc @ 0:f234630e38ff

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 09 Nov 2014 13:03:36 +0200
parents
children
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdarg.h>
4 #include <assert.h>
5 #include "opengl.h"
7 #include "gpuscene.h"
8 #include "sphere.h"
9 #include "plane.h"
10 #include "image.h"
11 #include "rend.h"
12 #include "glsdr.h"
14 static bool init(const char *scene_fname);
15 static void cleanup();
16 static void disp();
17 static void draw_text(float r, float g, float b, const char *fmt, ...);
18 //static void update_texture(const float *fb);
19 static void idle();
20 static void reshape(int x, int y);
21 static void handle_keys(float dt);
22 static void keyb(unsigned char key, int x, int y);
23 static void keyb_up(unsigned char key, int x, int y);
24 static void skeyb(int key, int x, int y);
25 static void mouse(int bn, int st, int x, int y);
26 static void motion(int x, int y);
27 static void sball_motion(int x, int y, int z);
28 static void sball_rotate(int x, int y, int z);
29 static void sball_button(int bn, int state);
31 static unsigned int tex;
32 static long last_fps_upd, first_time = -1;
33 static long frames, total_frames;
34 static float fps;
35 static int xsz = 800;
36 static int ysz = 450;
37 //static int tex_xsz, tex_ysz;
39 static GPUScene *scn;
40 static FlyCamera *cam;
42 static float img_scale = 1.0f;
43 static bool keystate[256];
45 static char *scene_fname;
46 static bool sdr_valid = true;
48 int main(int argc, char **argv)
49 {
50 glutInit(&argc, argv);
52 int num_samples = 1;
54 for(int i=1; i<argc; i++) {
55 if(argv[i][0] == '-') {
56 if(strcmp(argv[i], "-size") == 0) {
57 if(sscanf(argv[++i], "%dx%d", &xsz, &ysz) < 2) {
58 fprintf(stderr, "-size must be followed by the image resolution (WxH)\n");
59 return 1;
60 }
62 } else if(strcmp(argv[i], "-samples") == 0) {
63 num_samples = atoi(argv[++i]);
64 if(num_samples <= 0) {
65 fprintf(stderr, "-samples must be followed by the number of samples per pixel\n");
66 return 1;
67 }
68 } else if(strcmp(argv[i], "-scale") == 0) {
69 img_scale = atof(argv[++i]);
70 if(img_scale <= 1.0f) {
71 fprintf(stderr, "-scale must be followed by an image scale factor >= 1\n");
72 return 1;
73 }
74 } else {
75 fprintf(stderr, "invalid option: %s\n", argv[i]);
76 return 1;
77 }
78 } else {
79 if(scene_fname) {
80 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
81 return 1;
82 }
83 scene_fname = argv[i];
84 }
85 }
87 glutInitWindowSize(xsz * img_scale, ysz * img_scale);
88 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
89 glutCreateWindow("single threaded");
91 glutDisplayFunc(disp);
92 glutIdleFunc(idle);
93 glutReshapeFunc(reshape);
94 glutKeyboardFunc(keyb);
95 glutKeyboardUpFunc(keyb_up);
96 glutSpecialFunc(skeyb);
97 glutMouseFunc(mouse);
98 glutMotionFunc(motion);
99 glutSpaceballMotionFunc(sball_motion);
100 glutSpaceballRotateFunc(sball_rotate);
101 glutSpaceballButtonFunc(sball_button);
103 glewInit();
105 if(!init(scene_fname)) {
106 return 1;
107 }
108 atexit(cleanup);
110 glutMainLoop();
111 return 0;
112 }
114 static bool init(const char *scene_fname)
115 {
116 scn = new GPUScene;
117 if(!scn->load(scene_fname ? scene_fname : "scene")) {
118 return false;
119 }
121 cam = new FlyCamera;
122 cam->input_move(0, 1.5, -10);
123 cam->input_rotate(25, 0, 0);
124 scn->set_camera(cam);
126 if(!init_renderer(scn, xsz, ysz)) {
127 return false;
128 }
130 glGenTextures(1, &tex);
131 glBindTexture(GL_TEXTURE_2D, tex);
132 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
133 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
134 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
135 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
137 int srgb_capable;
138 if(GLEW_EXT_framebuffer_sRGB && (glGetIntegerv(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &srgb_capable), srgb_capable)) {
139 printf("enabling sRGB framebuffer\n");
140 glEnable(GL_FRAMEBUFFER_SRGB);
141 } else {
142 printf("using post shader for gamma correction\n");
143 unsigned int post_sdr = create_program_load(0, "sdr/postsdr.glsl");
144 if(post_sdr) {
145 glUseProgram(post_sdr);
146 }
147 }
149 last_fps_upd = glutGet(GLUT_ELAPSED_TIME);
150 first_time = last_fps_upd;
151 total_frames = 0;
152 return true;
153 }
155 static void cleanup()
156 {
157 long interval = glutGet(GLUT_ELAPSED_TIME) - first_time;
158 printf("average fps: %.2f\n", (float)total_frames / ((float)interval / 1000.0f));
160 glDeleteTextures(1, &tex);
162 destroy_renderer();
163 delete scn;
164 }
166 static void disp()
167 {
168 static long prev_msec;
169 long interval, msec = glutGet(GLUT_ELAPSED_TIME);
171 handle_keys((msec - prev_msec) / 1000.0f);
172 prev_msec = msec;
174 //update_texture();
175 if(sdr_valid) {
176 render_frame(msec);
177 } else {
178 glUseProgram(0);
179 glMatrixMode(GL_MODELVIEW);
180 glLoadIdentity();
181 glMatrixMode(GL_PROJECTION);
182 glLoadIdentity();
184 glLineWidth(8.0);
185 glBegin(GL_LINES);
186 glColor3f(1, 0, 0);
187 glVertex2f(-1, -1);
188 glVertex2f(1, 1);
189 glVertex2f(-1, 1);
190 glVertex2f(1, -1);
191 glEnd();
192 glLineWidth(1.0);
193 }
195 draw_text(0.8, 0.75, 0, "fps: %.2f", fps);
197 glutSwapBuffers();
198 frames++;
199 total_frames++;
201 interval = (msec = glutGet(GLUT_ELAPSED_TIME)) - last_fps_upd;
202 if(interval >= 2000) {
203 float tm = (float)interval / 1000.0f;
204 fps = (float)frames / tm;
205 /*printf("%.2f fps \r", (float)frames / tm);
206 fflush(stdout);*/
207 last_fps_upd = msec;
208 frames = 0;
209 }
210 }
212 void draw_text(float r, float g, float b, const char *fmt, ...)
213 {
214 char buf[256], *text = buf;
215 va_list ap;
217 va_start(ap, fmt);
218 vsprintf(buf, fmt, ap);
219 va_end(ap);
221 glUseProgram(0);
223 glMatrixMode(GL_MODELVIEW);
224 glPushMatrix();
225 glLoadIdentity();
226 glMatrixMode(GL_PROJECTION);
227 glPushMatrix();
228 glLoadIdentity();
229 glOrtho(0, xsz, 0, ysz, -1, 1);
231 glColor3f(r, g, b);
232 glRasterPos2f(2, 4);
233 while(*text) {
234 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *text++);
235 }
236 glColor3f(1, 1, 1);
238 glPopMatrix();
239 glMatrixMode(GL_MODELVIEW);
240 glPopMatrix();
241 }
244 /*
245 static void update_texture()
246 {
247 int ntx = next_pow2(xsz);
248 int nty = next_pow2(ysz);
250 if(ntx != tex_xsz || nty != tex_ysz) {
251 tex_xsz = ntx;
252 tex_ysz = nty;
254 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, tex_xsz, tex_ysz, 0, GL_RGB, GL_FLOAT, 0);
255 }
256 }
257 */
259 static void idle()
260 {
261 glutPostRedisplay();
262 }
264 static void reshape(int x, int y)
265 {
266 int tx, ty;
268 xsz = x / img_scale;
269 ysz = y / img_scale;
271 glViewport(0, 0, x, y);
273 /* setup the texture matrix that maps just the visible area
274 * of the texture to [0, 1]
275 */
276 tx = next_pow2(xsz);
277 ty = next_pow2(ysz);
279 glMatrixMode(GL_TEXTURE);
280 glLoadIdentity();
281 glScalef((float)xsz / tx, (float)ysz / ty, 1.0f);
283 resize_renderer(xsz, ysz);
284 }
286 static void handle_keys(float dt)
287 {
288 Vector3 move;
289 float tilt = 0.0f;
290 float offs = dt * 8.0;
292 if(keystate['w']) {
293 move.z += offs;
294 }
295 if(keystate['s']) {
296 move.z -= offs;
297 }
298 if(keystate['d']) {
299 move.x += offs;
300 }
301 if(keystate['a']) {
302 move.x -= offs;
303 }
305 if(keystate['q']) {
306 tilt -= dt;
307 }
308 if(keystate['e']) {
309 tilt += dt;
310 }
312 cam->input_move(move.x, move.y, move.z);
313 cam->input_rotate(0, 0, tilt);
314 }
316 static void keyb(unsigned char key, int x, int y)
317 {
318 keystate[key] = true;
320 switch(key) {
321 case 27:
322 exit(0);
324 case '`':
325 sdr_valid = reload_shader();
326 break;
327 }
328 }
330 static void keyb_up(unsigned char key, int x, int y)
331 {
332 keystate[key] = false;
333 }
335 static void skeyb(int key, int x, int y)
336 {
337 switch(key) {
338 case GLUT_KEY_F1:
339 printf("reinitializing\n");
340 cleanup();
341 sdr_valid = init(scene_fname);
342 break;
344 default:
345 break;
346 }
347 }
349 static int prev_x, prev_y;
351 static void mouse(int bn, int st, int x, int y)
352 {
353 prev_x = x;
354 prev_y = y;
355 }
357 static void motion(int x, int y)
358 {
359 int dx = x - prev_x;
360 int dy = y - prev_y;
361 prev_x = x;
362 prev_y = y;
363 cam->input_rotate(-dy * 0.01, -dx * 0.01, 0);
364 }
366 static void sball_motion(int x, int y, int z)
367 {
368 float fx = x * 0.01;
369 float fy = y * 0.01;
370 float fz = z * 0.01;
371 cam->input_move(fx, fy, fz);
372 }
374 static void sball_rotate(int x, int y, int z)
375 {
376 float fx = x * 0.00025;
377 float fy = y * 0.00025;
378 float fz = z * 0.00025;
379 cam->input_rotate(fx, fy, fz);
380 }
382 static void sball_button(int bn, int state)
383 {
384 }
387 int next_pow2(int x)
388 {
389 x--;
390 x = (x >> 1) | x;
391 x = (x >> 2) | x;
392 x = (x >> 4) | x;
393 x = (x >> 8) | x;
394 x = (x >> 16) | x;
395 return x + 1;
396 }