oculus1

view src/vr.cc @ 15:402cbb6d9ce3

added the shader as a separate header file
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 21 Sep 2013 04:15:20 +0300
parents cceffea995a4
children f3672317e5c2
line source
1 #include <stdio.h>
2 #include <GL/glew.h>
3 #include "vr.h"
4 #include "vr_impl.h"
5 #include "vr_sdr.h"
7 static bool init_ovr();
8 static bool init_sdr();
10 VRContext vr_ctx;
11 static unsigned int sdrprog;
13 extern "C" int vr_init(enum vr_init_mode mode)
14 {
15 glewInit();
17 if(!init_ovr()) {
18 return -1;
19 }
21 if(!init_sdr()) {
22 return -1;
23 }
25 return 0;
26 }
28 extern "C" void vr_shutdown(void)
29 {
30 delete [] vr_ctx.info.display;
31 //System::Destroy();
32 }
34 static bool init_ovr()
35 {
36 LogMaskConstants log_level = LogMask_All;
37 // initialize Oculus SDK
38 const char *logenv = getenv("VR_LOGLEVEL");
39 if(logenv) {
40 switch(atoi(logenv)) {
41 case 0:
42 log_level = LogMask_None;
43 break;
44 case 1:
45 log_level = LogMask_Regular;
46 break;
47 case 2:
48 default:
49 log_level = LogMask_All;
50 break;
51 }
52 }
54 System::Init(Log::ConfigureDefaultLog(log_level));
55 if(!(vr_ctx.ovr_devman = DeviceManager::Create())) {
56 fprintf(stderr, "failed to create OVR device manager\n");
57 return false;
58 }
60 // create the display device
61 HMDInfo info;
62 if(!(vr_ctx.ovr_hmd_dev = vr_ctx.ovr_devman->EnumerateDevices<HMDDevice>().CreateDevice())) {
63 fprintf(stderr, "no oculus rift devices found\n");
64 } else {
65 if(vr_ctx.ovr_hmd_dev->GetDeviceInfo(&info)) {
66 printf("oculus device info:\n");
67 printf(" name: %s\n", info.DisplayDeviceName);
68 printf(" ipd: %f\n", info.InterpupillaryDistance);
69 printf(" distortion: %f %f %f %f\n", info.DistortionK[0],
70 info.DistortionK[1], info.DistortionK[2], info.DistortionK[3]);
71 }
73 // calculate and store viewing parameters
74 vr_ctx.info.width = info.HResolution;
75 vr_ctx.info.height = info.VResolution;
76 vr_ctx.info.aspect = (float)vr_ctx.info.width / (float)vr_ctx.info.height;
78 vr_ctx.info.ipd = info.InterpupillaryDistance;
79 for(int i=0; i<4; i++) {
80 vr_ctx.info.distort[i] = info.DistortionK[i];
81 }
83 Util::Render::StereoConfig stereohelp;
84 stereohelp.SetFullViewport(Util::Render::Viewport(0, 0, vr_ctx.info.width, vr_ctx.info.height));
85 stereohelp.SetStereoMode(Util::Render::Stereo_LeftRight_Multipass);
86 stereohelp.SetHMDInfo(info);
87 stereohelp.SetDistortionFitPointVP(-1.0, 0.0);
89 vr_ctx.info.scale = stereohelp.GetDistortionScale();
91 float vhalfsz = vr_ctx.info.scale * info.VScreenSize * 0.5;
92 vr_ctx.info.fov = 2.0 * atan(vhalfsz / info.EyeToScreenDistance);
94 vr_ctx.info.lens_center_offset = 0.5 - info.LensSeparationDistance / info.HScreenSize;
96 // calculate center of projection shift to match the lens positions
97 float center_dist_meters = info.HScreenSize * 0.25;
98 float proj_shift = center_dist_meters - info.LensSeparationDistance * 0.5;
99 vr_ctx.info.proj_center_offset = 4.0 * proj_shift / info.HScreenSize;
101 // grab the display name
102 vr_ctx.info.display = new char[strlen(info.DisplayDeviceName) + 1];
103 strcpy(vr_ctx.info.display, info.DisplayDeviceName);
104 }
106 // get the sensor device
107 if(vr_ctx.ovr_hmd_dev) {
108 if(!(vr_ctx.ovr_sensor_dev = vr_ctx.ovr_hmd_dev->GetSensor())) {
109 fprintf(stderr, "failed to get oculus sensor device\n");
110 }
111 } else {
112 if(!(vr_ctx.ovr_sensor_dev = vr_ctx.ovr_devman->EnumerateDevices<SensorDevice>().CreateDevice())) {
113 fprintf(stderr, "failed to get oculus sensor device\n");
114 }
115 }
117 if(vr_ctx.ovr_sensor_dev) {
118 SensorInfo sinfo;
119 if(vr_ctx.ovr_sensor_dev->GetDeviceInfo(&sinfo)) {
120 printf("oculus sensor device info:\n");
121 printf(" name: %s\n", sinfo.ProductName);
122 }
124 vr_ctx.ovr_sfusion.AttachToSensor(vr_ctx.ovr_sensor_dev);
125 }
126 return true;
127 }
129 #define EXTERNAL_SHADER
131 static bool init_sdr()
132 {
133 int status;
135 #ifdef EXTERNAL_SHADER
136 FILE *fp = fopen("sdr.glsl", "rb");
137 if(!fp) {
138 perror("failed to load sdr.glsl");
139 return false;
140 }
141 fseek(fp, 0, SEEK_END);
142 long sz = ftell(fp);
143 rewind(fp);
145 char *buf = (char*)alloca(sz + 1);
146 fread(buf, 1, sz, fp);
147 buf[sz] = 0;
148 sdr_src = buf;
150 fclose(fp);
151 #endif
153 unsigned int sdr = glCreateShader(GL_FRAGMENT_SHADER);
154 glShaderSource(sdr, 1, &sdr_src, 0);
155 glCompileShader(sdr);
156 glGetShaderiv(sdr, GL_COMPILE_STATUS, &status);
157 if(!status) {
158 fprintf(stderr, "failed to compile distortion shader\n");
160 int loglen;
161 glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &loglen);
163 if(loglen > 0) {
164 char *log = (char*)alloca(loglen);
165 glGetShaderInfoLog(sdr, loglen, &loglen, log);
166 fprintf(stderr, "%s\n", log);
167 }
169 return false;
170 }
172 sdrprog = glCreateProgram();
173 glAttachShader(sdrprog, sdr);
174 glLinkProgram(sdrprog);
175 if(!status) {
176 fprintf(stderr, "failed to link distortion shader program\n");
177 glDeleteShader(sdr);
178 return false;
179 }
181 int loc;
183 glUseProgram(sdrprog);
185 if((loc = glGetUniformLocation(sdrprog, "tex")) != -1) {
186 glUniform1i(loc, 0);
187 }
188 if((loc = glGetUniformLocation(sdrprog, "lens_center_offset")) != -1) {
189 glUniform1f(loc, 0);
190 }
191 if((loc = glGetUniformLocation(sdrprog, "scr_center")) != -1) {
192 glUniform2f(loc, 0, 0);
193 }
194 if((loc = glGetUniformLocation(sdrprog, "scale")) != -1) {
195 glUniform1f(loc, vr_ctx.info.scale);
196 }
197 if((loc = glGetUniformLocation(sdrprog, "aspect")) != -1) {
198 printf("setting aspect: %f\n", vr_ctx.info.aspect / 2.0);
199 glUniform1f(loc, vr_ctx.info.aspect / 2.0);
200 }
201 if((loc = glGetUniformLocation(sdrprog, "scale_in")) != -1) {
202 glUniform2f(loc, 1, 1);
203 }
204 if((loc = glGetUniformLocation(sdrprog, "dist_factors")) != -1) {
205 glUniform4f(loc, vr_ctx.info.distort[0], vr_ctx.info.distort[1],
206 vr_ctx.info.distort[2], vr_ctx.info.distort[3]);
207 }
209 return true;
210 }
212 extern "C" int vr_get_width(void)
213 {
214 return vr_ctx.info.width;
215 }
217 extern "C" int vr_get_height(void)
218 {
219 return vr_ctx.info.height;
220 }
222 extern "C" float vr_get_fov(void)
223 {
224 return vr_ctx.info.fov;
225 }
227 extern "C" float vr_get_aspect(void)
228 {
229 return vr_ctx.info.aspect;
230 }
232 extern "C" void vr_set_eyedist(float ipd)
233 {
234 vr_ctx.info.ipd = ipd;
235 }
237 extern "C" float vr_get_eyedist(void)
238 {
239 return vr_ctx.info.ipd;
240 }
242 extern "C" void vr_set_distort(const float *coef)
243 {
244 memcpy(vr_ctx.info.distort, coef, sizeof vr_ctx.info.distort);
245 }
247 extern "C" void vr_get_distort(float *coef)
248 {
249 memcpy(coef, vr_ctx.info.distort, sizeof vr_ctx.info.distort);
250 }
252 extern "C" void vr_set_prediction_sec(float dt)
253 {
254 vr_ctx.ovr_sfusion.SetPrediction(dt);
255 }
257 extern "C" float vr_get_prediction_sec(void)
258 {
259 return vr_ctx.ovr_sfusion.GetPredictionDelta();
260 }
262 extern "C" void vr_get_view_matrix(float *res, int eye)
263 {
264 // TODO
265 }
267 extern "C" void vr_get_proj_matrix(float *res, int eye)
268 {
269 static float eye_scale[] = {0.0, 1.0, -1.0};
271 Matrix4f proj = Matrix4f::PerspectiveRH(vr_ctx.info.fov, vr_ctx.info.aspect / 2.0, 0.3, 1000.0);
272 proj = Matrix4f::Translation(vr_ctx.info.proj_center_offset * eye_scale[eye], 0, 0) * proj;
274 memcpy(res, proj.M[0], 16 * sizeof(float));
275 }
277 extern "C" void vr_get_translation(float *offs)
278 {
279 // current oculus devkit doesn't do translation
280 offs[0] = offs[1] = offs[2] = 0.0f;
281 }
283 extern "C" void vr_get_rotation(float *quat)
284 {
285 Quatf oq = vr_ctx.ovr_sfusion.GetPredictedOrientation();
286 quat[0] = oq.x;
287 quat[1] = oq.y;
288 quat[2] = oq.z;
289 quat[3] = oq.w;
290 }
292 extern "C" void vr_get_rotation_euler(float *euler)
293 {
294 Quatf oq = vr_ctx.ovr_sfusion.GetPredictedOrientation();
295 oq.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(euler + 1, euler, euler + 2);
296 }
298 extern "C" void vr_draw_eye(unsigned int tex, int eye)
299 {
300 static const float rects[3][4] = {
301 {-1, -1, 1, 1},
302 {-1, -1, 0, 1},
303 {0, -1, 1, 1}
304 };
305 static const float offs_scale[3] = {0.0, -1.0, 1.0};
307 glPushAttrib(GL_ENABLE_BIT);
308 glDisable(GL_DEPTH_TEST);
309 glDisable(GL_LIGHTING);
310 glEnable(GL_TEXTURE_2D);
312 glMatrixMode(GL_MODELVIEW);
313 glPushMatrix();
314 glLoadIdentity();
316 glMatrixMode(GL_PROJECTION);
317 glPushMatrix();
318 glLoadIdentity();
320 glUseProgram(sdrprog);
322 if(sdrprog) {
323 int loc;
324 if((loc = glGetUniformLocation(sdrprog, "lens_center_offset")) != -1) {
325 float offset = vr_ctx.info.lens_center_offset * offs_scale[eye];
326 glUniform1f(loc, offset);
327 }
328 }
330 glBindTexture(GL_TEXTURE_2D, tex);
331 glBegin(GL_QUADS);
332 glColor4f(1, 1, 1, 1);
333 glTexCoord2f(0, 0); glVertex2f(rects[eye][0], rects[eye][1]);
334 glTexCoord2f(1, 0); glVertex2f(rects[eye][2], rects[eye][1]);
335 glTexCoord2f(1, 1); glVertex2f(rects[eye][2], rects[eye][3]);
336 glTexCoord2f(0, 1); glVertex2f(rects[eye][0], rects[eye][3]);
337 glEnd();
339 glUseProgram(0);
341 glPopMatrix();
342 glMatrixMode(GL_MODELVIEW);
343 glPopMatrix();
345 glPopAttrib();
346 }