goat3dgfx
changeset 11:d061fe1a31ec
compile vr source files or not
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 24 Nov 2013 14:00:14 +0200 |
parents | b4c9a24c946e |
children | 1868c5975f31 |
files | Makefile.in configure src/camera.cc src/camera.h src/goat3dgfx.cc src/vr.h src/vr/vr.cc src/vr/vr_impl.h src/vr/vr_sdr.h |
diffstat | 9 files changed, 877 insertions(+), 1 deletions(-) [+] |
line diff
1.1 --- a/Makefile.in Sun Nov 24 13:30:44 2013 +0200 1.2 +++ b/Makefile.in Sun Nov 24 14:00:14 2013 +0200 1.3 @@ -1,6 +1,9 @@ 1.4 +ifdef use_vr 1.5 + vr_ccsrc = $(wildcard src/vr/*.cc) 1.6 +endif 1.7 1.8 csrc = $(wildcard src/*.c) 1.9 -ccsrc = $(wildcard src/*.cc) 1.10 +ccsrc = $(wildcard src/*.cc) $(vr_ccsrc) 1.11 obj = $(csrc:.c=.o) $(ccsrc:.cc=.o) 1.12 dep = $(obj:.o=.d) 1.13 name = goat3dgfx
2.1 --- a/configure Sun Nov 24 13:30:44 2013 +0200 2.2 +++ b/configure Sun Nov 24 14:00:14 2013 +0200 2.3 @@ -199,6 +199,8 @@ 2.4 emit "cfg_cflags = $CFLAGS" 2.5 emit "cfg_ldflags = $LDFLAGS" 2.6 2.7 + if $vr; then emit 'use_vr = true'; fi 2.8 + 2.9 cat Makefile.in >>Makefile 2.10 } 2.11
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/camera.cc Sun Nov 24 14:00:14 2013 +0200 3.3 @@ -0,0 +1,235 @@ 3.4 +#include "opengl.h" 3.5 +#include "camera.h" 3.6 +#include "vr.h" 3.7 + 3.8 +Camera::Camera() 3.9 +{ 3.10 + roll = 0.0; 3.11 + inval_cache(); 3.12 +} 3.13 + 3.14 +Camera::~Camera() 3.15 +{ 3.16 +} 3.17 + 3.18 +void Camera::calc_inv_matrix(Matrix4x4 *mat) const 3.19 +{ 3.20 + *mat = matrix().inverse(); 3.21 +} 3.22 + 3.23 +const Matrix4x4 &Camera::matrix() const 3.24 +{ 3.25 + if(!mcache.valid) { 3.26 + calc_matrix(&mcache.mat); 3.27 + mcache.valid = true; 3.28 + } 3.29 + return mcache.mat; 3.30 +} 3.31 + 3.32 +const Matrix4x4 &Camera::inv_matrix() const 3.33 +{ 3.34 + if(!mcache_inv.valid) { 3.35 + calc_inv_matrix(&mcache_inv.mat); 3.36 + mcache_inv.valid = true; 3.37 + } 3.38 + return mcache_inv.mat; 3.39 +} 3.40 + 3.41 +void Camera::use() const 3.42 +{ 3.43 + mult_matrix(matrix()); 3.44 +} 3.45 + 3.46 +void Camera::use_inverse() const 3.47 +{ 3.48 + mult_matrix(inv_matrix()); 3.49 +} 3.50 + 3.51 +void Camera::input_move(float x, float y, float z) 3.52 +{ 3.53 +} 3.54 + 3.55 +void Camera::input_rotate(float x, float y, float z) 3.56 +{ 3.57 +} 3.58 + 3.59 +void Camera::input_zoom(float factor) 3.60 +{ 3.61 +} 3.62 + 3.63 + 3.64 +// ---- orbit camera ---- 3.65 + 3.66 +OrbitCamera::OrbitCamera() 3.67 +{ 3.68 + theta = 0.0; 3.69 + phi = 0.0; 3.70 + rad = 10.0; 3.71 +} 3.72 + 3.73 +OrbitCamera::~OrbitCamera() 3.74 +{ 3.75 +} 3.76 + 3.77 +void OrbitCamera::calc_matrix(Matrix4x4 *mat) const 3.78 +{ 3.79 + mat->reset_identity(); 3.80 + mat->translate(Vector3(0, 0, -rad)); 3.81 + mat->rotate(Vector3(phi, 0, 0)); 3.82 + mat->rotate(Vector3(0, theta, 0)); 3.83 + mat->rotate(Vector3(0, 0, roll)); 3.84 +} 3.85 + 3.86 +void OrbitCamera::calc_inv_matrix(Matrix4x4 *mat) const 3.87 +{ 3.88 + mat->reset_identity(); 3.89 + mat->rotate(Vector3(0, 0, roll)); 3.90 + mat->rotate(Vector3(0, theta, 0)); 3.91 + mat->rotate(Vector3(phi, 0, 0)); 3.92 + mat->translate(Vector3(0, 0, -rad)); 3.93 +} 3.94 + 3.95 +void OrbitCamera::input_rotate(float x, float y, float z) 3.96 +{ 3.97 + theta += y; 3.98 + phi += x; 3.99 + roll += z; 3.100 + 3.101 + if(phi < -M_PI / 2) 3.102 + phi = -M_PI / 2; 3.103 + if(phi > M_PI) 3.104 + phi = M_PI; 3.105 + 3.106 + inval_cache(); 3.107 +} 3.108 + 3.109 +void OrbitCamera::input_zoom(float factor) 3.110 +{ 3.111 + rad += factor; 3.112 + if(rad < 0.0) 3.113 + rad = 0.0; 3.114 + 3.115 + inval_cache(); 3.116 +} 3.117 + 3.118 +void FpsCamera::calc_matrix(Matrix4x4 *mat) const 3.119 +{ 3.120 + mat->reset_identity(); 3.121 + mat->translate(Vector3(pos.x, pos.y, pos.z)); 3.122 + mat->rotate(Vector3(0, theta, 0)); 3.123 + mat->rotate(Vector3(phi, 0, 0)); 3.124 + mat->rotate(Vector3(0, 0, roll)); 3.125 +} 3.126 + 3.127 +void FpsCamera::calc_inv_matrix(Matrix4x4 *mat) const 3.128 +{ 3.129 + mat->reset_identity(); 3.130 + mat->rotate(Vector3(0, 0, roll)); 3.131 + mat->rotate(Vector3(phi, 0, 0)); 3.132 + mat->rotate(Vector3(0, theta, 0)); 3.133 + mat->translate(Vector3(-pos.x, -pos.y, -pos.z)); 3.134 +} 3.135 + 3.136 +void FpsCamera::input_move(float x, float y, float z) 3.137 +{ 3.138 + pos.x += x * cos(theta) - z * sin(theta); 3.139 + pos.z += x * sin(theta) + z * cos(theta); 3.140 + pos.y += y; 3.141 + inval_cache(); 3.142 +} 3.143 + 3.144 +const Vector3 &FpsCamera::get_position() const 3.145 +{ 3.146 + return pos; 3.147 +} 3.148 + 3.149 + 3.150 +FlyCamera::FlyCamera() 3.151 +{ 3.152 + pos.z = 10.0f; 3.153 +} 3.154 + 3.155 +void FlyCamera::calc_matrix(Matrix4x4 *mat) const 3.156 +{ 3.157 + Matrix3x3 rmat = rot.get_rotation_matrix().transposed(); 3.158 + Matrix4x4 tmat; 3.159 + tmat.set_translation(pos); 3.160 + *mat = tmat * Matrix4x4(rmat); 3.161 +} 3.162 + 3.163 +/*void FlyCamera::calc_inv_matrix(Matrix4x4 *mat) const 3.164 +{ 3.165 +}*/ 3.166 + 3.167 +const Vector3 &FlyCamera::get_position() const 3.168 +{ 3.169 + return pos; 3.170 +} 3.171 + 3.172 +const Quaternion &FlyCamera::get_rotation() const 3.173 +{ 3.174 + return rot; 3.175 +} 3.176 + 3.177 +void FlyCamera::input_move(float x, float y, float z) 3.178 +{ 3.179 + static const Vector3 vfwd(0, 0, 1), vright(1, 0, 0); 3.180 + 3.181 + Vector3 k = vfwd.transformed(rot); 3.182 + Vector3 i = vright.transformed(rot); 3.183 + Vector3 j = cross_product(k, i); 3.184 + 3.185 + pos += i * x + j * y + k * z; 3.186 + inval_cache(); 3.187 +} 3.188 + 3.189 +void FlyCamera::input_rotate(float x, float y, float z) 3.190 +{ 3.191 + Vector3 axis(x, y, z); 3.192 + float axis_len = axis.length(); 3.193 + rot.rotate(axis / axis_len, axis_len); 3.194 + rot.normalize(); 3.195 + 3.196 + inval_cache(); 3.197 +} 3.198 + 3.199 + 3.200 +// --- VR additions --- 3.201 +VRFpsCamera::VRFpsCamera() 3.202 +{ 3.203 + neck_eye_dist = 0.14; // default neck->eye distance 14cm 3.204 +} 3.205 + 3.206 +void VRFpsCamera::calc_matrix(Matrix4x4 *mat) const 3.207 +{ 3.208 + mat->reset_identity(); 3.209 + mat->translate(Vector3(pos.x, pos.y, pos.z)); 3.210 + mat->rotate(Vector3(0, theta, 0)); 3.211 + mat->rotate(Vector3(phi, 0, 0)); 3.212 + mat->rotate(Vector3(0, 0, roll)); 3.213 + mat->translate(Vector3(0, neck_eye_dist, 0)); 3.214 +} 3.215 + 3.216 +void VRFpsCamera::calc_inv_matrix(Matrix4x4 *mat) const 3.217 +{ 3.218 + mat->reset_identity(); 3.219 + mat->translate(Vector3(0, -neck_eye_dist, 0)); 3.220 + mat->rotate(Vector3(0, 0, roll)); 3.221 + mat->rotate(Vector3(phi, 0, 0)); 3.222 + mat->rotate(Vector3(0, theta, 0)); 3.223 + mat->translate(Vector3(-pos.x, -pos.y, -pos.z)); 3.224 +} 3.225 + 3.226 +void VRFpsCamera::track_vr() 3.227 +{ 3.228 + float euler[3]; 3.229 + vr_get_rotation_euler(euler); 3.230 + 3.231 + // input_rotate invalidates cache 3.232 + input_rotate(prev_angles[0] - euler[0], prev_angles[1] - euler[1], prev_angles[2] - euler[2]); 3.233 + 3.234 + prev_angles[0] = euler[0]; 3.235 + prev_angles[1] = euler[1]; 3.236 + prev_angles[2] = euler[2]; 3.237 +} 3.238 +
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/camera.h Sun Nov 24 14:00:14 2013 +0200 4.3 @@ -0,0 +1,98 @@ 4.4 +#ifndef CAMERA_H_ 4.5 +#define CAMERA_H_ 4.6 + 4.7 +#include <vmath/vmath.h> 4.8 + 4.9 +class Camera { 4.10 +protected: 4.11 + float roll; 4.12 + 4.13 + mutable struct { 4.14 + bool valid; 4.15 + Matrix4x4 mat; 4.16 + } mcache, mcache_inv; 4.17 + 4.18 + virtual void calc_matrix(Matrix4x4 *mat) const = 0; 4.19 + virtual void calc_inv_matrix(Matrix4x4 *mat) const; 4.20 + 4.21 + void inval_cache() { mcache.valid = mcache_inv.valid = false; } 4.22 + void set_glmat(const Matrix4x4 &m) const; 4.23 + 4.24 +public: 4.25 + Camera(); 4.26 + virtual ~Camera(); 4.27 + 4.28 + const Matrix4x4 &matrix() const; 4.29 + const Matrix4x4 &inv_matrix() const; 4.30 + 4.31 + void use() const; 4.32 + void use_inverse() const; 4.33 + 4.34 + // these do nothing, override to provide input handling 4.35 + virtual void input_move(float x, float y, float z); 4.36 + virtual void input_rotate(float x, float y, float z); 4.37 + virtual void input_zoom(float factor); 4.38 +}; 4.39 + 4.40 +class OrbitCamera : public Camera { 4.41 +protected: 4.42 + float theta, phi, rad; 4.43 + 4.44 + void calc_matrix(Matrix4x4 *mat) const; 4.45 + void calc_inv_matrix(Matrix4x4 *mat) const; 4.46 + 4.47 +public: 4.48 + OrbitCamera(); 4.49 + virtual ~OrbitCamera(); 4.50 + 4.51 + void input_rotate(float x, float y, float z); 4.52 + void input_zoom(float factor); 4.53 +}; 4.54 + 4.55 +class FpsCamera : public OrbitCamera { 4.56 +protected: 4.57 + Vector3 pos; 4.58 + 4.59 + void calc_matrix(Matrix4x4 *mat) const; 4.60 + void calc_inv_matrix(Matrix4x4 *mat) const; 4.61 + 4.62 +public: 4.63 + void input_move(float x, float y, float z); 4.64 + 4.65 + const Vector3 &get_position() const; 4.66 +}; 4.67 + 4.68 +class FlyCamera : public Camera { 4.69 +private: 4.70 + Vector3 pos; 4.71 + Quaternion rot; 4.72 + 4.73 + void calc_matrix(Matrix4x4 *mat) const; 4.74 + //void calc_inv_matrix(Matrix4x4 *mat) const; 4.75 + 4.76 +public: 4.77 + FlyCamera(); 4.78 + 4.79 + const Vector3 &get_position() const; 4.80 + const Quaternion &get_rotation() const; 4.81 + 4.82 + void input_move(float x, float y, float z); 4.83 + void input_rotate(float x, float y, float z); 4.84 +}; 4.85 + 4.86 + 4.87 +class VRFpsCamera : public FpsCamera { 4.88 +private: 4.89 + float neck_eye_dist; 4.90 + float prev_angles[3]; 4.91 + 4.92 + void calc_matrix(Matrix4x4 *mat) const; 4.93 + void calc_inv_matrix(Matrix4x4 *mat) const; 4.94 + 4.95 +public: 4.96 + VRFpsCamera(); 4.97 + 4.98 + void track_vr(); 4.99 +}; 4.100 + 4.101 +#endif // CAMERA_H_
5.1 --- a/src/goat3dgfx.cc Sun Nov 24 13:30:44 2013 +0200 5.2 +++ b/src/goat3dgfx.cc Sun Nov 24 14:00:14 2013 +0200 5.3 @@ -1,4 +1,7 @@ 5.4 +#include "config.h" 5.5 #include "goat3dgfx.h" 5.6 +#include "vr.h" 5.7 +#include "logger.h" 5.8 5.9 bool init_goat_graphics() 5.10 { 5.11 @@ -6,6 +9,13 @@ 5.12 5.13 glewInit(); 5.14 5.15 +#ifdef USE_VR 5.16 + if(vr_init() == -1) { 5.17 + log_fatal("failed to initialize the VR system\n"); 5.18 + return false; 5.19 + } 5.20 +#endif 5.21 + 5.22 return true; 5.23 } 5.24
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/vr.h Sun Nov 24 14:00:14 2013 +0200 6.3 @@ -0,0 +1,63 @@ 6.4 +#ifndef GOAT3DGFX_VR_H_ 6.5 +#define GOAT3DGFX_VR_H_ 6.6 + 6.7 +/* VR mode init options */ 6.8 +enum vr_init_mode { 6.9 + VR_INIT_NONE, 6.10 + VR_INIT_OCULUS, 6.11 + VR_INIT_STEREO 6.12 +}; 6.13 + 6.14 +/* possible eye values */ 6.15 +enum { 6.16 + VR_EYE_CENTER, 6.17 + VR_EYE_LEFT, 6.18 + VR_EYE_RIGHT 6.19 +}; 6.20 + 6.21 +#ifdef __cplusplus 6.22 +extern "C" { 6.23 +#endif 6.24 + 6.25 +int vr_init(enum vr_init_mode mode); 6.26 +void vr_shutdown(void); 6.27 + 6.28 +const char *vr_get_display_name(void); 6.29 +void vr_get_display_pos(int *xptr, int *yptr); 6.30 + 6.31 +int vr_get_width(void); 6.32 +int vr_get_height(void); 6.33 + 6.34 +float vr_get_fov(void); 6.35 +float vr_get_aspect(void); 6.36 + 6.37 +void vr_set_eyedist(float ipd); 6.38 +float vr_get_eyedist(void); 6.39 + 6.40 +/* expects an array of 4 barrel distortion coefficients: 6.41 + * polar scale: k_0 + k_1 r^2 + k_2 r^4 + k_3 r^6 6.42 + */ 6.43 +void vr_set_distort(const float *coef); 6.44 +void vr_get_distort(float *coef); 6.45 + 6.46 +void vr_set_prediction_sec(float dt); 6.47 +float vr_get_prediction_sec(void); 6.48 + 6.49 +void vr_get_view_matrix(float *res, int eye); 6.50 +void vr_get_proj_matrix(float *res, int eye); 6.51 + 6.52 +/* expects an array of at least 3 floats (x, y, z, offset). */ 6.53 +void vr_get_translation(float *offs); 6.54 +/* expects an array of at least 4 floats (x, y, z, w, quaternion). */ 6.55 +void vr_get_rotation(float *quat); 6.56 +/* expects an array of at least 3 floats (pitch, yaw, roll, angles). */ 6.57 +void vr_get_rotation_euler(float *euler); 6.58 + 6.59 +/* OpenGL stuff */ 6.60 +void vr_draw_eye(int eye, unsigned int tex, float tex_scale_x, float tex_scale_y); 6.61 + 6.62 +#ifdef __cplusplus 6.63 +} 6.64 +#endif 6.65 + 6.66 +#endif /* GOAT3DGFX_VR_H_ */
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/vr/vr.cc Sun Nov 24 14:00:14 2013 +0200 7.3 @@ -0,0 +1,384 @@ 7.4 +#include <stdio.h> 7.5 +#include <GL/glew.h> 7.6 +#include "vr.h" 7.7 +#include "vr_impl.h" 7.8 +#include "vr_sdr.h" 7.9 + 7.10 +#ifndef WIN32 7.11 +#include <alloca.h> 7.12 +#else 7.13 +#include <malloc.h> 7.14 +#endif 7.15 + 7.16 +static void init_ctx(); 7.17 +static bool init_ovr(); 7.18 +static bool init_sdr(); 7.19 + 7.20 +VRContext vr_ctx; 7.21 +static unsigned int sdrprog; 7.22 + 7.23 +extern "C" int vr_init(enum vr_init_mode mode) 7.24 +{ 7.25 + init_ctx(); 7.26 + 7.27 + if(!init_ovr()) { 7.28 + return -1; 7.29 + } 7.30 + 7.31 + if(!init_sdr()) { 7.32 + return -1; 7.33 + } 7.34 + 7.35 + return 0; 7.36 +} 7.37 + 7.38 +extern "C" void vr_shutdown(void) 7.39 +{ 7.40 + delete [] vr_ctx.info.display; 7.41 + //System::Destroy(); 7.42 +} 7.43 + 7.44 +static void init_ctx() 7.45 +{ 7.46 + vr_ctx.info.width = 1280; 7.47 + vr_ctx.info.height = 800; 7.48 + vr_ctx.info.fov = M_PI / 2.0; 7.49 + vr_ctx.info.aspect = (float)vr_ctx.info.width / (float)vr_ctx.info.height; 7.50 + vr_ctx.info.ipd = 0.035; 7.51 + vr_ctx.info.scale = 1.0; 7.52 +} 7.53 + 7.54 +static bool init_ovr() 7.55 +{ 7.56 + LogMaskConstants log_level = LogMask_All; 7.57 + // initialize Oculus SDK 7.58 + const char *logenv = getenv("VR_LOGLEVEL"); 7.59 + if(logenv) { 7.60 + switch(atoi(logenv)) { 7.61 + case 0: 7.62 + log_level = LogMask_None; 7.63 + break; 7.64 + case 1: 7.65 + log_level = LogMask_Regular; 7.66 + break; 7.67 + case 2: 7.68 + default: 7.69 + log_level = LogMask_All; 7.70 + break; 7.71 + } 7.72 + } 7.73 + 7.74 + System::Init(Log::ConfigureDefaultLog(log_level)); 7.75 + if(!(vr_ctx.ovr_devman = DeviceManager::Create())) { 7.76 + fprintf(stderr, "failed to create OVR device manager\n"); 7.77 + return false; 7.78 + } 7.79 + 7.80 + // create the display device 7.81 + HMDInfo info; 7.82 + if(!(vr_ctx.ovr_hmd_dev = vr_ctx.ovr_devman->EnumerateDevices<HMDDevice>().CreateDevice())) { 7.83 + fprintf(stderr, "no oculus rift devices found\n"); 7.84 + } else { 7.85 + if(vr_ctx.ovr_hmd_dev->GetDeviceInfo(&info)) { 7.86 + printf("oculus device info:\n"); 7.87 + printf(" name: %s\n", info.DisplayDeviceName); 7.88 + printf(" ipd: %f\n", info.InterpupillaryDistance); 7.89 + printf(" distortion: %f %f %f %f\n", info.DistortionK[0], 7.90 + info.DistortionK[1], info.DistortionK[2], info.DistortionK[3]); 7.91 + } 7.92 + 7.93 + // calculate and store viewing parameters 7.94 + vr_ctx.info.width = info.HResolution; 7.95 + vr_ctx.info.height = info.VResolution; 7.96 + vr_ctx.info.aspect = (float)vr_ctx.info.width / (float)vr_ctx.info.height; 7.97 + 7.98 + vr_ctx.info.ipd = info.InterpupillaryDistance; 7.99 + for(int i=0; i<4; i++) { 7.100 + vr_ctx.info.distort[i] = info.DistortionK[i]; 7.101 + } 7.102 + 7.103 + Util::Render::StereoConfig stereohelp; 7.104 + stereohelp.SetFullViewport(Util::Render::Viewport(0, 0, vr_ctx.info.width, vr_ctx.info.height)); 7.105 + stereohelp.SetStereoMode(Util::Render::Stereo_LeftRight_Multipass); 7.106 + stereohelp.SetHMDInfo(info); 7.107 + stereohelp.SetDistortionFitPointVP(-1.0, 0.0); 7.108 + 7.109 + vr_ctx.info.scale = stereohelp.GetDistortionScale(); 7.110 + 7.111 + float vhalfsz = vr_ctx.info.scale * info.VScreenSize * 0.5; 7.112 + vr_ctx.info.fov = 2.0 * atan(vhalfsz / info.EyeToScreenDistance); 7.113 + 7.114 + vr_ctx.info.lens_center_offset = 0.5 - info.LensSeparationDistance / info.HScreenSize; 7.115 + 7.116 + // calculate center of projection shift to match the lens positions 7.117 + float center_dist_meters = info.HScreenSize * 0.25; 7.118 + float proj_shift = center_dist_meters - info.LensSeparationDistance * 0.5; 7.119 + vr_ctx.info.proj_center_offset = 4.0 * proj_shift / info.HScreenSize; 7.120 + 7.121 + // grab the display info 7.122 + vr_ctx.info.display = new char[strlen(info.DisplayDeviceName) + 1]; 7.123 + strcpy(vr_ctx.info.display, info.DisplayDeviceName); 7.124 + 7.125 + vr_ctx.info.display_xoffs = info.DesktopX; 7.126 + vr_ctx.info.display_yoffs = info.DesktopY; 7.127 + 7.128 + printf("display: \"%s\" offset: %+d %+d\n", vr_ctx.info.display, 7.129 + vr_ctx.info.display_xoffs, vr_ctx.info.display_yoffs); 7.130 + } 7.131 + 7.132 + // get the sensor device 7.133 + if(vr_ctx.ovr_hmd_dev) { 7.134 + if(!(vr_ctx.ovr_sensor_dev = vr_ctx.ovr_hmd_dev->GetSensor())) { 7.135 + fprintf(stderr, "failed to get oculus sensor device\n"); 7.136 + } 7.137 + } else { 7.138 + if(!(vr_ctx.ovr_sensor_dev = vr_ctx.ovr_devman->EnumerateDevices<SensorDevice>().CreateDevice())) { 7.139 + fprintf(stderr, "failed to get oculus sensor device\n"); 7.140 + } 7.141 + } 7.142 + 7.143 + if(vr_ctx.ovr_sensor_dev) { 7.144 + SensorInfo sinfo; 7.145 + if(vr_ctx.ovr_sensor_dev->GetDeviceInfo(&sinfo)) { 7.146 + printf("oculus sensor device info:\n"); 7.147 + printf(" name: %s\n", sinfo.ProductName); 7.148 + } 7.149 + 7.150 + vr_ctx.ovr_sfusion.AttachToSensor(vr_ctx.ovr_sensor_dev); 7.151 + } 7.152 + return true; 7.153 +} 7.154 + 7.155 +#undef EXTERNAL_SHADER 7.156 + 7.157 +static bool init_sdr() 7.158 +{ 7.159 + int status; 7.160 + 7.161 +#ifdef EXTERNAL_SHADER 7.162 + FILE *fp = fopen("sdr/sdr.glsl", "rb"); 7.163 + if(!fp) { 7.164 + perror("failed to load sdr.glsl"); 7.165 + return false; 7.166 + } 7.167 + fseek(fp, 0, SEEK_END); 7.168 + long sz = ftell(fp); 7.169 + rewind(fp); 7.170 + 7.171 + char *buf = (char*)alloca(sz + 1); 7.172 + fread(buf, 1, sz, fp); 7.173 + buf[sz] = 0; 7.174 + sdr_src = buf; 7.175 + 7.176 + fclose(fp); 7.177 +#endif 7.178 + 7.179 + unsigned int sdr = glCreateShader(GL_FRAGMENT_SHADER); 7.180 + glShaderSource(sdr, 1, &sdr_src, 0); 7.181 + glCompileShader(sdr); 7.182 + glGetShaderiv(sdr, GL_COMPILE_STATUS, &status); 7.183 + if(!status) { 7.184 + fprintf(stderr, "failed to compile distortion shader\n"); 7.185 + 7.186 + int loglen; 7.187 + glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &loglen); 7.188 + 7.189 + if(loglen > 0) { 7.190 + char *log = (char*)alloca(loglen); 7.191 + glGetShaderInfoLog(sdr, loglen, &loglen, log); 7.192 + fprintf(stderr, "%s\n", log); 7.193 + } 7.194 + 7.195 + return false; 7.196 + } 7.197 + 7.198 + sdrprog = glCreateProgram(); 7.199 + glAttachShader(sdrprog, sdr); 7.200 + glLinkProgram(sdrprog); 7.201 + if(!status) { 7.202 + fprintf(stderr, "failed to link distortion shader program\n"); 7.203 + glDeleteShader(sdr); 7.204 + return false; 7.205 + } 7.206 + 7.207 + int loc; 7.208 + 7.209 + glUseProgram(sdrprog); 7.210 + 7.211 + if((loc = glGetUniformLocation(sdrprog, "tex")) != -1) { 7.212 + glUniform1i(loc, 0); 7.213 + } 7.214 + if((loc = glGetUniformLocation(sdrprog, "lens_center_offset")) != -1) { 7.215 + glUniform1f(loc, 0); 7.216 + } 7.217 + if((loc = glGetUniformLocation(sdrprog, "scr_center")) != -1) { 7.218 + glUniform2f(loc, 0, 0); 7.219 + } 7.220 + if((loc = glGetUniformLocation(sdrprog, "scale")) != -1) { 7.221 + glUniform1f(loc, vr_ctx.info.scale); 7.222 + } 7.223 + if((loc = glGetUniformLocation(sdrprog, "aspect")) != -1) { 7.224 + printf("setting aspect: %f\n", vr_ctx.info.aspect / 2.0); 7.225 + glUniform1f(loc, vr_ctx.info.aspect / 2.0); 7.226 + } 7.227 + if((loc = glGetUniformLocation(sdrprog, "scale_in")) != -1) { 7.228 + glUniform2f(loc, 1, 1); 7.229 + } 7.230 + if((loc = glGetUniformLocation(sdrprog, "dist_factors")) != -1) { 7.231 + glUniform4f(loc, vr_ctx.info.distort[0], vr_ctx.info.distort[1], 7.232 + vr_ctx.info.distort[2], vr_ctx.info.distort[3]); 7.233 + } 7.234 + 7.235 + return true; 7.236 +} 7.237 + 7.238 +extern "C" const char *vr_get_display_name(void) 7.239 +{ 7.240 + return vr_ctx.info.display; 7.241 +} 7.242 + 7.243 +extern "C" void vr_get_display_pos(int *xptr, int *yptr) 7.244 +{ 7.245 + *xptr = vr_ctx.info.display_xoffs; 7.246 + *yptr = vr_ctx.info.display_yoffs; 7.247 +} 7.248 + 7.249 +extern "C" int vr_get_width(void) 7.250 +{ 7.251 + return vr_ctx.info.width; 7.252 +} 7.253 + 7.254 +extern "C" int vr_get_height(void) 7.255 +{ 7.256 + return vr_ctx.info.height; 7.257 +} 7.258 + 7.259 +extern "C" float vr_get_fov(void) 7.260 +{ 7.261 + return vr_ctx.info.fov; 7.262 +} 7.263 + 7.264 +extern "C" float vr_get_aspect(void) 7.265 +{ 7.266 + return vr_ctx.info.aspect; 7.267 +} 7.268 + 7.269 +extern "C" void vr_set_eyedist(float ipd) 7.270 +{ 7.271 + vr_ctx.info.ipd = ipd; 7.272 +} 7.273 + 7.274 +extern "C" float vr_get_eyedist(void) 7.275 +{ 7.276 + return vr_ctx.info.ipd; 7.277 +} 7.278 + 7.279 +extern "C" void vr_set_distort(const float *coef) 7.280 +{ 7.281 + memcpy(vr_ctx.info.distort, coef, sizeof vr_ctx.info.distort); 7.282 +} 7.283 + 7.284 +extern "C" void vr_get_distort(float *coef) 7.285 +{ 7.286 + memcpy(coef, vr_ctx.info.distort, sizeof vr_ctx.info.distort); 7.287 +} 7.288 + 7.289 +extern "C" void vr_set_prediction_sec(float dt) 7.290 +{ 7.291 + vr_ctx.ovr_sfusion.SetPrediction(dt); 7.292 +} 7.293 + 7.294 +extern "C" float vr_get_prediction_sec(void) 7.295 +{ 7.296 + return vr_ctx.ovr_sfusion.GetPredictionDelta(); 7.297 +} 7.298 + 7.299 +extern "C" void vr_get_view_matrix(float *res, int eye) 7.300 +{ 7.301 + // TODO 7.302 +} 7.303 + 7.304 +extern "C" void vr_get_proj_matrix(float *res, int eye) 7.305 +{ 7.306 + static float eye_scale[] = {0.0, 1.0, -1.0}; 7.307 + 7.308 + Matrix4f proj = Matrix4f::PerspectiveRH(vr_ctx.info.fov, vr_ctx.info.aspect / 2.0, 0.3, 1000.0); 7.309 + proj = Matrix4f::Translation(vr_ctx.info.proj_center_offset * eye_scale[eye], 0, 0) * proj; 7.310 + 7.311 + memcpy(res, proj.M[0], 16 * sizeof(float)); 7.312 +} 7.313 + 7.314 +extern "C" void vr_get_translation(float *offs) 7.315 +{ 7.316 + // current oculus devkit doesn't do translation 7.317 + offs[0] = offs[1] = offs[2] = 0.0f; 7.318 +} 7.319 + 7.320 +extern "C" void vr_get_rotation(float *quat) 7.321 +{ 7.322 + Quatf oq = vr_ctx.ovr_sfusion.GetPredictedOrientation(); 7.323 + quat[0] = oq.x; 7.324 + quat[1] = oq.y; 7.325 + quat[2] = oq.z; 7.326 + quat[3] = oq.w; 7.327 +} 7.328 + 7.329 +extern "C" void vr_get_rotation_euler(float *euler) 7.330 +{ 7.331 + Quatf oq = vr_ctx.ovr_sfusion.GetPredictedOrientation(); 7.332 + oq.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(euler + 1, euler, euler + 2); 7.333 +} 7.334 + 7.335 +extern "C" void vr_draw_eye(int eye, unsigned int tex, float tex_scale_x, float tex_scale_y) 7.336 +{ 7.337 + static const float rects[3][4] = { 7.338 + {-1, -1, 1, 1}, 7.339 + {-1, -1, 0, 1}, 7.340 + {0, -1, 1, 1} 7.341 + }; 7.342 + static const float offs_scale[3] = {0.0, -1.0, 1.0}; 7.343 + 7.344 + glPushAttrib(GL_ENABLE_BIT); 7.345 + glDisable(GL_DEPTH_TEST); 7.346 + glDisable(GL_LIGHTING); 7.347 + glEnable(GL_TEXTURE_2D); 7.348 + 7.349 + glMatrixMode(GL_MODELVIEW); 7.350 + glPushMatrix(); 7.351 + glLoadIdentity(); 7.352 + 7.353 + glMatrixMode(GL_PROJECTION); 7.354 + glPushMatrix(); 7.355 + glLoadIdentity(); 7.356 + 7.357 + glUseProgram(sdrprog); 7.358 + 7.359 + if(sdrprog) { 7.360 + int loc; 7.361 + if((loc = glGetUniformLocation(sdrprog, "lens_center_offset")) != -1) { 7.362 + float offset = vr_ctx.info.lens_center_offset * offs_scale[eye]; 7.363 + glUniform1f(loc, offset); 7.364 + } 7.365 + 7.366 + if((loc = glGetUniformLocation(sdrprog, "tex_scale")) != -1) { 7.367 + glUniform2f(loc, tex_scale_x, tex_scale_y); 7.368 + } 7.369 + } 7.370 + 7.371 + glBindTexture(GL_TEXTURE_2D, tex); 7.372 + glBegin(GL_QUADS); 7.373 + glColor4f(1, 1, 1, 1); 7.374 + glTexCoord2f(0, 0); glVertex2f(rects[eye][0], rects[eye][1]); 7.375 + glTexCoord2f(1, 0); glVertex2f(rects[eye][2], rects[eye][1]); 7.376 + glTexCoord2f(1, 1); glVertex2f(rects[eye][2], rects[eye][3]); 7.377 + glTexCoord2f(0, 1); glVertex2f(rects[eye][0], rects[eye][3]); 7.378 + glEnd(); 7.379 + 7.380 + glUseProgram(0); 7.381 + 7.382 + glPopMatrix(); 7.383 + glMatrixMode(GL_MODELVIEW); 7.384 + glPopMatrix(); 7.385 + 7.386 + glPopAttrib(); 7.387 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/vr/vr_impl.h Sun Nov 24 14:00:14 2013 +0200 8.3 @@ -0,0 +1,36 @@ 8.4 +#ifndef VR_IMPL_H_ 8.5 +#define VR_IMPL_H_ 8.6 + 8.7 +#include <OVR.h> 8.8 + 8.9 +using namespace OVR; 8.10 + 8.11 +struct VRContext { 8.12 + DeviceManager *ovr_devman; 8.13 + HMDDevice *ovr_hmd_dev; 8.14 + SensorDevice *ovr_sensor_dev; 8.15 + SensorFusion ovr_sfusion; 8.16 + 8.17 + struct { 8.18 + char *display; 8.19 + int display_xoffs, display_yoffs; 8.20 + 8.21 + // the full width and height of the display (both eyes) 8.22 + int width, height; 8.23 + float fov; 8.24 + // the full aspect ratio of the display (both eyes) 8.25 + float aspect; 8.26 + float ipd; 8.27 + float distort[4]; 8.28 + // the right lens center offset (negate for left) 8.29 + float lens_center_offset; 8.30 + float proj_center_offset; 8.31 + float scale; // scaling to be applied to the two views to fill the screen 8.32 + } info; 8.33 +}; 8.34 + 8.35 +extern VRContext vr_ctx; 8.36 + 8.37 +bool vr_gl_init(); 8.38 + 8.39 +#endif // VR_IMPL_H_
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/vr/vr_sdr.h Sun Nov 24 14:00:14 2013 +0200 9.3 @@ -0,0 +1,45 @@ 9.4 +static const char *sdr_src = 9.5 + "uniform sampler2D tex;\n" 9.6 + "uniform float aspect, scale;\n" 9.7 + "uniform float lens_center_offset;\n" 9.8 + "uniform vec4 dist_factors;\n" 9.9 + "\n" 9.10 + "vec2 distort_texcoords(in vec2 tc);\n" 9.11 + "float barrel_scale(float x, in vec4 k);\n" 9.12 + "\n" 9.13 + "void main()\n" 9.14 + "{\n" 9.15 + " vec2 tc = distort_texcoords(gl_TexCoord[0].xy);\n" 9.16 + "\n" 9.17 + " float vis = any(greaterThan(tc, vec2(1.0)) || lessThan(tc, vec2(0.0))) ? 0.0 : 1.0;\n" 9.18 + "\n" 9.19 + " gl_FragColor.rgb = texture2D(tex, tc).rgb * vis;\n" 9.20 + " gl_FragColor.a = 1.0;\n" 9.21 + "}\n" 9.22 + "\n" 9.23 + "vec2 distort_texcoords(in vec2 tc)\n" 9.24 + "{\n" 9.25 + " // map tc [0, 1] -> [-1, 1]\n" 9.26 + " vec2 pt = tc * 2.0 - 1.0;\n" 9.27 + "\n" 9.28 + " pt.x += lens_center_offset * 2.0;\n" 9.29 + " pt.y /= aspect; // correct for aspect ratio\n" 9.30 + "\n" 9.31 + " float rad = barrel_scale(dot(pt, pt), dist_factors);\n" 9.32 + " pt *= rad; // scale the point by the computer distortion radius\n" 9.33 + "\n" 9.34 + " pt /= scale;\n" 9.35 + " pt.y *= aspect;\n" 9.36 + " pt.x -= lens_center_offset * 2.0;\n" 9.37 + "\n" 9.38 + " // map back to range [0, 1]\n" 9.39 + " return pt * 0.5 + 0.5;\n" 9.40 + "}\n" 9.41 + "\n" 9.42 + "float barrel_scale(float rad, in vec4 k)\n" 9.43 + "{\n" 9.44 + " float radsq = rad * rad;\n" 9.45 + " float radquad = radsq * radsq;\n" 9.46 + " return k.x + k.y * radsq + k.z * radquad + k.w * radquad * radsq;\n" 9.47 + "}\n"; 9.48 +