diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f21fedabea..b48d35c5e8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -641,13 +641,8 @@ void Application::paintGL() { } } else if (TV3DManager::isConnected()) { - if (glowEnabled) { - _glowEffect.prepare(); - } + TV3DManager::display(whichCamera); - if (glowEnabled) { - _glowEffect.render(); - } } else { if (glowEnabled) { diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index d9549438b5..e156e148ab 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -262,7 +262,7 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p 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 + // We only need to render the overlays to a texture once, then we just render the texture on the hemisphere // PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay() applicationOverlay.renderOverlay(true); const bool displayOverlays = Menu::getInstance()->isOptionChecked(MenuOption::DisplayOculusOverlays); diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index b5cc28b07f..98fe3ac6d4 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -93,6 +93,18 @@ void TV3DManager::display(Camera& whichCamera) { int portalW = Application::getInstance()->getGLWidget()->width() / 2; int portalH = Application::getInstance()->getGLWidget()->height(); + 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 + // PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay() + applicationOverlay.renderOverlay(true); + + if (glowEnabled) { + Application::getInstance()->getGlowEffect()->prepare(); + } + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_SCISSOR_TEST); @@ -102,13 +114,24 @@ void TV3DManager::display(Camera& whichCamera) { glPushMatrix(); { + glMatrixMode(GL_PROJECTION); glLoadIdentity(); // reset projection matrix glFrustum(_leftEye.left, _leftEye.right, _leftEye.bottom, _leftEye.top, nearZ, farZ); // set left view frustum + GLfloat p[4][4]; + glGetFloatv(GL_PROJECTION_MATRIX, &(p[0][0])); + GLfloat cotangent = p[1][1]; + GLfloat fov = atan(1.0f / cotangent); glTranslatef(_leftEye.modelTranslation, 0.0, 0.0); // translate to cancel parallax + + + printf("FOV %f\n", fov); + glMatrixMode(GL_MODELVIEW); glLoadIdentity(); Application::getInstance()->displaySide(whichCamera); + + applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov); } glPopMatrix(); glDisable(GL_SCISSOR_TEST); @@ -124,14 +147,27 @@ void TV3DManager::display(Camera& whichCamera) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); // reset projection matrix glFrustum(_rightEye.left, _rightEye.right, _rightEye.bottom, _rightEye.top, nearZ, farZ); // set left view frustum + GLfloat p[4][4]; + glGetFloatv(GL_PROJECTION_MATRIX, &(p[0][0])); + GLfloat cotangent = p[1][1]; + GLfloat fov = atan(1.0f / cotangent); glTranslatef(_rightEye.modelTranslation, 0.0, 0.0); // translate to cancel parallax + + printf("FOV %f\n", fov); + glMatrixMode(GL_MODELVIEW); glLoadIdentity(); Application::getInstance()->displaySide(whichCamera); + + applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov); } glPopMatrix(); glDisable(GL_SCISSOR_TEST); // reset the viewport to how we started glViewport(0, 0, Application::getInstance()->getGLWidget()->width(), Application::getInstance()->getGLWidget()->height()); + + if (glowEnabled) { + Application::getInstance()->getGlowEffect()->render(); + } } diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 77e8986297..07582e2781 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -206,7 +206,7 @@ void ApplicationOverlay::getClickLocation(int &x, int &y) const { } } -// Draws the FBO texture for Oculus rift. TODO: Draw a curved texture instead of plane. +// Draws the FBO texture for Oculus rift. void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) { if (_alpha == 0.0f) { @@ -293,6 +293,79 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) { } +// Draws the FBO texture for 3DTV. +void ApplicationOverlay::displayOverlayTexture3DTV(Camera& whichCamera, float aspectRatio, float fov) { + + if (_alpha == 0.0f) { + return; + } + + Application* application = Application::getInstance(); + + MyAvatar* myAvatar = application->getAvatar(); + const glm::vec3& viewMatrixTranslation = application->getViewMatrixTranslation(); + + glActiveTexture(GL_TEXTURE0); + + glEnable(GL_BLEND); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); + glBindTexture(GL_TEXTURE_2D, getFramebufferObject()->texture()); + glEnable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glEnable(GL_TEXTURE_2D); + + glMatrixMode(GL_MODELVIEW); + + glPushMatrix(); + glLoadIdentity(); + // Transform to world space + glm::quat rotation = whichCamera.getRotation(); + glm::vec3 axis2 = glm::axis(rotation); + glRotatef(-glm::degrees(glm::angle(rotation)), axis2.x, axis2.y, axis2.z); + glTranslatef(viewMatrixTranslation.x, viewMatrixTranslation.y, viewMatrixTranslation.z); + + // Translate to the front of the camera + glm::vec3 pos = whichCamera.getPosition(); + glm::quat rot = myAvatar->getOrientation(); + glm::vec3 axis = glm::axis(rot); + + glTranslatef(pos.x, pos.y, pos.z); + glRotatef(glm::degrees(glm::angle(rot)), axis.x, axis.y, axis.z); + + glColor4f(1.0f, 1.0f, 1.0f, _alpha); + + //Render + const GLfloat distance = 1.0f; + + const GLfloat halfQuadHeight = atan(fov) * distance; + const GLfloat halfQuadWidth = halfQuadHeight * aspectRatio; + const GLfloat quadWidth = halfQuadWidth * 2.0f; + const GLfloat quadHeight = halfQuadHeight * 2.0f; + + const GLfloat x = -halfQuadWidth; + const GLfloat y = -halfQuadHeight; + + glBegin(GL_QUADS); + + glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y + quadHeight, -distance); + glTexCoord2f(1.0f, 1.0f); glVertex3f(x + quadWidth, y + quadHeight, -distance); + glTexCoord2f(1.0f, 0.0f); glVertex3f(x + quadWidth, y, -distance); + glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y, -distance); + + glEnd(); + + glPopMatrix(); + + glDepthMask(GL_TRUE); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); + glEnable(GL_LIGHTING); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); +} + //Renders optional pointers void ApplicationOverlay::renderPointers() { Application* application = Application::getInstance(); diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index b9f9596ccf..7c1f87d575 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -29,6 +29,7 @@ public: void renderOverlay(bool renderToTexture = false); void displayOverlayTexture(); void displayOverlayTextureOculus(Camera& whichCamera); + void displayOverlayTexture3DTV(Camera& whichCamera, float aspectRatio, float fov); void computeOculusPickRay(float x, float y, glm::vec3& direction) const; void getClickLocation(int &x, int &y) const;