mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Working 3.2 Oculus SDK
This commit is contained in:
parent
e0a33f129c
commit
61b20b2be0
4 changed files with 356 additions and 124 deletions
|
@ -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);
|
||||
}
|
||||
|
|
64
interface/resources/shaders/oculus.vert
Normal file
64
interface/resources/shaders/oculus.vert
Normal file
|
@ -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
|
||||
}
|
|
@ -11,28 +11,39 @@
|
|||
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
#include "OculusManager.h"
|
||||
|
||||
#include <QOpenGLFramebufferObject>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#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<Axis_Y, Axis_X, Axis_Z, Rotate_CCW, Handed_R>(&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<Axis_Y, Axis_X, Axis_Z, Rotate_CCW, Handed_R>(&yaw, &pitch, &roll);
|
||||
// }
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -12,14 +12,21 @@
|
|||
#ifndef hifi_OculusManager_h
|
||||
#define hifi_OculusManager_h
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#ifdef HAVE_LIBOVR
|
||||
#include <OVR.h>
|
||||
//#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
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue