mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 03:50:40 +02:00
Adding support for eye per frame mode and offscreen render scaling
This commit is contained in:
parent
a7eebfd002
commit
eb816f7f6a
2 changed files with 39 additions and 20 deletions
|
@ -96,6 +96,12 @@ glm::quat OculusManager::_calibrationOrientation;
|
||||||
quint64 OculusManager::_calibrationStartTime;
|
quint64 OculusManager::_calibrationStartTime;
|
||||||
int OculusManager::_calibrationMessage = NULL;
|
int OculusManager::_calibrationMessage = NULL;
|
||||||
glm::vec3 OculusManager::_eyePositions[ovrEye_Count];
|
glm::vec3 OculusManager::_eyePositions[ovrEye_Count];
|
||||||
|
// TODO expose this as a developer toggle
|
||||||
|
bool OculusManager::_eyePerFrameMode = false;
|
||||||
|
ovrEyeType OculusManager::_lastEyeRendered = ovrEye_Count;
|
||||||
|
ovrSizei OculusManager::_recommendedTexSize = { 0, 0 };
|
||||||
|
float OculusManager::_offscreenRenderScale = 1.0;
|
||||||
|
|
||||||
|
|
||||||
void OculusManager::initSdk() {
|
void OculusManager::initSdk() {
|
||||||
ovr_Initialize();
|
ovr_Initialize();
|
||||||
|
@ -148,20 +154,16 @@ void OculusManager::connect() {
|
||||||
assert(configResult);
|
assert(configResult);
|
||||||
|
|
||||||
|
|
||||||
_renderTargetSize = { 0, 0 };
|
_recommendedTexSize = ovrHmd_GetFovTextureSize(_ovrHmd, ovrEye_Left, _eyeFov[ovrEye_Left], 1.0f);
|
||||||
|
_renderTargetSize = { _recommendedTexSize.w * 2, _recommendedTexSize.h };
|
||||||
for_each_eye([&](ovrEyeType eye) {
|
for_each_eye([&](ovrEyeType eye) {
|
||||||
//Get texture size
|
//Get texture size
|
||||||
ovrSizei recommendedTexSize = ovrHmd_GetFovTextureSize(_ovrHmd, eye, _eyeFov[eye], 1.0f);
|
|
||||||
_eyeTextures[eye].Header.API = ovrRenderAPI_OpenGL;
|
_eyeTextures[eye].Header.API = ovrRenderAPI_OpenGL;
|
||||||
_eyeTextures[eye].Header.RenderViewport.Pos = { _renderTargetSize.w, 0 };
|
|
||||||
_eyeTextures[eye].Header.RenderViewport.Size = recommendedTexSize;
|
|
||||||
_renderTargetSize.w += recommendedTexSize.w;
|
|
||||||
_renderTargetSize.h = std::max(recommendedTexSize.h, _renderTargetSize.h);
|
|
||||||
});
|
|
||||||
for_each_eye([&](ovrEyeType eye) {
|
|
||||||
_eyeTextures[eye].Header.TextureSize = _renderTargetSize;
|
_eyeTextures[eye].Header.TextureSize = _renderTargetSize;
|
||||||
|
_eyeTextures[eye].Header.RenderViewport.Pos = { 0, 0 };
|
||||||
});
|
});
|
||||||
|
_eyeTextures[ovrEye_Right].Header.RenderViewport.Pos.x = _recommendedTexSize.w;
|
||||||
|
|
||||||
ovrHmd_SetEnabledCaps(_ovrHmd, ovrHmdCap_LowPersistence);
|
ovrHmd_SetEnabledCaps(_ovrHmd, ovrHmdCap_LowPersistence);
|
||||||
|
|
||||||
ovrHmd_ConfigureTracking(_ovrHmd, ovrTrackingCap_Orientation | ovrTrackingCap_Position |
|
ovrHmd_ConfigureTracking(_ovrHmd, ovrTrackingCap_Orientation | ovrTrackingCap_Position |
|
||||||
|
@ -362,9 +364,6 @@ void OculusManager::generateDistortionMesh() {
|
||||||
// Allocate and generate distortion mesh vertices
|
// Allocate and generate distortion mesh vertices
|
||||||
ovrDistortionMesh meshData;
|
ovrDistortionMesh meshData;
|
||||||
ovrHmd_CreateDistortionMesh(_ovrHmd, _eyeRenderDesc[eyeNum].Eye, _eyeRenderDesc[eyeNum].Fov, _ovrHmd->DistortionCaps, &meshData);
|
ovrHmd_CreateDistortionMesh(_ovrHmd, _eyeRenderDesc[eyeNum].Eye, _eyeRenderDesc[eyeNum].Fov, _ovrHmd->DistortionCaps, &meshData);
|
||||||
|
|
||||||
ovrHmd_GetRenderScaleAndOffset(_eyeRenderDesc[eyeNum].Fov, _renderTargetSize, _eyeTextures[eyeNum].Header.RenderViewport,
|
|
||||||
_UVScaleOffset[eyeNum]);
|
|
||||||
|
|
||||||
// Parse the vertex data and create a render ready vertex buffer
|
// Parse the vertex data and create a render ready vertex buffer
|
||||||
DistortionVertex* pVBVerts = new DistortionVertex[meshData.VertexCount];
|
DistortionVertex* pVBVerts = new DistortionVertex[meshData.VertexCount];
|
||||||
|
@ -523,12 +522,20 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p
|
||||||
|
|
||||||
trackerPosition = bodyOrientation * trackerPosition;
|
trackerPosition = bodyOrientation * trackerPosition;
|
||||||
static ovrVector3f eyeOffsets[2] = { { 0, 0, 0 }, { 0, 0, 0 } };
|
static ovrVector3f eyeOffsets[2] = { { 0, 0, 0 }, { 0, 0, 0 } };
|
||||||
ovrPosef eyeRenderPose[ovrEye_Count];
|
ovrPosef eyePoses[ovrEye_Count];
|
||||||
ovrHmd_GetEyePoses(_ovrHmd, _frameIndex, eyeOffsets, eyeRenderPose, nullptr);
|
ovrHmd_GetEyePoses(_ovrHmd, _frameIndex, eyeOffsets, eyePoses, nullptr);
|
||||||
ovrHmd_BeginFrame(_ovrHmd, _frameIndex);
|
ovrHmd_BeginFrame(_ovrHmd, _frameIndex);
|
||||||
|
static ovrPosef eyeRenderPose[ovrEye_Count];
|
||||||
//Render each eye into an fbo
|
//Render each eye into an fbo
|
||||||
for_each_eye(_ovrHmd, [&](ovrEyeType eye){
|
for_each_eye(_ovrHmd, [&](ovrEyeType eye){
|
||||||
_activeEye = eye;
|
// If we're in eye-per-frame mode, only render one eye
|
||||||
|
// per call to display, and allow timewarp to correct for
|
||||||
|
// the other eye. Poor man's perf improvement
|
||||||
|
if (_eyePerFrameMode && eye == _lastEyeRendered) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_lastEyeRendered = _activeEye = eye;
|
||||||
|
eyeRenderPose[eye] = eyePoses[eye];
|
||||||
// Set the camera rotation for this eye
|
// Set the camera rotation for this eye
|
||||||
orientation.x = eyeRenderPose[eye].Orientation.x;
|
orientation.x = eyeRenderPose[eye].Orientation.x;
|
||||||
orientation.y = eyeRenderPose[eye].Orientation.y;
|
orientation.y = eyeRenderPose[eye].Orientation.y;
|
||||||
|
@ -558,7 +565,10 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p
|
||||||
glFrustum(-nearClip * port.LeftTan, nearClip * port.RightTan, -nearClip * port.DownTan,
|
glFrustum(-nearClip * port.LeftTan, nearClip * port.RightTan, -nearClip * port.DownTan,
|
||||||
nearClip * port.UpTan, nearClip, farClip);
|
nearClip * port.UpTan, nearClip, farClip);
|
||||||
|
|
||||||
const ovrRecti & vp = _eyeTextures[eye].Header.RenderViewport;
|
ovrRecti & vp = _eyeTextures[eye].Header.RenderViewport;
|
||||||
|
vp.Size.h = _recommendedTexSize.h * _offscreenRenderScale;
|
||||||
|
vp.Size.w = _recommendedTexSize.w * _offscreenRenderScale;
|
||||||
|
|
||||||
glViewport(vp.Pos.x, vp.Pos.y, vp.Size.w, vp.Size.h);
|
glViewport(vp.Pos.x, vp.Pos.y, vp.Size.w, vp.Size.h);
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
@ -602,7 +612,7 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, finalFbo->texture());
|
glBindTexture(GL_TEXTURE_2D, finalFbo->texture());
|
||||||
|
|
||||||
//Renders the distorted mesh onto the screen
|
//Renders the distorted mesh onto the screen
|
||||||
renderDistortionMesh(eyeRenderPose);
|
renderDistortionMesh(eyeRenderPose);
|
||||||
|
|
||||||
|
@ -612,6 +622,7 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p
|
||||||
for_each_eye([&](ovrEyeType eye) {
|
for_each_eye([&](ovrEyeType eye) {
|
||||||
ovrGLTexture & glEyeTexture = reinterpret_cast<ovrGLTexture&>(_eyeTextures[eye]);
|
ovrGLTexture & glEyeTexture = reinterpret_cast<ovrGLTexture&>(_eyeTextures[eye]);
|
||||||
glEyeTexture.OGL.TexId = finalFbo->texture();
|
glEyeTexture.OGL.TexId = finalFbo->texture();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ovrHmd_EndFrame(_ovrHmd, eyeRenderPose, _eyeTextures);
|
ovrHmd_EndFrame(_ovrHmd, eyeRenderPose, _eyeTextures);
|
||||||
|
@ -639,9 +650,13 @@ void OculusManager::renderDistortionMesh(ovrPosef eyeRenderPose[ovrEye_Count]) {
|
||||||
|
|
||||||
//Render the distortion meshes for each eye
|
//Render the distortion meshes for each eye
|
||||||
for (int eyeNum = 0; eyeNum < ovrEye_Count; eyeNum++) {
|
for (int eyeNum = 0; eyeNum < ovrEye_Count; eyeNum++) {
|
||||||
|
|
||||||
|
ovrHmd_GetRenderScaleAndOffset(_eyeRenderDesc[eyeNum].Fov, _renderTargetSize, _eyeTextures[eyeNum].Header.RenderViewport,
|
||||||
|
_UVScaleOffset[eyeNum]);
|
||||||
|
|
||||||
GLfloat uvScale[2] = { _UVScaleOffset[eyeNum][0].x, _UVScaleOffset[eyeNum][0].y };
|
GLfloat uvScale[2] = { _UVScaleOffset[eyeNum][0].x, _UVScaleOffset[eyeNum][0].y };
|
||||||
_program.setUniformValueArray(_eyeToSourceUVScaleLocation, uvScale, 1, 2);
|
_program.setUniformValueArray(_eyeToSourceUVScaleLocation, uvScale, 1, 2);
|
||||||
GLfloat uvOffset[2] = { _UVScaleOffset[eyeNum][1].x, _UVScaleOffset[eyeNum][1].y };
|
GLfloat uvOffset[2] = { _UVScaleOffset[eyeNum][1].x, 1.0f - _UVScaleOffset[eyeNum][1].y };
|
||||||
_program.setUniformValueArray(_eyeToSourceUVOffsetLocation, uvOffset, 1, 2);
|
_program.setUniformValueArray(_eyeToSourceUVOffsetLocation, uvOffset, 1, 2);
|
||||||
|
|
||||||
ovrMatrix4f timeWarpMatrices[2];
|
ovrMatrix4f timeWarpMatrices[2];
|
||||||
|
|
|
@ -28,7 +28,7 @@ class Text3DOverlay;
|
||||||
// the Oculus SDK will ideally provide the best practices for distortion in
|
// the Oculus SDK will ideally provide the best practices for distortion in
|
||||||
// in terms of performance and quality, and by using it we will get updated
|
// in terms of performance and quality, and by using it we will get updated
|
||||||
// best practices for free with new runtime releases.
|
// best practices for free with new runtime releases.
|
||||||
// #define OVR_CLIENT_DISTORTION 1
|
#define OVR_CLIENT_DISTORTION 1
|
||||||
|
|
||||||
|
|
||||||
// On Win32 platforms, enabling Direct HMD requires that the SDK be
|
// On Win32 platforms, enabling Direct HMD requires that the SDK be
|
||||||
|
@ -148,7 +148,11 @@ private:
|
||||||
static glm::quat _calibrationOrientation;
|
static glm::quat _calibrationOrientation;
|
||||||
static quint64 _calibrationStartTime;
|
static quint64 _calibrationStartTime;
|
||||||
static int _calibrationMessage;
|
static int _calibrationMessage;
|
||||||
|
// TODO drop this variable and use the existing 'Developer | Render | Scale Resolution' value
|
||||||
|
static ovrSizei _recommendedTexSize;
|
||||||
|
static float _offscreenRenderScale;
|
||||||
|
static bool _eyePerFrameMode;
|
||||||
|
static ovrEyeType _lastEyeRendered;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue