SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SLGLOculus.cpp
Go to the documentation of this file.
1 /**
2  * \file SLOculus.cpp
3  * \brief Wrapper around Oculus Rift
4  * \date July 2014
5  * \remarks Please use clangformat to format the code. See more code style on
6  * https://github.com/cpvrlab/SLProject4/wiki/SLProject-Coding-Style
7  * \authors Marc Wacker, Roman Kuehne, Marcus Hudritsch
8  * \copyright http://opensource.org/licenses/GPL-3.0
9 */
10 
11 #include <SLGLState.h>
12 #include <SLGLOVRWorkaround.h>
13 #include <SLGLOculus.h>
14 #include <SLGLProgram.h>
15 
16 //-----------------------------------------------------------------------------
17 /*! Constructor initializing with default values
18  */
20  : _usingDebugHmd(false),
21  _positionTrackingEnabled(false),
22  _lowPersistanceEnabled(false),
23  _timeWarpEnabled(false),
24  _displaySleep(false),
25  _isConnected(false),
26  _isCameraConnected(false),
27  _isPositionTracked(false),
28  _shaderFileDir(shaderDir)
29 {
30 }
31 //-----------------------------------------------------------------------------
32 /*! Destructor calling dispose
33  */
35 {
36  dispose();
37 
39  {
41  _stereoOculusDistProgram = nullptr;
42  }
43 }
44 //-----------------------------------------------------------------------------
45 /*! Deletes the buffer object
46  */
48 {
49 }
50 //-----------------------------------------------------------------------------
51 /*! Initialization of the Oculus Rift SDK and the device recognition.
52  */
54 {
56  _shaderFileDir + "StereoOculusDistortionMesh.vert",
57  _shaderFileDir + "StereoOculusDistortionMesh.frag");
58  _resolutionScale = 1.25f;
59  _resolution.set(1920, 1080);
60  renderResolution(1920, 1080);
61 
62  for (SLint i = 0; i < 2; ++i)
63  {
64  _position[i].set(0, 0, 0);
65  _orientation[i].set(0, 0, 0, 1);
66  _viewAdjust[i].set((i * 2 - 1) * 0.03f, 0, 0); //[-0.03, 0.03]m
67 
68  // not 100% correct projections but it just has to look somewhat right
69  _projection[i].perspective(125.0f, 0.88f, 0.1f, 1000.0f);
71  }
72 
75 }
76 //-----------------------------------------------------------------------------
77 /*! Renders the distortion mesh with time warp and chromatic abberation
78  */
80  SLint height,
81  SLuint tex,
82  const SLCol4f& background)
83 {
84  assert(_stereoOculusDistProgram && "SLGLOculus::renderDistortion: shader program not set");
86 
87  glViewport(0, 0, width, height);
88  glBindFramebuffer(GL_FRAMEBUFFER, 0);
89  glClearColor(0, 0, 0, 1);
90  glClear(GL_COLOR_BUFFER_BIT);
91  glDisable(GL_DEPTH_TEST);
92  glDisable(GL_CULL_FACE);
93  glActiveTexture(GL_TEXTURE0);
94  glBindTexture(GL_TEXTURE_2D, tex);
95 
96  sp->beginUse(nullptr, nullptr, nullptr);
97 
98  for (auto& eye : _distortionMeshVAO)
99  {
100  sp->uniform1i("u_texture", 0);
101  sp->uniform2f("u_eyeToSourceUVScale", 0.232f, -0.376f);
102  sp->uniform2f("u_eyeToSourceUVOffset", 0.246f, 0.5f);
103  SLMat4f identity;
104 
105  sp->uniformMatrix4fv("u_eyeRotationStart", 1, identity.m());
106  sp->uniformMatrix4fv("u_eyeRotationEnd", 1, identity.m());
107  eye.drawElementsAs(PT_triangles);
108  }
109 
110  sp->endUse();
111 
112  glEnable(GL_DEPTH_TEST);
113  glEnable(GL_CULL_FACE);
114 }
115 //-----------------------------------------------------------------------------
116 /*! Returns the view adjust vector as reported by the HMD for the specified eye
117  */
119 {
120  if (eye == ET_left)
121  return _viewAdjust[0];
122  else
123  return _viewAdjust[1];
124 }
125 //-----------------------------------------------------------------------------
126 /*! Returns an perspective projection matrix for the specified eye
127  */
128 const SLMat4f&
130 {
131  if (eye == ET_left)
132  return _projection[0];
133  else
134  return _projection[1];
135 }
136 //-----------------------------------------------------------------------------
137 /*! Returns an orthogonal projection matrix for the specified eye
138  */
139 const SLMat4f&
141 {
142  if (eye == ET_left)
143  return _orthoProjection[0];
144  else
145  return _orthoProjection[1];
146 }
147 //-----------------------------------------------------------------------------
148 /*! Recalculates values such as projection or render target size
149 This function gets called whenever some settings changed.
150 */
152 {
153  for (SLint i = 0; i < 2; ++i)
154  {
155  _position[i].set(0, 0, 0);
156  _orientation[i].set(0, 0, 0, 1);
157  _viewAdjust[i].set((i * 2 - 1) * 0.03f, 0, 0); //[-0.03, 0.03]m
158 
159  ovrFovPort fov;
160  fov.DownTan = 1.329f;
161  fov.UpTan = 1.329f;
162  fov.LeftTan = 1.058f;
163  fov.RightTan = 1.092f;
164  _projection[i] = CreateProjection(true, fov, 0.01f, 10000.0f);
165 
167  SLVec2f(1.0f / (549.618286f * ((SLfloat)_outputRes.x / _resolution.x)),
168  1.0f / (549.618286f * ((SLfloat)_outputRes.x / _resolution.x))),
169  0.8f,
170  _viewAdjust[i].x);
171 
172  SLMat4f flipY(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
173  _orthoProjection[i] = flipY * _orthoProjection[i];
174  }
175 
176  // done
177  _hmdSettingsChanged = false;
178 }
179 //-----------------------------------------------------------------------------
180 /*! Specify the final output resolution for this rift
181  */
183 {
184  if (width == _outputRes.x && height == _outputRes.y)
185  return;
186 
187  _outputRes.x = width;
188  _outputRes.y = height;
189 
190  _hmdSettingsChanged = true;
191 }
192 //-----------------------------------------------------------------------------
193 /*! Updates rift status and collects data for timewarp
194  */
196 {
197  // update changed settings
200 }
201 //-----------------------------------------------------------------------------
202 /*! Returns the Oculus orientation as quaternion. If no Oculus Rift is
203 recognized it returns a unit quaternion.
204 */
206 {
207  if (eye == ET_left)
208  return _orientation[0];
209  else
210  return _orientation[1];
211 }
212 //-----------------------------------------------------------------------------
213 /*! Returns the Oculus position.
214  */
216 {
217  if (eye == ET_left)
218  return _position[0];
219  else
220  return _position[1];
221 }
222 //-----------------------------------------------------------------------------
223 /*! enable or disable low persistance
224  */
226 {
227  if (val == _lowPersistanceEnabled)
228  return;
229 
231  _hmdSettingsChanged = true;
232 }
233 //-----------------------------------------------------------------------------
234 /*! enable or disable timewarp
235  */
237 {
238  if (val == _timeWarpEnabled)
239  return;
240 
241  _timeWarpEnabled = val;
242  _hmdSettingsChanged = true;
243 }
244 //-----------------------------------------------------------------------------
245 /*! enable or disable position tracking
246  */
248 {
249  if (val == _positionTrackingEnabled)
250  return;
251 
253  _hmdSettingsChanged = true;
254 }
255 //-----------------------------------------------------------------------------
256 /*! enable or disable position tracking
257  */
259 {
260  if (val == _displaySleep)
261  return;
262 
263  _displaySleep = val;
264  _hmdSettingsChanged = true;
265 }
266 //-----------------------------------------------------------------------------
float SLfloat
Definition: SL.h:173
unsigned int SLuint
Definition: SL.h:171
bool SLbool
Definition: SL.h:175
string SLstring
Definition: SL.h:158
int SLint
Definition: SL.h:170
SLEyeType
Enumeration for stereo eye type used for camera projection.
Definition: SLEnums.h:152
@ ET_right
Definition: SLEnums.h:155
@ ET_left
Definition: SLEnums.h:153
@ PT_triangles
Definition: SLGLEnums.h:35
Wrapper around Oculus Rift.
void createSLDistortionMesh(DistortionMeshVertexData **ppVertices, uint16_t **ppTriangleListIndices, SLuint *pNumVertices, SLuint *pNumTriangles, bool rightEye, const HmdRenderInfo &hmdRenderInfo, const DistortionRenderDesc &distortion, const ScaleAndOffset2D &eyeToSourceNDC)
SLMat4f ovrMatrix4f_OrthoSubProjection(SLMat4f projection, SLVec2f orthoScale, float orthoDistance, float eyeViewAdjustX)
SLMat4f CreateProjection(bool rightHanded, ovrFovPort tanHalfFov, float zNear, float zFar)
Singleton class for global render state.
SLVec2< SLfloat > SLVec2f
Definition: SLVec2.h:141
void positionTracking(SLbool val)
Definition: SLGLOculus.cpp:247
const SLVec3f & viewAdjust(SLEyeType eye)
Definition: SLGLOculus.cpp:118
const SLQuat4f & orientation(SLEyeType eye)
Definition: SLGLOculus.cpp:205
void lowPersistance(SLbool val)
Definition: SLGLOculus.cpp:225
SLbool _hmdSettingsChanged
settings need to be updated flag
Definition: SLGLOculus.h:103
void init()
Definition: SLGLOculus.cpp:53
SLstring _shaderFileDir
Definition: SLGLOculus.h:107
const SLVec3f & position(SLEyeType eye)
Definition: SLGLOculus.cpp:215
void beginFrame()
Definition: SLGLOculus.cpp:195
SLVec2i _resolution
Resolution of the HMD.
Definition: SLGLOculus.h:100
SLVec3f _viewAdjust[2]
view adjust vector
Definition: SLGLOculus.h:84
SLGLVertexArray _distortionMeshVAO[2]
distortion meshes for left and right eye
Definition: SLGLOculus.h:85
const SLMat4f & orthoProjection(SLEyeType eye)
Definition: SLGLOculus.cpp:140
const SLMat4f & projection(SLEyeType eye)
Definition: SLGLOculus.cpp:129
void renderDistortion(SLint width, SLint height, SLuint tex, const SLCol4f &background)
Definition: SLGLOculus.cpp:79
SLVec2i _outputRes
output resolution used for ortho projection
Definition: SLGLOculus.h:78
void dispose()
Definition: SLGLOculus.cpp:47
SLVec3f _position[2]
eye position
Definition: SLGLOculus.h:81
SLMat4f _projection[2]
projection matrices for left and right eye
Definition: SLGLOculus.h:82
void calculateHmdValues()
recalculate HMD settings changed
Definition: SLGLOculus.cpp:151
SLbool _displaySleep
is the display of the rift currently off
Definition: SLGLOculus.h:94
SLbool _timeWarpEnabled
time warp correction enabled
Definition: SLGLOculus.h:93
SLbool _lowPersistanceEnabled
low persistence rendering enabled
Definition: SLGLOculus.h:92
SLQuat4f _orientation[2]
eye orientation
Definition: SLGLOculus.h:80
SLGLOculus(SLstring shaderDir)
Definition: SLGLOculus.cpp:19
SLfloat _resolutionScale
required resolution scale for a 1.0 min pixel density
Definition: SLGLOculus.h:87
void timeWarp(SLbool val)
Definition: SLGLOculus.cpp:236
SLGLProgram * _stereoOculusDistProgram
Definition: SLGLOculus.h:105
void renderResolution(SLint width, SLint height)
Definition: SLGLOculus.cpp:182
void displaySleep(SLbool val)
Definition: SLGLOculus.cpp:258
SLMat4f _orthoProjection[2]
projection for 2d elements
Definition: SLGLOculus.h:83
SLbool _positionTrackingEnabled
is position tracking enabled
Definition: SLGLOculus.h:91
Generic Shader Program class inherited from SLGLProgram.
Encapsulation of an OpenGL shader program object.
Definition: SLGLProgram.h:56
SLint uniformMatrix4fv(const SLchar *name, SLsizei count, const SLfloat *value, GLboolean transpose=false) const
Passes a 4x4 float matrix values py pointer to the uniform variable "name".
void beginUse(SLCamera *cam, SLMaterial *mat, SLVLight *lights)
SLint uniform2f(const SLchar *name, SLfloat v0, SLfloat v1) const
Passes the float values v0 & v1 to the uniform variable "name".
SLint uniform1i(const SLchar *name, SLint v0) const
Passes the int values v0 to the uniform variable "name".
void endUse()
SLGLProgram::endUse stops the shader program.
void m(int i, T val)
Definition: SLMat4.h:93
void perspective(T fov, T aspect, T n, T f)
Defines a perspective projection matrix with a field of view angle.
Definition: SLMat4.h:874
void translate(T tx, T ty, T tz=0)
Definition: SLMat4.h:601
void set(T x, T y, T z, T w)
Definition: SLQuat4.h:140
T y
Definition: SLVec2.h:30
T x
Definition: SLVec2.h:30
void set(const T X, const T Y)
Definition: SLVec2.h:40
T x
Definition: SLVec3.h:43
void set(const T X, const T Y, const T Z)
Definition: SLVec3.h:59
float DownTan
The tangent of the angle between the viewing vector and the bottom edge of the field of view.
float UpTan
The tangent of the angle between the viewing vector and the top edge of the field of view.
float RightTan
The tangent of the angle between the viewing vector and the right edge of the field of view.
float LeftTan
The tangent of the angle between the viewing vector and the left edge of the field of view.