X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=laserbrain_demo;a=blobdiff_plain;f=src%2Fapp.cc;h=9245f06bf8adc627fea00361fc2303397b87301d;hp=96b3f86229e2106fd14c98162e6504b06c78a542;hb=31e1ffedb543e048673b7ba969607fbb8214ac9a;hpb=c64bd959ffb4034cb288780f13a351b00fb22ca0 diff --git a/src/app.cc b/src/app.cc index 96b3f86..9245f06 100644 --- a/src/app.cc +++ b/src/app.cc @@ -1,5 +1,6 @@ #include #include +#include #include "app.h" #include "opengl.h" #include "sdr.h" @@ -10,12 +11,18 @@ #include "metascene.h" #include "datamap.h" #include "ui.h" +#include "opt.h" +#include "post.h" + +#define NEAR_CLIP 5.0 +#define FAR_CLIP 10000.0 static void draw_scene(); long time_msec; int win_width, win_height; float win_aspect; +bool fb_srgb; bool opt_gear_wireframe; static float cam_dist = 0.0; @@ -24,24 +31,53 @@ static Vec3 cam_pos; static float floor_y; // last floor height static float user_eye_height = 165; -static float walk_speed = 400.0f; +static float walk_speed = 300.0f; +static float mouse_speed = 1.0f; static bool show_walk_mesh, noclip = false; +static bool have_headtracking, should_swap; + static int prev_mx, prev_my; static bool bnstate[8]; static bool keystate[256]; -static Mat4 view_matrix; +static Mat4 view_matrix, mouse_view_matrix, proj_matrix; static TextureSet texman; static Scene *scn; -static unsigned int sdr; +static unsigned int sdr, sdr_post_gamma; static long prev_msec; -bool app_init() +bool app_init(int argc, char **argv) { + if(!init_options(argc, argv, "demo.conf")) { + return false; + } + app_resize(opt.width, opt.height); + app_fullscreen(opt.fullscreen); + + if(opt.vr) { + if(goatvr_init() == -1) { + return false; + } + goatvr_set_origin_mode(GOATVR_HEAD); + goatvr_set_units_scale(100.0f); + + goatvr_startvr(); + should_swap = goatvr_should_swap() != 0; + user_eye_height = goatvr_get_eye_height(); + have_headtracking = goatvr_have_headtracking(); + + goatvr_recenter(); + } + + int srgb_capable; + glGetIntegerv(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &srgb_capable); + printf("Framebuffer %s sRGB-capable\n", srgb_capable ? "is" : "is not"); + fb_srgb = srgb_capable != 0; glEnable(GL_FRAMEBUFFER_SRGB); + glEnable(GL_MULTISAMPLE); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); @@ -53,6 +89,8 @@ bool app_init() float ambient[] = {0.0, 0.0, 0.0, 0.0}; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); + glClearColor(0.2, 0.2, 0.2, 1.0); + scn = new Scene(&texman); if(!load_scene(scn, "data/museum.scene")) { return false; @@ -75,12 +113,24 @@ bool app_init() set_uniform_int(sdr, "texmap", 0); set_uniform_int(sdr, "lightmap", 1); + if(!fb_srgb) { + sdr_post_gamma = create_program_load("sdr/post_gamma.v.glsl", "sdr/post_gamma.p.glsl"); + } + glUseProgram(0); + + if(opt.vr || opt.fullscreen) { + app_grab_mouse(true); + } return true; } void app_cleanup() { + app_grab_mouse(false); + if(opt.vr) { + goatvr_shutdown(); + } texman.clear(); } @@ -160,6 +210,15 @@ static void update(float dt) } floor_y = cam_pos.y - user_eye_height; } + + // calculate mouselook view matrix + mouse_view_matrix = Mat4::identity; + mouse_view_matrix.pre_translate(0, 0, -cam_dist); + if(!have_headtracking) { + mouse_view_matrix.pre_rotate_x(deg_to_rad(cam_phi)); + } + mouse_view_matrix.pre_rotate_y(deg_to_rad(cam_theta)); + mouse_view_matrix.pre_translate(-cam_pos.x, -cam_pos.y, -cam_pos.z); } static void set_light(int idx, const Vec3 &pos, const Vec3 &color) @@ -179,34 +238,63 @@ void app_display() float dt = (float)(time_msec - prev_msec) / 1000.0f; prev_msec = time_msec; - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + update(dt); - view_matrix = Mat4::identity; - view_matrix.pre_translate(0, 0, -cam_dist); - view_matrix.pre_rotate(deg_to_rad(cam_phi), 1, 0, 0); - view_matrix.pre_rotate(deg_to_rad(cam_theta), 0, 1, 0); - view_matrix.pre_translate(-cam_pos.x, -cam_pos.y, -cam_pos.z); + if(opt.vr) { + // VR mode + goatvr_draw_start(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(view_matrix[0]); + for(int i=0; i<2; i++) { + // for each eye + goatvr_draw_eye(i); - static const Vec3 lpos[] = { Vec3(-50, 75, 100), Vec3(100, 0, 30), Vec3(-10, -10, 60) }; - set_light(0, lpos[0], Vec3(1.0, 0.8, 0.7) * 0.8); - set_light(1, lpos[1], Vec3(0.6, 0.7, 1.0) * 0.6); - set_light(2, lpos[2], Vec3(0.8, 1.0, 0.8) * 0.3); + proj_matrix = goatvr_projection_matrix(i, NEAR_CLIP, FAR_CLIP); + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(proj_matrix[0]); - update(dt); + view_matrix = mouse_view_matrix * Mat4(goatvr_view_matrix(i)); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(view_matrix[0]); - draw_scene(); - draw_ui(); + draw_scene(); + } + goatvr_draw_done(); - app_swap_buffers(); + if(should_swap) { + app_swap_buffers(); + } + + } else { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + proj_matrix.perspective(deg_to_rad(50.0), win_aspect, NEAR_CLIP, FAR_CLIP); + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(proj_matrix[0]); + + view_matrix = mouse_view_matrix; + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(view_matrix[0]); + + draw_scene(); + + if(!fb_srgb && sdr_post_gamma) { + slow_post(sdr_post_gamma); + glUseProgram(0); + } + app_swap_buffers(); + } assert(glGetError() == GL_NO_ERROR); } static void draw_scene() { + static const Vec3 lpos[] = { Vec3(-50, 75, 100), Vec3(100, 0, 30), Vec3(-10, -10, 60) }; + set_light(0, lpos[0], Vec3(1.0, 0.8, 0.7) * 0.8); + set_light(1, lpos[1], Vec3(0.6, 0.7, 1.0) * 0.6); + set_light(2, lpos[2], Vec3(0.8, 1.0, 0.8) * 0.3); + glUseProgram(sdr); scn->draw(); glUseProgram(0); @@ -228,16 +316,15 @@ static void draw_scene() glPopAttrib(); } + + draw_ui(); } void app_reshape(int x, int y) { glViewport(0, 0, x, y); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(50.0, (float)x / (float)y, 1.0, 10000.0); + goatvr_set_fb_size(x, y, 1.0f); } void app_keyboard(int key, bool pressed) @@ -250,6 +337,15 @@ void app_keyboard(int key, bool pressed) app_quit(); break; + case 'f': + app_toggle_fullscreen(); + break; + + case '`': + app_toggle_grab_mouse(); + show_message("mouse %s", app_is_mouse_grabbed() ? "grabbed" : "released"); + break; + case 'w': if(mod & MOD_CTRL) { show_walk_mesh = !show_walk_mesh; @@ -264,6 +360,13 @@ void app_keyboard(int key, bool pressed) } break; + case 'p': + if(mod & MOD_CTRL) { + fb_srgb = !fb_srgb; + show_message("gamma correction for non-sRGB framebuffers: %s\n", fb_srgb ? "off" : "on"); + } + break; + case '=': walk_speed *= 1.25; show_message("walk speed: %g", walk_speed); @@ -273,6 +376,16 @@ void app_keyboard(int key, bool pressed) walk_speed *= 0.75; show_message("walk speed: %g", walk_speed); break; + + case ']': + mouse_speed *= 1.2; + show_message("mouse speed: %g", mouse_speed); + break; + + case '[': + mouse_speed *= 0.8; + show_message("mouse speed: %g", mouse_speed); + break; } } @@ -288,6 +401,22 @@ void app_mouse_button(int bn, bool pressed, int x, int y) bnstate[bn] = pressed; } +static inline void mouse_look(int dx, int dy) +{ + float scrsz = (float)win_height; + cam_theta += dx * 512.0 / scrsz; + cam_phi += dy * 512.0 / scrsz; + + if(cam_phi < -90) cam_phi = -90; + if(cam_phi > 90) cam_phi = 90; +} + +static void mouse_zoom(int dx, int dy) +{ + cam_dist += dy * 0.1; + if(cam_dist < 0.0) cam_dist = 0.0; +} + void app_mouse_motion(int x, int y) { int dx = x - prev_mx; @@ -297,20 +426,19 @@ void app_mouse_motion(int x, int y) if(!dx && !dy) return; - app_mouse_delta(dx, dy); + if(bnstate[0]) { + mouse_look(dx, dy); + } + if(bnstate[2]) { + mouse_zoom(dx, dy); + } } void app_mouse_delta(int dx, int dy) { - if(bnstate[0]) { - cam_theta += dx * 0.5; - cam_phi += dy * 0.5; - - if(cam_phi < -90) cam_phi = -90; - if(cam_phi > 90) cam_phi = 90; - } if(bnstate[2]) { - cam_dist += dy * 0.1; - if(cam_dist < 0.0) cam_dist = 0.0; + mouse_zoom(dx * mouse_speed, dy * mouse_speed); + } else { + mouse_look(dx * mouse_speed, dy * mouse_speed); } }