conworlds
view src/vr/vr_libovr.c @ 7:bd8202d6d28d
some progress...
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 22 Aug 2014 16:55:16 +0300 |
parents | 3c36bc28c6c2 |
children | 90abf4b93cc9 |
line source
1 #ifdef WIN32
2 #define OVR_OS_WIN32
3 #endif
5 #include "vr_impl.h"
7 #ifdef USE_LIBOVR
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <assert.h>
11 #include "opt.h"
13 #include <OVR_CAPI.h>
14 #include <OVR_CAPI_GL.h>
16 /* just dropping the prototype here to avoid including CAPI_HSWDisplay.h */
17 OVR_EXPORT void ovrhmd_EnableHSWDisplaySDKRender(ovrHmd hmd, ovrBool enabled);
19 static ovrHmd hmd;
20 static void *optdb;
21 static ovrEyeRenderDesc eye_render_desc[2];
22 static ovrSizei eye_res[2];
23 static ovrGLTexture eye_tex[2];
24 static ovrFovPort eye_fov[2];
25 static ovrPosef pose[2];
26 static int deferred_init_done;
28 static int init(void)
29 {
30 int i, num_hmds;
32 if(!ovr_Initialize()) {
33 return -1;
34 }
35 printf("initialized LibOVR %s\n", ovr_GetVersionString());
37 if(!(num_hmds = ovrHmd_Detect())) {
38 ovr_Shutdown();
39 return -1;
40 }
41 printf("%d Oculus HMD(s) found\n", num_hmds);
43 hmd = 0;
44 for(i=0; i<num_hmds; i++) {
45 ovrHmd h;
46 if(!(h = ovrHmd_Create(i))) {
47 break;
48 }
49 printf(" [%d]: %s - %s\n", h->Manufacturer, h->ProductName);
51 if(!hmd) {
52 hmd = h;
53 } else {
54 ovrHmd_Destroy(h);
55 }
56 }
58 if(!hmd) {
59 fprintf(stderr, "failed to initialize any Oculus HMDs\n");
60 return -1;
61 }
63 eye_fov[0] = hmd->DefaultEyeFov[0];
64 eye_fov[1] = hmd->DefaultEyeFov[1];
66 eye_res[0] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left, eye_fov[0], 1.0);
67 eye_res[1] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Right, eye_fov[1], 1.0);
69 /* create the options database */
70 if((optdb = create_options())) {
71 set_option_int(optdb, VR_OPT_DISPLAY_WIDTH, hmd->Resolution.w);
72 set_option_int(optdb, VR_OPT_DISPLAY_HEIGHT, hmd->Resolution.h);
73 set_option_int(optdb, VR_OPT_LEYE_XRES, eye_res[0].w);
74 set_option_int(optdb, VR_OPT_LEYE_YRES, eye_res[0].h);
75 set_option_int(optdb, VR_OPT_REYE_XRES, eye_res[1].w);
76 set_option_int(optdb, VR_OPT_REYE_YRES, eye_res[1].h);
77 set_option_float(optdb, VR_OPT_EYE_HEIGHT, ovrHmd_GetFloat(hmd, OVR_KEY_EYE_HEIGHT, OVR_DEFAULT_EYE_HEIGHT));
78 set_option_float(optdb, VR_OPT_IPD, ovrHmd_GetFloat(hmd, OVR_KEY_IPD, OVR_DEFAULT_IPD));
79 }
81 deferred_init_done = 0;
82 return 0;
83 }
85 static void deferred_init(void)
86 {
87 union ovrGLConfig glcfg;
88 unsigned int dcaps;
90 deferred_init_done = 1;
92 ovrHmd_ConfigureTracking(hmd, 0xffffffff, 0);
94 glcfg.OGL.Header.API = ovrRenderAPI_OpenGL;
95 glcfg.OGL.Header.RTSize = hmd->Resolution;
96 glcfg.OGL.Header.Multisample = 0;
97 #ifdef WIN32
98 glcfg.OGL.Window = GetActiveWindow();
99 glcfg.OGL.DC = wglGetCurrentDC();
100 ovrHmd_AttachToWindow(hmd, glcfg.OGL.Window, 0, 0);
101 assert(glcfg.OGL.Window);
102 #endif
104 dcaps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette | ovrDistortionCap_TimeWarp |
105 ovrDistortionCap_Overdrive | ovrDistortionCap_FlipInput;
107 if(!ovrHmd_ConfigureRendering(hmd, &glcfg.Config, dcaps, eye_fov, eye_render_desc)) {
108 fprintf(stderr, "failed to configure LibOVR distortion renderer\n");
109 }
111 ovrhmd_EnableHSWDisplaySDKRender(hmd, 0);
112 }
114 static void cleanup(void)
115 {
116 if(hmd) {
117 ovrHmd_Destroy(hmd);
118 ovr_Shutdown();
119 }
120 }
122 static int set_option(const char *opt, enum opt_type type, void *valp)
123 {
124 switch(type) {
125 case OTYPE_INT:
126 set_option_int(optdb, opt, *(int*)valp);
127 break;
129 case OTYPE_FLOAT:
130 set_option_float(optdb, opt, *(float*)valp);
131 break;
132 }
133 return 0;
134 }
136 static int get_option(const char *opt, enum opt_type type, void *valp)
137 {
138 switch(type) {
139 case OTYPE_INT:
140 return get_option_int(optdb, opt, valp);
141 case OTYPE_FLOAT:
142 return get_option_float(optdb, opt, valp);
143 }
144 return -1;
145 }
147 static int translation(int eye, float *vec)
148 {
149 if(!hmd) {
150 vec[0] = vec[1] = vec[2] = 0;
151 return -1;
152 }
154 pose[eye] = ovrHmd_GetEyePose(hmd, eye == VR_EYE_LEFT ? ovrEye_Left : ovrEye_Right);
155 vec[0] = pose[eye].Position.x;
156 vec[1] = pose[eye].Position.y;
157 vec[2] = pose[eye].Position.z;
158 return 0;
159 }
161 static int rotation(int eye, float *quat)
162 {
163 if(!hmd) {
164 quat[0] = quat[1] = quat[2] = 0.0f;
165 quat[3] = 1.0f;
166 return -1;
167 }
169 pose[eye] = ovrHmd_GetEyePose(hmd, eye == VR_EYE_LEFT ? ovrEye_Left : ovrEye_Right);
170 quat[0] = pose[eye].Orientation.x;
171 quat[1] = pose[eye].Orientation.y;
172 quat[2] = pose[eye].Orientation.z;
173 quat[3] = pose[eye].Orientation.w;
174 return 0;
175 }
177 static const float idmat[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
179 static void proj_matrix(int eye, float znear, float zfar, float *mat)
180 {
181 ovrMatrix4f vmat;
183 if(!hmd) {
184 memcpy(mat, idmat, sizeof idmat);
185 return;
186 }
188 vmat = ovrMatrix4f_Projection(eye_render_desc[eye].Fov, znear, zfar, 1);
189 memcpy(mat, vmat.M[0], 16 * sizeof(float));
190 }
192 static int new_frame = 1;
194 static void begin(int eye)
195 {
196 if(!hmd) return;
198 if(!deferred_init_done) {
199 deferred_init();
200 }
202 if(new_frame) {
203 ovrHmd_BeginFrame(hmd, 0);
204 new_frame = 0;
205 }
206 }
208 static void present(void)
209 {
210 if(!hmd) return;
212 ovrHmd_EndFrame(hmd, pose, &eye_tex[0].Texture);
213 new_frame = 1;
214 }
216 static void set_eye_texture(int eye, unsigned int tex, float umin, float vmin, float umax, float vmax)
217 {
218 ovrSizei texsz;
219 ovrRecti rect;
221 glBindTexture(GL_TEXTURE_2D, tex);
222 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &texsz.w);
223 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &texsz.h);
225 rect.Pos.x = (int)(umin * texsz.w);
226 rect.Pos.y = (int)(vmin * texsz.h);
227 rect.Size.w = (int)((umax - umin) * texsz.w);
228 rect.Size.h = (int)((vmax - vmin) * texsz.h);
230 eye_tex[eye].OGL.Header.API = ovrRenderAPI_OpenGL;
231 eye_tex[eye].OGL.Header.TextureSize = texsz;
232 eye_tex[eye].OGL.Header.RenderViewport = rect;
233 eye_tex[eye].OGL.TexId = tex;
234 }
236 static void recenter(void)
237 {
238 if(hmd) {
239 ovrHmd_RecenterPose(hmd);
240 }
241 }
243 struct vr_module *vr_module_libovr(void)
244 {
245 static struct vr_module m;
247 if(!m.init) {
248 m.name = "libovr";
249 m.init = init;
250 m.cleanup = cleanup;
251 m.set_option = set_option;
252 m.get_option = get_option;
253 m.translation = translation;
254 m.rotation = rotation;
255 m.proj_matrix = proj_matrix;
256 m.begin = begin;
257 m.present = present;
258 m.set_eye_texture = set_eye_texture;
259 m.recenter = recenter;
260 }
261 return &m;
262 }
264 #else /* no libovr */
266 static int init(void)
267 {
268 return -1;
269 }
271 struct vr_module *vr_module_libovr(void)
272 {
273 static struct vr_module m;
275 if(!m.init) {
276 m.name = "libovr";
277 m.init = init;
278 }
279 return &m;
280 }
282 #endif /* USE_LIBOVR */