Merge pull request #3392 from ey6es/master

Fixes for 3DTV/Oculus (deferred lighting/ambient occlusion/glow/culling/pointers).
This commit is contained in:
Philip Rosedale 2014-09-10 17:43:53 -07:00
commit 2216f89b8d
9 changed files with 82 additions and 25 deletions

View file

@ -2724,6 +2724,9 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()");
// transform by eye offset
// load the view frustum
loadViewFrustum(whichCamera, _displayViewFrustum);
// flip x if in mirror mode (also requires reversing winding order for backface culling)
if (whichCamera.getMode() == CAMERA_MODE_MIRROR) {
glScalef(-1.0f, 1.0f, 1.0f);
@ -2971,7 +2974,14 @@ void Application::getProjectionMatrix(glm::dmat4* projectionMatrix) {
void Application::computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const {
// allow 3DTV/Oculus to override parameters from camera
_viewFrustum.computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
if (OculusManager::isConnected()) {
OculusManager::overrideOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
} else if (TV3DManager::isConnected()) {
TV3DManager::overrideOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
}
}
glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) {

View file

@ -192,6 +192,7 @@ public:
const AudioReflector* getAudioReflector() const { return &_audioReflector; }
Camera* getCamera() { return &_myCamera; }
ViewFrustum* getViewFrustum() { return &_viewFrustum; }
ViewFrustum* getDisplayViewFrustum() { return &_displayViewFrustum; }
ViewFrustum* getShadowViewFrustum() { return &_shadowViewFrustum; }
VoxelImporter* getVoxelImporter() { return &_voxelImporter; }
VoxelSystem* getVoxels() { return &_voxels; }
@ -486,6 +487,7 @@ private:
ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc.
ViewFrustum _lastQueriedViewFrustum; /// last view frustum used to query octree servers (voxels, particles)
ViewFrustum _displayViewFrustum;
ViewFrustum _shadowViewFrustum;
quint64 _lastQueriedTime;

View file

@ -133,7 +133,7 @@ const GLenum COLOR_NORMAL_DRAW_BUFFERS[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTA
void MetavoxelSystem::render() {
// update the frustum
ViewFrustum* viewFrustum = Application::getInstance()->getViewFrustum();
ViewFrustum* viewFrustum = Application::getInstance()->getDisplayViewFrustum();
_frustum.set(viewFrustum->getFarTopLeft(), viewFrustum->getFarTopRight(), viewFrustum->getFarBottomLeft(),
viewFrustum->getFarBottomRight(), viewFrustum->getNearTopLeft(), viewFrustum->getNearTopRight(),
viewFrustum->getNearBottomLeft(), viewFrustum->getNearBottomRight());
@ -181,6 +181,14 @@ void MetavoxelSystem::render() {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryNormalTextureID());
// get the viewport side (left, right, both)
int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
const int VIEWPORT_X_INDEX = 0;
const int VIEWPORT_WIDTH_INDEX = 2;
float sMin = viewport[VIEWPORT_X_INDEX] / (float)primaryFBO->width();
float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)primaryFBO->width();
if (Menu::getInstance()->getShadowsEnabled()) {
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID());
@ -210,10 +218,13 @@ void MetavoxelSystem::render() {
program->setUniformValue(locations->nearLocation, nearVal);
program->setUniformValue(locations->depthScale, (farVal - nearVal) / farVal);
float nearScale = -1.0f / nearVal;
program->setUniformValue(locations->depthTexCoordOffset, left * nearScale, bottom * nearScale);
program->setUniformValue(locations->depthTexCoordScale, (right - left) * nearScale, (top - bottom) * nearScale);
float sScale = 1.0f / sWidth;
float depthTexCoordScaleS = (right - left) * nearScale * sScale;
program->setUniformValue(locations->depthTexCoordOffset, left * nearScale - sMin * depthTexCoordScaleS,
bottom * nearScale);
program->setUniformValue(locations->depthTexCoordScale, depthTexCoordScaleS, (top - bottom) * nearScale);
renderFullscreenQuad();
renderFullscreenQuad(sMin, sMin + sWidth);
program->release();
@ -226,7 +237,7 @@ void MetavoxelSystem::render() {
} else {
_directionalLight.bind();
renderFullscreenQuad();
renderFullscreenQuad(sMin, sMin + sWidth);
_directionalLight.release();
}
@ -245,7 +256,7 @@ void MetavoxelSystem::render() {
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
renderFullscreenQuad();
renderFullscreenQuad(sMin, sMin + sWidth);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
@ -2176,7 +2187,7 @@ private:
SpannerRenderVisitor::SpannerRenderVisitor(const MetavoxelLOD& lod) :
SpannerVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getSpannersAttribute(),
QVector<AttributePointer>(), QVector<AttributePointer>(), QVector<AttributePointer>(),
lod, encodeOrder(Application::getInstance()->getViewFrustum()->getDirection())),
lod, encodeOrder(Application::getInstance()->getDisplayViewFrustum()->getDirection())),
_containmentDepth(INT_MAX) {
}
@ -2212,7 +2223,7 @@ private:
BufferRenderVisitor::BufferRenderVisitor(const AttributePointer& attribute) :
MetavoxelVisitor(QVector<AttributePointer>() << attribute),
_order(encodeOrder(Application::getInstance()->getViewFrustum()->getDirection())),
_order(encodeOrder(Application::getInstance()->getDisplayViewFrustum()->getDirection())),
_containmentDepth(INT_MAX) {
}
@ -2246,12 +2257,12 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox
float viewportWidth = viewport[VIEWPORT_WIDTH_INDEX];
float viewportHeight = viewport[VIEWPORT_HEIGHT_INDEX];
float viewportDiagonal = sqrtf(viewportWidth * viewportWidth + viewportHeight * viewportHeight);
float worldDiagonal = glm::distance(Application::getInstance()->getViewFrustum()->getNearBottomLeft(),
Application::getInstance()->getViewFrustum()->getNearTopRight());
float worldDiagonal = glm::distance(Application::getInstance()->getDisplayViewFrustum()->getNearBottomLeft(),
Application::getInstance()->getDisplayViewFrustum()->getNearTopRight());
_pointProgram.bind();
_pointProgram.setUniformValue(_pointScaleLocation, viewportDiagonal *
Application::getInstance()->getViewFrustum()->getNearClip() / worldDiagonal);
Application::getInstance()->getDisplayViewFrustum()->getNearClip() / worldDiagonal);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

View file

@ -53,6 +53,7 @@ unsigned int OculusManager::_frameIndex = 0;
bool OculusManager::_frameTimingActive = false;
bool OculusManager::_programInitialized = false;
Camera* OculusManager::_camera = NULL;
int OculusManager::_activeEyeIndex = -1;
#endif
@ -330,6 +331,8 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p
//Render each eye into an fbo
for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++) {
_activeEyeIndex = eyeIndex;
#if defined(__APPLE__) || defined(_WIN32)
ovrEyeType eye = _ovrHmd->EyeRenderOrder[eyeIndex];
#else
@ -363,6 +366,7 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p
Application::getInstance()->displaySide(*_camera);
applicationOverlay.displayOverlayTextureOculus(*_camera);
_activeEyeIndex = -1;
}
//Wait till time-warp to reduce latency
@ -528,3 +532,16 @@ QSize OculusManager::getRenderTargetSize() {
return QSize(100, 100);
#endif
}
void OculusManager::overrideOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) {
#ifdef HAVE_LIBOVR
if (_activeEyeIndex != -1) {
const ovrFovPort& port = _eyeFov[_activeEyeIndex];
right = nearVal * port.RightTan;
left = -nearVal * port.LeftTan;
top = nearVal * port.UpTan;
bottom = -nearVal * port.DownTan;
}
#endif
}

