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

Emmanuel Gil Peyrot emmanuel.peyrot at collabora.com
Tue Feb 9 19:04:50 UTC 2016


 slideshow/Package_opengl.mk                                          |    1 
 slideshow/opengl/vortexFragmentShader.glsl                           |   34 ++
 slideshow/opengl/vortexGeometryShader.glsl                           |   32 +-
 slideshow/opengl/vortexVertexShader.glsl                             |   19 -
 slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx |  160 ++++++++--
 slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.hxx |    4 
 6 files changed, 214 insertions(+), 36 deletions(-)

New commits:
commit 49f55eabda703e9b651f3ca549193b89c2a5b0fd
Author: Emmanuel Gil Peyrot <emmanuel.peyrot at collabora.com>
Date:   Tue Feb 9 09:27:46 2016 +0000

    slideshow: Add shadows to the Vortex transition
    
    These are done using a shadow mapping technique, we render both slides
    from the point of view of the light, and then do a second pass in which
    we lower the light of the fragment if some other cube is above it.
    
    also:
    
    slideshow: Only retrieve each uniform location once
    
    Change-Id: I8aaa1428c4481661283bf69b5e56aa4d95fb80dd
    Reviewed-on: https://gerrit.libreoffice.org/22232
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/22245
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/slideshow/Package_opengl.mk b/slideshow/Package_opengl.mk
index 2781cd7..eef06e9 100644
--- a/slideshow/Package_opengl.mk
+++ b/slideshow/Package_opengl.mk
@@ -25,6 +25,7 @@ $(eval $(call gb_Package_add_files,slideshow_opengl_shader,$(LIBO_ETC_FOLDER)/op
 		staticFragmentShader.glsl \
 		vortexVertexShader.glsl \
 		vortexGeometryShader.glsl \
+		vortexFragmentShader.glsl \
 		rippleFragmentShader.glsl \
 ))
 
diff --git a/slideshow/opengl/vortexFragmentShader.glsl b/slideshow/opengl/vortexFragmentShader.glsl
new file mode 100644
index 0000000..3212ebe
--- /dev/null
+++ b/slideshow/opengl/vortexFragmentShader.glsl
@@ -0,0 +1,34 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#version 150
+
+uniform sampler2D slideTexture;
+uniform sampler2D leavingShadowTexture;
+uniform sampler2D enteringShadowTexture;
+
+in vec2 v_texturePosition;
+in vec3 v_normal;
+in vec4 shadowCoordinate;
+
+void main() {
+    vec3 lightVector = vec3(0.0, 0.0, 1.0);
+    float light = max(dot(lightVector, v_normal), 0.0);
+    vec4 fragment = texture2D(slideTexture, v_texturePosition);
+    float visibility = 1.0;
+    const float epsilon = 0.0001;
+    if (texture2D(leavingShadowTexture, shadowCoordinate.xy).r < shadowCoordinate.z - epsilon)
+        visibility *= 0.7;
+    if (texture2D(enteringShadowTexture, shadowCoordinate.xy).r < shadowCoordinate.z - epsilon)
+        visibility *= 0.7;
+    vec4 black = vec4(0.0, 0.0, 0.0, fragment.a);
+    gl_FragColor = mix(black, fragment, visibility * light);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/slideshow/opengl/vortexGeometryShader.glsl b/slideshow/opengl/vortexGeometryShader.glsl
index 46999ef..312baba 100644
--- a/slideshow/opengl/vortexGeometryShader.glsl
+++ b/slideshow/opengl/vortexGeometryShader.glsl
@@ -14,16 +14,41 @@ layout(triangle_strip, max_vertices=11) out;
 
 in vec2 g_texturePosition[];
 in vec3 g_normal[];
+in mat4 projectionMatrix[];
 in mat4 modelViewMatrix[];
+in mat4 shadowMatrix[];
 in mat4 transform[];
 in float nTime[];
 in float startTime[];
 in float endTime[];
 
-uniform mat4 u_projectionMatrix;
-
 out vec2 v_texturePosition;
 out vec3 v_normal;
+out vec4 shadowCoordinate;
+
+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(int index, vec3 translation, float fdsq)
 {
@@ -37,7 +62,8 @@ void emitHexagonVertex(int index, vec3 translation, float fdsq)
     v_normal = normalize(vec3(normalMatrix * transform[index] * vec4(g_normal[index], 0.0)));
     v_normal.z *= fdsq;
 
-    gl_Position = u_projectionMatrix * modelViewMatrix[index] * pos;
+    gl_Position = projectionMatrix[index] * modelViewMatrix[index] * pos;
+    shadowCoordinate = translationMatrix(vec3(0.5, 0.5, 0.5)) * scaleMatrix(vec3(0.5, 0.5, 0.5)) * shadowMatrix[index] * modelViewMatrix[index] * pos;
     v_texturePosition = g_texturePosition[index];
     EmitVertex();
 }
diff --git a/slideshow/opengl/vortexVertexShader.glsl b/slideshow/opengl/vortexVertexShader.glsl
index 603c629..9bab2d9 100755
--- a/slideshow/opengl/vortexVertexShader.glsl
+++ b/slideshow/opengl/vortexVertexShader.glsl
@@ -16,6 +16,7 @@ in vec3 a_normal;
 in vec2 a_texCoord;
 in float tileInfo;
 
+uniform mat4 u_projectionMatrix;
 uniform mat4 u_modelViewMatrix;
 uniform mat4 u_sceneTransformMatrix;
 uniform mat4 u_primitiveTransformMatrix;
@@ -25,10 +26,15 @@ uniform float time;
 uniform ivec2 numTiles;
 uniform sampler2D permTexture;
 uniform float slide;
+uniform float shadow;
+uniform mat4 orthoProjectionMatrix;
+uniform mat4 orthoViewMatrix;
 
 out vec2 g_texturePosition;
 out vec3 g_normal;
+out mat4 projectionMatrix;
 out mat4 modelViewMatrix;
+out mat4 shadowMatrix;
 out mat4 transform;
 out float nTime;
 out float startTime;
@@ -134,13 +140,14 @@ void main( void )
                   * rotationMatrix(vec3(0.0, 1.0, 0.0), clamp(rotation, -1.0, 1.0) * M_PI)
                   * translationMatrix(-translationVector)
                   * transform;
+    }
 
