oculus1

view libovr/Src/Util/Util_Render_Stereo.h @ 23:0c76f70fb7e9

merged
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 28 Sep 2013 04:13:33 +0300
parents e2f9e4603129
children
line source
1 /************************************************************************************
3 PublicHeader: OVR.h
4 Filename : Util_Render_Stereo.h
5 Content : Sample stereo rendering configuration classes.
6 Created : October 22, 2012
7 Authors : Michael Antonov
9 Copyright : Copyright 2012 Oculus, Inc. All Rights reserved.
11 Use of this software is subject to the terms of the Oculus Inc license
12 agreement provided at the time of installation or download, or which
13 otherwise accompanies this software in either electronic or hard copy form.
15 *************************************************************************************/
17 #ifndef OVR_Util_Render_Stereo_h
18 #define OVR_Util_Render_Stereo_h
20 #include "../OVR_Device.h"
22 namespace OVR { namespace Util { namespace Render {
25 //-----------------------------------------------------------------------------------
26 // ***** Stereo Enumerations
28 // StereoMode describes rendering modes that can be used by StereoConfig.
29 // These modes control whether stereo rendering is used or not (Stereo_None),
30 // and how it is implemented.
31 enum StereoMode
32 {
33 Stereo_None = 0,
34 Stereo_LeftRight_Multipass = 1
35 };
38 // StereoEye specifies which eye we are rendering for; it is used to
39 // retrieve StereoEyeParams.
40 enum StereoEye
41 {
42 StereoEye_Center,
43 StereoEye_Left,
44 StereoEye_Right
45 };
48 //-----------------------------------------------------------------------------------
49 // ***** Viewport
51 // Viewport describes a rectangular area used for rendering, in pixels.
52 struct Viewport
53 {
54 int x, y;
55 int w, h;
57 Viewport() {}
58 Viewport(int x1, int y1, int w1, int h1) : x(x1), y(y1), w(w1), h(h1) { }
60 bool operator == (const Viewport& vp) const
61 { return (x == vp.x) && (y == vp.y) && (w == vp.w) && (h == vp.h); }
62 bool operator != (const Viewport& vp) const
63 { return !operator == (vp); }
64 };
67 //-----------------------------------------------------------------------------------
68 // ***** DistortionConfig
70 // DistortionConfig Provides controls for the distortion shader.
71 // - K[0] - K[3] are coefficients for the distortion function.
72 // - XCenterOffset is the offset of lens distortion center from the
73 // center of one-eye screen half. [-1, 1] Range.
74 // - Scale is a factor of how much larger will the input image be,
75 // with a factor of 1.0f being no scaling. An inverse of this
76 // value is applied to sampled UV coordinates (1/Scale).
77 // - ChromaticAberration is an array of parameters for controlling
78 // additional Red and Blue scaling in order to reduce chromatic aberration
79 // caused by the Rift lenses.
80 class DistortionConfig
81 {
82 public:
83 DistortionConfig(float k0 = 1.0f, float k1 = 0.0f, float k2 = 0.0f, float k3 = 0.0f)
84 : XCenterOffset(0), YCenterOffset(0), Scale(1.0f)
85 {
86 SetCoefficients(k0, k1, k2, k3);
87 SetChromaticAberration();
88 }
90 void SetCoefficients(float k0, float k1 = 0.0f, float k2 = 0.0f, float k3 = 0.0f)
91 { K[0] = k0; K[1] = k1; K[2] = k2; K[3] = k3; }
93 void SetChromaticAberration(float red1 = 1.0f, float red2 = 0.0f, float blue1 = 1.0f, float blue2 = 0.0f)
94 { ChromaticAberration[0] = red1; ChromaticAberration[1] = red2; ChromaticAberration[2] = blue1; ChromaticAberration[3] = blue2; }
97 // DistortionFn applies distortion equation to the argument. The returned
98 // value should match distortion equation used in shader.
99 float DistortionFn(float r) const
100 {
101 float rsq = r * r;
102 float scale = r * (K[0] + K[1] * rsq + K[2] * rsq * rsq + K[3] * rsq * rsq * rsq);
103 return scale;
104 }
106 // DistortionFnInverse computes the inverse of the distortion function on an argument.
107 float DistortionFnInverse(float r);
109 float K[4];
110 float XCenterOffset, YCenterOffset;
111 float Scale;
113 float ChromaticAberration[4]; // Additional per-channel scaling is applied after distortion:
114 // Index [0] - Red channel constant coefficient.
115 // Index [1] - Red channel r^2 coefficient.
116 // Index [2] - Blue channel constant coefficient.
117 // Index [3] - Blue channel r^2 coefficient.
118 };
121 //-----------------------------------------------------------------------------------
122 // ***** StereoEyeParams
124 // StereoEyeParams describes RenderDevice configuration needed to render
125 // the scene for one eye.
126 class StereoEyeParams
127 {
128 public:
129 StereoEye Eye;
130 Viewport VP; // Viewport that we are rendering to
131 const DistortionConfig* pDistortion;
133 Matrix4f ViewAdjust; // Translation to be applied to view matrix.
134 Matrix4f Projection; // Projection matrix used with this eye.
135 Matrix4f OrthoProjection; // Orthographic projection used with this eye.
137 void Init(StereoEye eye, const Viewport &vp, float vofs,
138 const Matrix4f& proj, const Matrix4f& orthoProj,
139 const DistortionConfig* distortion = 0)
140 {
141 Eye = eye;
142 VP = vp;
143 ViewAdjust = Matrix4f::Translation(Vector3f(vofs,0,0));
144 Projection = proj;
145 OrthoProjection = orthoProj;
146 pDistortion = distortion;
147 }
148 };
151 //-----------------------------------------------------------------------------------
152 // ***** StereoConfig
154 // StereoConfig maintains a scene stereo state and allow switching between different
155 // stereo rendering modes. To support rendering, StereoConfig keeps track of HMD
156 // variables such as screen size, eye-to-screen distance and distortion, and computes
157 // extra data such as FOV and distortion center offsets based on it. Rendering
158 // parameters are returned though StereoEyeParams for each eye.
159 //
160 // Beyond regular 3D projection, this class supports rendering a 2D orthographic
161 // surface for UI and text. The 2D surface will be defined as fitting within a 2D
162 // field of view (85 degrees by default) and used [-1,1] coordinate system with
163 // square pixels. The (0,0) coordinate corresponds to eye center location
164 // that is properly adjusted during rendering through SterepRenderParams::Adjust2D.
165 // Genreally speaking, text outside [-1,1] coordinate range will not be readable.
167 class StereoConfig
168 {
169 public:
171 StereoConfig(StereoMode mode = Stereo_LeftRight_Multipass,
172 const Viewport& fullViewport = Viewport(0,0, 1280,800));
175 // *** Modifiable State Access
177 // Sets a stereo rendering mode and updates internal cached
178 // state (matrices, per-eye view) based on it.
179 void SetStereoMode(StereoMode mode) { Mode = mode; DirtyFlag = true; }
180 StereoMode GetStereoMode() const { return Mode; }
182 // Sets HMD parameters; also initializes distortion coefficients.
183 void SetHMDInfo(const HMDInfo& hmd);
184 const HMDInfo& GetHMDInfo() const { return HMD; }
186 // Query physical eye-to-screen distance in meters, which combines screen-to-lens and
187 // and lens-to-eye pupil distances. Modifying this value adjusts FOV.
188 float GetEyeToScreenDistance() const { return HMD.EyeToScreenDistance; }
189 void SetEyeToScreenDistance(float esd) { HMD.EyeToScreenDistance = esd; DirtyFlag = true; }
191 // Interpupillary distance used for stereo, in meters. Default is 0.064m (64 mm).
192 void SetIPD(float ipd) { InterpupillaryDistance = ipd; IPDOverride = DirtyFlag = true; }
193 float GetIPD() const { return InterpupillaryDistance; }
195 // Set full render target viewport; for HMD this includes both eyes.
196 void SetFullViewport(const Viewport& vp);
197 const Viewport& GetFullViewport() const { return FullView; }
199 // Aspect ratio defaults to ((w/h)*multiplier) computed per eye.
200 // Aspect multiplier allows adjusting aspect ratio consistently for Stereo/NoStereo.
201 void SetAspectMultiplier(float m) { AspectMultiplier = m; DirtyFlag = true; }
202 float GetAspectMultiplier() const { return AspectMultiplier; }
205 // For the distorted image to fill rendered viewport, input texture render target needs to be
206 // scaled by DistortionScale before sampling. The scale factor is computed by fitting a point
207 // on of specified radius from a distortion center, more easily specified as a coordinate.
208 // SetDistortionFitPointVP sets the (x,y) coordinate of the point that scale will be "fit" to,
209 // assuming [-1,1] coordinate range for full left-eye viewport. A fit point is a location
210 // where source (pre-distortion) and target (post-distortion) image match each other.
211 // For the right eye, the interpretation of 'u' will be inverted.
212 void SetDistortionFitPointVP(float x, float y);
213 // SetDistortionFitPointPixels sets the (x,y) coordinate of the point that scale will be "fit" to,
214 // specified in pixeld for full left-eye texture.
215 void SetDistortionFitPointPixels(float x, float y);
217 // Changes all distortion settings.
218 // Note that setting HMDInfo also changes Distortion coefficients.
219 void SetDistortionConfig(const DistortionConfig& d) { Distortion = d; DirtyFlag = true; }
221 // Modify distortion coefficients; useful for adjustment tweaking.
222 void SetDistortionK(int i, float k) { Distortion.K[i] = k; DirtyFlag = true; }
223 float GetDistortionK(int i) const { return Distortion.K[i]; }
225 // Sets the fieldOfView that the 2D coordinate area stretches to.
226 void Set2DAreaFov(float fovRadians);
229 // *** Computed State
231 // Return current aspect ratio.
232 float GetAspect() { updateIfDirty(); return Aspect; }
234 // Return computed vertical FOV in radians/degrees.
235 float GetYFOVRadians() { updateIfDirty(); return YFov; }
236 float GetYFOVDegrees() { return RadToDegree(GetYFOVRadians()); }
238 // Query horizontal projection center offset as a distance away from the
239 // one-eye [-1,1] unit viewport.
240 // Positive return value should be used for left eye, negative for right eye.
241 float GetProjectionCenterOffset() { updateIfDirty(); return ProjectionCenterOffset; }
243 // GetDistortionConfig isn't const because XCenterOffset bay need to be recomputed.
244 const DistortionConfig& GetDistortionConfig() { updateIfDirty(); return Distortion; }
246 // Returns DistortionScale factor by which input texture size is increased to make
247 // post-distortion result distortion fit the viewport.
248 float GetDistortionScale() { updateIfDirty(); return Distortion.Scale; }
250 // Returns the size of a pixel within 2D coordinate system.
251 float Get2DUnitPixel() { updateIfDirty(); return (2.0f / (FovPixels * Distortion.Scale)); }
253 // Returns full set of Stereo rendering parameters for the specified eye.
254 const StereoEyeParams& GetEyeRenderParams(StereoEye eye);
256 private:
258 void updateIfDirty() { if (DirtyFlag) updateComputedState(); }
259 void updateComputedState();
261 void updateDistortionOffsetAndScale();
262 void updateProjectionOffset();
263 void update2D();
264 void updateEyeParams();
267 // *** Modifiable State
269 StereoMode Mode;
270 float InterpupillaryDistance;
271 float AspectMultiplier; // Multiplied into aspect ratio to change it.
272 HMDInfo HMD;
273 DistortionConfig Distortion;
274 float DistortionFitX, DistortionFitY; // In [-1,1] half-screen viewport units.
275 Viewport FullView; // Entire window viewport.
277 float Area2DFov; // FOV range mapping to [-1, 1] 2D area.
279 // *** Computed State
281 bool DirtyFlag; // Set when any if the modifiable state changed.
282 bool IPDOverride; // True after SetIPD was called.
283 float YFov; // Vertical FOV.
284 float Aspect; // Aspect ratio: (w/h)*AspectMultiplier.
285 float ProjectionCenterOffset;
286 StereoEyeParams EyeRenderParams[2];
289 // ** 2D Rendering
291 // Number of 2D pixels in the FOV. This defines [-1,1] coordinate range for 2D.
292 float FovPixels;
293 Matrix4f OrthoCenter;
294 float OrthoPixelOffset;
295 };
298 }}} // OVR::Util::Render
300 #endif