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