Kaydet (Commit) d886fef2 authored tarafından Emmanuel Gil Peyrot's avatar Emmanuel Gil Peyrot Kaydeden (comit) Tomaž Vajngerl

slideshow: Improve the Vortex transition to match PowerPoint better

Change-Id: I60e0b71d41a726459baeb7e590745d6bfb58e884
üst 1d411cad
...@@ -23,7 +23,6 @@ $(eval $(call gb_Package_add_files,slideshow_opengl_shader,$(LIBO_ETC_FOLDER)/op ...@@ -23,7 +23,6 @@ $(eval $(call gb_Package_add_files,slideshow_opengl_shader,$(LIBO_ETC_FOLDER)/op
reflectionVertexShader.glsl \ reflectionVertexShader.glsl \
reflectionFragmentShader.glsl \ reflectionFragmentShader.glsl \
staticFragmentShader.glsl \ staticFragmentShader.glsl \
vortexFragmentShader.glsl \
vortexVertexShader.glsl \ vortexVertexShader.glsl \
rippleFragmentShader.glsl \ rippleFragmentShader.glsl \
)) ))
......
/* -*- 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 120
uniform sampler2D leavingSlideTexture;
uniform sampler2D enteringSlideTexture;
uniform float time;
varying vec2 v_texturePosition;
varying float v_textureSelect;
varying vec3 v_normal;
void main()
{
vec3 lightVector = vec3(0.0, 0.0, 1.0);
float light = abs(dot(lightVector, v_normal));
vec4 fragment;
if (v_textureSelect == 0)
{
fragment = texture2D(leavingSlideTexture, v_texturePosition);
}
else
{
vec2 pos = v_texturePosition;
pos.x = 1 - pos.x;
fragment = texture2D(enteringSlideTexture, pos);
}
vec4 black = vec4(0.0, 0.0, 0.0, fragment.a);
gl_FragColor = mix(black, fragment, light);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -28,13 +28,30 @@ uniform float time; ...@@ -28,13 +28,30 @@ uniform float time;
uniform ivec2 numTiles; uniform ivec2 numTiles;
uniform sampler2D permTexture; uniform sampler2D permTexture;
attribute float tileInfo; attribute float tileInfo;
varying float v_textureSelect; uniform float slide;
varying vec4 debug;
float snoise(vec2 p) float snoise(vec2 p)
{ {
return texture2D(permTexture, p).r; 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 translationMatrix(vec3 axis)
{
mat4 matrix = identityMatrix();
matrix[3] = vec4(axis, 1.0);
return matrix;
}
mat4 rotationMatrix(vec3 axis, float angle) mat4 rotationMatrix(vec3 axis, float angle)
{ {
axis = normalize(axis); axis = normalize(axis);
...@@ -53,13 +70,6 @@ void main( void ) ...@@ -53,13 +70,6 @@ void main( void )
vec4 v = vec4(a_position, 1.0); vec4 v = vec4(a_position, 1.0);
vec4 normal = vec4(a_normal, 1.0); vec4 normal = vec4(a_normal, 1.0);
// Not sure it this is like what it should eventually be; just
// experimenting to get at least something.
// Move the tile on a semicircular path so that it will end up at
// the correct place. All tiles move the same direction around the
// vertical centre axis.
// Each tile moves during only half of the transition. The letmost // Each tile moves during only half of the transition. The letmost
// tiles start moving at the start and arrive at their end // tiles start moving at the start and arrive at their end
// position around time=0.5, when the tiles there (the rightmost // position around time=0.5, when the tiles there (the rightmost
...@@ -70,49 +80,69 @@ void main( void ) ...@@ -70,49 +80,69 @@ void main( void )
int tileXIndex = int(mod(int(tileInfo), 256)); int tileXIndex = int(mod(int(tileInfo), 256));
int tileYIndex = int(mod(int(tileInfo) / 256, 256)); int tileYIndex = int(mod(int(tileInfo) / 256, 256));
int vertexIndexInTile = int(mod(int(tileInfo) / (256*256), 256));
// A semi-random number 0..1, different for neighbouring tiles. // A semi-random number 0..1, different for neighbouring tiles, to know when they should start moving.
float fuzz = snoise(vec2(float(tileXIndex)/(numTiles.x-1), float(tileYIndex)/(numTiles.y-1))); float startTimeFuzz = snoise(vec2(float(tileXIndex)/(numTiles.x-1), float(tileYIndex)/(numTiles.y-1)));
// Semi-random rotation direction, identical for tiles that rotate into each other's location // A semi-random number -1.5..1.5, different for neighbouring tiles, to specify their rotation center.
// so that they don't pass through each others in flight, which looks ugly. // The additional 0.5 on each side is because we want some tiles to rotate outside.
float direction = (snoise(vec2(floor(abs(float(numTiles.x-1)/2-tileXIndex))/(float(numTiles.x-1)/2), float(tileYIndex)/(numTiles.y-1))) < 0.5 ? -1 : 1); float rotationFuzz = snoise(vec2(float(numTiles.x + tileXIndex)/(numTiles.x-1), float(tileYIndex)/(numTiles.y-1))) * 3.0 - 1.5;
float startTime = float(tileXIndex)/(numTiles.x-1) * 0.5 + fuzz*0.2; float startTime = float(tileXIndex)/(numTiles.x-1) * 0.2 + startTimeFuzz * 0.2;
float endTime = min(startTime + 0.5, 1.0); float endTime = min(startTime + 0.7, 1.0);
const float ALMOST_ONE = 0.999; bool isLeavingSlide = (slide < 0.5);
const vec4 invalidPosition = vec4(-256.0, -256.0, -256.0, -256.0);
if (time <= startTime) float nTime;
{
// Still at start location, nothing needed
v_textureSelect = 0;
}
else if (time > startTime && time <= endTime)
{
// Moving
float rotation = direction * (time - startTime) / (endTime - startTime);
// Avoid z fighting // Don’t display the tile before or after its rotation, depending on the slide.
mat4 matrix = rotationMatrix(vec3(0, 1, 0), max(min(rotation, ALMOST_ONE), -ALMOST_ONE)*M_PI); if (!isLeavingSlide)
v = matrix * v; {
normal = matrix * normal; if (time < max(0.3, startTime))
{
v_textureSelect = float(rotation > 0.5 || rotation < -0.5); gl_Position = invalidPosition;
return;
}
nTime = 1.0 - time;
} }
else else
{ {
// At end location. Tile is 180 degrees rotated if (time > endTime)
{
// Avoid z fighting gl_Position = invalidPosition;
mat4 matrix = rotationMatrix(vec3(0, 1, 0), direction*ALMOST_ONE*M_PI); return;
v = matrix * v; }
normal = matrix * normal; nTime = time;
}
v_textureSelect = 1; mat4 transform = identityMatrix();
if (nTime > startTime && nTime <= endTime)
{
// We are in the rotation part.
float rotation = -(nTime - startTime) / (endTime - startTime);
// Translation vector to set the origin of the rotation.
vec3 translationVector = vec3(rotationFuzz, 0.0, 0.0);
// Compute the actual rotation matrix.
transform = translationMatrix(translationVector)
* rotationMatrix(vec3(0, 1, 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;
}
} }
// Apply our transform operations.
v = transform * v;
normal = transform * normal;
mat4 modelViewMatrix = u_modelViewMatrix * u_operationsTransformMatrix * u_sceneTransformMatrix * u_primitiveTransformMatrix; mat4 modelViewMatrix = u_modelViewMatrix * u_operationsTransformMatrix * u_sceneTransformMatrix * u_primitiveTransformMatrix;
mat3 normalMatrix = mat3(transpose(inverse(modelViewMatrix))); mat3 normalMatrix = mat3(transpose(inverse(modelViewMatrix)));
gl_Position = u_projectionMatrix * modelViewMatrix * v; gl_Position = u_projectionMatrix * modelViewMatrix * v;
......
...@@ -1557,12 +1557,12 @@ public: ...@@ -1557,12 +1557,12 @@ public:
private: private:
virtual void prepare( double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight ) override; virtual void prepare( double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight ) override;
virtual void finish( double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight ) override;
virtual GLuint makeShader() const override; virtual GLuint makeShader() const override;
virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex ) 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; GLint mnTileInfoLocation;
GLuint mnTileInfoBuffer; GLuint mnTileInfoBuffer;
...@@ -1573,8 +1573,6 @@ private: ...@@ -1573,8 +1573,6 @@ private:
void VortexTransition::prepare( double, double, double, double, double ) void VortexTransition::prepare( double, double, double, double, double )
{ {
glDisable(GL_CULL_FACE);
glBindBuffer(GL_ARRAY_BUFFER, mnTileInfoBuffer); glBindBuffer(GL_ARRAY_BUFFER, mnTileInfoBuffer);
CHECK_GL_ERROR(); CHECK_GL_ERROR();
glEnableVertexAttribArray(mnTileInfoLocation); glEnableVertexAttribArray(mnTileInfoLocation);
...@@ -1586,14 +1584,9 @@ void VortexTransition::prepare( double, double, double, double, double ) ...@@ -1586,14 +1584,9 @@ void VortexTransition::prepare( double, double, double, double, double )
CHECK_GL_ERROR(); CHECK_GL_ERROR();
} }
void VortexTransition::finish( double, double, double, double, double )
{
glEnable(GL_CULL_FACE);
}
GLuint VortexTransition::makeShader() const GLuint VortexTransition::makeShader() const
{ {
return OpenGLHelper::LoadShaders( "vortexVertexShader", "vortexFragmentShader" ); return OpenGLHelper::LoadShaders( "vortexVertexShader", "basicFragmentShader" );
} }
void VortexTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex ) void VortexTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex )
...@@ -1643,6 +1636,26 @@ void VortexTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 ...@@ -1643,6 +1636,26 @@ void VortexTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32
CHECK_GL_ERROR(); CHECK_GL_ERROR();
} }
void VortexTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale )
{
CHECK_GL_ERROR();
applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
GLint location = glGetUniformLocation( m_nProgramObject, "time" );
if( location != -1 )
glUniform1f( location, nTime );
location = glGetUniformLocation( m_nProgramObject, "slide" );
if( location != -1 )
glUniform1f( location, 0.0 );
displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale );
if( location != -1 )
glUniform1f( location, 1.0 );
displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale );
CHECK_GL_ERROR();
}
std::shared_ptr<OGLTransitionImpl> std::shared_ptr<OGLTransitionImpl>
makeVortexTransition(const Primitives_t& rLeavingSlidePrimitives, makeVortexTransition(const Primitives_t& rLeavingSlidePrimitives,
const Primitives_t& rEnteringSlidePrimitives, const Primitives_t& rEnteringSlidePrimitives,
...@@ -1659,7 +1672,7 @@ makeVortexTransition(const Primitives_t& rLeavingSlidePrimitives, ...@@ -1659,7 +1672,7 @@ makeVortexTransition(const Primitives_t& rLeavingSlidePrimitives,
std::shared_ptr<OGLTransitionImpl> makeVortex() std::shared_ptr<OGLTransitionImpl> makeVortex()
{ {
const int NX = 40, NY = 40; const int NX = 64, NY = 64;
Primitive Slide; Primitive Slide;
for (int x = 0; x < NX; x++) for (int x = 0; x < NX; x++)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment