vrchess
changeset 10:e3f0ca1d008a
added preliminary OpenHMD module
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 22 Aug 2014 20:11:15 +0300 |
parents | c2eecf764daa |
children | 5dc4e2b8f6f5 |
files | Makefile src/vr/opt.c src/vr/vr.c src/vr/vr_impl.h src/vr/vr_libovr.c src/vr/vr_modules.c src/vr/vr_openhmd.c |
diffstat | 7 files changed, 235 insertions(+), 8 deletions(-) [+] |
line diff
1.1 --- a/Makefile Fri Aug 22 18:48:25 2014 +0300 1.2 +++ b/Makefile Fri Aug 22 20:11:15 2014 +0300 1.3 @@ -7,6 +7,9 @@ 1.4 # comment out to disable LibOVR (oculus sdk) 1.5 #ovr_cflags = -DUSE_LIBOVR 1.6 #ovr_libs = -lovr 1.7 +# comment out to disable OpenHMD 1.8 +ohmd_cflags = -DUSE_OPENHMD 1.9 +ohmd_libs = -lopenhmd 1.10 1.11 CFLAGS = -pedantic -Wall -g $(ovr_cflags) 1.12 CXXFLAGS = -std=c++11 $(CFLAGS)
2.1 --- a/src/vr/opt.c Fri Aug 22 18:48:25 2014 +0300 2.2 +++ b/src/vr/opt.c Fri Aug 22 20:11:15 2014 +0300 2.3 @@ -5,7 +5,7 @@ 2.4 #include "opt.h" 2.5 #include "rbtree.h" 2.6 2.7 -static void opt_del_func(void *opt, void *cls) 2.8 +static void opt_del_func(struct rbnode *opt, void *cls) 2.9 { 2.10 free(opt); 2.11 }
3.1 --- a/src/vr/vr.c Fri Aug 22 18:48:25 2014 +0300 3.2 +++ b/src/vr/vr.c Fri Aug 22 20:11:15 2014 +0300 3.3 @@ -152,7 +152,17 @@ 3.4 3.5 int vr_view_matrix(int eye, float *mat) 3.6 { 3.7 - /* TODO combine vr_view_translation and vr_view_rotation */ 3.8 + float offs[3], quat[4]; 3.9 + 3.10 + if(vrm && vrm->view_matrix) { 3.11 + vrm->view_matrix(eye, mat); 3.12 + return 1; 3.13 + } 3.14 + 3.15 + if(!vr_view_translation(eye, offs) && !vr_view_rotation(eye, quat)) { 3.16 + return 0; 3.17 + } 3.18 + /* TODO construct matrix */ 3.19 return 0; 3.20 } 3.21
4.1 --- a/src/vr/vr_impl.h Fri Aug 22 18:48:25 2014 +0300 4.2 +++ b/src/vr/vr_impl.h Fri Aug 22 20:11:15 2014 +0300 4.3 @@ -16,6 +16,7 @@ 4.4 void (*translation)(int eye, float *vec); 4.5 void (*rotation)(int eye, float *quat); 4.6 4.7 + void (*view_matrix)(int eye, float *mat); 4.8 void (*proj_matrix)(int eye, float znear, float zfar, float *mat); 4.9 4.10 void (*begin)(int eye);
5.1 --- a/src/vr/vr_libovr.c Fri Aug 22 18:48:25 2014 +0300 5.2 +++ b/src/vr/vr_libovr.c Fri Aug 22 20:11:15 2014 +0300 5.3 @@ -104,16 +104,16 @@ 5.4 #endif 5.5 5.6 ovrHmd_AttachToWindow(hmd, win, 0, 0); 5.7 - //ovrHmd_SetEnabledCaps(hmd, ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction); 5.8 + /*ovrHmd_SetEnabledCaps(hmd, ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction);*/ 5.9 5.10 - dcaps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette;// | ovrDistortionCap_TimeWarp;// | 5.11 - //ovrDistortionCap_Overdrive; 5.12 + dcaps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette;/* | ovrDistortionCap_TimeWarp;// | 5.13 + ovrDistortionCap_Overdrive; */ 5.14 5.15 if(!ovrHmd_ConfigureRendering(hmd, &glcfg.Config, dcaps, eye_fov, eye_render_desc)) { 5.16 fprintf(stderr, "failed to configure LibOVR distortion renderer\n"); 5.17 } 5.18 5.19 - //ovrhmd_EnableHSWDisplaySDKRender(hmd, 0); 5.20 + /* ovrhmd_EnableHSWDisplaySDKRender(hmd, 0); */ 5.21 } 5.22 5.23 static void cleanup(void)
6.1 --- a/src/vr/vr_modules.c Fri Aug 22 18:48:25 2014 +0300 6.2 +++ b/src/vr/vr_modules.c Fri Aug 22 20:11:15 2014 +0300 6.3 @@ -4,6 +4,7 @@ 6.4 #include "vr_impl.h" 6.5 6.6 struct vr_module *vr_module_libovr(void); 6.7 +struct vr_module *vr_module_openhmd(void); 6.8 struct vr_module *vr_module_null(void); 6.9 6.10 static struct vr_module *modules; 6.11 @@ -23,11 +24,13 @@ 6.12 vr_register_module(m); 6.13 } 6.14 6.15 + if((m = vr_module_openhmd())) { 6.16 + vr_register_module(m); 6.17 + } 6.18 + 6.19 if((m = vr_module_null())) { 6.20 vr_register_module(m); 6.21 } 6.22 - 6.23 - /* more ... */ 6.24 } 6.25 6.26 void vr_clear_modules(void)
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/vr/vr_openhmd.c Fri Aug 22 20:11:15 2014 +0300 7.3 @@ -0,0 +1,210 @@ 7.4 +#include "vr_impl.h" 7.5 + 7.6 +#ifdef USE_OPENHMD 7.7 +#include <stdio.h> 7.8 +#include <stdlib.h> 7.9 +#include <openhmd/openhmd.h> 7.10 +#include "opt.h" 7.11 + 7.12 +/* a noble spirit embiggens the framebuffer to avoid aliasing in the middle */ 7.13 +#define EMBIGGEN 1.5 7.14 + 7.15 +static ohmd_context *ctx; 7.16 +static ohmd_device *dev; 7.17 +static void *optdb; 7.18 +static int new_frame = 1; 7.19 + 7.20 +static int disp_width, disp_height; 7.21 +static float ipd; 7.22 + 7.23 +static struct { 7.24 + unsigned int id; 7.25 + float umin, umax; 7.26 + float vmin, vmax; 7.27 +} eye_tex[2]; 7.28 + 7.29 + 7.30 +static int init(void) 7.31 +{ 7.32 + int i, num_hmds; 7.33 + 7.34 + if(!(ctx = ohmd_ctx_create())) { 7.35 + fprintf(stderr, "failed to create OpenHMD context\n"); 7.36 + ohmd_ctx_destroy(ctx); 7.37 + return -1; 7.38 + } 7.39 + if(!(num_hmds = ohmd_ctx_probe(ctx))) { 7.40 + fprintf(stderr, "no HMDs detected\n"); 7.41 + return -1; 7.42 + } 7.43 + 7.44 + for(i=0; i<num_hmds; i++) { 7.45 + const char *vendor = ohmd_list_gets(ctx, i, OHMD_VENDOR); 7.46 + const char *product = ohmd_list_gets(ctx, i, OHMD_PRODUCT); 7.47 + const char *devpath = ohmd_list_gets(ctx, i, OHMD_PATH); 7.48 + 7.49 + printf("[%d] %s - %s (path: %s)\n", i, vendor, product, devpath); 7.50 + } 7.51 + 7.52 + printf("opening device 0\n"); 7.53 + 7.54 + if(!(dev = ohmd_list_open_device(ctx, 0))) { 7.55 + fprintf(stderr, "failed to open device 0: %s\n", ohmd_ctx_get_error(ctx)); 7.56 + return -1; 7.57 + } 7.58 + 7.59 + ohmd_device_geti(dev, OHMD_SCREEN_HORIZONTAL_SIZE, &disp_width); 7.60 + ohmd_device_geti(dev, OHMD_SCREEN_VERTICAL_SIZE, &disp_height); 7.61 + ohmd_device_getf(dev, OHMD_EYE_IPD, &ipd); 7.62 + 7.63 + if((optdb = create_options())) { 7.64 + set_option_int(optdb, VR_OPT_DISPLAY_WIDTH, disp_width); 7.65 + set_option_int(optdb, VR_OPT_DISPLAY_HEIGHT, disp_height); 7.66 + set_option_float(optdb, VR_OPT_IPD, ipd); 7.67 + 7.68 + set_option_int(optdb, VR_OPT_LEYE_XRES, (int)(disp_width / 2.0 * FB_EMBIGGEN)); 7.69 + set_option_int(optdb, VR_OPT_LEYE_YRES, (int)(disp_height * FB_EMBIGGEN)); 7.70 + set_option_int(optdb, VR_OPT_REYE_XRES, (int)(disp_width / 2.0 * FB_EMBIGGEN)); 7.71 + set_option_int(optdb, VR_OPT_REYE_YRES, (int)(disp_height * FB_EMBIGGEN)); 7.72 + } 7.73 + 7.74 + return 0; 7.75 +} 7.76 + 7.77 +static void cleanup(void) 7.78 +{ 7.79 + if(ctx) { 7.80 + ohmd_ctx_destroy(ctx); 7.81 + } 7.82 +} 7.83 + 7.84 + 7.85 +static int set_option(const char *opt, enum opt_type type, void *valp) 7.86 +{ 7.87 + switch(type) { 7.88 + case OTYPE_INT: 7.89 + set_option_int(optdb, opt, *(int*)valp); 7.90 + break; 7.91 + 7.92 + case OTYPE_FLOAT: 7.93 + set_option_float(optdb, opt, *(float*)valp); 7.94 + break; 7.95 + } 7.96 + return 0; 7.97 +} 7.98 + 7.99 +static int get_option(const char *opt, enum opt_type type, void *valp) 7.100 +{ 7.101 + switch(type) { 7.102 + case OTYPE_INT: 7.103 + return get_option_int(optdb, opt, valp); 7.104 + case OTYPE_FLOAT: 7.105 + return get_option_float(optdb, opt, valp); 7.106 + } 7.107 + return -1; 7.108 +} 7.109 + 7.110 +static int translation(int eye, float *vec) 7.111 +{ 7.112 + float xform[16]; 7.113 + 7.114 + view_matrix(eye, xform); 7.115 + 7.116 + vec[0] = xform[3]; 7.117 + vec[1] = xform[7]; 7.118 + vec[2] = xform[11]; 7.119 + return 0; 7.120 +} 7.121 + 7.122 +static int rotation(int eye, float *quat) 7.123 +{ 7.124 + if(!dev) { 7.125 + quat[0] = quat[1] = quat[2] = 0.0f; 7.126 + quat[3] = 1.0f; 7.127 + return -1; 7.128 + } 7.129 + 7.130 + ohmd_device_getf(dev, OHMD_ROTATION_QUAT, quat); 7.131 + return 0; 7.132 +} 7.133 + 7.134 + 7.135 +static void view_matrix(int eye, float *mat) 7.136 +{ 7.137 + ohmd_device_getf(dev, OHMD_LEFT_EYE_GL_MODELVIEW_MATRIX + eye, mat); 7.138 +} 7.139 + 7.140 +static void proj_matrix(int eye, float znear, float zfar, float *mat) 7.141 +{ 7.142 + ohmd_device_setf(dev, OHMD_PROJECTION_ZNEAR, znear); 7.143 + ohmd_device_setf(dev, OHMD_PROJECTION_ZFAR, zfar); 7.144 + ohmd_device_getf(dev, OHMD_LEFT_EYE_GL_PROJECTION_MATRIX + eye, mat); 7.145 +} 7.146 + 7.147 +static void begin(int eye) 7.148 +{ 7.149 + if(new_frame) { 7.150 + ohmd_ctx_update(ctx); 7.151 + new_frame = 0; 7.152 + } 7.153 +} 7.154 + 7.155 +static int present(void) 7.156 +{ 7.157 + new_frame = 1; 7.158 + return 0; 7.159 +} 7.160 + 7.161 +static void set_eye_texture(int eye, unsigned int tex, float umin, float vmin, float umax, float vmax) 7.162 +{ 7.163 + eye_tex[eye].id = tex; 7.164 + eye_tex[eye].umin = umin; 7.165 + eye_tex[eye].umax = umax; 7.166 + eye_tex[eye].vmin = vmin; 7.167 + eye_tex[eye].vmax = vmax; 7.168 +} 7.169 + 7.170 +static void recenter(void) 7.171 +{ 7.172 + /* TODO does OHMD support the magnetometer? */ 7.173 +} 7.174 + 7.175 + 7.176 +struct vr_module *vr_module_openhmd(void) 7.177 +{ 7.178 + static struct vr_module m; 7.179 + 7.180 + if(!m.init) { 7.181 + m.name = "openhmd"; 7.182 + m.init = init; 7.183 + m.cleanup = cleanup; 7.184 + m.set_option = set_option; 7.185 + m.get_option = get_option; 7.186 + m.view_matrix = view_matrix; 7.187 + m.proj_matrix = proj_matrix; 7.188 + m.begin = begin; 7.189 + m.present = present; 7.190 + m.set_eye_texture = set_eye_texture; 7.191 + m.recenter = recenter; 7.192 + } 7.193 +} 7.194 + 7.195 +#else /* don't use OpenHMD */ 7.196 + 7.197 +static int init(void) 7.198 +{ 7.199 + return -1; 7.200 +} 7.201 + 7.202 +struct vr_module *vr_module_openhmd(void) 7.203 +{ 7.204 + static struct vr_module m; 7.205 + 7.206 + if(!m.init) { 7.207 + m.name = "openhmd"; 7.208 + m.init = init; 7.209 + } 7.210 + return &m; 7.211 +} 7.212 + 7.213 +#endif /* USE_OPENHMD */