oculus1
diff libovr/Src/Util/Util_Render_Stereo.h @ 1:e2f9e4603129
added LibOVR and started a simple vr wrapper.
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 14 Sep 2013 16:14:59 +0300 |
parents | |
children | b069a5c27388 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libovr/Src/Util/Util_Render_Stereo.h Sat Sep 14 16:14:59 2013 +0300 1.3 @@ -0,0 +1,1 @@ 1.4 +/************************************************************************************ 1.5 1.6 PublicHeader: OVR.h 1.7 Filename : Util_Render_Stereo.h 1.8 Content : Sample stereo rendering configuration classes. 1.9 Created : October 22, 2012 1.10 Authors : Michael Antonov 1.11 1.12 Copyright : Copyright 2012 Oculus, Inc. All Rights reserved. 1.13 1.14 Use of this software is subject to the terms of the Oculus Inc license 1.15 agreement provided at the time of installation or download, or which 1.16 otherwise accompanies this software in either electronic or hard copy form. 1.17 1.18 *************************************************************************************/ 1.19 1.20 #ifndef OVR_Util_Render_Stereo_h 1.21 #define OVR_Util_Render_Stereo_h 1.22 1.23 #include "../OVR_Device.h" 1.24 1.25 namespace OVR { namespace Util { namespace Render { 1.26 1.27 1.28 //----------------------------------------------------------------------------------- 1.29 // ***** Stereo Enumerations 1.30 1.31 // StereoMode describes rendering modes that can be used by StereoConfig. 1.32 // These modes control whether stereo rendering is used or not (Stereo_None), 1.33 // and how it is implemented. 1.34 enum StereoMode 1.35 { 1.36 Stereo_None = 0, 1.37 Stereo_LeftRight_Multipass = 1 1.38 }; 1.39 1.40 1.41 // StereoEye specifies which eye we are rendering for; it is used to 1.42 // retrieve StereoEyeParams. 1.43 enum StereoEye 1.44 { 1.45 StereoEye_Center, 1.46 StereoEye_Left, 1.47 StereoEye_Right 1.48 }; 1.49 1.50 1.51 //----------------------------------------------------------------------------------- 1.52 // ***** Viewport 1.53 1.54 // Viewport describes a rectangular area used for rendering, in pixels. 1.55 struct Viewport 1.56 { 1.57 int x, y; 1.58 int w, h; 1.59 1.60 Viewport() {} 1.61 Viewport(int x1, int y1, int w1, int h1) : x(x1), y(y1), w(w1), h(h1) { } 1.62 1.63 bool operator == (const Viewport& vp) const 1.64 { return (x == vp.x) && (y == vp.y) && (w == vp.w) && (h == vp.h); } 1.65 bool operator != (const Viewport& vp) const 1.66 { return !operator == (vp); } 1.67 }; 1.68 1.69 1.70 //----------------------------------------------------------------------------------- 1.71 // ***** DistortionConfig 1.72 1.73 // DistortionConfig Provides controls for the distortion shader. 1.74 // - K[0] - K[3] are coefficients for the distortion function. 1.75 // - XCenterOffset is the offset of lens distortion center from the 1.76 // center of one-eye screen half. [-1, 1] Range. 1.77 // - Scale is a factor of how much larger will the input image be, 1.78 // with a factor of 1.0f being no scaling. An inverse of this 1.79 // value is applied to sampled UV coordinates (1/Scale). 1.80 // - ChromaticAberration is an array of parameters for controlling 1.81 // additional Red and Blue scaling in order to reduce chromatic aberration 1.82 // caused by the Rift lenses. 1.83 class DistortionConfig 1.84 { 1.85 public: 1.86 DistortionConfig(float k0 = 1.0f, float k1 = 0.0f, float k2 = 0.0f, float k3 = 0.0f) 1.87 : XCenterOffset(0), YCenterOffset(0), Scale(1.0f) 1.88 { 1.89 SetCoefficients(k0, k1, k2, k3); 1.90 SetChromaticAberration(); 1.91 } 1.92 1.93 void SetCoefficients(float k0, float k1 = 0.0f, float k2 = 0.0f, float k3 = 0.0f) 1.94 { K[0] = k0; K[1] = k1; K[2] = k2; K[3] = k3; } 1.95 1.96 void SetChromaticAberration(float red1 = 1.0f, float red2 = 0.0f, float blue1 = 1.0f, float blue2 = 0.0f) 1.97 { ChromaticAberration[0] = red1; ChromaticAberration[1] = red2; ChromaticAberration[2] = blue1; ChromaticAberration[3] = blue2; } 1.98 1.99 1.100 // DistortionFn applies distortion equation to the argument. The returned 1.101 // value should match distortion equation used in shader. 1.102 float DistortionFn(float r) const 1.103 { 1.104 float rsq = r * r; 1.105 float scale = r * (K[0] + K[1] * rsq + K[2] * rsq * rsq + K[3] * rsq * rsq * rsq); 1.106 return scale; 1.107 } 1.108 1.109 // DistortionFnInverse computes the inverse of the distortion function on an argument. 1.110 float DistortionFnInverse(float r); 1.111 1.112 float K[4]; 1.113 float XCenterOffset, YCenterOffset; 1.114 float Scale; 1.115 1.116 float ChromaticAberration[4]; // Additional per-channel scaling is applied after distortion: 1.117 // Index [0] - Red channel constant coefficient. 1.118 // Index [1] - Red channel r^2 coefficient. 1.119 // Index [2] - Blue channel constant coefficient. 1.120 // Index [3] - Blue channel r^2 coefficient. 1.121 }; 1.122 1.123 1.124 //----------------------------------------------------------------------------------- 1.125 // ***** StereoEyeParams 1.126 1.127 // StereoEyeParams describes RenderDevice configuration needed to render 1.128 // the scene for one eye. 1.129 class StereoEyeParams 1.130 { 1.131 public: 1.132 StereoEye Eye; 1.133 Viewport VP; // Viewport that we are rendering to 1.134 const DistortionConfig* pDistortion; 1.135 1.136 Matrix4f ViewAdjust; // Translation to be applied to view matrix. 1.137 Matrix4f Projection; // Projection matrix used with this eye. 1.138 Matrix4f OrthoProjection; // Orthographic projection used with this eye. 1.139 1.140 void Init(StereoEye eye, const Viewport &vp, float vofs, 1.141 const Matrix4f& proj, const Matrix4f& orthoProj, 1.142 const DistortionConfig* distortion = 0) 1.143 { 1.144 Eye = eye; 1.145 VP = vp; 1.146 ViewAdjust = Matrix4f::Translation(Vector3f(vofs,0,0)); 1.147 Projection = proj; 1.148 OrthoProjection = orthoProj; 1.149 pDistortion = distortion; 1.150 } 1.151 }; 1.152 1.153 1.154 //----------------------------------------------------------------------------------- 1.155 // ***** StereoConfig 1.156 1.157 // StereoConfig maintains a scene stereo state and allow switching between different 1.158 // stereo rendering modes. To support rendering, StereoConfig keeps track of HMD 1.159 // variables such as screen size, eye-to-screen distance and distortion, and computes 1.160 // extra data such as FOV and distortion center offsets based on it. Rendering 1.161 // parameters are returned though StereoEyeParams for each eye. 1.162 // 1.163 // Beyond regular 3D projection, this class supports rendering a 2D orthographic 1.164 // surface for UI and text. The 2D surface will be defined as fitting within a 2D 1.165 // field of view (85 degrees by default) and used [-1,1] coordinate system with 1.166 // square pixels. The (0,0) coordinate corresponds to eye center location 1.167 // that is properly adjusted during rendering through SterepRenderParams::Adjust2D. 1.168 // Genreally speaking, text outside [-1,1] coordinate range will not be readable. 1.169 1.170 class StereoConfig 1.171 { 1.172 public: 1.173 1.174 StereoConfig(StereoMode mode = Stereo_LeftRight_Multipass, 1.175 const Viewport& fullViewport = Viewport(0,0, 1280,800)); 1.176 1.177 1.178 // *** Modifiable State Access 1.179 1.180 // Sets a stereo rendering mode and updates internal cached 1.181 // state (matrices, per-eye view) based on it. 1.182 void SetStereoMode(StereoMode mode) { Mode = mode; DirtyFlag = true; } 1.183 StereoMode GetStereoMode() const { return Mode; } 1.184 1.185 // Sets HMD parameters; also initializes distortion coefficients. 1.186 void SetHMDInfo(const HMDInfo& hmd); 1.187 const HMDInfo& GetHMDInfo() const { return HMD; } 1.188 1.189 // Query physical eye-to-screen distance in meters, which combines screen-to-lens and 1.190 // and lens-to-eye pupil distances. Modifying this value adjusts FOV. 1.191 float GetEyeToScreenDistance() const { return HMD.EyeToScreenDistance; } 1.192 void SetEyeToScreenDistance(float esd) { HMD.EyeToScreenDistance = esd; DirtyFlag = true; } 1.193 1.194 // Interpupillary distance used for stereo, in meters. Default is 0.064m (64 mm). 1.195 void SetIPD(float ipd) { InterpupillaryDistance = ipd; IPDOverride = DirtyFlag = true; } 1.196 float GetIPD() const { return InterpupillaryDistance; } 1.197 1.198 // Set full render target viewport; for HMD this includes both eyes. 1.199 void SetFullViewport(const Viewport& vp); 1.200 const Viewport& GetFullViewport() const { return FullView; } 1.201 1.202 // Aspect ratio defaults to ((w/h)*multiplier) computed per eye. 1.203 // Aspect multiplier allows adjusting aspect ratio consistently for Stereo/NoStereo. 1.204 void SetAspectMultiplier(float m) { AspectMultiplier = m; DirtyFlag = true; } 1.205 float GetAspectMultiplier() const { return AspectMultiplier; } 1.206 1.207 1.208 // For the distorted image to fill rendered viewport, input texture render target needs to be 1.209 // scaled by DistortionScale before sampling. The scale factor is computed by fitting a point 1.210 // on of specified radius from a distortion center, more easily specified as a coordinate. 1.211 // SetDistortionFitPointVP sets the (x,y) coordinate of the point that scale will be "fit" to, 1.212 // assuming [-1,1] coordinate range for full left-eye viewport. A fit point is a location 1.213 // where source (pre-distortion) and target (post-distortion) image match each other. 1.214 // For the right eye, the interpretation of 'u' will be inverted. 1.215 void SetDistortionFitPointVP(float x, float y); 1.216 // SetDistortionFitPointPixels sets the (x,y) coordinate of the point that scale will be "fit" to, 1.217 // specified in pixeld for full left-eye texture. 1.218 void SetDistortionFitPointPixels(float x, float y); 1.219 1.220 // Changes all distortion settings. 1.221 // Note that setting HMDInfo also changes Distortion coefficients. 1.222 void SetDistortionConfig(const DistortionConfig& d) { Distortion = d; DirtyFlag = true; } 1.223 1.224 // Modify distortion coefficients; useful for adjustment tweaking. 1.225 void SetDistortionK(int i, float k) { Distortion.K[i] = k; DirtyFlag = true; } 1.226 float GetDistortionK(int i) const { return Distortion.K[i]; } 1.227 1.228 // Sets the fieldOfView that the 2D coordinate area stretches to. 1.229 void Set2DAreaFov(float fovRadians); 1.230 1.231 1.232 // *** Computed State 1.233 1.234 // Return current aspect ratio. 1.235 float GetAspect() { updateIfDirty(); return Aspect; } 1.236 1.237 // Return computed vertical FOV in radians/degrees. 1.238 float GetYFOVRadians() { updateIfDirty(); return YFov; } 1.239 float GetYFOVDegrees() { return RadToDegree(GetYFOVRadians()); } 1.240 1.241 // Query horizontal projection center offset as a distance away from the 1.242 // one-eye [-1,1] unit viewport. 1.243 // Positive return value should be used for left eye, negative for right eye. 1.244 float GetProjectionCenterOffset() { updateIfDirty(); return ProjectionCenterOffset; } 1.245 1.246 // GetDistortionConfig isn't const because XCenterOffset bay need to be recomputed. 1.247 const DistortionConfig& GetDistortionConfig() { updateIfDirty(); return Distortion; } 1.248 1.249 // Returns DistortionScale factor by which input texture size is increased to make 1.250 // post-distortion result distortion fit the viewport. 1.251 float GetDistortionScale() { updateIfDirty(); return Distortion.Scale; } 1.252 1.253 // Returns the size of a pixel within 2D coordinate system. 1.254 float Get2DUnitPixel() { updateIfDirty(); return (2.0f / (FovPixels * Distortion.Scale)); } 1.255 1.256 // Returns full set of Stereo rendering parameters for the specified eye. 1.257 const StereoEyeParams& GetEyeRenderParams(StereoEye eye); 1.258 1.259 private: 1.260 1.261 void updateIfDirty() { if (DirtyFlag) updateComputedState(); } 1.262 void updateComputedState(); 1.263 1.264 void updateDistortionOffsetAndScale(); 1.265 void updateProjectionOffset(); 1.266 void update2D(); 1.267 void updateEyeParams(); 1.268 1.269 1.270 // *** Modifiable State 1.271 1.272 StereoMode Mode; 1.273 float InterpupillaryDistance; 1.274 float AspectMultiplier; // Multiplied into aspect ratio to change it. 1.275 HMDInfo HMD; 1.276 DistortionConfig Distortion; 1.277 float DistortionFitX, DistortionFitY; // In [-1,1] half-screen viewport units. 1.278 Viewport FullView; // Entire window viewport. 1.279 1.280 float Area2DFov; // FOV range mapping to [-1, 1] 2D area. 1.281 1.282 // *** Computed State 1.283 1.284 bool DirtyFlag; // Set when any if the modifiable state changed. 1.285 bool IPDOverride; // True after SetIPD was called. 1.286 float YFov; // Vertical FOV. 1.287 float Aspect; // Aspect ratio: (w/h)*AspectMultiplier. 1.288 float ProjectionCenterOffset; 1.289 StereoEyeParams EyeRenderParams[2]; 1.290 1.291 1.292 // ** 2D Rendering 1.293 1.294 // Number of 2D pixels in the FOV. This defines [-1,1] coordinate range for 2D. 1.295 float FovPixels; 1.296 Matrix4f OrthoCenter; 1.297 float OrthoPixelOffset; 1.298 }; 1.299 1.300 1.301 }}} // OVR::Util::Render 1.302 1.303 #endif 1.304 \ No newline at end of file