libgoatvr

annotate src/vr_openhmd.c @ 7:6896f9cf9621

- configure now emits config.status with the current confure invocation - now vr_init will heed the VR_MODULE env var for the name of the module to use - more stuff on the openhmd module
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 19 Sep 2014 15:16:51 +0300
parents d861e4d6850f
children 3d9ec6fe97d7
rev   line source
nuclear@0 1 #include "vr_impl.h"
nuclear@0 2
nuclear@0 3 #ifdef USE_OPENHMD
nuclear@0 4 #include <stdio.h>
nuclear@0 5 #include <stdlib.h>
nuclear@0 6 #include <openhmd/openhmd.h>
nuclear@0 7 #include "opt.h"
nuclear@0 8
nuclear@0 9 /* a noble spirit embiggens the framebuffer to avoid aliasing in the middle */
nuclear@1 10 #define FB_EMBIGGEN 1.5
nuclear@0 11
nuclear@0 12 static ohmd_context *ctx;
nuclear@0 13 static ohmd_device *dev;
nuclear@0 14 static void *optdb;
nuclear@0 15 static int new_frame = 1;
nuclear@0 16
nuclear@0 17 static int disp_width, disp_height;
nuclear@0 18 static float ipd;
nuclear@0 19
nuclear@0 20 static struct {
nuclear@0 21 unsigned int id;
nuclear@0 22 float umin, umax;
nuclear@0 23 float vmin, vmax;
nuclear@0 24 } eye_tex[2];
nuclear@0 25
nuclear@0 26
nuclear@0 27 static int init(void)
nuclear@0 28 {
nuclear@0 29 int i, num_hmds;
nuclear@0 30
nuclear@0 31 if(!(ctx = ohmd_ctx_create())) {
nuclear@0 32 fprintf(stderr, "failed to create OpenHMD context\n");
nuclear@0 33 ohmd_ctx_destroy(ctx);
nuclear@0 34 return -1;
nuclear@0 35 }
nuclear@0 36 if(!(num_hmds = ohmd_ctx_probe(ctx))) {
nuclear@0 37 fprintf(stderr, "no HMDs detected\n");
nuclear@0 38 return -1;
nuclear@0 39 }
nuclear@0 40
nuclear@0 41 for(i=0; i<num_hmds; i++) {
nuclear@0 42 const char *vendor = ohmd_list_gets(ctx, i, OHMD_VENDOR);
nuclear@0 43 const char *product = ohmd_list_gets(ctx, i, OHMD_PRODUCT);
nuclear@0 44 const char *devpath = ohmd_list_gets(ctx, i, OHMD_PATH);
nuclear@0 45
nuclear@0 46 printf("[%d] %s - %s (path: %s)\n", i, vendor, product, devpath);
nuclear@0 47 }
nuclear@0 48
nuclear@0 49 printf("opening device 0\n");
nuclear@0 50
nuclear@0 51 if(!(dev = ohmd_list_open_device(ctx, 0))) {
nuclear@0 52 fprintf(stderr, "failed to open device 0: %s\n", ohmd_ctx_get_error(ctx));
nuclear@0 53 return -1;
nuclear@0 54 }
nuclear@0 55
nuclear@0 56 ohmd_device_geti(dev, OHMD_SCREEN_HORIZONTAL_SIZE, &disp_width);
nuclear@0 57 ohmd_device_geti(dev, OHMD_SCREEN_VERTICAL_SIZE, &disp_height);
nuclear@0 58 ohmd_device_getf(dev, OHMD_EYE_IPD, &ipd);
nuclear@7 59 ipd /= 100.0f; /* convert ipd to meters */
nuclear@0 60
nuclear@0 61 if((optdb = create_options())) {
nuclear@0 62 set_option_int(optdb, VR_OPT_DISPLAY_WIDTH, disp_width);
nuclear@0 63 set_option_int(optdb, VR_OPT_DISPLAY_HEIGHT, disp_height);
nuclear@0 64 set_option_float(optdb, VR_OPT_IPD, ipd);
nuclear@0 65
nuclear@0 66 set_option_int(optdb, VR_OPT_LEYE_XRES, (int)(disp_width / 2.0 * FB_EMBIGGEN));
nuclear@0 67 set_option_int(optdb, VR_OPT_LEYE_YRES, (int)(disp_height * FB_EMBIGGEN));
nuclear@0 68 set_option_int(optdb, VR_OPT_REYE_XRES, (int)(disp_width / 2.0 * FB_EMBIGGEN));
nuclear@0 69 set_option_int(optdb, VR_OPT_REYE_YRES, (int)(disp_height * FB_EMBIGGEN));
nuclear@0 70 }
nuclear@0 71
nuclear@0 72 return 0;
nuclear@0 73 }
nuclear@0 74
nuclear@0 75 static void cleanup(void)
nuclear@0 76 {
nuclear@0 77 if(ctx) {
nuclear@0 78 ohmd_ctx_destroy(ctx);
nuclear@0 79 }
nuclear@0 80 }
nuclear@0 81
nuclear@0 82
nuclear@0 83 static int set_option(const char *opt, enum opt_type type, void *valp)
nuclear@0 84 {
nuclear@0 85 switch(type) {
nuclear@0 86 case OTYPE_INT:
nuclear@0 87 set_option_int(optdb, opt, *(int*)valp);
nuclear@0 88 break;
nuclear@0 89
nuclear@0 90 case OTYPE_FLOAT:
nuclear@0 91 set_option_float(optdb, opt, *(float*)valp);
nuclear@0 92 break;
nuclear@0 93 }
nuclear@0 94 return 0;
nuclear@0 95 }
nuclear@0 96
nuclear@0 97 static int get_option(const char *opt, enum opt_type type, void *valp)
nuclear@0 98 {
nuclear@0 99 switch(type) {
nuclear@0 100 case OTYPE_INT:
nuclear@0 101 return get_option_int(optdb, opt, valp);
nuclear@0 102 case OTYPE_FLOAT:
nuclear@0 103 return get_option_float(optdb, opt, valp);
nuclear@0 104 }
nuclear@0 105 return -1;
nuclear@0 106 }
nuclear@0 107
nuclear@7 108 static void translation(int eye, float *vec)
nuclear@0 109 {
nuclear@7 110 /* OpenHMD doesn't support positional tracking, so just return the eye offset */
nuclear@0 111
nuclear@7 112 vec[0] = (eye == VR_EYE_LEFT ? -ipd : ipd) / 2.0;
nuclear@7 113 vec[1] = vec[2] = 0.0f;
nuclear@0 114 }
nuclear@0 115
nuclear@7 116 static void rotation(int eye, float *quat)
nuclear@0 117 {
nuclear@0 118 if(!dev) {
nuclear@0 119 quat[0] = quat[1] = quat[2] = 0.0f;
nuclear@0 120 quat[3] = 1.0f;
nuclear@7 121 return;
nuclear@0 122 }
nuclear@0 123
nuclear@0 124 ohmd_device_getf(dev, OHMD_ROTATION_QUAT, quat);
nuclear@0 125 }
nuclear@0 126
nuclear@0 127
nuclear@0 128 static void view_matrix(int eye, float *mat)
nuclear@0 129 {
nuclear@0 130 ohmd_device_getf(dev, OHMD_LEFT_EYE_GL_MODELVIEW_MATRIX + eye, mat);
nuclear@0 131 }
nuclear@0 132
nuclear@0 133 static void proj_matrix(int eye, float znear, float zfar, float *mat)
nuclear@0 134 {
nuclear@7 135 ohmd_device_setf(dev, OHMD_PROJECTION_ZNEAR, &znear);
nuclear@7 136 ohmd_device_setf(dev, OHMD_PROJECTION_ZFAR, &zfar);
nuclear@0 137 ohmd_device_getf(dev, OHMD_LEFT_EYE_GL_PROJECTION_MATRIX + eye, mat);
nuclear@0 138 }
nuclear@0 139
nuclear@0 140 static void begin(int eye)
nuclear@0 141 {
nuclear@0 142 if(new_frame) {
nuclear@0 143 ohmd_ctx_update(ctx);
nuclear@0 144 new_frame = 0;
nuclear@0 145 }
nuclear@0 146 }
nuclear@0 147
nuclear@0 148 static int present(void)
nuclear@0 149 {
nuclear@0 150 new_frame = 1;
nuclear@0 151 return 0;
nuclear@0 152 }
nuclear@0 153
nuclear@0 154 static void set_eye_texture(int eye, unsigned int tex, float umin, float vmin, float umax, float vmax)
nuclear@0 155 {
nuclear@0 156 eye_tex[eye].id = tex;
nuclear@0 157 eye_tex[eye].umin = umin;
nuclear@0 158 eye_tex[eye].umax = umax;
nuclear@0 159 eye_tex[eye].vmin = vmin;
nuclear@0 160 eye_tex[eye].vmax = vmax;
nuclear@0 161 }
nuclear@0 162
nuclear@0 163 static void recenter(void)
nuclear@0 164 {
nuclear@7 165 /* TODO grab the current rotation quat, invert it, and use it to
nuclear@7 166 * multiply with the rotation quat query results
nuclear@7 167 */
nuclear@0 168 }
nuclear@0 169
nuclear@0 170
nuclear@0 171 struct vr_module *vr_module_openhmd(void)
nuclear@0 172 {
nuclear@0 173 static struct vr_module m;
nuclear@0 174
nuclear@0 175 if(!m.init) {
nuclear@0 176 m.name = "openhmd";
nuclear@0 177 m.init = init;
nuclear@0 178 m.cleanup = cleanup;
nuclear@0 179 m.set_option = set_option;
nuclear@0 180 m.get_option = get_option;
nuclear@7 181 m.translation = translation;
nuclear@7 182 m.rotation = rotation;
nuclear@0 183 m.view_matrix = view_matrix;
nuclear@0 184 m.proj_matrix = proj_matrix;
nuclear@0 185 m.begin = begin;
nuclear@0 186 m.present = present;
nuclear@0 187 m.set_eye_texture = set_eye_texture;
nuclear@0 188 m.recenter = recenter;
nuclear@0 189 }
nuclear@7 190 return &m;
nuclear@0 191 }
nuclear@0 192
nuclear@0 193 #else /* don't use OpenHMD */
nuclear@0 194
nuclear@0 195 static int init(void)
nuclear@0 196 {
nuclear@0 197 return -1;
nuclear@0 198 }
nuclear@0 199
nuclear@0 200 struct vr_module *vr_module_openhmd(void)
nuclear@0 201 {
nuclear@0 202 static struct vr_module m;
nuclear@0 203
nuclear@0 204 if(!m.init) {
nuclear@0 205 m.name = "openhmd";
nuclear@0 206 m.init = init;
nuclear@0 207 }
nuclear@0 208 return &m;
nuclear@0 209 }
nuclear@0 210
nuclear@0 211 #endif /* USE_OPENHMD */