conworlds
diff 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 diff
1.1 --- a/src/vr/vr_libovr.c Thu Aug 21 01:08:03 2014 +0300 1.2 +++ b/src/vr/vr_libovr.c Fri Aug 22 16:55:16 2014 +0300 1.3 @@ -2,20 +2,32 @@ 1.4 #define OVR_OS_WIN32 1.5 #endif 1.6 1.7 -#include <stdio.h> 1.8 -#include <stdlib.h> 1.9 #include "vr_impl.h" 1.10 1.11 #ifdef USE_LIBOVR 1.12 +#include <stdio.h> 1.13 +#include <stdlib.h> 1.14 +#include <assert.h> 1.15 +#include "opt.h" 1.16 + 1.17 #include <OVR_CAPI.h> 1.18 #include <OVR_CAPI_GL.h> 1.19 1.20 +/* just dropping the prototype here to avoid including CAPI_HSWDisplay.h */ 1.21 +OVR_EXPORT void ovrhmd_EnableHSWDisplaySDKRender(ovrHmd hmd, ovrBool enabled); 1.22 + 1.23 static ovrHmd hmd; 1.24 +static void *optdb; 1.25 +static ovrEyeRenderDesc eye_render_desc[2]; 1.26 +static ovrSizei eye_res[2]; 1.27 +static ovrGLTexture eye_tex[2]; 1.28 +static ovrFovPort eye_fov[2]; 1.29 +static ovrPosef pose[2]; 1.30 +static int deferred_init_done; 1.31 1.32 static int init(void) 1.33 { 1.34 int i, num_hmds; 1.35 - union ovrGLConfig glcfg; 1.36 1.37 if(!ovr_Initialize()) { 1.38 return -1; 1.39 @@ -48,48 +60,185 @@ 1.40 return -1; 1.41 } 1.42 1.43 + eye_fov[0] = hmd->DefaultEyeFov[0]; 1.44 + eye_fov[1] = hmd->DefaultEyeFov[1]; 1.45 + 1.46 + eye_res[0] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left, eye_fov[0], 1.0); 1.47 + eye_res[1] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Right, eye_fov[1], 1.0); 1.48 + 1.49 + /* create the options database */ 1.50 + if((optdb = create_options())) { 1.51 + set_option_int(optdb, VR_OPT_DISPLAY_WIDTH, hmd->Resolution.w); 1.52 + set_option_int(optdb, VR_OPT_DISPLAY_HEIGHT, hmd->Resolution.h); 1.53 + set_option_int(optdb, VR_OPT_LEYE_XRES, eye_res[0].w); 1.54 + set_option_int(optdb, VR_OPT_LEYE_YRES, eye_res[0].h); 1.55 + set_option_int(optdb, VR_OPT_REYE_XRES, eye_res[1].w); 1.56 + set_option_int(optdb, VR_OPT_REYE_YRES, eye_res[1].h); 1.57 + set_option_float(optdb, VR_OPT_EYE_HEIGHT, ovrHmd_GetFloat(hmd, OVR_KEY_EYE_HEIGHT, OVR_DEFAULT_EYE_HEIGHT)); 1.58 + set_option_float(optdb, VR_OPT_IPD, ovrHmd_GetFloat(hmd, OVR_KEY_IPD, OVR_DEFAULT_IPD)); 1.59 + } 1.60 + 1.61 + deferred_init_done = 0; 1.62 + return 0; 1.63 +} 1.64 + 1.65 +static void deferred_init(void) 1.66 +{ 1.67 + union ovrGLConfig glcfg; 1.68 + unsigned int dcaps; 1.69 + 1.70 + deferred_init_done = 1; 1.71 + 1.72 ovrHmd_ConfigureTracking(hmd, 0xffffffff, 0); 1.73 1.74 glcfg.OGL.Header.API = ovrRenderAPI_OpenGL; 1.75 glcfg.OGL.Header.RTSize = hmd->Resolution; 1.76 glcfg.OGL.Header.Multisample = 0; 1.77 - glcfg.OGL.Window = 0; 1.78 - glcfg.OGL.DC = 0; 1.79 +#ifdef WIN32 1.80 + glcfg.OGL.Window = GetActiveWindow(); 1.81 + glcfg.OGL.DC = wglGetCurrentDC(); 1.82 + ovrHmd_AttachToWindow(hmd, glcfg.OGL.Window, 0, 0); 1.83 + assert(glcfg.OGL.Window); 1.84 +#endif 1.85 1.86 - if(!ovrHmd_ConfigureRendering(hmd, &glcfg.Config, distort_caps, eyes_fov, eye_rend_desc))) { 1.87 + dcaps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette | ovrDistortionCap_TimeWarp | 1.88 + ovrDistortionCap_Overdrive | ovrDistortionCap_FlipInput; 1.89 + 1.90 + if(!ovrHmd_ConfigureRendering(hmd, &glcfg.Config, dcaps, eye_fov, eye_render_desc)) { 1.91 fprintf(stderr, "failed to configure LibOVR distortion renderer\n"); 1.92 - return -1; 1.93 } 1.94 + 1.95 + ovrhmd_EnableHSWDisplaySDKRender(hmd, 0); 1.96 } 1.97 1.98 static void cleanup(void) 1.99 { 1.100 if(hmd) { 1.101 ovrHmd_Destroy(hmd); 1.102 - ovr_Destroy(); 1.103 + ovr_Shutdown(); 1.104 } 1.105 } 1.106 1.107 -static void view_matrix(int eye, float *mat) 1.108 +static int set_option(const char *opt, enum opt_type type, void *valp) 1.109 { 1.110 + switch(type) { 1.111 + case OTYPE_INT: 1.112 + set_option_int(optdb, opt, *(int*)valp); 1.113 + break; 1.114 + 1.115 + case OTYPE_FLOAT: 1.116 + set_option_float(optdb, opt, *(float*)valp); 1.117 + break; 1.118 + } 1.119 + return 0; 1.120 } 1.121 1.122 -static void proj_matrix(int eye, float *mat) 1.123 +static int get_option(const char *opt, enum opt_type type, void *valp) 1.124 { 1.125 + switch(type) { 1.126 + case OTYPE_INT: 1.127 + return get_option_int(optdb, opt, valp); 1.128 + case OTYPE_FLOAT: 1.129 + return get_option_float(optdb, opt, valp); 1.130 + } 1.131 + return -1; 1.132 } 1.133 1.134 +static int translation(int eye, float *vec) 1.135 +{ 1.136 + if(!hmd) { 1.137 + vec[0] = vec[1] = vec[2] = 0; 1.138 + return -1; 1.139 + } 1.140 + 1.141 + pose[eye] = ovrHmd_GetEyePose(hmd, eye == VR_EYE_LEFT ? ovrEye_Left : ovrEye_Right); 1.142 + vec[0] = pose[eye].Position.x; 1.143 + vec[1] = pose[eye].Position.y; 1.144 + vec[2] = pose[eye].Position.z; 1.145 + return 0; 1.146 +} 1.147 + 1.148 +static int rotation(int eye, float *quat) 1.149 +{ 1.150 + if(!hmd) { 1.151 + quat[0] = quat[1] = quat[2] = 0.0f; 1.152 + quat[3] = 1.0f; 1.153 + return -1; 1.154 + } 1.155 + 1.156 + pose[eye] = ovrHmd_GetEyePose(hmd, eye == VR_EYE_LEFT ? ovrEye_Left : ovrEye_Right); 1.157 + quat[0] = pose[eye].Orientation.x; 1.158 + quat[1] = pose[eye].Orientation.y; 1.159 + quat[2] = pose[eye].Orientation.z; 1.160 + quat[3] = pose[eye].Orientation.w; 1.161 + return 0; 1.162 +} 1.163 + 1.164 +static const float idmat[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; 1.165 + 1.166 +static void proj_matrix(int eye, float znear, float zfar, float *mat) 1.167 +{ 1.168 + ovrMatrix4f vmat; 1.169 + 1.170 + if(!hmd) { 1.171 + memcpy(mat, idmat, sizeof idmat); 1.172 + return; 1.173 + } 1.174 + 1.175 + vmat = ovrMatrix4f_Projection(eye_render_desc[eye].Fov, znear, zfar, 1); 1.176 + memcpy(mat, vmat.M[0], 16 * sizeof(float)); 1.177 +} 1.178 + 1.179 +static int new_frame = 1; 1.180 + 1.181 static void begin(int eye) 1.182 { 1.183 -} 1.184 + if(!hmd) return; 1.185 1.186 -static void end(void) 1.187 -{ 1.188 + if(!deferred_init_done) { 1.189 + deferred_init(); 1.190 + } 1.191 + 1.192 + if(new_frame) { 1.193 + ovrHmd_BeginFrame(hmd, 0); 1.194 + new_frame = 0; 1.195 + } 1.196 } 1.197 1.198 static void present(void) 1.199 { 1.200 + if(!hmd) return; 1.201 + 1.202 + ovrHmd_EndFrame(hmd, pose, &eye_tex[0].Texture); 1.203 + new_frame = 1; 1.204 } 1.205 1.206 +static void set_eye_texture(int eye, unsigned int tex, float umin, float vmin, float umax, float vmax) 1.207 +{ 1.208 + ovrSizei texsz; 1.209 + ovrRecti rect; 1.210 + 1.211 + glBindTexture(GL_TEXTURE_2D, tex); 1.212 + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &texsz.w); 1.213 + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &texsz.h); 1.214 + 1.215 + rect.Pos.x = (int)(umin * texsz.w); 1.216 + rect.Pos.y = (int)(vmin * texsz.h); 1.217 + rect.Size.w = (int)((umax - umin) * texsz.w); 1.218 + rect.Size.h = (int)((vmax - vmin) * texsz.h); 1.219 + 1.220 + eye_tex[eye].OGL.Header.API = ovrRenderAPI_OpenGL; 1.221 + eye_tex[eye].OGL.Header.TextureSize = texsz; 1.222 + eye_tex[eye].OGL.Header.RenderViewport = rect; 1.223 + eye_tex[eye].OGL.TexId = tex; 1.224 +} 1.225 + 1.226 +static void recenter(void) 1.227 +{ 1.228 + if(hmd) { 1.229 + ovrHmd_RecenterPose(hmd); 1.230 + } 1.231 +} 1.232 1.233 struct vr_module *vr_module_libovr(void) 1.234 { 1.235 @@ -99,11 +248,15 @@ 1.236 m.name = "libovr"; 1.237 m.init = init; 1.238 m.cleanup = cleanup; 1.239 - m.view_matrix = view_matrix; 1.240 + m.set_option = set_option; 1.241 + m.get_option = get_option; 1.242 + m.translation = translation; 1.243 + m.rotation = rotation; 1.244 m.proj_matrix = proj_matrix; 1.245 m.begin = begin; 1.246 - m.end = end; 1.247 m.present = present; 1.248 + m.set_eye_texture = set_eye_texture; 1.249 + m.recenter = recenter; 1.250 } 1.251 return &m; 1.252 }