conworlds

annotate src/vr/vr_openhmd.c @ 10:e3f0ca1d008a

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