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 */