# HG changeset patch # User John Tsiombikas # Date 1408505623 -10800 # Node ID e6948e131526a658d77c8ab425f0e5edc024da08 # Parent a797e426e309d33dcf98a6ca08c7ce2bc35be4f1 adding a vr wrapper diff -r a797e426e309 -r e6948e131526 .clang_complete --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.clang_complete Wed Aug 20 06:33:43 2014 +0300 @@ -0,0 +1,2 @@ +-Isrc +-Isrc/vr diff -r a797e426e309 -r e6948e131526 Makefile --- a/Makefile Tue Aug 19 11:01:04 2014 +0300 +++ b/Makefile Wed Aug 20 06:33:43 2014 +0300 @@ -1,4 +1,4 @@ -csrc = $(wildcard src/*.c) +csrc = $(wildcard src/*.c) $(wildcard src/vr/*.c) ccsrc = $(wildcard src/*.cc) obj = $(csrc:.c=.o) $(ccsrc:.cc=.o) dep = $(obj:.o=.d) diff -r a797e426e309 -r e6948e131526 src/game.cc --- a/src/game.cc Tue Aug 19 11:01:04 2014 +0300 +++ b/src/game.cc Wed Aug 20 06:33:43 2014 +0300 @@ -2,7 +2,7 @@ #include "opengl.h" #include "camera.h" #include "texture.h" -//#include "OVR_CAPI_GL.h" +#include "vr/vr.h" static void draw_scene(); @@ -15,6 +15,8 @@ bool game_init() { + vr_init(); + glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); @@ -33,6 +35,7 @@ void game_cleanup() { floor_tex.destroy(); + vr_shutdown(); } @@ -71,17 +74,26 @@ void game_render(int eye) { + float mat[16]; Matrix4x4 view_matrix = cam.get_matrix().inverse(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); - gluPerspective(60.0, (float)fb_width / (float)fb_height, 0.5, 500.0); + if(eye == 0 || !vr_proj_matrix(eye < 0 ? 0 : 1, mat)) { + gluPerspective(60.0, (float)fb_width / (float)fb_height, 0.5, 500.0); + } else { + glLoadTransposeMatrixf(mat); + } glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glLoadTransposeMatrixf(view_matrix[0]); + if(eye == 0 || !vr_view_matrix(eye < 0 ? 0 : 1, mat)) { + glLoadIdentity(); + } else { + glLoadTransposeMatrixf(mat); + } + glMultTransposeMatrixf(view_matrix[0]); draw_scene(); } diff -r a797e426e309 -r e6948e131526 src/vr/vr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/vr/vr.c Wed Aug 20 06:33:43 2014 +0300 @@ -0,0 +1,124 @@ +#include +#include +#include "vr.h" +#include "vr_impl.h" + + +static struct vr_module *vrm; +static float idmat[] = { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 +}; +static float fbtex_rect[] = { + 0, 0, 1, 1 +}; + +int vr_init(void) +{ + int i, nmodules; + + if(vrm) { + vr_shutdown(); + } + + vr_init_modules(); + + nmodules = vr_get_num_modules(); + for(i=0; iinit() != -1) { + /* add to the active modules array */ + vr_activate_module(i); + if(!vrm) { + vr_use_module(0); + } + } + } + + if(!vrm) { + return -1; + } + return 0; +} + +void vr_shutdown(void) +{ + vr_clear_modules(); + vrm = 0; + fbtex_rect[0] = fbtex_rect[1] = 0; + fbtex_rect[2] = fbtex_rect[3] = 1; +} + +int vr_module_count(void) +{ + return vr_get_num_active_modules(); +} + +const char *vr_module_name(int idx) +{ + struct vr_module *m = vr_get_active_module(idx); + if(!m) { + return 0; + } + return m->name; +} + +int vr_use_module(int idx) +{ + if(idx >= 0 && idx < vr_get_num_active_modules()) { + vrm = vr_get_active_module(idx); + printf("using vr module: %s\n", vrm->name); + return 0; + } + return -1; +} + +int vr_use_module_named(const char *name) +{ + int i, count = vr_get_num_active_modules(); + + for(i=0; iname, name) == 0) { + return vr_use_module(i); + } + } + return -1; +} + +int vr_view_matrix(int eye, float *mat) +{ + if(vrm && vrm->view_matrix) { + vrm->view_matrix(eye, mat); + return 1; + } + memcpy(mat, idmat, sizeof idmat); + return 0; +} + +int vr_proj_matrix(int eye, float *mat) +{ + if(vrm && vrm->proj_matrix) { + vrm->proj_matrix(eye, mat); + return 1; + } + memcpy(mat, idmat, sizeof idmat); + return 0; +} + +void vr_present(unsigned int fbtex) +{ + if(vrm && vrm->draw) { + vrm->draw(fbtex, fbtex_rect[0], fbtex_rect[2], fbtex_rect[1], fbtex_rect[3]); + } +} + +void vr_fbrect(float u, float umax, float v, float vmax) +{ + fbtex_rect[0] = u; + fbtex_rect[1] = v; + fbtex_rect[2] = umax; + fbtex_rect[3] = vmax; +} diff -r a797e426e309 -r e6948e131526 src/vr/vr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/vr/vr.h Wed Aug 20 06:33:43 2014 +0300 @@ -0,0 +1,33 @@ +#ifndef VR_H_ +#define VR_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +int vr_init(void); +void vr_shutdown(void); + +int vr_module_count(void); +const char *vr_module_name(int idx); + +int vr_use_module(int idx); +int vr_use_module_named(const char *name); + +/* returns non-zero if the active vr module provides this kind of matrix + * information, otherwise it returns zero, and sets mat to identity + */ +int vr_view_matrix(int eye, float *mat); +int vr_proj_matrix(int eye, float *mat); + +/* fbtex should be a texture containing both eye views side by side (LR) */ +void vr_present(unsigned int fbtex); + +/* set the area of the framebuffer texture to be used */ +void vr_fbrect(float u, float umax, float v, float vmax); + +#ifdef __cplusplus +} +#endif + +#endif /* VR_H_ */ diff -r a797e426e309 -r e6948e131526 src/vr/vr_impl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/vr/vr_impl.h Wed Aug 20 06:33:43 2014 +0300 @@ -0,0 +1,29 @@ +#ifndef VR_IMPL_H_ +#define VR_IMPL_H_ + +struct vr_module { + char *name; + + int (*init)(void); + void (*cleanup)(void); + + void (*view_matrix)(int eye, float *mat); + void (*proj_matrix)(int eye, float *mat); + + void (*draw)(unsigned int fbtex, float u, float maxu, float v, float maxv); +}; + +void vr_init_modules(void); + +void vr_clear_modules(void); +void vr_register_module(struct vr_module *mod); + +int vr_get_num_modules(void); +struct vr_module *vr_get_module(int idx); + +void vr_activate_module(int idx); + +int vr_get_num_active_modules(void); +struct vr_module *vr_get_active_module(int idx); + +#endif /* VR_IMPL_H_ */ diff -r a797e426e309 -r e6948e131526 src/vr/vr_libovr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/vr/vr_libovr.c Wed Aug 20 06:33:43 2014 +0300 @@ -0,0 +1,37 @@ +#include "vr_impl.h" + +static int init(void) +{ + return -1; +} + +static void cleanup(void) +{ +} + +static void view_matrix(int eye, float *mat) +{ +} + +static void proj_matrix(int eye, float *mat) +{ +} + +static void draw(unsigned int fbtex, float u, float maxu, float v, float maxv) +{ +} + +struct vr_module *vr_module_libovr(void) +{ + static struct vr_module m; + + if(!m.init) { + m.name = "libovr"; + m.init = init; + m.cleanup = cleanup; + m.view_matrix = view_matrix; + m.proj_matrix = proj_matrix; + m.draw = draw; + } + return &m; +} diff -r a797e426e309 -r e6948e131526 src/vr/vr_modules.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/vr/vr_modules.c Wed Aug 20 06:33:43 2014 +0300 @@ -0,0 +1,91 @@ +/* XXX this might become partly auto-generated in the future */ +#include +#include +#include "vr_impl.h" + +struct vr_module *vr_module_libovr(void); +struct vr_module *vr_module_null(void); + +static struct vr_module *modules; +static int num_modules, modules_max_size; + +static int *active_modules; +static int num_act_modules, act_modules_max_size; + + +void vr_init_modules(void) +{ + struct vr_module *m; + + vr_clear_modules(); + + if((m = vr_module_libovr())) { + vr_register_module(m); + } + + if((m = vr_module_null())) { + vr_register_module(m); + } + + /* more ... */ +} + +void vr_clear_modules(void) +{ + free(modules); + free(active_modules); + modules = 0; + num_modules = modules_max_size = 0; + active_modules = 0; + num_act_modules = act_modules_max_size = 0; +} + +void vr_register_module(struct vr_module *mod) +{ + if(num_modules >= modules_max_size) { + int newsz = modules_max_size ? modules_max_size * 2 : 2; + struct vr_module *newmods = realloc(modules, newsz * sizeof *newmods); + if(!newmods) { + fprintf(stderr, "failed to resize modules array up to %d\n", newsz); + return; + } + modules = newmods; + modules_max_size = newsz; + } + modules[num_modules++] = *mod; +} + +int vr_get_num_modules(void) +{ + return num_modules; +} + +struct vr_module *vr_get_module(int idx) +{ + return modules + idx; +} + +void vr_activate_module(int idx) +{ + if(num_act_modules >= act_modules_max_size) { + int newsz = act_modules_max_size ? act_modules_max_size * 2 : 2; + int *newact = realloc(active_modules, newsz * sizeof *newact); + if(!newact) { + fprintf(stderr, "failed to resize active modules array up to %d\n", newsz); + return; + } + active_modules = newact; + act_modules_max_size = newsz; + } + active_modules[num_act_modules++] = idx; +} + +int vr_get_num_active_modules(void) +{ + return num_act_modules; +} + +struct vr_module *vr_get_active_module(int idx) +{ + return modules + active_modules[idx]; +} diff -r a797e426e309 -r e6948e131526 src/vr/vr_null.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/vr/vr_null.c Wed Aug 20 06:33:43 2014 +0300 @@ -0,0 +1,61 @@ +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include "vr_impl.h" + +static int init(void) +{ + return 0; +} + +static void draw(unsigned int fbtex, float u, float maxu, float v, float maxv) +{ + glPushAttrib(GL_ENABLE_BIT | GL_TRANSFORM_BIT); + + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + glDisable(GL_CULL_FACE); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + glBegin(GL_QUADS); + glTexCoord2f(u, v); + glVertex2f(-1, -1); + glTexCoord2f((u + maxu) / 2, v); + glVertex2f(1, -1); + glTexCoord2f((u + maxu) / 2, maxv); + glVertex2f(1, 1); + glTexCoord2f(u, maxv); + glVertex2f(-1, 1); + glEnd(); + + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glPopAttrib(); +} + +struct vr_module *vr_module_null(void) +{ + static struct vr_module m; + + if(!m.init) { + m.name = "null"; + m.init = init; + m.draw = draw; + } + return &m; +}