diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 60d35f522e..a16cc2b9e4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2796,6 +2796,11 @@ void Application::updateShadowMap() { maxima = glm::max(maxima, points[i]); } + // save the combined matrix for rendering + _shadowMatrix = glm::transpose(glm::translate(0.5f, 0.5f, 0.5f) * glm::scale(0.5f, 0.5f, 0.5f) * + glm::ortho(minima.x, maxima.x, minima.y, maxima.y, -maxima.z, -minima.z) * + glm::mat4_cast(rotation) * glm::translate(translation)); + glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); diff --git a/interface/src/Application.h b/interface/src/Application.h index b94ccd1e72..33858e8556 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -156,6 +156,8 @@ public: /// result from matrix multiplication at high translation magnitudes. void loadTranslatedViewMatrix(const glm::vec3& translation); + const glm::mat4& getShadowMatrix() const { return _shadowMatrix; } + /// Computes the off-axis frustum parameters for the view frustum, taking mirroring into account. void computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& near, float& far, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const; @@ -350,6 +352,8 @@ private: glm::mat4 _untranslatedViewMatrix; glm::vec3 _viewMatrixTranslation; + glm::mat4 _shadowMatrix; + Environment _environment; int _headMouseX, _headMouseY; diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 62419565c6..c4e700ad82 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -1386,20 +1386,39 @@ void VoxelSystem::render(bool texture) { } void VoxelSystem::applyScaleAndBindProgram(bool texture) { - glPushMatrix(); - glScalef(_treeScale, _treeScale, _treeScale); - if (texture) { + if (Menu::getInstance()->isOptionChecked(MenuOption::Shadows)) { + glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID()); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + glEnable(GL_TEXTURE_2D); + + glTexGenfv(GL_S, GL_EYE_PLANE, (const GLfloat*)&Application::getInstance()->getShadowMatrix()[0]); + glTexGenfv(GL_T, GL_EYE_PLANE, (const GLfloat*)&Application::getInstance()->getShadowMatrix()[1]); + glTexGenfv(GL_R, GL_EYE_PLANE, (const GLfloat*)&Application::getInstance()->getShadowMatrix()[2]); + + } else if (texture) { _perlinModulateProgram.bind(); glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPermutationNormalTextureID()); } + + glPushMatrix(); + glScalef(_treeScale, _treeScale, _treeScale); } void VoxelSystem::removeScaleAndReleaseProgram(bool texture) { // scale back down to 1 so heads aren't massive glPopMatrix(); - if (texture) { + if (Menu::getInstance()->isOptionChecked(MenuOption::Shadows)) { + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + glDisable(GL_TEXTURE_GEN_R); + glDisable(GL_TEXTURE_2D); + + } else if (texture) { _perlinModulateProgram.release(); glBindTexture(GL_TEXTURE_2D, 0); } diff --git a/interface/src/renderer/TextureCache.cpp b/interface/src/renderer/TextureCache.cpp index 94857b2c1e..bffc342f09 100644 --- a/interface/src/renderer/TextureCache.cpp +++ b/interface/src/renderer/TextureCache.cpp @@ -192,6 +192,10 @@ QOpenGLFramebufferObject* TextureCache::getShadowFramebufferObject() { 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + const float DISTANT_BORDER[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, DISTANT_BORDER); glBindTexture(GL_TEXTURE_2D, 0); _shadowFramebufferObject->bind();