summaryrefslogtreecommitdiff
path: root/slideshow
diff options
context:
space:
mode:
authorEmmanuel Gil Peyrot <emmanuel.peyrot@collabora.com>2016-02-09 23:59:16 +0000
committerMichael Meeks <michael.meeks@collabora.com>2016-02-09 23:59:52 +0000
commitd323f2487d84fbd3909cd2166b98a2a875b71bf8 (patch)
tree6a76c24bfb28cc632d8261435263d7be8b2772ef /slideshow
parent1f8ddf1b8ff4727473676de9c7fda24b49b9599d (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.glsl11
-rw-r--r--slideshow/opengl/honeycombGeometryShader.glsl32
-rw-r--r--slideshow/opengl/honeycombVertexShader.glsl20
-rw-r--r--slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx125
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>