gpuray_glsl
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/main.cc Sun Nov 09 13:03:36 2014 +0200 1.3 @@ -0,0 +1,396 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <stdarg.h> 1.7 +#include <assert.h> 1.8 +#include "opengl.h" 1.9 + 1.10 +#include "gpuscene.h" 1.11 +#include "sphere.h" 1.12 +#include "plane.h" 1.13 +#include "image.h" 1.14 +#include "rend.h" 1.15 +#include "glsdr.h" 1.16 + 1.17 +static bool init(const char *scene_fname); 1.18 +static void cleanup(); 1.19 +static void disp(); 1.20 +static void draw_text(float r, float g, float b, const char *fmt, ...); 1.21 +//static void update_texture(const float *fb); 1.22 +static void idle(); 1.23 +static void reshape(int x, int y); 1.24 +static void handle_keys(float dt); 1.25 +static void keyb(unsigned char key, int x, int y); 1.26 +static void keyb_up(unsigned char key, int x, int y); 1.27 +static void skeyb(int key, int x, int y); 1.28 +static void mouse(int bn, int st, int x, int y); 1.29 +static void motion(int x, int y); 1.30 +static void sball_motion(int x, int y, int z); 1.31 +static void sball_rotate(int x, int y, int z); 1.32 +static void sball_button(int bn, int state); 1.33 + 1.34 +static unsigned int tex; 1.35 +static long last_fps_upd, first_time = -1; 1.36 +static long frames, total_frames; 1.37 +static float fps; 1.38 +static int xsz = 800; 1.39 +static int ysz = 450; 1.40 +//static int tex_xsz, tex_ysz; 1.41 + 1.42 +static GPUScene *scn; 1.43 +static FlyCamera *cam; 1.44 + 1.45 +static float img_scale = 1.0f; 1.46 +static bool keystate[256]; 1.47 + 1.48 +static char *scene_fname; 1.49 +static bool sdr_valid = true; 1.50 + 1.51 +int main(int argc, char **argv) 1.52 +{ 1.53 + glutInit(&argc, argv); 1.54 + 1.55 + int num_samples = 1; 1.56 + 1.57 + for(int i=1; i<argc; i++) { 1.58 + if(argv[i][0] == '-') { 1.59 + if(strcmp(argv[i], "-size") == 0) { 1.60 + if(sscanf(argv[++i], "%dx%d", &xsz, &ysz) < 2) { 1.61 + fprintf(stderr, "-size must be followed by the image resolution (WxH)\n"); 1.62 + return 1; 1.63 + } 1.64 + 1.65 + } else if(strcmp(argv[i], "-samples") == 0) { 1.66 + num_samples = atoi(argv[++i]); 1.67 + if(num_samples <= 0) { 1.68 + fprintf(stderr, "-samples must be followed by the number of samples per pixel\n"); 1.69 + return 1; 1.70 + } 1.71 + } else if(strcmp(argv[i], "-scale") == 0) { 1.72 + img_scale = atof(argv[++i]); 1.73 + if(img_scale <= 1.0f) { 1.74 + fprintf(stderr, "-scale must be followed by an image scale factor >= 1\n"); 1.75 + return 1; 1.76 + } 1.77 + } else { 1.78 + fprintf(stderr, "invalid option: %s\n", argv[i]); 1.79 + return 1; 1.80 + } 1.81 + } else { 1.82 + if(scene_fname) { 1.83 + fprintf(stderr, "unexpected argument: %s\n", argv[i]); 1.84 + return 1; 1.85 + } 1.86 + scene_fname = argv[i]; 1.87 + } 1.88 + } 1.89 + 1.90 + glutInitWindowSize(xsz * img_scale, ysz * img_scale); 1.91 + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 1.92 + glutCreateWindow("single threaded"); 1.93 + 1.94 + glutDisplayFunc(disp); 1.95 + glutIdleFunc(idle); 1.96 + glutReshapeFunc(reshape); 1.97 + glutKeyboardFunc(keyb); 1.98 + glutKeyboardUpFunc(keyb_up); 1.99 + glutSpecialFunc(skeyb); 1.100 + glutMouseFunc(mouse); 1.101 + glutMotionFunc(motion); 1.102 + glutSpaceballMotionFunc(sball_motion); 1.103 + glutSpaceballRotateFunc(sball_rotate); 1.104 + glutSpaceballButtonFunc(sball_button); 1.105 + 1.106 + glewInit(); 1.107 + 1.108 + if(!init(scene_fname)) { 1.109 + return 1; 1.110 + } 1.111 + atexit(cleanup); 1.112 + 1.113 + glutMainLoop(); 1.114 + return 0; 1.115 +} 1.116 + 1.117 +static bool init(const char *scene_fname) 1.118 +{ 1.119 + scn = new GPUScene; 1.120 + if(!scn->load(scene_fname ? scene_fname : "scene")) { 1.121 + return false; 1.122 + } 1.123 + 1.124 + cam = new FlyCamera; 1.125 + cam->input_move(0, 1.5, -10); 1.126 + cam->input_rotate(25, 0, 0); 1.127 + scn->set_camera(cam); 1.128 + 1.129 + if(!init_renderer(scn, xsz, ysz)) { 1.130 + return false; 1.131 + } 1.132 + 1.133 + glGenTextures(1, &tex); 1.134 + glBindTexture(GL_TEXTURE_2D, tex); 1.135 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1.136 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1.137 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1.138 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1.139 + 1.140 + int srgb_capable; 1.141 + if(GLEW_EXT_framebuffer_sRGB && (glGetIntegerv(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &srgb_capable), srgb_capable)) { 1.142 + printf("enabling sRGB framebuffer\n"); 1.143 + glEnable(GL_FRAMEBUFFER_SRGB); 1.144 + } else { 1.145 + printf("using post shader for gamma correction\n"); 1.146 + unsigned int post_sdr = create_program_load(0, "sdr/postsdr.glsl"); 1.147 + if(post_sdr) { 1.148 + glUseProgram(post_sdr); 1.149 + } 1.150 + } 1.151 + 1.152 + last_fps_upd = glutGet(GLUT_ELAPSED_TIME); 1.153 + first_time = last_fps_upd; 1.154 + total_frames = 0; 1.155 + return true; 1.156 +} 1.157 + 1.158 +static void cleanup() 1.159 +{ 1.160 + long interval = glutGet(GLUT_ELAPSED_TIME) - first_time; 1.161 + printf("average fps: %.2f\n", (float)total_frames / ((float)interval / 1000.0f)); 1.162 + 1.163 + glDeleteTextures(1, &tex); 1.164 + 1.165 + destroy_renderer(); 1.166 + delete scn; 1.167 +} 1.168 + 1.169 +static void disp() 1.170 +{ 1.171 + static long prev_msec; 1.172 + long interval, msec = glutGet(GLUT_ELAPSED_TIME); 1.173 + 1.174 + handle_keys((msec - prev_msec) / 1000.0f); 1.175 + prev_msec = msec; 1.176 + 1.177 + //update_texture(); 1.178 + if(sdr_valid) { 1.179 + render_frame(msec); 1.180 + } else { 1.181 + glUseProgram(0); 1.182 + glMatrixMode(GL_MODELVIEW); 1.183 + glLoadIdentity(); 1.184 + glMatrixMode(GL_PROJECTION); 1.185 + glLoadIdentity(); 1.186 + 1.187 + glLineWidth(8.0); 1.188 + glBegin(GL_LINES); 1.189 + glColor3f(1, 0, 0); 1.190 + glVertex2f(-1, -1); 1.191 + glVertex2f(1, 1); 1.192 + glVertex2f(-1, 1); 1.193 + glVertex2f(1, -1); 1.194 + glEnd(); 1.195 + glLineWidth(1.0); 1.196 + } 1.197 + 1.198 + draw_text(0.8, 0.75, 0, "fps: %.2f", fps); 1.199 + 1.200 + glutSwapBuffers(); 1.201 + frames++; 1.202 + total_frames++; 1.203 + 1.204 + interval = (msec = glutGet(GLUT_ELAPSED_TIME)) - last_fps_upd; 1.205 + if(interval >= 2000) { 1.206 + float tm = (float)interval / 1000.0f; 1.207 + fps = (float)frames / tm; 1.208 + /*printf("%.2f fps \r", (float)frames / tm); 1.209 + fflush(stdout);*/ 1.210 + last_fps_upd = msec; 1.211 + frames = 0; 1.212 + } 1.213 +} 1.214 + 1.215 +void draw_text(float r, float g, float b, const char *fmt, ...) 1.216 +{ 1.217 + char buf[256], *text = buf; 1.218 + va_list ap; 1.219 + 1.220 + va_start(ap, fmt); 1.221 + vsprintf(buf, fmt, ap); 1.222 + va_end(ap); 1.223 + 1.224 + glUseProgram(0); 1.225 + 1.226 + glMatrixMode(GL_MODELVIEW); 1.227 + glPushMatrix(); 1.228 + glLoadIdentity(); 1.229 + glMatrixMode(GL_PROJECTION); 1.230 + glPushMatrix(); 1.231 + glLoadIdentity(); 1.232 + glOrtho(0, xsz, 0, ysz, -1, 1); 1.233 + 1.234 + glColor3f(r, g, b); 1.235 + glRasterPos2f(2, 4); 1.236 + while(*text) { 1.237 + glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *text++); 1.238 + } 1.239 + glColor3f(1, 1, 1); 1.240 + 1.241 + glPopMatrix(); 1.242 + glMatrixMode(GL_MODELVIEW); 1.243 + glPopMatrix(); 1.244 +} 1.245 + 1.246 + 1.247 +/* 1.248 +static void update_texture() 1.249 +{ 1.250 + int ntx = next_pow2(xsz); 1.251 + int nty = next_pow2(ysz); 1.252 + 1.253 + if(ntx != tex_xsz || nty != tex_ysz) { 1.254 + tex_xsz = ntx; 1.255 + tex_ysz = nty; 1.256 + 1.257 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, tex_xsz, tex_ysz, 0, GL_RGB, GL_FLOAT, 0); 1.258 + } 1.259 +} 1.260 +*/ 1.261 + 1.262 +static void idle() 1.263 +{ 1.264 + glutPostRedisplay(); 1.265 +} 1.266 + 1.267 +static void reshape(int x, int y) 1.268 +{ 1.269 + int tx, ty; 1.270 + 1.271 + xsz = x / img_scale; 1.272 + ysz = y / img_scale; 1.273 + 1.274 + glViewport(0, 0, x, y); 1.275 + 1.276 + /* setup the texture matrix that maps just the visible area 1.277 + * of the texture to [0, 1] 1.278 + */ 1.279 + tx = next_pow2(xsz); 1.280 + ty = next_pow2(ysz); 1.281 + 1.282 + glMatrixMode(GL_TEXTURE); 1.283 + glLoadIdentity(); 1.284 + glScalef((float)xsz / tx, (float)ysz / ty, 1.0f); 1.285 + 1.286 + resize_renderer(xsz, ysz); 1.287 +} 1.288 + 1.289 +static void handle_keys(float dt) 1.290 +{ 1.291 + Vector3 move; 1.292 + float tilt = 0.0f; 1.293 + float offs = dt * 8.0; 1.294 + 1.295 + if(keystate['w']) { 1.296 + move.z += offs; 1.297 + } 1.298 + if(keystate['s']) { 1.299 + move.z -= offs; 1.300 + } 1.301 + if(keystate['d']) { 1.302 + move.x += offs; 1.303 + } 1.304 + if(keystate['a']) { 1.305 + move.x -= offs; 1.306 + } 1.307 + 1.308 + if(keystate['q']) { 1.309 + tilt -= dt; 1.310 + } 1.311 + if(keystate['e']) { 1.312 + tilt += dt; 1.313 + } 1.314 + 1.315 + cam->input_move(move.x, move.y, move.z); 1.316 + cam->input_rotate(0, 0, tilt); 1.317 +} 1.318 + 1.319 +static void keyb(unsigned char key, int x, int y) 1.320 +{ 1.321 + keystate[key] = true; 1.322 + 1.323 + switch(key) { 1.324 + case 27: 1.325 + exit(0); 1.326 + 1.327 + case '`': 1.328 + sdr_valid = reload_shader(); 1.329 + break; 1.330 + } 1.331 +} 1.332 + 1.333 +static void keyb_up(unsigned char key, int x, int y) 1.334 +{ 1.335 + keystate[key] = false; 1.336 +} 1.337 + 1.338 +static void skeyb(int key, int x, int y) 1.339 +{ 1.340 + switch(key) { 1.341 + case GLUT_KEY_F1: 1.342 + printf("reinitializing\n"); 1.343 + cleanup(); 1.344 + sdr_valid = init(scene_fname); 1.345 + break; 1.346 + 1.347 + default: 1.348 + break; 1.349 + } 1.350 +} 1.351 + 1.352 +static int prev_x, prev_y; 1.353 + 1.354 +static void mouse(int bn, int st, int x, int y) 1.355 +{ 1.356 + prev_x = x; 1.357 + prev_y = y; 1.358 +} 1.359 + 1.360 +static void motion(int x, int y) 1.361 +{ 1.362 + int dx = x - prev_x; 1.363 + int dy = y - prev_y; 1.364 + prev_x = x; 1.365 + prev_y = y; 1.366 + cam->input_rotate(-dy * 0.01, -dx * 0.01, 0); 1.367 +} 1.368 + 1.369 +static void sball_motion(int x, int y, int z) 1.370 +{ 1.371 + float fx = x * 0.01; 1.372 + float fy = y * 0.01; 1.373 + float fz = z * 0.01; 1.374 + cam->input_move(fx, fy, fz); 1.375 +} 1.376 + 1.377 +static void sball_rotate(int x, int y, int z) 1.378 +{ 1.379 + float fx = x * 0.00025; 1.380 + float fy = y * 0.00025; 1.381 + float fz = z * 0.00025; 1.382 + cam->input_rotate(fx, fy, fz); 1.383 +} 1.384 + 1.385 +static void sball_button(int bn, int state) 1.386 +{ 1.387 +} 1.388 + 1.389 + 1.390 +int next_pow2(int x) 1.391 +{ 1.392 + x--; 1.393 + x = (x >> 1) | x; 1.394 + x = (x >> 2) | x; 1.395 + x = (x >> 4) | x; 1.396 + x = (x >> 8) | x; 1.397 + x = (x >> 16) | x; 1.398 + return x + 1; 1.399 +}