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  }