oculus1

annotate src/vr.cc @ 12:d797639e0234

moving on to the distortion... not correct yet
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 20 Sep 2013 10:14:29 +0300
parents 3265970a7315
children 464e1d135d68
rev   line source
nuclear@1 1 #include <stdio.h>
nuclear@12 2 #include <GL/glew.h>
nuclear@1 3 #include "vr.h"
nuclear@1 4 #include "vr_impl.h"
nuclear@1 5
nuclear@12 6 static const char *sdr_src =
nuclear@12 7 "uniform sampler2D tex;\n"
nuclear@12 8 "uniform vec2 lens_center;\n"
nuclear@12 9 "uniform vec2 scr_center;\n"
nuclear@12 10 "uniform vec2 scale;\n"
nuclear@12 11 "uniform vec2 scale_in;\n"
nuclear@12 12 "uniform vec4 warp_param;\n"
nuclear@12 13 "\n"
nuclear@12 14 "vec2 warp(in vec2 pt)\n"
nuclear@12 15 "{\n"
nuclear@12 16 " vec2 theta = (pt - lens_center) * scale_in;\n"
nuclear@12 17 " float rsq = length(theta);\n"
nuclear@12 18 " vec2 rvec = theta * (warp_param.x + warp_param.y * rsq +\n"
nuclear@12 19 " warp_param.z * rsq * rsq +\n"
nuclear@12 20 " warp_param.w * rsq * rsq * rsq);\n"
nuclear@12 21 " return lens_center + scale * rvec;\n"
nuclear@12 22 "}\n"
nuclear@12 23 "\n"
nuclear@12 24 "void main()\n"
nuclear@12 25 "{\n"
nuclear@12 26 " vec2 tc = warp(gl_TexCoord[0].xy);\n"
nuclear@12 27 " gl_FragColor.rgb = texture2D(tex, tc).rgb;\n"
nuclear@12 28 " gl_FragColor.a = 1.0;\n"
nuclear@12 29 "}\n";
nuclear@12 30
nuclear@1 31 static bool init_ovr();
nuclear@12 32 static bool init_sdr();
nuclear@1 33
nuclear@3 34 VRContext vr_ctx;
nuclear@12 35 static unsigned int sdrprog;
nuclear@1 36
nuclear@1 37 extern "C" int vr_init(enum vr_init_mode mode)
nuclear@1 38 {
nuclear@12 39 glewInit();
nuclear@12 40
nuclear@1 41 if(!init_ovr()) {
nuclear@1 42 return -1;
nuclear@1 43 }
nuclear@12 44
nuclear@12 45 if(!init_sdr()) {
nuclear@12 46 return -1;
nuclear@12 47 }
nuclear@12 48
nuclear@1 49 return 0;
nuclear@1 50 }
nuclear@1 51
nuclear@1 52 extern "C" void vr_shutdown(void)
nuclear@1 53 {
nuclear@3 54 //System::Destroy();
nuclear@1 55 }
nuclear@1 56
nuclear@1 57 static bool init_ovr()
nuclear@1 58 {
nuclear@8 59 LogMaskConstants log_level = LogMask_All;
nuclear@1 60 // initialize Oculus SDK
nuclear@5 61 const char *logenv = getenv("VR_LOGLEVEL");
nuclear@5 62 if(logenv) {
nuclear@5 63 switch(atoi(logenv)) {
nuclear@5 64 case 0:
nuclear@5 65 log_level = LogMask_None;
nuclear@5 66 break;
nuclear@5 67 case 1:
nuclear@5 68 log_level = LogMask_Regular;
nuclear@5 69 break;
nuclear@5 70 case 2:
nuclear@5 71 default:
nuclear@5 72 log_level = LogMask_All;
nuclear@5 73 break;
nuclear@5 74 }
nuclear@5 75 }
nuclear@5 76
nuclear@5 77 System::Init(Log::ConfigureDefaultLog(log_level));
nuclear@3 78 if(!(vr_ctx.ovr_devman = DeviceManager::Create())) {
nuclear@1 79 fprintf(stderr, "failed to create OVR device manager\n");
nuclear@1 80 return false;
nuclear@1 81 }
nuclear@1 82
nuclear@1 83 // create the display device
nuclear@4 84 HMDInfo info;
nuclear@3 85 if(!(vr_ctx.ovr_hmd_dev = vr_ctx.ovr_devman->EnumerateDevices<HMDDevice>().CreateDevice())) {
nuclear@1 86 fprintf(stderr, "no oculus rift devices found\n");
nuclear@4 87 } else {
nuclear@4 88 if(vr_ctx.ovr_hmd_dev->GetDeviceInfo(&info)) {
nuclear@4 89 printf("oculus device info:\n");
nuclear@4 90 printf(" name: %s\n", info.DisplayDeviceName);
nuclear@4 91 printf(" ipd: %f\n", info.InterpupillaryDistance);
nuclear@4 92 printf(" distortion: %f %f %f %f\n", info.DistortionK[0],
nuclear@4 93 info.DistortionK[1], info.DistortionK[2], info.DistortionK[3]);
nuclear@4 94 }
nuclear@1 95
nuclear@4 96 // calculate and store viewing parameters
nuclear@4 97 float vhalfsz = info.VScreenSize * 0.5;
nuclear@4 98 vr_ctx.info.fov = 2.0 * atan(vhalfsz / info.EyeToScreenDistance);
nuclear@4 99
nuclear@4 100 vr_ctx.info.width = info.HResolution;
nuclear@4 101 vr_ctx.info.height = info.VResolution;
nuclear@4 102 vr_ctx.info.aspect = (float)vr_ctx.info.width / (float)vr_ctx.info.height;
nuclear@4 103
nuclear@4 104 vr_ctx.info.ipd = info.InterpupillaryDistance;
nuclear@4 105 for(int i=0; i<4; i++) {
nuclear@4 106 vr_ctx.info.distort[i] = info.DistortionK[i];
nuclear@4 107 }
nuclear@12 108
nuclear@12 109 vr_ctx.info.lens_center = info.LensSeparationDistance / info.HScreenSize;
nuclear@1 110 }
nuclear@1 111
nuclear@1 112 // get the sensor device
nuclear@4 113 if(vr_ctx.ovr_hmd_dev) {
nuclear@4 114 if(!(vr_ctx.ovr_sensor_dev = vr_ctx.ovr_hmd_dev->GetSensor())) {
nuclear@4 115 fprintf(stderr, "failed to get oculus sensor device\n");
nuclear@4 116 }
nuclear@4 117 } else {
nuclear@4 118 if(!(vr_ctx.ovr_sensor_dev = vr_ctx.ovr_devman->EnumerateDevices<SensorDevice>().CreateDevice())) {
nuclear@4 119 fprintf(stderr, "failed to get oculus sensor device\n");
nuclear@4 120 }
nuclear@1 121 }
nuclear@1 122
nuclear@4 123 if(vr_ctx.ovr_sensor_dev) {
nuclear@4 124 SensorInfo sinfo;
nuclear@4 125 if(vr_ctx.ovr_sensor_dev->GetDeviceInfo(&sinfo)) {
nuclear@4 126 printf("oculus sensor device info:\n");
nuclear@4 127 printf(" name: %s\n", sinfo.ProductName);
nuclear@4 128 }
nuclear@4 129
nuclear@4 130 vr_ctx.ovr_sfusion.AttachToSensor(vr_ctx.ovr_sensor_dev);
nuclear@1 131 }
nuclear@1 132 return true;
nuclear@1 133 }
nuclear@3 134
nuclear@12 135 static bool init_sdr()
nuclear@12 136 {
nuclear@12 137 int status;
nuclear@12 138
nuclear@12 139 unsigned int sdr = glCreateShader(GL_FRAGMENT_SHADER);
nuclear@12 140 glShaderSource(sdr, 1, &sdr_src, 0);
nuclear@12 141 glCompileShader(sdr);
nuclear@12 142 glGetShaderiv(sdr, GL_COMPILE_STATUS, &status);
nuclear@12 143 if(!status) {
nuclear@12 144 fprintf(stderr, "failed to compile distortion shader\n");
nuclear@12 145 return false;
nuclear@12 146 }
nuclear@12 147
nuclear@12 148 sdrprog = glCreateProgram();
nuclear@12 149 glAttachShader(sdrprog, sdr);
nuclear@12 150 glLinkProgram(sdrprog);
nuclear@12 151 if(!status) {
nuclear@12 152 fprintf(stderr, "failed to link distortion shader program\n");
nuclear@12 153 glDeleteShader(sdr);
nuclear@12 154 return false;
nuclear@12 155 }
nuclear@12 156
nuclear@12 157 int loc;
nuclear@12 158
nuclear@12 159 glUseProgram(sdrprog);
nuclear@12 160
nuclear@12 161 if((loc = glGetUniformLocation(sdrprog, "tex")) != -1) {
nuclear@12 162 glUniform1i(loc, 0);
nuclear@12 163 }
nuclear@12 164 if((loc = glGetUniformLocation(sdrprog, "lens_center")) != -1) {
nuclear@12 165 glUniform2f(loc, 0.5, 0.5);
nuclear@12 166 }
nuclear@12 167 if((loc = glGetUniformLocation(sdrprog, "scr_center")) != -1) {
nuclear@12 168 glUniform2f(loc, 0, 0);
nuclear@12 169 }
nuclear@12 170 if((loc = glGetUniformLocation(sdrprog, "scale")) != -1) {
nuclear@12 171 glUniform2f(loc, 1, 1);
nuclear@12 172 }
nuclear@12 173 if((loc = glGetUniformLocation(sdrprog, "scale_in")) != -1) {
nuclear@12 174 glUniform2f(loc, 1, 1);
nuclear@12 175 }
nuclear@12 176 if((loc = glGetUniformLocation(sdrprog, "warp_param")) != -1) {
nuclear@12 177 glUniform4f(loc, vr_ctx.info.distort[0], vr_ctx.info.distort[1],
nuclear@12 178 vr_ctx.info.distort[2], vr_ctx.info.distort[3]);
nuclear@12 179 }
nuclear@12 180
nuclear@12 181 return true;
nuclear@12 182 }
nuclear@12 183
nuclear@3 184 extern "C" int vr_get_width(void)
nuclear@3 185 {
nuclear@3 186 return vr_ctx.info.width;
nuclear@3 187 }
nuclear@3 188
nuclear@3 189 extern "C" int vr_get_height(void)
nuclear@3 190 {
nuclear@3 191 return vr_ctx.info.height;
nuclear@3 192 }
nuclear@3 193
nuclear@3 194 extern "C" float vr_get_fov(void)
nuclear@3 195 {
nuclear@3 196 return vr_ctx.info.fov;
nuclear@3 197 }
nuclear@3 198
nuclear@3 199 extern "C" float vr_get_aspect(void)
nuclear@3 200 {
nuclear@3 201 return vr_ctx.info.aspect;
nuclear@3 202 }
nuclear@3 203
nuclear@3 204 extern "C" void vr_set_eyedist(float ipd)
nuclear@3 205 {
nuclear@3 206 vr_ctx.info.ipd = ipd;
nuclear@3 207 }
nuclear@3 208
nuclear@3 209 extern "C" float vr_get_eyedist(void)
nuclear@3 210 {
nuclear@3 211 return vr_ctx.info.ipd;
nuclear@3 212 }
nuclear@3 213
nuclear@3 214 extern "C" void vr_set_distort(const float *coef)
nuclear@3 215 {
nuclear@3 216 memcpy(vr_ctx.info.distort, coef, sizeof vr_ctx.info.distort);
nuclear@3 217 }
nuclear@3 218
nuclear@3 219 extern "C" void vr_get_distort(float *coef)
nuclear@3 220 {
nuclear@3 221 memcpy(coef, vr_ctx.info.distort, sizeof vr_ctx.info.distort);
nuclear@3 222 }
nuclear@3 223
nuclear@3 224 extern "C" void vr_set_prediction_sec(float dt)
nuclear@3 225 {
nuclear@3 226 vr_ctx.ovr_sfusion.SetPrediction(dt);
nuclear@3 227 }
nuclear@3 228
nuclear@3 229 extern "C" float vr_get_prediction_sec(void)
nuclear@3 230 {
nuclear@3 231 return vr_ctx.ovr_sfusion.GetPredictionDelta();
nuclear@3 232 }
nuclear@3 233
nuclear@3 234 extern "C" void vr_get_translation(float *offs)
nuclear@3 235 {
nuclear@3 236 // current oculus devkit doesn't do translation
nuclear@3 237 offs[0] = offs[1] = offs[2] = 0.0f;
nuclear@3 238 }
nuclear@3 239
nuclear@3 240 extern "C" void vr_get_rotation(float *quat)
nuclear@3 241 {
nuclear@3 242 Quatf oq = vr_ctx.ovr_sfusion.GetPredictedOrientation();
nuclear@3 243 quat[0] = oq.x;
nuclear@3 244 quat[1] = oq.y;
nuclear@3 245 quat[2] = oq.z;
nuclear@3 246 quat[3] = oq.w;
nuclear@3 247 }
nuclear@3 248
nuclear@3 249 extern "C" void vr_get_rotation_euler(float *euler)
nuclear@3 250 {
nuclear@3 251 Quatf oq = vr_ctx.ovr_sfusion.GetPredictedOrientation();
nuclear@3 252 oq.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(euler + 1, euler, euler + 2);
nuclear@3 253 }
nuclear@12 254
nuclear@12 255 extern "C" void vr_draw_eye(unsigned int tex, int eye)
nuclear@12 256 {
nuclear@12 257 static const float rects[3][4] = {
nuclear@12 258 {-1, -1, 1, 1},
nuclear@12 259 {-1, -1, 0, 1},
nuclear@12 260 {0, -1, 1, 1}
nuclear@12 261 };
nuclear@12 262 static const float offs_scale[3] = {0.0, -1.0, 1.0};
nuclear@12 263
nuclear@12 264 glPushAttrib(GL_ENABLE_BIT);
nuclear@12 265 glDisable(GL_DEPTH_TEST);
nuclear@12 266 glDisable(GL_LIGHTING);
nuclear@12 267 glEnable(GL_TEXTURE_2D);
nuclear@12 268
nuclear@12 269 glMatrixMode(GL_MODELVIEW);
nuclear@12 270 glPushMatrix();
nuclear@12 271 glLoadIdentity();
nuclear@12 272
nuclear@12 273 glMatrixMode(GL_PROJECTION);
nuclear@12 274 glPushMatrix();
nuclear@12 275 glLoadIdentity();
nuclear@12 276
nuclear@12 277 glUseProgram(sdrprog);
nuclear@12 278
nuclear@12 279 int loc;
nuclear@12 280 if((loc = glGetUniformLocation(sdrprog, "lens_center")) != -1) {
nuclear@12 281 float lens_center = 0.5 - vr_ctx.info.lens_center * offs_scale[eye];
nuclear@12 282 glUniform2f(loc, lens_center, 0.5);
nuclear@12 283 printf("lens_center = %f\n", lens_center);
nuclear@12 284 }
nuclear@12 285
nuclear@12 286 glBindTexture(GL_TEXTURE_2D, tex);
nuclear@12 287 glBegin(GL_QUADS);
nuclear@12 288 glColor4f(1, 1, 1, 1);
nuclear@12 289 glTexCoord2f(0, 0); glVertex2f(rects[eye][0], rects[eye][1]);
nuclear@12 290 glTexCoord2f(1, 0); glVertex2f(rects[eye][2], rects[eye][1]);
nuclear@12 291 glTexCoord2f(1, 1); glVertex2f(rects[eye][2], rects[eye][3]);
nuclear@12 292 glTexCoord2f(0, 1); glVertex2f(rects[eye][0], rects[eye][3]);
nuclear@12 293 glEnd();
nuclear@12 294
nuclear@12 295 glUseProgram(0);
nuclear@12 296
nuclear@12 297 glPopMatrix();
nuclear@12 298 glMatrixMode(GL_MODELVIEW);
nuclear@12 299 glPopMatrix();
nuclear@12 300
nuclear@12 301 glPopAttrib();
nuclear@12 302 }