-        // Add a translation movement to the leaving slide so it doesn’t exactly mirror the entering one.
-        if (isLeavingSlide && nTime > 0.3)
-        {
-            float movement = smoothstep(0.0, 1.0, (nTime - 0.3) * 2.0);
-            transform = translationMatrix(vec3(-movement, 0.0, -0.5 * movement)) * transform;
-        }
+    if (shadow < 0.5) {
+        projectionMatrix = u_projectionMatrix;
+        shadowMatrix = orthoProjectionMatrix * orthoViewMatrix;
+    } else {
+        projectionMatrix = orthoProjectionMatrix * orthoViewMatrix;
+        shadowMatrix = mat4(0.0);
     }
 
     modelViewMatrix = u_modelViewMatrix * u_operationsTransformMatrix * u_sceneTransformMatrix * u_primitiveTransformMatrix;
diff --git a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx
index cf310c6..25b307a 100644
--- a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx
+++ b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx
@@ -32,6 +32,7 @@
 #include <vcl/opengl/OpenGLHelper.hxx>
 
 #include <algorithm>
+#include <array>
 #include <utility>
 
 #include <comphelper/random.hxx>
@@ -169,6 +170,7 @@ bool OGLTransitionImpl::prepare( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteri
     m_nPrimitiveTransformLocation = glGetUniformLocation( m_nProgramObject, "u_primitiveTransformMatrix" );
     m_nSceneTransformLocation = glGetUniformLocation( m_nProgramObject, "u_sceneTransformMatrix" );
     m_nOperationsTransformLocation = glGetUniformLocation( m_nProgramObject, "u_operationsTransformMatrix" );
+    m_nTimeLocation = glGetUniformLocation( m_nProgramObject, "time" );
 
     glGenVertexArrays(1, &m_nVertexArrayObject);
     glBindVertexArray(m_nVertexArrayObject);
@@ -250,9 +252,7 @@ void OGLTransitionImpl::displaySlides_( double nTime, sal_Int32 glLeavingSlideTe
     CHECK_GL_ERROR();
     applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
 
-    GLint location = glGetUniformLocation( m_nProgramObject, "time" );
-    if( location != -1 )
-        glUniform1f( location, nTime );
+    glUniform1f( m_nTimeLocation, nTime );
 
     glActiveTexture( GL_TEXTURE2 );
     glBindTexture( GL_TEXTURE_2D, glEnteringSlideTex );
@@ -1547,24 +1547,28 @@ class VortexTransition : public PermTextureTransition
 public:
     VortexTransition(const TransitionScene& rScene, const TransitionSettings& rSettings, int nNX, int nNY)
         : PermTextureTransition(rScene, rSettings)
-        , mnTileInfoLocation(0)
-        , mnTileInfoBuffer(0)
         , maNumTiles(nNX,nNY)
     {
         mvTileInfo.resize(6*maNumTiles.x*maNumTiles.y);
+        mnFramebuffers[0] = 0;
+        mnFramebuffers[1] = 0;
+        mnDepthTextures[0] = 0;
+        mnDepthTextures[1] = 0;
     }
 
 private:
     virtual void prepare( double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight ) override;
-
+    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 mnTileInfoLocation;
-    GLuint mnTileInfoBuffer;
+    GLint mnSlideLocation = -1;
+    GLint mnTileInfoLocation = -1;
+    GLuint mnTileInfoBuffer = 0u;
+    GLint mnShadowLocation = -1;
+    std::array<GLuint, 2> mnFramebuffers;
+    std::array<GLuint, 2> mnDepthTextures;
 
     glm::ivec2 maNumTiles;
 
@@ -1584,9 +1588,39 @@ void VortexTransition::prepare( double, double, double, double, double )
     CHECK_GL_ERROR();
 }
 
+void VortexTransition::finishTransition()
+{
+    PermTextureTransition::finishTransition();
+
+    CHECK_GL_ERROR();
+    glDeleteTextures(2, mnDepthTextures.data());
+    mnDepthTextures = {0u, 0u};
+    CHECK_GL_ERROR();
+    glDeleteFramebuffers(2, mnFramebuffers.data());
+    mnFramebuffers = {0u, 0u};
+    glDeleteBuffers(1, &mnTileInfoBuffer);
+    mnTileInfoBuffer = 0u;
+    mnSlideLocation = -1;
+    mnTileInfoLocation = -1;
+    mnShadowLocation = -1;
+    CHECK_GL_ERROR();
+}
+
 GLuint VortexTransition::makeShader() const
 {
-    return OpenGLHelper::LoadShaders( "vortexVertexShader", "basicFragmentShader", "vortexGeometryShader" );
+    return OpenGLHelper::LoadShaders( "vortexVertexShader", "vortexFragmentShader", "vortexGeometryShader" );
+}
+
+static glm::mat4 lookAt(glm::vec3 eye, glm::vec3 center, glm::vec3 up) {
+    glm::vec3 f = glm::normalize(center - eye);
+    glm::vec3 u = glm::normalize(up);
+    glm::vec3 s = glm::normalize(glm::cross(f, u));
+    u = glm::cross(s, f);
+
+    return glm::mat4(s.x, u.x, -f.x, 0,
+                     s.y, u.y, -f.y, 0,
+                     s.z, u.z, -f.z, 0,
+                     -glm::dot(s, eye), -glm::dot(u, eye), glm::dot(f, eye), 1);
 }
 
 void VortexTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex )
