From 61b20b2be0880e9607bb8e888fe1444866e2cb64 Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Thu, 26 Jun 2014 09:56:19 -0700 Subject: [PATCH] Working 3.2 Oculus SDK --- interface/resources/shaders/oculus.frag | 36 +-- interface/resources/shaders/oculus.vert | 64 +++++ interface/src/devices/OculusManager.cpp | 328 +++++++++++++++++------- interface/src/devices/OculusManager.h | 52 +++- 4 files changed, 356 insertions(+), 124 deletions(-) create mode 100644 interface/resources/shaders/oculus.vert diff --git a/interface/resources/shaders/oculus.frag b/interface/resources/shaders/oculus.frag index f2b066a974..8e96428e17 100644 --- a/interface/resources/shaders/oculus.frag +++ b/interface/resources/shaders/oculus.frag @@ -4,12 +4,11 @@ // oculus.frag // fragment shader // -// Created by Andrzej Kapolka on 11/26/13. -// Copyright 2013 High Fidelity, Inc. +// Created by Ben Arnold on 6/24/14. +// Copyright 2014 High Fidelity, Inc. // -// this shader is an adaptation (HLSL -> GLSL, removed conditional) of the one in the Oculus sample -// code (Samples/OculusRoomTiny/RenderTiny_D3D1X_Device.cpp), which is under the Apache license -// (http://www.apache.org/licenses/LICENSE-2.0) +// this shader is an adaptation (HLSL -> GLSL) of the one in the +// Oculus_SDK_Overview.pdf for the 3.2 SDK. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -17,23 +16,16 @@ uniform sampler2D texture; -uniform vec2 lensCenter; -uniform vec2 screenCenter; -uniform vec2 scale; -uniform vec2 scaleIn; -uniform vec4 hmdWarpParam; - -vec2 hmdWarp(vec2 in01) { - vec2 theta = (in01 - lensCenter) * scaleIn; - float rSq = theta.x * theta.x + theta.y * theta.y; - vec2 theta1 = theta * (hmdWarpParam.x + hmdWarpParam.y * rSq + - hmdWarpParam.z * rSq * rSq + hmdWarpParam.w * rSq * rSq * rSq); - return lensCenter + scale * theta1; -} +varying float vFade; +varying vec2 oTexCoord0; +varying vec2 oTexCoord1; +varying vec2 oTexCoord2; void main(void) { - vec2 tc = hmdWarp(gl_TexCoord[0].st); - vec2 below = step(screenCenter.st + vec2(-0.25, -0.5), tc.st); - vec2 above = vec2(1.0, 1.0) - step(screenCenter.st + vec2(0.25, 0.5), tc.st); - gl_FragColor = mix(vec4(0.0, 0.0, 0.0, 1.0), texture2D(texture, tc), above.s * above.t * below.s * below.t); + // 3 samples for fixing chromatic aberrations + float r = texture2D(texture, oTexCoord0.xy).r; + float g = texture2D(texture, oTexCoord1.xy).g; + float b = texture2D(texture, oTexCoord2.xy).b; + + gl_FragColor = vec4(r * vFade, g * vFade, b * vFade, 1.0); } diff --git a/interface/resources/shaders/oculus.vert b/interface/resources/shaders/oculus.vert new file mode 100644 index 0000000000..bc9eba4cf3 --- /dev/null +++ b/interface/resources/shaders/oculus.vert @@ -0,0 +1,64 @@ +#version 120 + +// +// oculus.vert +// vertex shader +// +// Created by Ben Arnold on 6/24/14. +// Copyright 2014 High Fidelity, Inc. +// +// this shader is an adaptation (HLSL -> GLSL) of the one in the +// Oculus_SDK_Overview.pdf for the 3.2 SDK. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +uniform vec2 EyeToSourceUVScale; +uniform vec2 EyeToSourceUVOffset; +uniform mat4 EyeRotationStart; +uniform mat4 EyeRotationEnd; + +attribute vec2 position; +attribute vec4 color; +attribute vec2 texCoord0; +attribute vec2 texCoord1; +attribute vec2 texCoord2; + +varying float vFade; +varying vec2 oTexCoord0; +varying vec2 oTexCoord1; +varying vec2 oTexCoord2; + +vec2 TimewarpTexCoord(vec2 texCoord, mat4 rotMat) +{ + // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic + // aberration and distortion). These are now "real world" vectors in direction (x,y,1) + // relative to the eye of the HMD. Apply the 3x3 timewarp rotation to these vectors. + vec3 transformed = vec3( rotMat * vec4(texCoord.xy, 1, 1) ).xyz; + + // Project them back onto the Z=1 plane of the rendered images. + vec2 flattened = (transformed.xy / transformed.z); + + // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye) + return (EyeToSourceUVScale * flattened + EyeToSourceUVOffset); +} + +void main() +{ + float timewarpMixFactor = color.a; + mat4 mixedEyeRot = EyeRotationStart * mat4(1.0 - timewarpMixFactor) + EyeRotationEnd * mat4(timewarpMixFactor); + + + oTexCoord0 = TimewarpTexCoord(texCoord0, mixedEyeRot); + oTexCoord1 = TimewarpTexCoord(texCoord1, mixedEyeRot); + oTexCoord2 = TimewarpTexCoord(texCoord2, mixedEyeRot); + + //Flip y texture coordinates + oTexCoord0.y = 1.0 - oTexCoord0.y; + oTexCoord1.y = 1.0 - oTexCoord1.y; + oTexCoord2.y = 1.0 - oTexCoord2.y; + + gl_Position = vec4(position.xy, 0.5, 1.0); + vFade = color.r; // For vignette fade +} \ No newline at end of file diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 19c6a2b193..8ef0945b55 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -11,28 +11,39 @@ #include "InterfaceConfig.h" +#include "OculusManager.h" + #include #include #include "Application.h" -#include "OculusManager.h" + +using namespace OVR; ProgramObject OculusManager::_program; int OculusManager::_textureLocation; -int OculusManager::_lensCenterLocation; -int OculusManager::_screenCenterLocation; -int OculusManager::_scaleLocation; -int OculusManager::_scaleInLocation; -int OculusManager::_hmdWarpParamLocation; +int OculusManager::_eyeToSourceUVScaleLocation; +int OculusManager::_eyeToSourceUVOffsetLocation; +int OculusManager::_eyeRotationStartLocation; +int OculusManager::_eyeRotationEndLocation; +int OculusManager::_positionAttributeLocation; +int OculusManager::_colorAttributeLocation; +int OculusManager::_texCoord0AttributeLocation; +int OculusManager::_texCoord1AttributeLocation; +int OculusManager::_texCoord2AttributeLocation; bool OculusManager::_isConnected = false; #ifdef HAVE_LIBOVR -using namespace OVR; -using namespace OVR::Util::Render; ovrHmd OculusManager::_ovrHmd; ovrHmdDesc OculusManager::_ovrHmdDesc; +ovrFovPort OculusManager::_eyeFov[ovrEye_Count]; +ovrSizei OculusManager::_renderTargetSize; +ovrVector2f OculusManager::_UVScaleOffset[ovrEye_Count][2]; +GLuint OculusManager::_vbo[ovrEye_Count]; +GLuint OculusManager::_indicesVbo[ovrEye_Count]; +GLsizei OculusManager::_meshSize[ovrEye_Count]; #endif @@ -46,25 +57,109 @@ void OculusManager::connect() { ovrHmd_GetDesc(_ovrHmd, &_ovrHmdDesc); + _eyeFov[0] = _ovrHmdDesc.DefaultEyeFov[0]; + _eyeFov[1] = _ovrHmdDesc.DefaultEyeFov[1]; + + //Get texture size + ovrSizei recommendedTex0Size = ovrHmd_GetFovTextureSize(_ovrHmd, ovrEye_Left, + _ovrHmdDesc.DefaultEyeFov[0], 1.0f); + ovrSizei recommendedTex1Size = ovrHmd_GetFovTextureSize(_ovrHmd, ovrEye_Right, + _ovrHmdDesc.DefaultEyeFov[1], 1.0f); + _renderTargetSize.w = recommendedTex0Size.w + recommendedTex1Size.w; + _renderTargetSize.h = recommendedTex0Size.h; + if (_renderTargetSize.h < recommendedTex1Size.h) { + _renderTargetSize.h = recommendedTex1Size.h; + } + ovrHmd_StartSensor(_ovrHmd, ovrSensorCap_Orientation | ovrSensorCap_YawCorrection | - ovrSensorCap_Position | ovrHmdCap_LowPersistence, + ovrSensorCap_Position, ovrSensorCap_Orientation); + _program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/oculus.vert"); _program.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/oculus.frag"); _program.link(); - + + generateDistortionMesh(); + + // Uniforms _textureLocation = _program.uniformLocation("texture"); - _lensCenterLocation = _program.uniformLocation("lensCenter"); - _screenCenterLocation = _program.uniformLocation("screenCenter"); - _scaleLocation = _program.uniformLocation("scale"); - _scaleInLocation = _program.uniformLocation("scaleIn"); - _hmdWarpParamLocation = _program.uniformLocation("hmdWarpParam"); + _eyeToSourceUVScaleLocation = _program.uniformLocation("EyeToSourceUVScale"); + _eyeToSourceUVOffsetLocation = _program.uniformLocation("EyeToSourceUVOffset"); + _eyeRotationStartLocation = _program.uniformLocation("EyeRotationStart"); + _eyeRotationEndLocation = _program.uniformLocation("EyeRotationEnd"); + + // Attributes + _positionAttributeLocation = _program.attributeLocation("position"); + _colorAttributeLocation = _program.attributeLocation("color"); + _texCoord0AttributeLocation = _program.attributeLocation("texCoord0"); + _texCoord1AttributeLocation = _program.attributeLocation("texCoord1"); + _texCoord2AttributeLocation = _program.attributeLocation("texCoord2"); + } else { ovr_Shutdown(); } #endif } +void OculusManager::generateDistortionMesh() { +#ifdef HAVE_LIBOVR + ovrEyeRenderDesc eyeDesc[2]; + eyeDesc[0] = ovrHmd_GetRenderDesc(_ovrHmd, ovrEye_Left, _eyeFov[0]); + eyeDesc[1] = ovrHmd_GetRenderDesc(_ovrHmd, ovrEye_Right, _eyeFov[1]); + + ovrRecti eyeRenderViewport[2]; + eyeRenderViewport[0].Pos = Vector2i(0, 0); + eyeRenderViewport[0].Size = Sizei(_renderTargetSize.w / 2, _renderTargetSize.h); + eyeRenderViewport[1].Pos = Vector2i((_renderTargetSize.w + 1) / 2, 0); + eyeRenderViewport[1].Size = eyeRenderViewport[0].Size; + + for (int eyeNum = 0; eyeNum < ovrEye_Count; eyeNum++) { + // Allocate and generate distortion mesh vertices + ovrDistortionMesh meshData; + ovrHmd_CreateDistortionMesh(_ovrHmd, eyeDesc[eyeNum].Eye, eyeDesc[eyeNum].Fov, _ovrHmdDesc.DistortionCaps, &meshData); + + ovrHmd_GetRenderScaleAndOffset(eyeDesc[eyeNum].Fov, _renderTargetSize, eyeRenderViewport[eyeNum], + _UVScaleOffset[eyeNum]); + + // Parse the vertex data and create a render ready vertex buffer + DistortionVertex* pVBVerts = (DistortionVertex*)OVR_ALLOC(sizeof(DistortionVertex) * meshData.VertexCount); + _meshSize[eyeNum] = meshData.IndexCount; + + DistortionVertex* v = pVBVerts; + ovrDistortionVertex* ov = meshData.pVertexData; + for (unsigned int vertNum = 0; vertNum < meshData.VertexCount; vertNum++) { + v->pos.x = ov->Pos.x; + v->pos.y = ov->Pos.y; + v->texR.x = ov->TexR.x; + v->texR.y = ov->TexR.y; + v->texG.x = ov->TexG.x; + v->texG.y = ov->TexG.y; + v->texB.x = ov->TexB.x; + v->texB.y = ov->TexB.y; + v->color.r = v->color.g = v->color.b = (GLubyte)(ov->VignetteFactor * 255.99f); + v->color.a = (GLubyte)(ov->TimeWarpFactor * 255.99f); + v++; + ov++; + } + + //vertices + glGenBuffers(1, &(_vbo[eyeNum])); + glBindBuffer(GL_ARRAY_BUFFER, _vbo[eyeNum]); + glBufferData(GL_ARRAY_BUFFER, sizeof(DistortionVertex) * meshData.VertexCount, pVBVerts, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + OVR_FREE(pVBVerts); + + //indices + glGenBuffers(1, &(_indicesVbo[eyeNum])); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indicesVbo[eyeNum]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short) * meshData.IndexCount, meshData.pIndexData, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + ovrHmd_DestroyDistortionMesh(&meshData); + } +#endif +} + bool OculusManager::isConnected() { #ifdef HAVE_LIBOVR return _isConnected && Menu::getInstance()->isOptionChecked(MenuOption::EnableVRMode); @@ -75,14 +170,30 @@ bool OculusManager::isConnected() { void OculusManager::configureCamera(Camera& camera, int screenWidth, int screenHeight) { #ifdef HAVE_LIBOVR - _stereoConfig.SetFullViewport(Viewport(0, 0, screenWidth, screenHeight)); - camera.setAspectRatio(_stereoConfig.GetAspect()); - camera.setFieldOfView(_stereoConfig.GetYFOVDegrees()); + ovrSizei recommendedTex0Size = ovrHmd_GetFovTextureSize(_ovrHmd, ovrEye_Left, + _ovrHmdDesc.DefaultEyeFov[0], 1.0f); + ovrSizei recommendedTex1Size = ovrHmd_GetFovTextureSize(_ovrHmd, ovrEye_Right, + _ovrHmdDesc.DefaultEyeFov[1], 1.0f); + + float width = recommendedTex0Size.w + recommendedTex1Size.w; + float height = recommendedTex0Size.h; + if (height < recommendedTex1Size.h) { + height = recommendedTex1Size.h; + } + + camera.setAspectRatio(width / height); + camera.setFieldOfView(110); #endif } void OculusManager::display(Camera& whichCamera) { #ifdef HAVE_LIBOVR + static unsigned int frameIndex = 0; + ovrFrameTiming hmdFrameTiming = ovrHmd_BeginFrameTiming(_ovrHmd, frameIndex); + + ovrEyeRenderDesc eyeDesc[2]; + eyeDesc[0] = ovrHmd_GetRenderDesc(_ovrHmd, ovrEye_Left, _eyeFov[0]); + eyeDesc[1] = ovrHmd_GetRenderDesc(_ovrHmd, ovrEye_Right, _eyeFov[1]); ApplicationOverlay& applicationOverlay = Application::getInstance()->getApplicationOverlay(); // We only need to render the overlays to a texture once, then we just render the texture as a quad // PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay() @@ -91,119 +202,146 @@ void OculusManager::display(Camera& whichCamera) { Application::getInstance()->getGlowEffect()->prepare(); + ovrPosef eyeRenderPose[ovrEye_Count]; + + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + // render the left eye view to the left side of the screen - const StereoEyeParams& leftEyeParams = _stereoConfig.GetEyeRenderParams(StereoEye_Left); + glMatrixMode(GL_PROJECTION); glPushMatrix(); - glLoadIdentity(); - glTranslatef(_stereoConfig.GetProjectionCenterOffset(), 0, 0); - gluPerspective(whichCamera.getFieldOfView(), whichCamera.getAspectRatio(), - whichCamera.getNearClip(), whichCamera.getFarClip()); - - glViewport(leftEyeParams.VP.x, leftEyeParams.VP.y, leftEyeParams.VP.w, leftEyeParams.VP.h); + glMatrixMode(GL_MODELVIEW); glPushMatrix(); - glLoadIdentity(); - glTranslatef(_stereoConfig.GetIPD() * 0.5f, 0, 0); - - Application::getInstance()->displaySide(whichCamera); - if (displayOverlays) { - applicationOverlay.displayOverlayTextureOculus(whichCamera); - } - - // and the right eye to the right side - const StereoEyeParams& rightEyeParams = _stereoConfig.GetEyeRenderParams(StereoEye_Right); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glTranslatef(-_stereoConfig.GetProjectionCenterOffset(), 0, 0); - gluPerspective(whichCamera.getFieldOfView(), whichCamera.getAspectRatio(), - whichCamera.getNearClip(), whichCamera.getFarClip()); - - glViewport(rightEyeParams.VP.x, rightEyeParams.VP.y, rightEyeParams.VP.w, rightEyeParams.VP.h); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glTranslatef(_stereoConfig.GetIPD() * -0.5f, 0, 0); - - Application::getInstance()->displaySide(whichCamera); + eyeRenderPose[0] = ovrHmd_GetEyePose(_ovrHmd, ovrEye_Left); + eyeRenderPose[1] = ovrHmd_GetEyePose(_ovrHmd, ovrEye_Right); - if (displayOverlays) { - applicationOverlay.displayOverlayTextureOculus(whichCamera); + for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++) { + + ovrEyeType eye = _ovrHmdDesc.EyeRenderOrder[eyeIndex]; + + Matrix4f proj = ovrMatrix4f_Projection(eyeDesc[eye].Fov, whichCamera.getNearClip(), whichCamera.getFarClip(), true); + proj.Transpose(); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glLoadMatrixf((GLfloat *)proj.M); + glTranslatef(0.0f, 0, 0); + + // gluPerspective(whichCamera.getFieldOfView(), whichCamera.getAspectRatio(), + // whichCamera.getNearClip(), whichCamera.getFarClip()); + + + glViewport(eyeDesc[eye].DistortedViewport.Pos.x, eyeDesc[eye].DistortedViewport.Pos.y, + eyeDesc[eye].DistortedViewport.Size.w, eyeDesc[eye].DistortedViewport.Size.h); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(eyeDesc[eye].ViewAdjust.x, eyeDesc[eye].ViewAdjust.y, eyeDesc[eye].ViewAdjust.z); + + Application::getInstance()->displaySide(whichCamera); + + if (displayOverlays) { + applicationOverlay.displayOverlayTextureOculus(whichCamera); + } } - + + //Wait till time-warp to reduce latency + ovr_WaitTillTime(hmdFrameTiming.TimewarpPointSeconds); + glPopMatrix(); - + // restore our normal viewport - const Viewport& fullViewport = _stereoConfig.GetFullViewport(); - glViewport(fullViewport.x, fullViewport.y, fullViewport.w, fullViewport.h); + glViewport(0, 0, Application::getInstance()->getGLWidget()->width(), Application::getInstance()->getGLWidget()->height()); QOpenGLFramebufferObject* fbo = Application::getInstance()->getGlowEffect()->render(true); glBindTexture(GL_TEXTURE_2D, fbo->texture()); glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glLoadIdentity(); - gluOrtho2D(fullViewport.x, fullViewport.x + fullViewport.w, fullViewport.y, fullViewport.y + fullViewport.h); + gluOrtho2D(0, Application::getInstance()->getGLWidget()->width(), 0, Application::getInstance()->getGLWidget()->height()); glDisable(GL_DEPTH_TEST); - - // for reference on setting these values, see SDK file Samples/OculusRoomTiny/RenderTiny_Device.cpp - - float scaleFactor = 1.0 / _stereoConfig.GetDistortionScale(); - float aspectRatio = _stereoConfig.GetAspect(); - + glDisable(GL_BLEND); _program.bind(); _program.setUniformValue(_textureLocation, 0); - const DistortionConfig& distortionConfig = _stereoConfig.GetDistortionConfig(); - _program.setUniformValue(_lensCenterLocation, (0.5 + distortionConfig.XCenterOffset * 0.5) * 0.5, 0.5); - _program.setUniformValue(_screenCenterLocation, 0.25, 0.5); - _program.setUniformValue(_scaleLocation, 0.25 * scaleFactor, 0.5 * scaleFactor * aspectRatio); - _program.setUniformValue(_scaleInLocation, 4, 2 / aspectRatio); - _program.setUniformValue(_hmdWarpParamLocation, distortionConfig.K[0], distortionConfig.K[1], - distortionConfig.K[2], distortionConfig.K[3]); + + _program.enableAttributeArray(_positionAttributeLocation); + _program.enableAttributeArray(_colorAttributeLocation); + _program.enableAttributeArray(_texCoord0AttributeLocation); + _program.enableAttributeArray(_texCoord1AttributeLocation); + _program.enableAttributeArray(_texCoord2AttributeLocation); + + for (int eyeNum = 0; eyeNum < ovrEye_Count; eyeNum++) { + GLfloat uvScale[2] = { _UVScaleOffset[eyeNum][0].x, _UVScaleOffset[eyeNum][0].y }; + _program.setUniformValueArray(_eyeToSourceUVScaleLocation, uvScale, 1, 2); + GLfloat uvOffset[2] = { _UVScaleOffset[eyeNum][1].x, _UVScaleOffset[eyeNum][1].y }; + _program.setUniformValueArray(_eyeToSourceUVOffsetLocation, uvOffset, 1, 2); - glColor3f(1, 0, 1); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); - glVertex2f(0, 0); - glTexCoord2f(0.5, 0); - glVertex2f(leftEyeParams.VP.w, 0); - glTexCoord2f(0.5, 1); - glVertex2f(leftEyeParams.VP.w, leftEyeParams.VP.h); - glTexCoord2f(0, 1); - glVertex2f(0, leftEyeParams.VP.h); - glEnd(); + ovrMatrix4f timeWarpMatrices[2]; + Matrix4f transposeMatrices[2]; + ovrHmd_GetEyeTimewarpMatrices(_ovrHmd, (ovrEyeType)eyeNum, eyeRenderPose[eyeNum], timeWarpMatrices); + transposeMatrices[0] = Matrix4f(timeWarpMatrices[0]); + transposeMatrices[1] = Matrix4f(timeWarpMatrices[1]); + + transposeMatrices[0].Transpose(); + transposeMatrices[1].Transpose(); - _program.setUniformValue(_lensCenterLocation, 0.5 + (0.5 - distortionConfig.XCenterOffset * 0.5) * 0.5, 0.5); - _program.setUniformValue(_screenCenterLocation, 0.75, 0.5); - - glBegin(GL_QUADS); - glTexCoord2f(0.5, 0); - glVertex2f(leftEyeParams.VP.w, 0); - glTexCoord2f(1, 0); - glVertex2f(fullViewport.w, 0); - glTexCoord2f(1, 1); - glVertex2f(fullViewport.w, leftEyeParams.VP.h); - glTexCoord2f(0.5, 1); - glVertex2f(leftEyeParams.VP.w, leftEyeParams.VP.h); - glEnd(); + glUniformMatrix4fv(_eyeRotationStartLocation, 1, GL_FALSE, (GLfloat *)transposeMatrices[0].M); + + glUniformMatrix4fv(_eyeRotationEndLocation, 1, GL_FALSE, (GLfloat *)transposeMatrices[1].M); + + glBindBuffer(GL_ARRAY_BUFFER, _vbo[eyeNum]); + //pos + glVertexAttribPointer(_positionAttributeLocation, 2, GL_FLOAT, GL_FALSE, sizeof(DistortionVertex), (void *)0); + glVertexAttribPointer(_texCoord0AttributeLocation, 2, GL_FLOAT, GL_FALSE, sizeof(DistortionVertex), (void *)8); + glVertexAttribPointer(_texCoord1AttributeLocation, 2, GL_FLOAT, GL_FALSE, sizeof(DistortionVertex), (void *)16); + glVertexAttribPointer(_texCoord2AttributeLocation, 2, GL_FLOAT, GL_FALSE, sizeof(DistortionVertex), (void *)24); + glVertexAttribPointer(_colorAttributeLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(DistortionVertex), (void *)32); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indicesVbo[eyeNum]); + glDrawElements(GL_TRIANGLES, _meshSize[eyeNum], GL_UNSIGNED_SHORT, 0); + int error = glGetError(); + if (error != GL_NO_ERROR) { + printf("ERROR %d\n", error); + } + } + + _program.disableAttributeArray(_positionAttributeLocation); + _program.disableAttributeArray(_colorAttributeLocation); + _program.disableAttributeArray(_texCoord0AttributeLocation); + _program.disableAttributeArray(_texCoord1AttributeLocation); + _program.disableAttributeArray(_texCoord2AttributeLocation); glEnable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + glBindBuffer(GL_ARRAY_BUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); _program.release(); - - glPopMatrix(); + + ovrHmd_EndFrameTiming(_ovrHmd); + frameIndex++; #endif } void OculusManager::reset() { #ifdef HAVE_LIBOVR - _sensorFusion->Reset(); + //_sensorFusion->Reset(); #endif } void OculusManager::getEulerAngles(float& yaw, float& pitch, float& roll) { #ifdef HAVE_LIBOVR - _sensorFusion->GetPredictedOrientation().GetEulerAngles(&yaw, &pitch, &roll); + ovrSensorState ss = ovrHmd_GetSensorState(_ovrHmd, 0.0); + + // if (ss.StatusFlags & (ovrStatus_OrientationTracked | ovrStatus_PositionTracked)) { + ovrPosef pose = ss.Recorded.Pose; + Quatf orientation = Quatf(pose.Orientation); + orientation.GetEulerAngles(&yaw, &pitch, &roll); + // } #endif } diff --git a/interface/src/devices/OculusManager.h b/interface/src/devices/OculusManager.h index 795fdde7ff..2a131a5f55 100644 --- a/interface/src/devices/OculusManager.h +++ b/interface/src/devices/OculusManager.h @@ -12,14 +12,21 @@ #ifndef hifi_OculusManager_h #define hifi_OculusManager_h -#include - #ifdef HAVE_LIBOVR #include +//#include <../src/OVR_CAPI.h> #endif +#include "../src/Util/Util_Render_Stereo.h" +using namespace OVR::Util::Render; + +#include <../src/Kernel/OVR_SysFile.h> +#include <../src/Kernel/OVR_Log.h> +#include <../src/Kernel/OVR_Timer.h> + #include "renderer/ProgramObject.h" + const float DEFAULT_OCULUS_UI_ANGULAR_SIZE = 72.0f; class Camera; @@ -29,6 +36,8 @@ class OculusManager { public: static void connect(); + static void generateDistortionMesh(); + static bool isConnected(); static void configureCamera(Camera& camera, int screenWidth, int screenHeight); @@ -45,18 +54,47 @@ public: static void updateYawOffset(); private: + + struct DistortionVertex { + glm::vec2 pos; + glm::vec2 texR; + glm::vec2 texG; + glm::vec2 texB; + struct { + GLubyte r; + GLubyte g; + GLubyte b; + GLubyte a; + } color; + }; + static ProgramObject _program; + //Uniforms static int _textureLocation; - static int _lensCenterLocation; - static int _screenCenterLocation; - static int _scaleLocation; - static int _scaleInLocation; - static int _hmdWarpParamLocation; + static int _eyeToSourceUVScaleLocation; + static int _eyeToSourceUVOffsetLocation; + static int _eyeRotationStartLocation; + static int _eyeRotationEndLocation; + //Attributes + static int _positionAttributeLocation; + static int _colorAttributeLocation; + static int _texCoord0AttributeLocation; + static int _texCoord1AttributeLocation; + static int _texCoord2AttributeLocation; + static bool _isConnected; + + #ifdef HAVE_LIBOVR static ovrHmd _ovrHmd; static ovrHmdDesc _ovrHmdDesc; + static ovrFovPort _eyeFov[ovrEye_Count]; + static ovrSizei _renderTargetSize; + static ovrVector2f _UVScaleOffset[ovrEye_Count][2]; + static GLuint _vbo[ovrEye_Count]; + static GLuint _indicesVbo[ovrEye_Count]; + static GLsizei _meshSize[ovrEye_Count]; #endif };