Util_Render_Stereo.h
Go to the documentation of this file.
00001 /************************************************************************************
00002 
00003 PublicHeader:   OVR.h
00004 Filename    :   Util_Render_Stereo.h
00005 Content     :   Sample stereo rendering configuration classes.
00006 Created     :   October 22, 2012
00007 Authors     :   Michael Antonov
00008 
00009 Copyright   :   Copyright 2012 Oculus, Inc. All Rights reserved.
00010 
00011 Use of this software is subject to the terms of the Oculus Inc license
00012 agreement provided at the time of installation or download, or which
00013 otherwise accompanies this software in either electronic or hard copy form.
00014 
00015 *************************************************************************************/
00016 
00017 #ifndef OVR_Util_Render_Stereo_h
00018 #define OVR_Util_Render_Stereo_h
00019 
00020 #include "../OVR_Device.h"
00021 
00022 namespace OVR { namespace Util { namespace Render {
00023 
00024 
00025 //-----------------------------------------------------------------------------------
00026 // ***** Stereo Enumerations
00027 
00028 // StereoMode describes rendering modes that can be used by StereoConfig.
00029 // These modes control whether stereo rendering is used or not (Stereo_None),
00030 // and how it is implemented.
00031 enum StereoMode
00032 {
00033     Stereo_None                 = 0,
00034     Stereo_LeftRight_Multipass  = 1
00035 };
00036 
00037 
00038 // StereoEye specifies which eye we are rendering for; it is used to
00039 // retrieve StereoEyeParams.
00040 enum StereoEye
00041 {
00042     StereoEye_Center,
00043     StereoEye_Left,
00044     StereoEye_Right    
00045 };
00046 
00047 
00048 //-----------------------------------------------------------------------------------
00049 // ***** Viewport
00050 
00051 // Viewport describes a rectangular area used for rendering, in pixels.
00052 struct Viewport
00053 {
00054     int x, y;
00055     int w, h;
00056 
00057     Viewport() {}
00058     Viewport(int x1, int y1, int w1, int h1) : x(x1), y(y1), w(w1), h(h1) { }
00059 
00060     bool operator == (const Viewport& vp) const
00061     { return (x == vp.x) && (y == vp.y) && (w == vp.w) && (h == vp.h); }
00062     bool operator != (const Viewport& vp) const
00063     { return !operator == (vp); }
00064 };
00065 
00066 
00067 //-----------------------------------------------------------------------------------
00068 // ***** DistortionConfig
00069 
00070 // DistortionConfig Provides controls for the distortion shader.
00071 //  - K[0] - K[3] are coefficients for the distortion function.
00072 //  - XCenterOffset is the offset of lens distortion center from the 
00073 //    center of one-eye screen half. [-1, 1] Range.
00074 //  - Scale is a factor of how much larger will the input image be,
00075 //    with a factor of 1.0f being no scaling. An inverse of this 
00076 //    value is applied to sampled UV coordinates (1/Scale).
00077 //  - ChromaticAberration is an array of parameters for controlling
00078 //    additional Red and Blue scaling in order to reduce chromatic aberration
00079 //    caused by the Rift lenses.
00080 class DistortionConfig
00081 {
00082 public:
00083     DistortionConfig(float k0 = 1.0f, float k1 = 0.0f, float k2 = 0.0f, float k3 = 0.0f)
00084         : XCenterOffset(0), YCenterOffset(0), Scale(1.0f)
00085     { 
00086         SetCoefficients(k0, k1, k2, k3);
00087         SetChromaticAberration();
00088     }
00089 
00090     void SetCoefficients(float k0, float k1 = 0.0f, float k2 = 0.0f, float k3 = 0.0f)
00091     { K[0] = k0; K[1] = k1;  K[2] = k2; K[3] = k3; }
00092 
00093     void SetChromaticAberration(float red1 = 1.0f, float red2 = 0.0f, float blue1 = 1.0f, float blue2 = 0.0f)
00094     { ChromaticAberration[0] = red1; ChromaticAberration[1] = red2; ChromaticAberration[2] = blue1; ChromaticAberration[3] = blue2; }
00095 
00096 
00097     // DistortionFn applies distortion equation to the argument. The returned
00098     // value should match distortion equation used in shader.
00099     float  DistortionFn(float r) const
00100     {        
00101         float rsq   = r * r;
00102         float scale = r * (K[0] + K[1] * rsq + K[2] * rsq * rsq + K[3] * rsq * rsq * rsq);
00103         return scale;
00104     }
00105 
00106     // DistortionFnInverse computes the inverse of the distortion function on an argument.
00107     float DistortionFnInverse(float r);
00108 
00109     float   K[4];
00110     float   XCenterOffset, YCenterOffset;
00111     float   Scale;
00112 
00113     float   ChromaticAberration[4]; // Additional per-channel scaling is applied after distortion:
00114                                     // Index [0] - Red channel constant coefficient.
00115                                     // Index [1] - Red channel r^2 coefficient.
00116                                     // Index [2] - Blue channel constant coefficient.
00117                                     // Index [3] - Blue channel r^2 coefficient.
00118 };
00119 
00120 
00121 //-----------------------------------------------------------------------------------
00122 // ***** StereoEyeParams
00123 
00124 // StereoEyeParams describes RenderDevice configuration needed to render
00125 // the scene for one eye. 
00126 class StereoEyeParams
00127 {
00128 public:
00129     StereoEye                Eye;
00130     Viewport                 VP;               // Viewport that we are rendering to        
00131     const DistortionConfig*  pDistortion;
00132 
00133     Matrix4f                 ViewAdjust;       // Translation to be applied to view matrix.
00134     Matrix4f                 Projection;       // Projection matrix used with this eye.
00135     Matrix4f                 OrthoProjection;  // Orthographic projection used with this eye.
00136 
00137     void Init(StereoEye eye, const Viewport &vp, float vofs,
00138               const Matrix4f& proj, const Matrix4f& orthoProj,
00139               const DistortionConfig* distortion = 0)
00140     {
00141         Eye                    = eye;
00142         VP                     = vp;
00143         ViewAdjust             = Matrix4f::Translation(Vector3f(vofs,0,0));
00144         Projection             = proj;
00145         OrthoProjection        = orthoProj;
00146         pDistortion            = distortion;        
00147     }
00148 };
00149 
00150 
00151 //-----------------------------------------------------------------------------------
00152 // *****  StereoConfig
00153 
00154 // StereoConfig maintains a scene stereo state and allow switching between different
00155 // stereo rendering modes. To support rendering, StereoConfig keeps track of HMD
00156 // variables such as screen size, eye-to-screen distance and distortion, and computes
00157 // extra data such as FOV and distortion center offsets based on it. Rendering
00158 // parameters are returned though StereoEyeParams for each eye.
00159 //
00160 // Beyond regular 3D projection, this class supports rendering a 2D orthographic
00161 // surface for UI and text. The 2D surface will be defined as fitting within a 2D
00162 // field of view (85 degrees by default) and used [-1,1] coordinate system with
00163 // square pixels. The (0,0) coordinate corresponds to eye center location
00164 // that is properly adjusted during rendering through SterepRenderParams::Adjust2D.
00165 // Genreally speaking, text outside [-1,1] coordinate range will not be readable.
00166 
00167 class StereoConfig
00168 {
00169 public:
00170 
00171     StereoConfig(StereoMode mode = Stereo_LeftRight_Multipass,
00172                  const Viewport& fullViewport = Viewport(0,0, 1280,800));
00173  
00174 
00175     // *** Modifiable State Access
00176 
00177     // Sets a stereo rendering mode and updates internal cached
00178     // state (matrices, per-eye view) based on it.
00179     void        SetStereoMode(StereoMode mode)  { Mode = mode; DirtyFlag = true; }
00180     StereoMode  GetStereoMode() const           { return Mode; }
00181 
00182     // Sets HMD parameters; also initializes distortion coefficients.
00183     void        SetHMDInfo(const HMDInfo& hmd);
00184     const HMDInfo& GetHMDInfo() const           { return HMD; }
00185 
00186     // Query physical eye-to-screen distance in meters, which combines screen-to-lens and
00187     // and lens-to-eye pupil distances. Modifying this value adjusts FOV.
00188     float       GetEyeToScreenDistance() const  { return HMD.EyeToScreenDistance; }
00189     void        SetEyeToScreenDistance(float esd) { HMD.EyeToScreenDistance = esd; DirtyFlag = true; }
00190 
00191     // Interpupillary distance used for stereo, in meters. Default is 0.064m (64 mm).
00192     void        SetIPD(float ipd)               { InterpupillaryDistance = ipd; IPDOverride = DirtyFlag = true; }
00193     float       GetIPD() const                  { return InterpupillaryDistance; }
00194 
00195     // Set full render target viewport; for HMD this includes both eyes. 
00196     void        SetFullViewport(const Viewport& vp);
00197     const Viewport& GetFullViewport() const     { return FullView; }
00198 
00199     // Aspect ratio defaults to ((w/h)*multiplier) computed per eye.
00200     // Aspect multiplier allows adjusting aspect ratio consistently for Stereo/NoStereo.
00201     void        SetAspectMultiplier(float m)    { AspectMultiplier = m; DirtyFlag = true; }
00202     float       GetAspectMultiplier() const     { return AspectMultiplier; }
00203 
00204     
00205     // For the distorted image to fill rendered viewport, input texture render target needs to be
00206     // scaled by DistortionScale before sampling. The scale factor is computed by fitting a point
00207     // on of specified radius from a distortion center, more easily specified as a coordinate.
00208     // SetDistortionFitPointVP sets the (x,y) coordinate of the point that scale will be "fit" to,
00209     // assuming [-1,1] coordinate range for full left-eye viewport. A fit point is a location
00210     // where source (pre-distortion) and target (post-distortion) image match each other.
00211     // For the right eye, the interpretation of 'u' will be inverted.  
00212     void       SetDistortionFitPointVP(float x, float y);
00213     // SetDistortionFitPointPixels sets the (x,y) coordinate of the point that scale will be "fit" to,
00214     // specified in pixeld for full left-eye texture.
00215     void       SetDistortionFitPointPixels(float x, float y);
00216 
00217     // Changes all distortion settings.
00218     // Note that setting HMDInfo also changes Distortion coefficients.
00219     void        SetDistortionConfig(const DistortionConfig& d) { Distortion = d; DirtyFlag = true; }
00220     
00221     // Modify distortion coefficients; useful for adjustment tweaking.
00222     void        SetDistortionK(int i, float k)  { Distortion.K[i] = k; DirtyFlag = true; }
00223     float       GetDistortionK(int i) const     { return Distortion.K[i]; }
00224 
00225     // Sets the fieldOfView that the 2D coordinate area stretches to.
00226     void        Set2DAreaFov(float fovRadians);
00227 
00228 
00229     // *** Computed State
00230 
00231     // Return current aspect ratio.
00232     float      GetAspect()                      { updateIfDirty(); return Aspect; }
00233     
00234     // Return computed vertical FOV in radians/degrees.
00235     float      GetYFOVRadians()                 { updateIfDirty(); return YFov; }
00236     float      GetYFOVDegrees()                 { return RadToDegree(GetYFOVRadians()); }
00237 
00238     // Query horizontal projection center offset as a distance away from the
00239     // one-eye [-1,1] unit viewport.
00240     // Positive return value should be used for left eye, negative for right eye. 
00241     float      GetProjectionCenterOffset()      { updateIfDirty(); return ProjectionCenterOffset; }
00242 
00243     // GetDistortionConfig isn't const because XCenterOffset bay need to be recomputed.  
00244     const DistortionConfig& GetDistortionConfig() { updateIfDirty(); return Distortion; }
00245 
00246     // Returns DistortionScale factor by which input texture size is increased to make
00247     // post-distortion result distortion fit the viewport.
00248     float      GetDistortionScale()             { updateIfDirty(); return Distortion.Scale; }
00249 
00250     // Returns the size of a pixel within 2D coordinate system.
00251     float      Get2DUnitPixel()                 { updateIfDirty();  return (2.0f / (FovPixels * Distortion.Scale)); }
00252 
00253     // Returns full set of Stereo rendering parameters for the specified eye.
00254     const StereoEyeParams& GetEyeRenderParams(StereoEye eye);
00255    
00256 private:    
00257 
00258     void updateIfDirty()   { if (DirtyFlag) updateComputedState(); }
00259     void updateComputedState();
00260 
00261     void updateDistortionOffsetAndScale();
00262     void updateProjectionOffset();
00263     void update2D();
00264     void updateEyeParams();
00265 
00266 
00267     // *** Modifiable State
00268 
00269     StereoMode         Mode;
00270     float              InterpupillaryDistance;
00271     float              AspectMultiplier;               // Multiplied into aspect ratio to change it.
00272     HMDInfo            HMD;
00273     DistortionConfig   Distortion;
00274     float              DistortionFitX, DistortionFitY; // In [-1,1] half-screen viewport units.
00275     Viewport           FullView;                       // Entire window viewport.
00276 
00277     float              Area2DFov;                      // FOV range mapping to [-1, 1] 2D area.
00278  
00279     // *** Computed State
00280  
00281     bool               DirtyFlag;   // Set when any if the modifiable state changed.
00282     bool               IPDOverride; // True after SetIPD was called.    
00283     float              YFov;        // Vertical FOV.
00284     float              Aspect;      // Aspect ratio: (w/h)*AspectMultiplier.
00285     float              ProjectionCenterOffset;
00286     StereoEyeParams    EyeRenderParams[2];
00287 
00288   
00289     // ** 2D Rendering
00290 
00291     // Number of 2D pixels in the FOV. This defines [-1,1] coordinate range for 2D.  
00292     float              FovPixels;
00293     Matrix4f           OrthoCenter;
00294     float              OrthoPixelOffset;
00295 };
00296 
00297 
00298 }}}  // OVR::Util::Render
00299 
00300 #endif


oculus_sdk
Author(s): Tully Foote
autogenerated on Thu Jun 6 2019 20:13:49