@@ -1595,10 +1629,16 @@ void VortexTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32
     PermTextureTransition::prepareTransition( glLeavingSlideTex, glEnteringSlideTex );
     CHECK_GL_ERROR();
 
+    mnSlideLocation = glGetUniformLocation(m_nProgramObject, "slide");
     mnTileInfoLocation = glGetAttribLocation(m_nProgramObject, "tileInfo");
-    CHECK_GL_ERROR();
-
     GLint nNumTilesLocation = glGetUniformLocation(m_nProgramObject, "numTiles");
+    mnShadowLocation = glGetUniformLocation(m_nProgramObject, "shadow");
+    GLint nOrthoProjectionMatrix = glGetUniformLocation(m_nProgramObject, "orthoProjectionMatrix");
+    GLint nOrthoViewMatrix = glGetUniformLocation(m_nProgramObject, "orthoViewMatrix");
+    GLint location = glGetUniformLocation(m_nProgramObject, "leavingShadowTexture");
+    glUniform1i(location, 2);
+    location = glGetUniformLocation(m_nProgramObject, "enteringShadowTexture");
+    glUniform1i(location, 3);
     CHECK_GL_ERROR();
 
     glUniform2iv(nNumTilesLocation, 1, glm::value_ptr(maNumTiles));
@@ -1634,24 +1674,92 @@ void VortexTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32
 
     glBindBuffer(GL_ARRAY_BUFFER, 0);
     CHECK_GL_ERROR();
