libgoatvr

annotate src/vr_openhmd.c @ 5:e63cb28fc644

working on the linux side a bit
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 18 Sep 2014 10:56:45 +0300
parents ded3d0a74e19
children 6896f9cf9621
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@0 59
nuclear@0 60 if((optdb = create_options())) {
nuclear@0 61 set_option_int(optdb, VR_OPT_DISPLAY_WIDTH, disp_width);
nuclear@0 62 set_option_int(optdb, VR_OPT_DISPLAY_HEIGHT, disp_height);
nuclear@0 63 set_option_float(optdb, VR_OPT_IPD, ipd);
nuclear@0 64
nuclear@0 65 set_option_int(optdb, VR_OPT_LEYE_XRES, (int)(disp_width / 2.0 * FB_EMBIGGEN));
nuclear@0 66 set_option_int(optdb, VR_OPT_LEYE_YRES, (int)(disp_height * FB_EMBIGGEN));
nuclear@0 67 set_option_int(optdb, VR_OPT_REYE_XRES, (int)(disp_width / 2.0 * FB_EMBIGGEN));
nuclear@0 68 set_option_int(optdb, VR_OPT_REYE_YRES, (int)(disp_height * FB_EMBIGGEN));
nuclear@0 69 }
nuclear@0 70
nuclear@0 71 return 0;
nuclear@0 72 }
nuclear@0 73
nuclear@0 74 static void cleanup(void)
nuclear@0 75 {
nuclear@0 76 if(ctx) {
nuclear@0 77 ohmd_ctx_destroy(ctx);
nuclear@0 78 }
nuclear@0 79 }
nuclear@0 80
nuclear@0 81
nuclear@0 82 static int set_option(const char *opt, enum opt_type type, void *valp)
nuclear@0 83 {
nuclear@0 84 switch(type) {
nuclear@0 85 case OTYPE_INT:
nuclear@0 86 set_option_int(optdb, opt, *(int*)valp);
nuclear@0 87 break;
nuclear@0 88
nuclear@0 89 case OTYPE_FLOAT:
nuclear@0 90 set_option_float(optdb, opt, *(float*)valp);
nuclear@0 91 break;
nuclear@0 92 }
nuclear@0 93 return 0;
nuclear@0 94 }
nuclear@0 95
nuclear@0 96 static int get_option(const char *opt, enum opt_type type, void *valp)
nuclear@0 97 {
nuclear@0 98 switch(type) {
nuclear@0 99 case OTYPE_INT:
nuclear@0 100 return get_option_int(optdb, opt, valp);
nuclear@0 101 case OTYPE_FLOAT:
nuclear@0 102 return get_option_float(optdb, opt, valp);
nuclear@0 103 }
nuclear@0 104 return -1;
nuclear@0 105 }
nuclear@0 106
nuclear@0 107 static int translation(int eye, float *vec)
nuclear@0 108 {
nuclear@0 109 float xform[16];
nuclear@0 110
nuclear@0 111 view_matrix(eye, xform);
nuclear@0 112
nuclear@0 113 vec[0] = xform[3];
nuclear@0 114 vec[1] = xform[7];
nuclear@0 115 vec[2] = xform[11];
nuclear@0 116 return 0;
nuclear@0 117 }
nuclear@0 118
nuclear@0 119 static int rotation(int eye, float *quat)
nuclear@0 120 {
nuclear@0 121 if(!dev) {
nuclear@0 122 quat[0] = quat[1] = quat[2] = 0.0f;
nuclear@0 123 quat[3] = 1.0f;
nuclear@0 124 return -1;
nuclear@0 125 }
nuclear@0 126
nuclear@0 127 ohmd_device_getf(dev, OHMD_ROTATION_QUAT, quat);
nuclear@0 128 return 0;
nuclear@0 129 }
nuclear@0 130
nuclear@0 131
nuclear@0 132 static void view_matrix(int eye, float *mat)
nuclear@0 133 {
nuclear@0 134 ohmd_device_getf(dev, OHMD_LEFT_EYE_GL_MODELVIEW_MATRIX + eye, mat);
nuclear@0 135 }
nuclear@0 136
nuclear@0 137 static void proj_matrix(int eye, float znear, float zfar, float *mat)
nuclear@0 138 {
nuclear@0 139 ohmd_device_setf(dev, OHMD_PROJECTION_ZNEAR, znear);
nuclear@0 140 ohmd_device_setf(dev, OHMD_PROJECTION_ZFAR, zfar);
nuclear@0 141 ohmd_device_getf(dev, OHMD_LEFT_EYE_GL_PROJECTION_MATRIX + eye, mat);
nuclear@0 142 }
nuclear@0 143
nuclear@0 144 static void begin(int eye)
nuclear@0 145 {
nuclear@0 146 if(new_frame) {
nuclear@0 147 ohmd_ctx_update(ctx);
nuclear@0 148 new_frame = 0;
nuclear@0 149 }
nuclear@0 150 }
nuclear@0 151
nuclear@0 152 static int present(void)
nuclear@0 153 {
nuclear@0 154 new_frame = 1;
nuclear@0 155 return 0;
nuclear@0 156 }
nuclear@0 157
nuclear@0 158 static void set_eye_texture(int eye, unsigned int tex, float umin, float vmin, float umax, float vmax)
nuclear@0 159 {
nuclear@0 160 eye_tex[eye].id = tex;
nuclear@0 161 eye_tex[eye].umin = umin;
nuclear@0 162 eye_tex[eye].umax = umax;
nuclear@0 163 eye_tex[eye].vmin = vmin;
nuclear@0 164 eye_tex[eye].vmax = vmax;
nuclear@0 165 }
nuclear@0 166
nuclear@0 167 static void recenter(void)
nuclear@0 168 {
nuclear@0 169 /* TODO does OHMD support the magnetometer? */
nuclear@0 170 }
nuclear@0 171
nuclear@0 172
nuclear@0 173 struct vr_module *vr_module_openhmd(void)
nuclear@0 174 {
nuclear@0 175 static struct vr_module m;
nuclear@0 176
nuclear@0 177 if(!m.init) {
nuclear@0 178 m.name = "openhmd";
nuclear@0 179 m.init = init;
nuclear@0 180 m.cleanup = cleanup;
nuclear@0 181 m.set_option = set_option;
nuclear@0 182 m.get_option = get_option;
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@0 190 }
nuclear@0 191
nuclear@0 192 #else /* don't use OpenHMD */
nuclear@0 193
nuclear@0 194 static int init(void)
nuclear@0 195 {
nuclear@0 196 return -1;
nuclear@0 197 }
nuclear@0 198
nuclear@0 199 struct vr_module *vr_module_openhmd(void)
nuclear@0 200 {
nuclear@0 201 static struct vr_module m;
nuclear@0 202
nuclear@0 203 if(!m.init) {
nuclear@0 204 m.name = "openhmd";
nuclear@0 205 m.init = init;
nuclear@0 206 }
nuclear@0 207 return &m;
nuclear@0 208 }
nuclear@0 209
nuclear@0 210 #endif /* USE_OPENHMD */