[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - slideshow/opengl slideshow/source

Emmanuel Gil Peyrot emmanuel.peyrot at collabora.com
Wed Feb 10 06:20:53 UTC 2016


 slideshow/opengl/honeycombFragmentShader.glsl                        |   11 
 slideshow/opengl/honeycombGeometryShader.glsl                        |   32 ++
 slideshow/opengl/honeycombVertexShader.glsl                          |   20 +
 slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx |  125 +++++++++-
 4 files changed, 171 insertions(+), 17 deletions(-)

New commits:
commit 48395acdae355a4c272cdbaf54131b3bcc96d63d
Author: Emmanuel Gil Peyrot <emmanuel.peyrot at collabora.com>
Date:   Tue Feb 9 23:59:16 2016 +0000

    slideshow: Add shadows to Honeycomb, using the same way as Vortex
    
    Change-Id: I1f8f11f900f281792b417c1efead272fe3e8432e
    Reviewed-on: https://gerrit.libreoffice.org/22255
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/slideshow/opengl/honeycombFragmentShader.glsl b/slideshow/opengl/honeycombFragmentShader.glsl
index 7e52951..41b6738 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 f1c0c70..5269fad 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 d54783b..32fdece 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 25b307a..fc66cb6 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>


More information about the Libreoffice-commits mailing list