+
+    double EyePos(10.0);
+    double RealF(1.0);
+    double RealN(-1.0);
+    double RealL(-2.0);
+    double RealR(2.0);
+    double RealB(-2.0);
+    double RealT(2.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(-1, 1, EyePos), glm::vec3(-0.5, 0.5, 0), glm::vec3(0, 1, 0));
+    glUniformMatrix4fv(nOrthoViewMatrix, 1, false, glm::value_ptr(view));
+
+    // Generate the framebuffers and textures for the shadows.
+    glGenTextures(2, mnDepthTextures.data());
+    glGenFramebuffers(2, mnFramebuffers.data());
+
+    for (int i : {0, 1}) {
+        glBindTexture(GL_TEXTURE_2D, mnDepthTextures[i]);
+        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);
+
+        glBindFramebuffer(GL_FRAMEBUFFER, mnFramebuffers[i]);
+        glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, mnDepthTextures[i], 0);
+        glDrawBuffer(GL_NONE); // No color buffer is drawn to.
+
+        // 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);
+    glBindTexture(GL_TEXTURE_2D, 0);
+
+    glActiveTexture( GL_TEXTURE2 );
+    glBindTexture( GL_TEXTURE_2D, mnDepthTextures[0] );
+    glActiveTexture( GL_TEXTURE3 );
+    glBindTexture( GL_TEXTURE_2D, mnDepthTextures[1] );
+    glActiveTexture( GL_TEXTURE0 );
 }
 
 void VortexTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale )
 {
     CHECK_GL_ERROR();
     applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
+    glUniform1f( m_nTimeLocation, nTime );
+    glUniform1f( mnShadowLocation, 1.0 );
 
-    GLint location = glGetUniformLocation( m_nProgramObject, "time" );
-    if( location != -1 )
-        glUniform1f( location, nTime );
+    std::array<GLint, 4> viewport;
+    glGetIntegerv(GL_VIEWPORT, viewport.data());
+    glViewport(0, 0, 2048, 2048);
 
-    location = glGetUniformLocation( m_nProgramObject, "slide" );
+    glBindFramebuffer(GL_FRAMEBUFFER, mnFramebuffers[0]);
+    glClear(GL_DEPTH_BUFFER_BIT);
+    glUniform1f( mnSlideLocation, 0.0 );
+    displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale );
+
+    glBindFramebuffer(GL_FRAMEBUFFER, mnFramebuffers[1]);
+    glClear(GL_DEPTH_BUFFER_BIT);
+    glUniform1f( mnSlideLocation, 1.0 );
+    displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale );
 
-    if( location != -1 )
-        glUniform1f( location, 0.0 );
+    glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    glUniform1f( mnShadowLocation, 0.0 );
+    glUniform1f( mnSlideLocation, 0.0 );
     displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale );
-    if( location != -1 )
-        glUniform1f( location, 1.0 );
+    glUniform1f( mnSlideLocation, 1.0 );
     displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale );
     CHECK_GL_ERROR();
 }
@@ -1672,7 +1780,7 @@ makeVortexTransition(const Primitives_t& rLeavingSlidePrimitives,
 
 std::shared_ptr<OGLTransitionImpl> makeVortex()
 {
-    const int NX = 64, NY = 64;
+    const int NX = 96, NY = 96;
     Primitive Slide;
 
     for (int x = 0; x < NX; x++)
@@ -1910,9 +2018,8 @@ private:
     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 = 0;
-    GLint maTimeLocation = 0;
-    GLint maSelectedTextureLocation = 0;
+    GLint maHexagonSizeLocation = -1;
+    GLint maSelectedTextureLocation = -1;
 };
 
 GLuint HoneycombTransition::makeShader() const
@@ -1927,7 +2034,6 @@ void HoneycombTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_In
 
     CHECK_GL_ERROR();
     maHexagonSizeLocation = glGetUniformLocation(m_nProgramObject, "hexagonSize");
-    maTimeLocation = glGetUniformLocation( m_nProgramObject, "time" );
     maSelectedTextureLocation = glGetUniformLocation( m_nProgramObject, "selectedTexture" );
     CHECK_GL_ERROR();
 
@@ -1942,7 +2048,7 @@ void HoneycombTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlide
 {
     CHECK_GL_ERROR();
     applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
-    glUniform1f( maTimeLocation, nTime );
+    glUniform1f( m_nTimeLocation, nTime );
 
     // The back (entering) slide needs to be drawn before the front (leaving) one in order for blending to work.
 
diff --git a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.hxx b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.hxx
index d8cbbfe..449a72f 100644
--- a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.hxx
+++ b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.hxx
@@ -240,6 +240,10 @@ protected:
     /** VBO in which to put primitive data
      */
     GLuint m_nVertexBufferObject = 0u;
+
+    /** Location of the "time" uniform
+     */
+    GLint m_nTimeLocation = -1;
 };
 
 


More information about the Libreoffice-commits mailing list