diff options
author | Emmanuel Gil Peyrot <emmanuel.peyrot@collabora.com> | 2016-02-09 23:59:16 +0000 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2016-02-09 23:59:52 +0000 |
commit | d323f2487d84fbd3909cd2166b98a2a875b71bf8 (patch) | |
tree | 6a76c24bfb28cc632d8261435263d7be8b2772ef /slideshow | |
parent | 1f8ddf1b8ff4727473676de9c7fda24b49b9599d (diff) |
slideshow: Add shadows to Honeycomb, using the same way as Vortex
Change-Id: I1f8f11f900f281792b417c1efead272fe3e8432e
Diffstat (limited to 'slideshow')
-rw-r--r-- | slideshow/opengl/honeycombFragmentShader.glsl | 11 | ||||
-rw-r--r-- | slideshow/opengl/honeycombGeometryShader.glsl | 32 | ||||
-rw-r--r-- | slideshow/opengl/honeycombVertexShader.glsl | 20 | ||||
-rw-r--r-- | slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx | 125 |
4 files changed, 171 insertions, 17 deletions
diff --git a/slideshow/opengl/honeycombFragmentShader.glsl b/slideshow/opengl/honeycombFragmentShader.glsl index 7e529517915f..41b6738a804f 100644 --- a/slideshow/opengl/honeycombFragmentShader.glsl +++ b/slideshow/opengl/honeycombFragmentShader.glsl @@ -13,8 +13,11 @@ in vec2 texturePosition; in float fuzz; in vec2 v_center; in vec3 normal; +in vec4 shadowCoordinate; uniform sampler2D slideTexture; +uniform sampler2D colorShadowTexture; +uniform sampler2D depthShadowTexture; uniform float selectedTexture; uniform float time; uniform float hexagonSize; @@ -70,8 +73,14 @@ void main() fragment.rgb *= actualTime; } } + float visibility = 1.0; + const float epsilon = 0.0001; + if (texture2D(depthShadowTexture, shadowCoordinate.xy).r < shadowCoordinate.z - epsilon) + visibility *= 0.7 + 0.3 * (1.0 - texture2D(colorShadowTexture, shadowCoordinate.xy).a); vec4 black = vec4(0.0, 0.0, 0.0, fragment.a); - gl_FragColor = mix(black, fragment, light); + if (fragment.a < 0.001) + discard; + gl_FragColor = mix(black, fragment, visibility * light); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/opengl/honeycombGeometryShader.glsl b/slideshow/opengl/honeycombGeometryShader.glsl index f1c0c7058162..5269fad45e1c 100644 --- a/slideshow/opengl/honeycombGeometryShader.glsl +++ b/slideshow/opengl/honeycombGeometryShader.glsl @@ -12,7 +12,9 @@ layout(triangles) in; layout(triangle_strip, max_vertices=27) out; -in mat4 modelViewProjectionMatrix[]; +in mat4 projectionMatrix[]; +in mat4 modelViewMatrix[]; +in mat4 shadowMatrix[]; uniform float hexagonSize; uniform sampler2D permTexture; @@ -21,6 +23,7 @@ out vec2 texturePosition; out float fuzz; out vec2 v_center; out vec3 normal; +out vec4 shadowCoordinate; const float expandFactor = 0.0318; @@ -29,10 +32,35 @@ float snoise(vec2 p) return texture2D(permTexture, p).r; } +mat4 identityMatrix(void) +{ + return mat4(1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0); +} + +mat4 scaleMatrix(vec3 axis) +{ + mat4 matrix = identityMatrix(); + matrix[0][0] = axis.x; + matrix[1][1] = axis.y; + matrix[2][2] = axis.z; + return matrix; +} + +mat4 translationMatrix(vec3 axis) +{ + mat4 matrix = identityMatrix(); + matrix[3] = vec4(axis, 1.0); + return matrix; +} + void emitHexagonVertex(vec3 center, vec2 translation) { vec4 pos = vec4(center + hexagonSize * expandFactor * vec3(translation, 0.0), 1.0); - gl_Position = modelViewProjectionMatrix[0] * pos; + gl_Position = projectionMatrix[0] * modelViewMatrix[0] * pos; + shadowCoordinate = translationMatrix(vec3(0.5, 0.5, 0.5)) * scaleMatrix(vec3(0.5, 0.5, 0.5)) * shadowMatrix[0] * modelViewMatrix[0] * pos; texturePosition = vec2((pos.x + 1), (1 - pos.y)) / 2; EmitVertex(); } diff --git a/slideshow/opengl/honeycombVertexShader.glsl b/slideshow/opengl/honeycombVertexShader.glsl index d54783b82b7b..32fdecef01f9 100644 --- a/slideshow/opengl/honeycombVertexShader.glsl +++ b/slideshow/opengl/honeycombVertexShader.glsl @@ -21,8 +21,13 @@ uniform mat4 u_operationsTransformMatrix; uniform float time; uniform float selectedTexture; +uniform float shadow; +uniform mat4 orthoProjectionMatrix; +uniform mat4 orthoViewMatrix; -out mat4 modelViewProjectionMatrix; +out mat4 projectionMatrix; +out mat4 modelViewMatrix; +out mat4 shadowMatrix; mat4 translationMatrix(vec3 axis) { @@ -55,7 +60,7 @@ mat4 rotationMatrix(vec3 axis, float angle) void main( void ) { - mat4 modelViewMatrix = u_modelViewMatrix * u_operationsTransformMatrix * u_sceneTransformMatrix * u_primitiveTransformMatrix; + mat4 nmodelViewMatrix = u_modelViewMatrix * u_operationsTransformMatrix * u_sceneTransformMatrix * u_primitiveTransformMatrix; mat4 transformMatrix; // TODO: use the aspect ratio of the slide instead. @@ -76,7 +81,16 @@ void main( void ) * rotationMatrix(vec3(0.0, 0.0, 1.0), pow(0.8 * (time - 1.0), 2.0) * M_PI) * invertSlideScaleMatrix; } - modelViewProjectionMatrix = u_projectionMatrix * modelViewMatrix * transformMatrix; + + if (shadow < 0.5) { + projectionMatrix = u_projectionMatrix; + shadowMatrix = orthoProjectionMatrix * orthoViewMatrix; + } else { + projectionMatrix = orthoProjectionMatrix * orthoViewMatrix; + shadowMatrix = mat4(0.0); + } + + modelViewMatrix = nmodelViewMatrix * transformMatrix; gl_Position = vec4(a_position, 1.0); } diff --git a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx index b764dd7e53f8..5a420314f7c7 100644 --- a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx +++ b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx @@ -2011,17 +2011,42 @@ public: HoneycombTransition(const TransitionScene& rScene, const TransitionSettings& rSettings) : PermTextureTransition(rScene, rSettings) { + mnDepthTextures[0] = 0; + mnDepthTextures[1] = 0; } private: + virtual void finishTransition() override; virtual GLuint makeShader() const override; virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex ) override; virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale ) override; GLint maHexagonSizeLocation = -1; GLint maSelectedTextureLocation = -1; + GLint mnShadowLocation = -1; + GLuint mnFramebuffer = 0u; + std::array<GLuint, 2> mnDepthTextures; }; +void HoneycombTransition::finishTransition() +{ + PermTextureTransition::finishTransition(); + + CHECK_GL_ERROR(); + glActiveTexture( GL_TEXTURE2 ); + glBindTexture( GL_TEXTURE_2D, 0 ); + glActiveTexture( GL_TEXTURE3 ); + glBindTexture( GL_TEXTURE_2D, 0 ); + glActiveTexture( GL_TEXTURE0 ); + CHECK_GL_ERROR(); + glDeleteTextures(2, mnDepthTextures.data()); + mnDepthTextures = {0u, 0u}; + CHECK_GL_ERROR(); + glDeleteFramebuffers(1, &mnFramebuffer); + mnFramebuffer = 0u; + CHECK_GL_ERROR(); +} + GLuint HoneycombTransition::makeShader() const { return OpenGLHelper::LoadShaders( "honeycombVertexShader", "honeycombFragmentShader", "honeycombGeometryShader" ); @@ -2035,38 +2060,116 @@ void HoneycombTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_In CHECK_GL_ERROR(); maHexagonSizeLocation = glGetUniformLocation(m_nProgramObject, "hexagonSize"); maSelectedTextureLocation = glGetUniformLocation( m_nProgramObject, "selectedTexture" ); + mnShadowLocation = glGetUniformLocation(m_nProgramObject, "shadow"); + GLint nOrthoProjectionMatrix = glGetUniformLocation(m_nProgramObject, "orthoProjectionMatrix"); + GLint nOrthoViewMatrix = glGetUniformLocation(m_nProgramObject, "orthoViewMatrix"); + GLint location = glGetUniformLocation(m_nProgramObject, "colorShadowTexture"); + glUniform1i(location, 2); + location = glGetUniformLocation(m_nProgramObject, "depthShadowTexture"); + glUniform1i(location, 3); CHECK_GL_ERROR(); // We want to see the entering slide behind the leaving one. glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); CHECK_GL_ERROR(); + + double EyePos(10.0); + double RealF(1.0); + double RealN(-1.0); + double RealL(-4.0); + double RealR(4.0); + double RealB(-4.0); + double RealT(4.0); + double ClipN(EyePos+5.0*RealN); + double ClipF(EyePos+15.0*RealF); + double ClipL(RealL*8.0); + double ClipR(RealR*8.0); + double ClipB(RealB*8.0); + double ClipT(RealT*8.0); + + glm::mat4 projection = glm::ortho<float>(ClipL, ClipR, ClipB, ClipT, ClipN, ClipF); + //This scaling is to take the plane with BottomLeftCorner(-1,-1,0) and TopRightCorner(1,1,0) and map it to the screen after the perspective division. + glm::vec3 scale(1.0 / (((RealR * 2.0 * ClipN) / (EyePos * (ClipR - ClipL))) - ((ClipR + ClipL) / (ClipR - ClipL))), + 1.0 / (((RealT * 2.0 * ClipN) / (EyePos * (ClipT - ClipB))) - ((ClipT + ClipB) / (ClipT - ClipB))), + 1.0); + projection = glm::scale(projection, scale); + glUniformMatrix4fv(nOrthoProjectionMatrix, 1, false, glm::value_ptr(projection)); + + glm::mat4 view = lookAt(glm::vec3(0, 0, EyePos), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); + glUniformMatrix4fv(nOrthoViewMatrix, 1, false, glm::value_ptr(view)); + + // Generate the framebuffer and textures for the shadows. + glGenTextures(2, mnDepthTextures.data()); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, mnDepthTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2048, 2048, 0, GL_RGBA, GL_FLOAT, 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_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, mnDepthTextures[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 2048, 2048, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 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_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glActiveTexture(GL_TEXTURE0); + glGenFramebuffers(1, &mnFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, mnFramebuffer); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mnDepthTextures[0], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, mnDepthTextures[1], 0); + + // Always check that our framebuffer is ok + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + SAL_WARN("slideshow.opengl", "Wrong framebuffer!"); + return; + } + + glBindFramebuffer(GL_FRAMEBUFFER, 0); } void HoneycombTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale ) { CHECK_GL_ERROR(); - applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale ); - glUniform1f( m_nTimeLocation, nTime ); - - // The back (entering) slide needs to be drawn before the front (leaving) one in order for blending to work. + applyOverallOperations(nTime, SlideWidthScale, SlideHeightScale); + glUniform1f(m_nTimeLocation, nTime); + glUniform1f(mnShadowLocation, 1.0); + CHECK_GL_ERROR(); const float borderSize = 0.15f; - CHECK_GL_ERROR(); - glUniform1f(maSelectedTextureLocation, 0.0); + std::array<GLint, 4> viewport; + glGetIntegerv(GL_VIEWPORT, viewport.data()); + glViewport(0, 0, 2048, 2048); + glBindFramebuffer(GL_FRAMEBUFFER, mnFramebuffer); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glUniform1f(mnShadowLocation, 1.0); + glUniform1f(maSelectedTextureLocation, 1.0); glUniform1f(maHexagonSizeLocation, 1.0 - borderSize); - displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale ); + displaySlide(nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale); glUniform1f(maHexagonSizeLocation, 1.0 + borderSize); - displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale ); - CHECK_GL_ERROR(); + displaySlide(nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale); + // The back (entering) slide needs to be drawn before the front (leaving) one in order for blending to work. + glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glUniform1f(mnShadowLocation, 0.0); + glUniform1f(maSelectedTextureLocation, 0.0); + glUniform1f(maHexagonSizeLocation, 1.0 - borderSize); + displaySlide(nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale); + glUniform1f(maHexagonSizeLocation, 1.0 + borderSize); + displaySlide(nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale); glUniform1f(maSelectedTextureLocation, 1.0); glUniform1f(maHexagonSizeLocation, 1.0 - borderSize); - displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale ); + displaySlide(nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale); glUniform1f(maHexagonSizeLocation, 1.0 + borderSize); - displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale ); + displaySlide(nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale); + CHECK_GL_ERROR(); } std::shared_ptr<OGLTransitionImpl> |