diff options
author | Emmanuel Gil Peyrot <emmanuel.peyrot@collabora.com> | 2015-11-20 20:13:05 +0000 |
---|---|---|
committer | Tomaž Vajngerl <tomaz.vajngerl@collabora.com> | 2015-11-20 21:48:58 +0100 |
commit | b3ce63e5a5899088def6458ae80a354c926f9891 (patch) | |
tree | 77e3ae24e0d1e4469bd3e296da5ef4688de0d75c | |
parent | f62990a835e4751366f0e499f2f9c9b92889c039 (diff) |
slideshow: Reimplement reflections in shaders, and port Rochade and TurnAround
This removes the hack reflections were previously, where a black quad
was drawn on top of a mirror version of the first primitive only.
Change-Id: I8c0863ab30e85d0130a8d7e838f3514e9be93788
5 files changed, 171 insertions, 87 deletions
diff --git a/slideshow/Package_opengl.mk b/slideshow/Package_opengl.mk index 82fb3b937f18..1293c05f62c4 100644 --- a/slideshow/Package_opengl.mk +++ b/slideshow/Package_opengl.mk @@ -15,6 +15,8 @@ $(eval $(call gb_Package_add_files,slideshow_opengl_shader,$(LIBO_ETC_FOLDER)/op dissolveFragmentShader.glsl \ fadeBlackFragmentShader.glsl \ fadeFragmentShader.glsl \ + reflectionVertexShader.glsl \ + reflectionFragmentShader.glsl \ staticFragmentShader.glsl \ vortexFragmentShader.glsl \ vortexVertexShader.glsl \ diff --git a/slideshow/opengl/reflectionFragmentShader.glsl b/slideshow/opengl/reflectionFragmentShader.glsl new file mode 100644 index 000000000000..9bf8ecb70c3d --- /dev/null +++ b/slideshow/opengl/reflectionFragmentShader.glsl @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2015 by Collabora, Ltd. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#version 130 + +uniform sampler2D slideTexture; +varying float v_isShadow; +varying vec2 v_texturePosition; + +void main() { + vec4 fragment = texture2D(slideTexture, v_texturePosition); + if (v_isShadow > 0.5) { + if (v_texturePosition.y > 1.0 - 0.3) + gl_FragColor = mix(fragment, vec4(0.0, 0.0, 0.0, 0.0), (1.0 - v_texturePosition.y) / 0.3); + else + discard; + } else { + gl_FragColor = fragment; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/opengl/reflectionVertexShader.glsl b/slideshow/opengl/reflectionVertexShader.glsl new file mode 100644 index 000000000000..b08d0cc82f59 --- /dev/null +++ b/slideshow/opengl/reflectionVertexShader.glsl @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#version 130 + +varying float v_isShadow; +varying vec2 v_texturePosition; + +void main( void ) +{ + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + v_texturePosition = gl_MultiTexCoord0.xy; + v_isShadow = float(gl_VertexID >= 6); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx index 1f4cf9fdb782..dd791aed6017 100644 --- a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx +++ b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.cxx @@ -93,53 +93,6 @@ void OGLTransitionImpl::finish() finishTransition(); } -static void blendSlide( double depth ) -{ - CHECK_GL_ERROR(); - double showHeight = -1 + depth*2; - GLfloat reflectionColor[] = {0, 0, 0, 0.25}; - - glDisable( GL_DEPTH_TEST ); - glBegin( GL_QUADS ); - glColor4fv( reflectionColor ); - glVertex3f( -1, -1, 0 ); - glColor4f( 0, 0, 0, 1 ); - glVertex3f(-1, showHeight, 0 ); - glVertex3f( 1, showHeight, 0 ); - glColor4fv( reflectionColor ); - glVertex3f( 1, -1, 0 ); - glEnd(); - - glBegin( GL_QUADS ); - glColor4f( 0, 0, 0, 1 ); - glVertex3f( -1, showHeight, 0 ); - glVertex3f( -1, 1, 0 ); - glVertex3f( 1, 1, 0 ); - glVertex3f( 1, showHeight, 0 ); - glEnd(); - glEnable( GL_DEPTH_TEST ); - CHECK_GL_ERROR(); -} - -static void slideShadow( double nTime, const Primitive& primitive, double sw, double sh ) -{ - CHECK_GL_ERROR(); - double reflectionDepth = 0.3; - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_LIGHTING); - - glPushMatrix(); - primitive.applyOperations( nTime, sw, sh ); - blendSlide( reflectionDepth ); - glPopMatrix(); - - glDisable(GL_BLEND); - glEnable(GL_LIGHTING); - CHECK_GL_ERROR(); -} - void OGLTransitionImpl::prepare( double, double, double, double, double ) { } @@ -256,33 +209,8 @@ OGLTransitionImpl::displaySlide( double SlideWidthScale, double SlideHeightScale ) { CHECK_GL_ERROR(); - //TODO change to foreach glBindTexture(GL_TEXTURE_2D, glSlideTex); CHECK_GL_ERROR(); - - // display slide reflection - // note that depth test is turned off while blending the shadow - // so the slides has to be rendered in right order, see rochade as example - if( maSettings.mbReflectSlides ) { - double surfaceLevel = -0.04; - - /* reflected slides */ - glPushMatrix(); - - glm::mat4 matrix; - matrix = glm::scale(matrix, glm::vec3(1, -1, 1)); - matrix = glm::translate(matrix, glm::vec3(0, 2 - surfaceLevel, 0)); - glMultMatrixf(glm::value_ptr(matrix)); - - glCullFace(GL_FRONT); - display_primitives(primitives, nTime, SlideWidthScale, SlideHeightScale); - glCullFace(GL_BACK); - - slideShadow( nTime, primitives[0], SlideWidthScale, SlideHeightScale ); - - glPopMatrix(); - } - display_primitives(primitives, nTime, SlideWidthScale, SlideHeightScale); CHECK_GL_ERROR(); } @@ -493,6 +421,69 @@ void ShaderTransition::impl_setTextureUniforms() namespace { +class ReflectionTransition : public ShaderTransition +{ +public: + ReflectionTransition(const TransitionScene& rScene, const TransitionSettings& rSettings) + : ShaderTransition(rScene, rSettings) + {} + +private: + virtual GLuint makeShader() const override; + virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale ) override; + + virtual void impl_prepareTransition() override { + glDisable(GL_CULL_FACE); + } + + virtual void impl_finishTransition() override { + glEnable(GL_CULL_FACE); + } +}; + +GLuint ReflectionTransition::makeShader() const +{ + return OpenGLHelper::LoadShaders( "reflectionVertexShader", "reflectionFragmentShader" ); +} + +void ReflectionTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, + double SlideWidthScale, double SlideHeightScale ) +{ + CHECK_GL_ERROR(); + applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale ); + + sal_Int32 texture; + Primitives_t slide; + if (nTime < 0.5) { + texture = glLeavingSlideTex; + slide = getScene().getLeavingSlide(); + } else { + texture = glEnteringSlideTex; + slide = getScene().getEnteringSlide(); + } + + displaySlide( nTime, texture, slide, SlideWidthScale, SlideHeightScale ); + CHECK_GL_ERROR(); +} + +std::shared_ptr<OGLTransitionImpl> +makeReflectionTransition( + const Primitives_t& rLeavingSlidePrimitives, + const Primitives_t& rEnteringSlidePrimitives, + const Operations_t& rOverallOperations, + const TransitionSettings& rSettings = TransitionSettings()) +{ + return std::make_shared<ReflectionTransition>( + TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives, rOverallOperations, SceneObjects_t()), + rSettings) + ; +} + +} + +namespace +{ + class SimpleTransition : public ShaderTransition { public: @@ -639,25 +630,30 @@ std::shared_ptr<OGLTransitionImpl> makeFallLeaving() std::shared_ptr<OGLTransitionImpl> makeTurnAround() { Primitive Slide; - TransitionSettings aSettings; - aSettings.mbReflectSlides = true; Slide.pushTriangle(glm::vec2(0,0),glm::vec2(1,0),glm::vec2(0,1)); Slide.pushTriangle(glm::vec2(1,0),glm::vec2(0,1),glm::vec2(1,1)); Primitives_t aLeavingPrimitives; aLeavingPrimitives.push_back(Slide); + Slide.Operations.push_back(makeSScale(glm::vec3(1, -1, 1), glm::vec3(0, -1.02, 0), false, -1, 0)); + aLeavingPrimitives.push_back(Slide); + + Slide.Operations.clear(); Slide.Operations.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0,1,0),glm::vec3(0,0,0),-180,false,0.0,1.0)); Primitives_t aEnteringPrimitives; aEnteringPrimitives.push_back(Slide); + Slide.Operations.push_back(makeSScale(glm::vec3(1, -1, 1), glm::vec3(0, -1.02, 0), false, -1, 0)); + aEnteringPrimitives.push_back(Slide); + Operations_t aOperations; aOperations.push_back(makeSTranslate(glm::vec3(0, 0, -1.5),true, 0, 0.5)); aOperations.push_back(makeSTranslate(glm::vec3(0, 0, 1.5), true, 0.5, 1)); aOperations.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0, 1, 0),glm::vec3(0, 0, 0), -180, true, 0.0, 1.0)); - return makeSimpleTransition(aLeavingPrimitives, aEnteringPrimitives, aOperations, aSettings); + return makeReflectionTransition(aLeavingPrimitives, aEnteringPrimitives, aOperations, aSettings); } std::shared_ptr<OGLTransitionImpl> makeTurnDown() @@ -755,15 +751,15 @@ std::shared_ptr<OGLTransitionImpl> makeIris() namespace { -class RochadeTransition : public SimpleTransition +class RochadeTransition : public ReflectionTransition { public: RochadeTransition(const TransitionScene& rScene, const TransitionSettings& rSettings) - : SimpleTransition(rScene, rSettings) + : ReflectionTransition(rScene, rSettings) {} private: - virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale ) override; + virtual void displaySlides_(double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale) override; }; void RochadeTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale ) @@ -798,9 +794,7 @@ makeRochadeTransition( std::shared_ptr<OGLTransitionImpl> makeRochade() { Primitive Slide; - TransitionSettings aSettings; - aSettings.mbReflectSlides = true; double w, h; @@ -815,6 +809,9 @@ std::shared_ptr<OGLTransitionImpl> makeRochade() Primitives_t aLeavingSlide; aLeavingSlide.push_back(Slide); + Slide.Operations.push_back(makeSScale(glm::vec3(1, -1, 1), glm::vec3(0, -1.02, 0), false, -1, 0)); + aLeavingSlide.push_back(Slide); + Slide.Operations.clear(); Slide.Operations.push_back(makeSEllipseTranslate(w, h, 0.75, 0.25, true, 0, 1)); Slide.Operations.push_back(makeSTranslate(glm::vec3(0, 0, -h), false, -1, 0)); @@ -823,6 +820,9 @@ std::shared_ptr<OGLTransitionImpl> makeRochade() Primitives_t aEnteringSlide; aEnteringSlide.push_back(Slide); + Slide.Operations.push_back(makeSScale(glm::vec3(1, -1, 1), glm::vec3(0, -1.02, 0), false, -1, 0)); + aEnteringSlide.push_back(Slide); + return makeRochadeTransition(aLeavingSlide, aEnteringSlide, aSettings); } diff --git a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.hxx b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.hxx index a9f8b627dd07..4238f8ea8b91 100644 --- a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.hxx +++ b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionImpl.hxx @@ -51,8 +51,7 @@ struct TransitionSettings TransitionSettings() : mbUseMipMapLeaving( true ), mbUseMipMapEntering( true ), - mnRequiredGLVersion( 1.0 ), - mbReflectSlides( false ) + mnRequiredGLVersion( 1.0 ) { } @@ -64,11 +63,6 @@ struct TransitionSettings /** which GL version does the transition require */ float mnRequiredGLVersion; - - /** Whether to reflect slides, the reflection happens on flat surface beneath the slides. - ** Now it only works with slides which keep their rectangular shape together. - */ - bool mbReflectSlides; }; typedef std::vector<Primitive> Primitives_t; |