View file

@ -43,6 +43,9 @@ public:
static glm::vec3 getRelativePosition();
static QSize getRenderTargetSize();
static void overrideOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane);
private:
#ifdef HAVE_LIBOVR
static void generateDistortionMesh();
@ -92,6 +95,7 @@ private:
static bool _frameTimingActive;
static bool _programInitialized;
static Camera* _camera;
static int _activeEyeIndex;
#endif
};

View file

@ -25,6 +25,7 @@ int TV3DManager::_screenHeight = 1;
double TV3DManager::_aspect = 1.0;
eyeFrustum TV3DManager::_leftEye;
eyeFrustum TV3DManager::_rightEye;
eyeFrustum* TV3DManager::_activeEye = NULL;
bool TV3DManager::isConnected() {
@ -93,8 +94,6 @@ void TV3DManager::display(Camera& whichCamera) {
int portalW = Application::getInstance()->getGLWidget()->getDeviceWidth() / 2;
int portalH = Application::getInstance()->getGLWidget()->getDeviceHeight();
const bool glowEnabled = Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect);
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
@ -102,9 +101,7 @@ void TV3DManager::display(Camera& whichCamera) {
applicationOverlay.renderOverlay(true);
const bool displayOverlays = Menu::getInstance()->isOptionChecked(MenuOption::UserInterface);
if (glowEnabled) {
Application::getInstance()->getGlowEffect()->prepare();
}
Application::getInstance()->getGlowEffect()->prepare();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -115,7 +112,7 @@ void TV3DManager::display(Camera& whichCamera) {
glPushMatrix();
{
_activeEye = &_leftEye;
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // reset projection matrix
glFrustum(_leftEye.left, _leftEye.right, _leftEye.bottom, _leftEye.top, nearZ, farZ); // set left view frustum
@ -132,6 +129,7 @@ void TV3DManager::display(Camera& whichCamera) {
if (displayOverlays) {
applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov);
}
_activeEye = NULL;
}
glPopMatrix();
glDisable(GL_SCISSOR_TEST);
@ -144,6 +142,7 @@ void TV3DManager::display(Camera& whichCamera) {
glScissor(portalX, portalY, portalW, portalH);
glPushMatrix();
{
_activeEye = &_rightEye;
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // reset projection matrix
glFrustum(_rightEye.left, _rightEye.right, _rightEye.bottom, _rightEye.top, nearZ, farZ); // set left view frustum
@ -160,6 +159,7 @@ void TV3DManager::display(Camera& whichCamera) {
if (displayOverlays) {
applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov);
}
_activeEye = NULL;
}
glPopMatrix();
glDisable(GL_SCISSOR_TEST);
@ -168,7 +168,15 @@ void TV3DManager::display(Camera& whichCamera) {
glViewport(0, 0, Application::getInstance()->getGLWidget()->getDeviceWidth(),
Application::getInstance()->getGLWidget()->getDeviceHeight());
if (glowEnabled) {
Application::getInstance()->getGlowEffect()->render();
Application::getInstance()->getGlowEffect()->render();
}
void TV3DManager::overrideOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) {
if (_activeEye) {
left = _activeEye->left;
right = _activeEye->right;
bottom = _activeEye->bottom;
top = _activeEye->top;
}
}

View file

@ -14,6 +14,8 @@
#include <iostream>
#include <glm/glm.hpp>
class Camera;
struct eyeFrustum {
@ -32,6 +34,8 @@ public:
static bool isConnected();
static void configureCamera(Camera& camera, int screenWidth, int screenHeight);
static void display(Camera& whichCamera);
static void overrideOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane);
private:
static void setFrustum(Camera& whichCamera);
static int _screenWidth;
@ -39,6 +43,7 @@ private:
static double _aspect;
static eyeFrustum _leftEye;
static eyeFrustum _rightEye;
static eyeFrustum* _activeEye;
};
#endif // hifi_TV3DManager_h

View file

@ -116,9 +116,9 @@ void AmbientOcclusionEffect::render() {
glGetIntegerv(GL_VIEWPORT, viewport);
const int VIEWPORT_X_INDEX = 0;
const int VIEWPORT_WIDTH_INDEX = 2;
QSize widgetSize = Application::getInstance()->getGLWidget()->getDeviceSize();
float sMin = viewport[VIEWPORT_X_INDEX] / (float)widgetSize.width();
float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)widgetSize.width();
QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject();
float sMin = viewport[VIEWPORT_X_INDEX] / (float)primaryFBO->width();
float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)primaryFBO->width();
_occlusionProgram->bind();
_occlusionProgram->setUniformValue(_nearLocation, nearVal);
@ -126,7 +126,7 @@ void AmbientOcclusionEffect::render() {
_occlusionProgram->setUniformValue(_leftBottomLocation, left, bottom);
_occlusionProgram->setUniformValue(_rightTopLocation, right, top);
_occlusionProgram->setUniformValue(_noiseScaleLocation, viewport[VIEWPORT_WIDTH_INDEX] / (float)ROTATION_WIDTH,
widgetSize.height() / (float)ROTATION_HEIGHT);
primaryFBO->height() / (float)ROTATION_HEIGHT);
_occlusionProgram->setUniformValue(_texCoordOffsetLocation, sMin, 0.0f);
_occlusionProgram->setUniformValue(_texCoordScaleLocation, sWidth, 1.0f);
@ -148,7 +148,7 @@ void AmbientOcclusionEffect::render() {
glBindTexture(GL_TEXTURE_2D, freeFBO->texture());
_blurProgram->bind();
_blurProgram->setUniformValue(_blurScaleLocation, 1.0f / widgetSize.width(), 1.0f / widgetSize.height());
_blurProgram->setUniformValue(_blurScaleLocation, 1.0f / primaryFBO->width(), 1.0f / primaryFBO->height());
renderFullscreenQuad(sMin, sMin + sWidth);

View file

@ -414,7 +414,7 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) {
renderTexturedHemisphere();
renderPointersOculus(whichCamera.getPosition());
renderPointersOculus(myAvatar->getHead()->getEyePosition());
glDepthMask(GL_TRUE);
glBindTexture(GL_TEXTURE_2D, 0);