summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sd/source/ui/slideshow/slideshowviewimpl.cxx12
-rw-r--r--sd/source/ui/slideshow/slideshowviewimpl.hxx1
-rw-r--r--sd/xml/transitions-ogl.xml (renamed from sd/xml/transitions-ogl)0
-rw-r--r--slideshow/source/engine/OGLTrans/OGLTrans_Shaders.cxx143
-rw-r--r--slideshow/source/engine/OGLTrans/OGLTrans_Shaders.hxx71
-rw-r--r--slideshow/source/engine/OGLTrans/OGLTrans_TransitionImpl.cxx609
-rw-r--r--slideshow/source/engine/OGLTrans/OGLTrans_TransitionImpl.hxx102
-rw-r--r--slideshow/source/engine/OGLTrans/OGLTrans_TransitionerImpl.cxx1201
-rw-r--r--slideshow/source/engine/OGLTrans/makefile.mk4
-rw-r--r--slideshow/source/engine/slideshowimpl.cxx20
-rw-r--r--slideshow/source/engine/transitions/slidetransitionfactory.cxx193
11 files changed, 2029 insertions, 327 deletions
diff --git a/sd/source/ui/slideshow/slideshowviewimpl.cxx b/sd/source/ui/slideshow/slideshowviewimpl.cxx
index 9b279fa64bf9..f4de77f03394 100644
--- a/sd/source/ui/slideshow/slideshowviewimpl.cxx
+++ b/sd/source/ui/slideshow/slideshowviewimpl.cxx
@@ -487,6 +487,18 @@ void SAL_CALL SlideShowView::setMouseCursor( sal_Int16 nPointerShape ) throw (Ru
mxWindowPeer->setPointer( mxPointer );
}
+awt::Rectangle SAL_CALL SlideShowView::getCanvasArea( ) throw (RuntimeException)
+{
+ awt::Rectangle aRectangle;
+
+ if( mxWindow.is() )
+ return mxWindow->getPosSize();
+
+ aRectangle.X = aRectangle.Y = aRectangle.Width = aRectangle.Height = 0;
+
+ return aRectangle;
+}
+
void SlideShowView::updateimpl( ::osl::ClearableMutexGuard& rGuard, SlideshowImpl* pSlideShow )
{
if( pSlideShow )
diff --git a/sd/source/ui/slideshow/slideshowviewimpl.hxx b/sd/source/ui/slideshow/slideshowviewimpl.hxx
index 2073faaa045d..8eebe162b942 100644
--- a/sd/source/ui/slideshow/slideshowviewimpl.hxx
+++ b/sd/source/ui/slideshow/slideshowviewimpl.hxx
@@ -236,6 +236,7 @@ public:
virtual void SAL_CALL addMouseMotionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseMotionListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL removeMouseMotionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseMotionListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setMouseCursor( sal_Int16 nPointerShape ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Rectangle SAL_CALL getCanvasArea( ) throw (::com::sun::star::uno::RuntimeException);
// XWindowListener methods
virtual void SAL_CALL windowResized( const ::com::sun::star::awt::WindowEvent& e ) throw (::com::sun::star::uno::RuntimeException);
diff --git a/sd/xml/transitions-ogl b/sd/xml/transitions-ogl.xml
index 8db94340611a..8db94340611a 100644
--- a/sd/xml/transitions-ogl
+++ b/sd/xml/transitions-ogl.xml
diff --git a/slideshow/source/engine/OGLTrans/OGLTrans_Shaders.cxx b/slideshow/source/engine/OGLTrans/OGLTrans_Shaders.cxx
new file mode 100644
index 000000000000..6970edeb35d9
--- /dev/null
+++ b/slideshow/source/engine/OGLTrans/OGLTrans_Shaders.cxx
@@ -0,0 +1,143 @@
+/*************************************************************************
+ *
+ * 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
+ *
+ * $RCSfile: $
+ * $Revision: $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#include <osl/diagnose.hxx>
+
+#include "OGLTrans_Shaders.hxx"
+
+namespace unx
+{
+#include <GL/glx.h>
+#include <GL/glxext.h>
+}
+
+bool OGLShaders::cbInitialized = false;
+
+#ifdef GL_VERSION_2_0
+
+PFNGLCREATESHADERPROC OGLShaders::glCreateShader = NULL;
+PFNGLSHADERSOURCEPROC OGLShaders::glShaderSource = NULL;
+PFNGLCOMPILESHADERPROC OGLShaders::glCompileShader = NULL;
+PFNGLGETSHADERIVPROC OGLShaders::glGetShaderiv = NULL;
+PFNGLGETSHADERINFOLOGPROC OGLShaders::glGetShaderInfoLog = NULL;
+PFNGLDELETESHADERPROC OGLShaders::glDeleteShader = NULL;
+PFNGLCREATEPROGRAMPROC OGLShaders::glCreateProgram = NULL;
+PFNGLATTACHSHADERPROC OGLShaders::glAttachShader = NULL;
+PFNGLLINKPROGRAMPROC OGLShaders::glLinkProgram = NULL;
+PFNGLGETPROGRAMIVPROC OGLShaders::glGetProgramiv = NULL;
+PFNGLGETPROGRAMINFOLOGPROC OGLShaders::glGetProgramInfoLog = NULL;
+PFNGLUSEPROGRAMPROC OGLShaders::glUseProgram = NULL;
+PFNGLDELETEPROGRAMPROC OGLShaders::glDeleteProgram = NULL;
+PFNGLGETUNIFORMLOCATIONPROC OGLShaders::glGetUniformLocation = NULL;
+PFNGLUNIFORM1IPROC OGLShaders::glUniform1i = NULL;
+PFNGLUNIFORM1FPROC OGLShaders::glUniform1f = NULL;
+#endif
+
+bool OGLShaders::Initialize()
+{
+#ifdef GL_VERSION_2_0
+ if( !cbInitialized ) {
+ glCreateShader = (PFNGLCREATESHADERPROC) unx::glXGetProcAddress( (unsigned char *) "glCreateShader" );
+ glShaderSource = (PFNGLSHADERSOURCEPROC) unx::glXGetProcAddress( (unsigned char *) "glShaderSource" );
+ glCompileShader = (PFNGLCOMPILESHADERPROC) unx::glXGetProcAddress( (unsigned char *) "glCompileShader" );
+ glGetShaderiv = (PFNGLGETSHADERIVPROC) unx::glXGetProcAddress( (unsigned char *) "glGetShaderiv" );
+ glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) unx::glXGetProcAddress( (unsigned char *) "glGetShaderInfoLog" );
+ glDeleteShader = (PFNGLDELETESHADERPROC) unx::glXGetProcAddress( (unsigned char *) "glDeleteShader" );
+ glCreateProgram = (PFNGLCREATEPROGRAMPROC) unx::glXGetProcAddress( (unsigned char *) "glCreateProgram" );
+ glAttachShader = (PFNGLATTACHSHADERPROC) unx::glXGetProcAddress( (unsigned char *) "glAttachShader" );
+ glLinkProgram = (PFNGLLINKPROGRAMPROC) unx::glXGetProcAddress( (unsigned char *) "glLinkProgram" );
+ glGetProgramiv = (PFNGLGETPROGRAMIVPROC) unx::glXGetProcAddress( (unsigned char *) "glGetProgramiv" );
+ glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) unx::glXGetProcAddress( (unsigned char *) "glGetProgramInfoLog" );
+ glUseProgram = (PFNGLUSEPROGRAMPROC) unx::glXGetProcAddress( (unsigned char *) "glUseProgram" );
+ glDeleteProgram = (PFNGLDELETEPROGRAMPROC) unx::glXGetProcAddress( (unsigned char *) "glDeleteProgram" );
+ glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) unx::glXGetProcAddress( (unsigned char *) "glGetUniformLocation" );
+ glUniform1i = (PFNGLUNIFORM1IPROC) unx::glXGetProcAddress( (unsigned char *) "glUniform1i" );
+ glUniform1f = (PFNGLUNIFORM1FPROC) unx::glXGetProcAddress( (unsigned char *) "glUniform1f" );
+ cbInitialized = true;
+ }
+
+ return glCreateShader != NULL;
+#else
+ return false;
+#endif
+}
+
+GLuint OGLShaders::LinkProgram( const char *vertexShader, const char *fragmentShader )
+{
+#ifdef GL_VERSION_2_0
+ if( !Initialize() )
+ return 0;
+
+ GLhandleARB vertexObject, fragmentObject, programObject;
+ GLint vertexCompiled, fragmentCompiled, programLinked;
+ char log[1024];
+
+ vertexObject = glCreateShader( GL_VERTEX_SHADER );
+ fragmentObject = glCreateShader( GL_FRAGMENT_SHADER );
+ OSL_TRACE("checkpoint 1: shaders created (%d) vertex: %d fragment: %d", glGetError() == GL_NO_ERROR, vertexObject, fragmentObject );
+
+
+ glShaderSource( vertexObject, 1, &vertexShader, NULL );
+ glShaderSource( fragmentObject, 1, &fragmentShader, NULL );
+
+ glCompileShader( vertexObject );
+ glGetShaderInfoLog( vertexObject, sizeof( log ), NULL, log );
+ OSL_TRACE("vertex compile log: %s", log);
+ glGetShaderiv( vertexObject, GL_COMPILE_STATUS, &vertexCompiled );
+ glCompileShader( fragmentObject );
+ glGetShaderInfoLog( fragmentObject, sizeof( log ), NULL, log );
+ OSL_TRACE("fragment compile log: %s", log);
+ glGetShaderiv( fragmentObject, GL_COMPILE_STATUS, &fragmentCompiled );
+
+ if( !vertexCompiled || !fragmentCompiled )
+ return 0;
+
+ OSL_TRACE("checkpoint 2: shaders compiled (%d)", glGetError() == GL_NO_ERROR);
+
+ programObject = glCreateProgram();
+ glAttachShader( programObject, vertexObject );
+ glAttachShader( programObject, fragmentObject );
+
+ glLinkProgram( programObject );
+ glGetProgramInfoLog( programObject, sizeof( log ), NULL, log );
+ OSL_TRACE("program link log: %s", log);
+ glGetProgramiv( programObject, GL_LINK_STATUS, &programLinked );
+
+ if( !programLinked )
+ return 0;
+
+ OSL_TRACE("checkpoint 3: program linked (%d)", glGetError() == GL_NO_ERROR);
+
+ return programObject;
+#else
+ return 0;
+#endif
+}
+
diff --git a/slideshow/source/engine/OGLTrans/OGLTrans_Shaders.hxx b/slideshow/source/engine/OGLTrans/OGLTrans_Shaders.hxx
new file mode 100644
index 000000000000..64762f1977c4
--- /dev/null
+++ b/slideshow/source/engine/OGLTrans/OGLTrans_Shaders.hxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * 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
+ *
+ * $RCSfile: $
+ * $Revision: $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_OGLTRANS_SHADERS_HXX_
+#define INCLUDED_OGLTRANS_SHADERS_HXX_
+
+#define GL_GLEXT_PROTOTYPES 1
+#include <GL/gl.h>
+#include <GL/glext.h>
+
+class OGLShaders {
+ static bool Initialize();
+ static bool cbInitialized;
+
+public:
+
+ static GLuint LinkProgram( const char *vertexShader, const char *fragmentShader );
+
+ /** GL shader functions
+ */
+#ifdef GL_VERSION_2_0
+
+ static PFNGLCREATESHADERPROC glCreateShader;
+ static PFNGLSHADERSOURCEPROC glShaderSource;
+ static PFNGLCOMPILESHADERPROC glCompileShader;
+ static PFNGLGETSHADERIVPROC glGetShaderiv;
+ static PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
+ static PFNGLDELETESHADERPROC glDeleteShader;
+
+ static PFNGLCREATEPROGRAMPROC glCreateProgram;
+ static PFNGLATTACHSHADERPROC glAttachShader;
+ static PFNGLLINKPROGRAMPROC glLinkProgram;
+ static PFNGLGETPROGRAMIVPROC glGetProgramiv;
+ static PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
+ static PFNGLUSEPROGRAMPROC glUseProgram;
+ static PFNGLDELETEPROGRAMPROC glDeleteProgram;
+
+ static PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
+ static PFNGLUNIFORM1IPROC glUniform1i;
+ static PFNGLUNIFORM1FPROC glUniform1f;
+#endif
+};
+
+#endif
diff --git a/slideshow/source/engine/OGLTrans/OGLTrans_TransitionImpl.cxx b/slideshow/source/engine/OGLTrans/OGLTrans_TransitionImpl.cxx
index 8717b33e0380..af39e2de454c 100644
--- a/slideshow/source/engine/OGLTrans/OGLTrans_TransitionImpl.cxx
+++ b/slideshow/source/engine/OGLTrans/OGLTrans_TransitionImpl.cxx
@@ -27,9 +27,11 @@
* for a copy of the LGPLv3 License.
*
************************************************************************/
-#include "OGLTrans_TransitionImpl.hxx"
+#include "OGLTrans_TransitionImpl.hxx"
+#include "OGLTrans_Shaders.hxx"
#include <GL/gl.h>
+#include <math.h>
void OGLTransitionImpl::clear()
@@ -42,6 +44,33 @@ void OGLTransitionImpl::clear()
for(unsigned int i(0); i < maSceneObjects.size(); ++i)
delete maSceneObjects[i];
maSceneObjects.clear();
+
+ mbReflectSlides = false;
+
+#ifdef GL_VERSION_2_0
+ if( mProgramObject ) {
+ OGLShaders::glDeleteProgram( mProgramObject );
+ mProgramObject = 0;
+ }
+
+ if( mVertexObject ) {
+ OGLShaders::glDeleteShader( mVertexObject );
+ mVertexObject = 0;
+ }
+
+ if( mFragmentObject ) {
+ OGLShaders::glDeleteShader( mFragmentObject );
+ mFragmentObject = 0;
+ }
+#endif
+
+ if( maHelperTexture ) {
+ glDeleteTextures( 1, &maHelperTexture );
+ maHelperTexture = 0;
+ }
+
+ if( mmClearTransition )
+ (this->*mmClearTransition)();
}
OGLTransitionImpl::~OGLTransitionImpl()
@@ -49,11 +78,14 @@ OGLTransitionImpl::~OGLTransitionImpl()
clear();
}
-void OGLTransitionImpl::prepare()
+void OGLTransitionImpl::prepare( ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex )
{
for(unsigned int i(0); i < maSceneObjects.size(); ++i) {
maSceneObjects[i]->prepare();
}
+
+ if( mmPrepareTransition )
+ (this->*mmPrepareTransition)( glLeavingSlideTex, glEnteringSlideTex );
}
void OGLTransitionImpl::finish()
@@ -63,6 +95,49 @@ void OGLTransitionImpl::finish()
}
}
+static void blendSlide( double depth )
+{
+ 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 );
+}
+
+static void slideShadow( double nTime, Primitive& primitive, double sw, double sh )
+{
+ 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);
+}
+
void OGLTransitionImpl::display( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex,
double SlideWidth, double SlideHeight, double DispWidth, double DispHeight )
{
@@ -71,31 +146,81 @@ void OGLTransitionImpl::display( double nTime, ::sal_Int32 glLeavingSlideTex, ::
SlideWidthScale = SlideWidth/DispWidth;
SlideHeightScale = SlideHeight/DispHeight;
+ if( mmPrepare ) {
+ clear();
+ (this->*mmPrepare)( nTime, SlideWidth, SlideHeight, DispWidth, DispHeight );
+ }
+
glPushMatrix();
- glEnable(GL_TEXTURE_2D);
- //TODO change to foreach
+ displaySlides( nTime, glLeavingSlideTex, glEnteringSlideTex, SlideWidthScale, SlideHeightScale );
+ displayScene( nTime, SlideWidth, SlideHeight, DispWidth, DispHeight );
+ glPopMatrix();
+}
+
+void OGLTransitionImpl::applyOverallOperations( double nTime, double SlideWidthScale, double SlideHeightScale )
+{
for(unsigned int i(0); i < OverallOperations.size(); ++i)
OverallOperations[i]->interpolate(nTime,SlideWidthScale,SlideHeightScale);
- glBindTexture(GL_TEXTURE_2D, glLeavingSlideTex);
- for(unsigned int i(0); i < maLeavingSlidePrimitives.size(); ++i)
- maLeavingSlidePrimitives[i].display(nTime,SlideWidthScale,SlideHeightScale);
- glBindTexture(GL_TEXTURE_2D, glEnteringSlideTex);
- for(unsigned int i(0); i < maEnteringSlidePrimitives.size(); ++i)
- maEnteringSlidePrimitives[i].display(nTime,SlideWidthScale,SlideHeightScale);
+}
- for(unsigned int i(0); i < maSceneObjects.size(); ++i)
- maSceneObjects[i]->display(nTime, SlideWidth, SlideHeight, DispWidth, DispHeight);
+void OGLTransitionImpl::displaySlide( double nTime, ::sal_Int32 glSlideTex, std::vector<Primitive>& primitives,
+ double SlideWidthScale, double SlideHeightScale )
+{
+ //TODO change to foreach
+ glBindTexture(GL_TEXTURE_2D, glSlideTex);
+ // 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( mbReflectSlides ) {
+ double surfaceLevel = -0.04;
- glPopMatrix();
+ /* reflected slides */
+ glPushMatrix();
+
+ glScaled( 1, -1, 1 );
+ glTranslated( 0, 2 - surfaceLevel, 0 );
+
+ glCullFace(GL_FRONT);
+ for(unsigned int i(0); i < primitives.size(); ++i)
+ primitives[i].display(nTime, SlideWidthScale, SlideHeightScale);
+ glCullFace(GL_BACK);
+
+ slideShadow( nTime, primitives[0], SlideWidthScale, SlideHeightScale );
+
+ glPopMatrix();
+ }
+
+ for(unsigned int i(0); i < primitives.size(); ++i)
+ primitives[i].display(nTime, SlideWidthScale, SlideHeightScale);
+}
+
+void OGLTransitionImpl::displaySlides( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex,
+ double SlideWidthScale, double SlideHeightScale )
+{
+ if( mmDisplaySlides )
+ (this->*mmDisplaySlides)( nTime, glLeavingSlideTex, glEnteringSlideTex, SlideWidthScale, SlideHeightScale );
+ else {
+ applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
+
+ glEnable(GL_TEXTURE_2D);
+ displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale );
+ displaySlide( nTime, glEnteringSlideTex, maEnteringSlidePrimitives, SlideWidthScale, SlideHeightScale );
+ }
+}
+
+void OGLTransitionImpl::displayScene( double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight )
+{
+ glEnable(GL_TEXTURE_2D);
+ for(unsigned int i(0); i < maSceneObjects.size(); ++i)
+ maSceneObjects[i]->display(nTime, SlideWidth, SlideHeight, DispWidth, DispHeight);
}
void Primitive::display(double nTime, double WidthScale, double HeightScale)
{
glPushMatrix();
- for(unsigned int i(0); i < Operations.size(); ++i)
- Operations[i]->interpolate( nTime ,WidthScale,HeightScale);
- glScaled(WidthScale,HeightScale,1);
+
+ applyOperations( nTime, WidthScale, HeightScale );
glEnableClientState( GL_VERTEX_ARRAY );
if(!Normals.empty())
@@ -110,6 +235,13 @@ void Primitive::display(double nTime, double WidthScale, double HeightScale)
glPopMatrix();
}
+void Primitive::applyOperations(double nTime, double WidthScale, double HeightScale)
+{
+ for(unsigned int i(0); i < Operations.size(); ++i)
+ Operations[i]->interpolate( nTime ,WidthScale,HeightScale);
+ glScaled(WidthScale,HeightScale,1);
+}
+
Primitive::~Primitive()
{
for(unsigned int i( 0 ); i < Operations.size(); ++i)
@@ -216,6 +348,8 @@ void OGLTransitionImpl::makeFallLeaving()
Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(1,0,0),basegfx::B3DVector(0,-1,0), 90,true,0.0,1.0));
maLeavingSlidePrimitives.push_back(Slide);
+
+ mbUseMipMapEntering = false;
}
void OGLTransitionImpl::makeTurnAround()
@@ -223,6 +357,8 @@ void OGLTransitionImpl::makeTurnAround()
clear();
Primitive Slide;
+ mbReflectSlides = true;
+
Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1));
Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1));
maLeavingSlidePrimitives.push_back(Slide);
@@ -248,6 +384,8 @@ void OGLTransitionImpl::makeTurnDown()
Slide.Operations.push_back(new SRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(-1, 1, 0), -90, true, 0.0, 1.0));
Slide.Operations.push_back(new SRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(-1, 1, 0), 90, false, -1.0, 0.0));
maEnteringSlidePrimitives.push_back(Slide);
+
+ mbUseMipMapLeaving = false;
}
void OGLTransitionImpl::makeIris()
@@ -259,8 +397,8 @@ void OGLTransitionImpl::makeIris()
Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1));
maEnteringSlidePrimitives.push_back (Slide);
- Slide.Operations.push_back (new STranslate (basegfx::B3DVector (0, 0, 0.0001), false, -1, 0));
- Slide.Operations.push_back (new STranslate (basegfx::B3DVector (0, 0, -0.0002), false, 0.5, 1));
+ Slide.Operations.push_back (new STranslate (basegfx::B3DVector (0, 0, 0.000001), false, -1, 0));
+ Slide.Operations.push_back (new STranslate (basegfx::B3DVector (0, 0, -0.000002), false, 0.5, 1));
maLeavingSlidePrimitives.push_back (Slide);
@@ -313,6 +451,24 @@ void OGLTransitionImpl::makeIris()
}
maSceneObjects.push_back (pIris);
+
+ mbUseMipMapLeaving = mbUseMipMapEntering = false;
+}
+
+void OGLTransitionImpl::displaySlidesRochade( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex,
+ double SlideWidthScale, double SlideHeightScale )
+{
+ applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
+
+ glEnable(GL_TEXTURE_2D);
+
+ if( nTime > .5) {
+ displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale );
+ displaySlide( nTime, glEnteringSlideTex, maEnteringSlidePrimitives, SlideWidthScale, SlideHeightScale );
+ } else {
+ displaySlide( nTime, glEnteringSlideTex, maEnteringSlidePrimitives, SlideWidthScale, SlideHeightScale );
+ displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale );
+ }
}
void OGLTransitionImpl::makeRochade()
@@ -320,10 +476,13 @@ void OGLTransitionImpl::makeRochade()
clear();
Primitive Slide;
+ mbReflectSlides = true;
+ mmDisplaySlides = &OGLTransitionImpl::displaySlidesRochade;
+
double w, h;
w = 2.2;
- h = 5;
+ h = 10;
Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1));
Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1));
@@ -567,6 +726,13 @@ RotateAndScaleDepthByWidth::RotateAndScaleDepthByWidth(const basegfx::B3DVector&
bInterpolate = bInter;
}
+RotateAndScaleDepthByHeight::RotateAndScaleDepthByHeight(const basegfx::B3DVector& Axis,const basegfx::B3DVector& Origin,double Angle, bool bInter, double T0, double T1):axis(Axis),origin(Origin),angle(Angle)
+{
+ nT0 = T0;
+ nT1 = T1;
+ bInterpolate = bInter;
+}
+
STranslate::STranslate(const basegfx::B3DVector& Vector, bool bInter, double T0, double T1):vector(Vector)
{
@@ -598,7 +764,9 @@ void SRotate::interpolate(double t,double SlideWidthScale,double SlideHeightScal
t = nT1;
t = intervalInter(t,nT0,nT1);
glTranslated(SlideWidthScale*origin.getX(),SlideHeightScale*origin.getY(),origin.getZ());
+ glScaled(SlideWidthScale,SlideHeightScale,1);
glRotated(t*angle,axis.getX(),axis.getY(),axis.getZ());
+ glScaled(1/SlideWidthScale,1/SlideHeightScale,1);
glTranslated(-SlideWidthScale*origin.getX(),-SlideHeightScale*origin.getY(),-origin.getZ());
}
@@ -626,6 +794,18 @@ void RotateAndScaleDepthByWidth::interpolate(double t,double SlideWidthScale,dou
glTranslated(-SlideWidthScale*origin.getX(),-SlideHeightScale*origin.getY(),-SlideWidthScale*origin.getZ());
}
+void RotateAndScaleDepthByHeight::interpolate(double t,double SlideWidthScale,double SlideHeightScale)
+{
+ if(t <= nT0)
+ return;
+ if(!bInterpolate || t > nT1)
+ t = nT1;
+ t = intervalInter(t,nT0,nT1);
+ glTranslated(SlideWidthScale*origin.getX(),SlideHeightScale*origin.getY(),SlideHeightScale*origin.getZ());
+ glRotated(t*angle,axis.getX(),axis.getY(),axis.getZ());
+ glTranslated(-SlideWidthScale*origin.getX(),-SlideHeightScale*origin.getY(),-SlideHeightScale*origin.getZ());
+}
+
SEllipseTranslate::SEllipseTranslate(double dWidth, double dHeight, double dStartPosition, double dEndPosition, bool bInter, double T0, double T1)
{
nT0 = T0;
@@ -678,6 +858,11 @@ RotateAndScaleDepthByWidth* RotateAndScaleDepthByWidth::clone()
return new RotateAndScaleDepthByWidth(*this);
}
+RotateAndScaleDepthByHeight* RotateAndScaleDepthByHeight::clone()
+{
+ return new RotateAndScaleDepthByHeight(*this);
+}
+
const Primitive& Primitive::operator=(const Primitive& rvalue)
{
for(unsigned int i( 0 ); i < rvalue.Operations.size(); ++i)
@@ -745,3 +930,389 @@ void Primitive::pushTriangle(const basegfx::B2DVector& SlideLocation0,const base
Normals.push_back(basegfx::B3DVector(0,0,1));//all normals always face the screen when untransformed.
Normals.push_back(basegfx::B3DVector(0,0,1));//all normals always face the screen when untransformed.
}
+
+void OGLTransitionImpl::makeDiamond()
+{
+ mmPrepare = &OGLTransitionImpl::prepareDiamond;
+ mbUseMipMapLeaving = mbUseMipMapEntering = false;
+}
+
+void OGLTransitionImpl::prepareDiamond( double nTime, double /* SlideWidth */, double /* SlideHeight */, double /* DispWidth */, double /* DispHeight */ )
+{
+ Primitive Slide1, Slide2;
+
+ Slide1.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1));
+ Slide1.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1));
+ maEnteringSlidePrimitives.push_back (Slide1);
+
+
+ if( nTime >= 0.5 ) {
+ double m = 1 - nTime;
+
+ Slide2.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (m,0), basegfx::B2DVector (0,m));
+ Slide2.pushTriangle (basegfx::B2DVector (nTime,0), basegfx::B2DVector (1,0), basegfx::B2DVector (1,m));
+ Slide2.pushTriangle (basegfx::B2DVector (1,nTime), basegfx::B2DVector (1,1), basegfx::B2DVector (nTime,1));
+ Slide2.pushTriangle (basegfx::B2DVector (0,nTime), basegfx::B2DVector (m,1), basegfx::B2DVector (0,1));
+ } else {
+ double l = 0.5 - nTime;
+ double h = 0.5 + nTime;
+
+ Slide2.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0.5,l));
+ Slide2.pushTriangle (basegfx::B2DVector (0.5,l), basegfx::B2DVector (1,0), basegfx::B2DVector (h,0.5));
+ Slide2.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (1,1), basegfx::B2DVector (h,0.5));
+ Slide2.pushTriangle (basegfx::B2DVector (h,0.5), basegfx::B2DVector (1,1), basegfx::B2DVector (0.5,h));
+ Slide2.pushTriangle (basegfx::B2DVector (0.5,h), basegfx::B2DVector (1,1), basegfx::B2DVector (0,1));
+ Slide2.pushTriangle (basegfx::B2DVector (l,0.5), basegfx::B2DVector (0.5,h), basegfx::B2DVector (0,1));
+ Slide2.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (l,0.5), basegfx::B2DVector (0,1));
+ Slide2.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (0.5,l), basegfx::B2DVector (l,0.5));
+ }
+ Slide2.Operations.push_back (new STranslate (basegfx::B3DVector (0, 0, 0.00000001), false, -1, 0));
+ maLeavingSlidePrimitives.push_back (Slide2);
+}
+
+void OGLTransitionImpl::makeVenetianBlinds( bool vertical, int parts )
+{
+ static double t30 = tan( M_PI/6.0 );
+ double n, ln = 0;
+ double p = 1.0/parts;
+
+ for( int i=0; i<parts; i++ ) {
+ Primitive Slide;
+ n = (i + 1)/(double)parts;
+ if( vertical ) {
+ Slide.pushTriangle (basegfx::B2DVector (ln,0), basegfx::B2DVector (n,0), basegfx::B2DVector (ln,1));
+ Slide.pushTriangle (basegfx::B2DVector (n,0), basegfx::B2DVector (ln,1), basegfx::B2DVector (n,1));
+ Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0, 1, 0), basegfx::B3DVector(n + ln - 1, 0, -t30*p), -120, true, 0.0, 1.0));
+ } else {
+ Slide.pushTriangle (basegfx::B2DVector (0,ln), basegfx::B2DVector (1,ln), basegfx::B2DVector (0,n));
+ Slide.pushTriangle (basegfx::B2DVector (1,ln), basegfx::B2DVector (0,n), basegfx::B2DVector (1,n));
+ Slide.Operations.push_back(new RotateAndScaleDepthByHeight(basegfx::B3DVector(1, 0, 0), basegfx::B3DVector(0, 1 - n - ln, -t30*p), -120, true, 0.0, 1.0));
+ }
+ maLeavingSlidePrimitives.push_back (Slide);
+
+ if( vertical ) {
+ Slide.Operations.push_back(new SRotate(basegfx::B3DVector(0, 1, 0), basegfx::B3DVector(2*n - 1, 0, 0), -60, false, -1, 0));
+ Slide.Operations.push_back(new SRotate(basegfx::B3DVector(0, 1, 0), basegfx::B3DVector(n + ln - 1, 0, 0), 180, false, -1, 0));
+ } else {
+ Slide.Operations.push_back(new SRotate(basegfx::B3DVector(1, 0, 0), basegfx::B3DVector(0, 1 - 2*n, 0), -60, false, -1, 0));
+ Slide.Operations.push_back(new SRotate(basegfx::B3DVector(1, 0, 0), basegfx::B3DVector(0, 1 - n - ln, 0), 180, false, -1, 0));
+ }
+ maEnteringSlidePrimitives.push_back (Slide);
+ ln = n;
+ }
+}
+
+void OGLTransitionImpl::displaySlidesFadeSmoothly( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale )
+{
+ applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
+
+ glDisable(GL_DEPTH_TEST);
+
+ displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale );
+
+ glDisable(GL_LIGHTING);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glColor4f( 1, 1, 1, nTime );
+ displaySlide( nTime, glEnteringSlideTex, maEnteringSlidePrimitives, SlideWidthScale, SlideHeightScale );
+ glDisable(GL_BLEND);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glEnable(GL_LIGHTING);
+
+ glEnable(GL_DEPTH_TEST);
+}
+
+void OGLTransitionImpl::makeFadeSmoothly()
+{
+ Primitive Slide;
+
+ Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1));
+ Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1));
+ maLeavingSlidePrimitives.push_back (Slide);
+ maEnteringSlidePrimitives.push_back (Slide);
+
+ mmDisplaySlides = &OGLTransitionImpl::displaySlidesFadeSmoothly;
+ mbUseMipMapLeaving = mbUseMipMapEntering = false;
+}
+
+void OGLTransitionImpl::displaySlidesFadeThroughBlack( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale )
+{
+ applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
+
+ glDisable(GL_DEPTH_TEST);
+
+ glDisable(GL_LIGHTING);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ if( nTime < 0.5 ) {
+ glColor4f( 1, 1, 1, 1 - nTime*2 );
+ displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale );
+ } else {
+ glColor4f( 1, 1, 1, (nTime - 0.5)*2 );
+ displaySlide( nTime, glEnteringSlideTex, maEnteringSlidePrimitives, SlideWidthScale, SlideHeightScale );
+ }
+ glDisable(GL_BLEND);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glEnable(GL_LIGHTING);
+
+ glEnable(GL_DEPTH_TEST);
+}
+
+void OGLTransitionImpl::makeFadeThroughBlack()
+{
+ Primitive Slide;
+
+ Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1));
+ Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1));
+ maLeavingSlidePrimitives.push_back (Slide);
+ maEnteringSlidePrimitives.push_back (Slide);
+
+ mmDisplaySlides = &OGLTransitionImpl::displaySlidesFadeThroughBlack;
+ mbUseMipMapLeaving = mbUseMipMapEntering = false;
+}
+
+static const char* basicVertexShader = "\n\
+varying vec2 v_texturePosition;\n\
+\n\
+void main( void )\n\
+{\n\
+ gl_Position = ftransform();\n\
+ v_texturePosition = gl_MultiTexCoord0.xy;\n\
+}\n\
+";
+
+static const char* staticFragmentShader = "\n\
+uniform sampler2D leavingSlideTexture;\n\
+uniform sampler2D enteringSlideTexture;\n\
+uniform sampler2D permTexture;\n\
+uniform float time;\n\
+varying vec2 v_texturePosition;\n\
+\n\
+float snoise(vec2 P) {\n\
+\n\
+ return texture2D(permTexture, P).r;\n\
+}\n\
+\n\
+\n\
+#define PART 0.5\n\
+#define START 0.4\n\
+#define END 0.9\n\
+\n\
+void main() {\n\
+ float sn = snoise(10.0*v_texturePosition+time*0.07);\n\
+ if( time < PART ) {\n\
+ float sn1 = snoise(vec2(time*15.0, 20.0*v_texturePosition.y));\n\
+ float sn2 = snoise(v_texturePosition);\n\
+ if (sn1 > 1.0 - time*time && sn2 < 2.0*time+0.1)\n\
+ gl_FragColor = vec4(sn, sn, sn, 1.0);\n\
+ else if (time > START )\n\
+ gl_FragColor = ((time-START)/(PART - START))*vec4(sn, sn, sn, 1.0) + (1.0 - (time - START)/(PART - START))*texture2D(leavingSlideTexture, v_texturePosition);\n\
+ else\n\
+ gl_FragColor = texture2D(leavingSlideTexture, v_texturePosition);\n\
+ } else if ( time < PART ) {\n\
+ gl_FragColor = texture2D(leavingSlideTexture, v_texturePosition);\n\
+ } else if ( time > END ) {\n\
+ gl_FragColor = ((1.0 - time)/(1.0 - END))*vec4(sn, sn, sn, 1.0) + ((time - END)/(1.0 - END))*texture2D(enteringSlideTexture, v_texturePosition);\n\
+ } else \n\
+ gl_FragColor = vec4(sn, sn, sn, 1.0);\n\
+}\n\
+";
+
+static const char* dissolveFragmentShader = "\n\
+uniform sampler2D leavingSlideTexture;\n\
+uniform sampler2D enteringSlideTexture;\n\
+uniform sampler2D permTexture;\n\
+uniform float time;\n\
+varying vec2 v_texturePosition;\n\
+\n\
+float snoise(vec2 P) {\n\
+\n\
+ return texture2D(permTexture, P).r;\n\
+}\n\
+\n\
+void main() {\n\
+ float sn = snoise(10.0*v_texturePosition);\n\
+ if( sn < time)\n\
+ gl_FragColor = texture2D(enteringSlideTexture, v_texturePosition);\n\
+ else\n\
+ gl_FragColor = texture2D(leavingSlideTexture, v_texturePosition);\n\
+}\n\
+";
+
+int permutation256 [256]= {
+215, 100, 200, 204, 233, 50, 85, 196,
+ 71, 141, 122, 160, 93, 131, 243, 234,
+162, 183, 36, 155, 4, 62, 35, 205,
+ 40, 102, 33, 27, 255, 55, 214, 156,
+ 75, 163, 134, 126, 249, 74, 197, 228,
+ 72, 90, 206, 235, 17, 22, 49, 169,
+227, 89, 16, 5, 117, 60, 248, 230,
+217, 68, 138, 96, 194, 170, 136, 10,
+112, 238, 184, 189, 176, 42, 225, 212,
+ 84, 58, 175, 244, 150, 168, 219, 236,
+101, 208, 123, 37, 164, 110, 158, 201,
+ 78, 114, 57, 48, 70, 142, 106, 43,
+232, 26, 32, 252, 239, 98, 191, 94,
+ 59, 149, 39, 187, 203, 190, 19, 13,
+133, 45, 61, 247, 23, 34, 20, 52,
+118, 209, 146, 193, 222, 18, 1, 152,
+ 46, 41, 91, 148, 115, 25, 135, 77,
+254, 147, 224, 161, 9, 213, 223, 250,
+231, 251, 127, 166, 63, 179, 81, 130,
+139, 28, 120, 151, 241, 86, 111, 0,
+ 88, 153, 172, 182, 159, 105, 178, 47,
+ 51, 167, 65, 66, 92, 73, 198, 211,
+245, 195, 31, 220, 140, 76, 221, 186,
+154, 185, 56, 83, 38, 165, 109, 67,
+124, 226, 132, 53, 229, 29, 12, 181,
+121, 24, 207, 199, 177, 113, 30, 80,
+ 3, 97, 188, 79, 216, 173, 8, 145,
+ 87, 128, 180, 237, 240, 137, 125, 104,
+ 15, 242, 119, 246, 103, 143, 95, 144,
+ 2, 44, 69, 157, 192, 174, 14, 54,
+218, 82, 64, 210, 11, 6, 129, 21,
+116, 171, 99, 202, 7, 107, 253, 108
+};
+
+void initPermTexture(GLuint *texID)
+{
+ glGenTextures(1, texID);
+ glBindTexture(GL_TEXTURE_2D, *texID);
+
+ static bool initialized = false;
+ static unsigned char permutation2D[256*256*4];
+ if( !initialized ) {
+ int x, y;
+
+ for( y=0; y < 256; y++ )
+ for( x=0; x < 256; x++ )
+ permutation2D[x*4 + y*1024] = permutation256[(y + permutation256[x]) & 0xff];
+
+ initialized = true;
+ }
+
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, permutation2D );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+}
+
+void OGLTransitionImpl::preparePermShader()
+{
+#ifdef GL_VERSION_2_0
+ if( mProgramObject ) {
+ OGLShaders::glUseProgram( mProgramObject );
+
+ GLint location = OGLShaders::glGetUniformLocation( mProgramObject, "leavingSlideTexture" );
+ if( location != -1 ) {
+ OGLShaders::glUniform1i( location, 0 ); // texture unit 0
+ }
+
+ glActiveTexture(GL_TEXTURE1);
+ if( !maHelperTexture )
+ initPermTexture( &maHelperTexture );
+ glActiveTexture(GL_TEXTURE0);
+
+ location = OGLShaders::glGetUniformLocation( mProgramObject, "permTexture" );
+ if( location != -1 ) {
+ OGLShaders::glUniform1i( location, 1 ); // texture unit 1
+ }
+
+ location = OGLShaders::glGetUniformLocation( mProgramObject, "enteringSlideTexture" );
+ if( location != -1 ) {
+ OGLShaders::glUniform1i( location, 2 ); // texture unit 2
+ }
+ }
+#endif
+}
+
+void OGLTransitionImpl::prepareStatic( ::sal_Int32 /* glLeavingSlideTex */, ::sal_Int32 /* glEnteringSlideTex */ )
+{
+ mProgramObject = OGLShaders::LinkProgram( basicVertexShader, staticFragmentShader );
+
+ preparePermShader();
+}
+
+void OGLTransitionImpl::displaySlidesShaders( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex,
+ double SlideWidthScale, double SlideHeightScale )
+{
+ applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
+
+#ifdef GL_VERSION_2_0
+ if( mProgramObject ) {
+ GLint location = OGLShaders::glGetUniformLocation( mProgramObject, "time" );
+ if( location != -1 ) {
+ OGLShaders::glUniform1f( location, nTime );
+ }
+ }
+
+ glActiveTexture( GL_TEXTURE2 );
+ glBindTexture( GL_TEXTURE_2D, glEnteringSlideTex );
+ glActiveTexture( GL_TEXTURE0 );
+#endif
+
+ displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale );
+}
+
+void OGLTransitionImpl::makeStatic()
+{
+ Primitive Slide;
+
+ Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1));
+ Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1));
+ maLeavingSlidePrimitives.push_back (Slide);
+ maEnteringSlidePrimitives.push_back (Slide);
+
+ mmDisplaySlides = &OGLTransitionImpl::displaySlidesShaders;
+ mmPrepareTransition = &OGLTransitionImpl::prepareStatic;
+ mbUseMipMapLeaving = mbUseMipMapEntering = false;
+
+ mnRequiredGLVersion = 2.0;
+}
+
+void OGLTransitionImpl::prepareDissolve( ::sal_Int32 /* glLeavingSlideTex */, ::sal_Int32 /* glEnteringSlideTex */ )
+{
+ mProgramObject = OGLShaders::LinkProgram( basicVertexShader, dissolveFragmentShader );
+
+ preparePermShader();
+}
+
+void OGLTransitionImpl::makeDissolve()
+{
+ Primitive Slide;
+
+ Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1));
+ Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1));
+ maLeavingSlidePrimitives.push_back (Slide);
+ maEnteringSlidePrimitives.push_back (Slide);
+
+ mmDisplaySlides = &OGLTransitionImpl::displaySlidesShaders;
+ mmPrepareTransition = &OGLTransitionImpl::prepareDissolve;
+ mbUseMipMapLeaving = mbUseMipMapEntering = false;
+
+ mnRequiredGLVersion = 2.0;
+}
+
+void OGLTransitionImpl::makeNewsflash()
+{
+ Primitive Slide;
+
+ Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1));
+ Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1));
+ Slide.Operations.push_back(new SRotate(basegfx::B3DVector(0,0,1),basegfx::B3DVector(0,0,0),3000,true,0,0.5));
+ Slide.Operations.push_back(new SScale(basegfx::B3DVector(0.01,0.01,0.01),basegfx::B3DVector(0,0,0),true,0,0.5));
+ Slide.Operations.push_back(new STranslate(basegfx::B3DVector(-10000, 0, 0),false, 0.5, 2));
+ maLeavingSlidePrimitives.push_back(Slide);
+
+ Slide.Operations.clear();
+ Slide.Operations.push_back(new SRotate(basegfx::B3DVector(0,0,1),basegfx::B3DVector(0,0,0),-3000,true,0.5,1));
+ Slide.Operations.push_back(new STranslate(basegfx::B3DVector(-100, 0, 0),false, -1, 1));
+ Slide.Operations.push_back(new STranslate(basegfx::B3DVector(100, 0, 0),false, 0.5, 1));
+ Slide.Operations.push_back(new SScale(basegfx::B3DVector(0.01,0.01,0.01),basegfx::B3DVector(0,0,0),false,-1,1));
+ Slide.Operations.push_back(new SScale(basegfx::B3DVector(100,100,100),basegfx::B3DVector(0,0,0),true,0.5,1));
+ maEnteringSlidePrimitives.push_back(Slide);
+
+ OverallOperations.push_back(new SRotate(basegfx::B3DVector(0,0,1),basegfx::B3DVector(0.2,0.2,0),1080,true,0,1));
+}
+
diff --git a/slideshow/source/engine/OGLTrans/OGLTrans_TransitionImpl.hxx b/slideshow/source/engine/OGLTrans/OGLTrans_TransitionImpl.hxx
index da4efdfe8a30..28991b0d09a0 100644
--- a/slideshow/source/engine/OGLTrans/OGLTrans_TransitionImpl.hxx
+++ b/slideshow/source/engine/OGLTrans/OGLTrans_TransitionImpl.hxx
@@ -62,15 +62,27 @@ class OGLTransitionImpl
{
public:
OGLTransitionImpl() :
+ mbUseMipMapLeaving( true ),
+ mbUseMipMapEntering( true ),
+ mnRequiredGLVersion( 1.0 ),
maLeavingSlidePrimitives(),
maEnteringSlidePrimitives(),
- maSceneObjects()
+ maSceneObjects(),
+ mbReflectSlides( false ),
+ mVertexObject( 0 ),
+ mFragmentObject( 0 ),
+ mProgramObject( 0 ),
+ maHelperTexture( 0 ),
+ mmPrepare( NULL ),
+ mmPrepareTransition( NULL ),
+ mmClearTransition( NULL ),
+ mmDisplaySlides( NULL )
{}
~OGLTransitionImpl();
- void prepare();
- void display( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight);
+ void prepare( ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex );
+ void display( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight );
void finish();
void makeOutsideCubeFaceToLeft();
@@ -83,6 +95,25 @@ public:
void makeTurnDown();
void makeIris();
void makeRochade();
+ void makeVenetianBlinds( bool vertical, int parts );
+ void makeStatic();
+ void makeDissolve();
+ void makeNewsflash();
+
+ /** 2D replacements
+ */
+ void makeDiamond();
+ void makeFadeSmoothly();
+ void makeFadeThroughBlack();
+
+ /** Whether to use mipmaping for slides textures
+ */
+ bool mbUseMipMapLeaving;
+ bool mbUseMipMapEntering;
+
+ /** which GL version does the transition require
+ */
+ float mnRequiredGLVersion;
private:
/** clears all the primitives and operations
@@ -104,6 +135,54 @@ private:
/** All the operations that should be applied to both leaving and entering slide primitives. These operations will be called in the order they were pushed back in. In OpenGL this effectively uses the operations in the opposite order they were pushed back.
*/
vector<Operation*> OverallOperations;
+
+ /** 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;
+
+ /** GLSL objects, shaders and program
+ */
+ GLuint mVertexObject, mFragmentObject, mProgramObject;
+
+ /** various data */
+ GLuint maHelperTexture;
+
+ /** When this method is not NULL, it is called in display method to prepare the slides, scene, etc.
+ ** We might later replace this by cleaner derived class.
+ */
+ void (OGLTransitionImpl::*mmPrepare)( double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight );
+
+ /** When this method is not NULL, it is called after glx context is ready to let the transition prepare GL related things, like GLSL program.
+ ** We might later replace this by cleaner derived class.
+ */
+ void (OGLTransitionImpl::*mmPrepareTransition)( ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex );
+
+ /** When this method is not NULL, it is called when the transition needs to clear after itself, like delete own textures etc.
+ ** We might later replace this by cleaner derived class.
+ */
+ void (OGLTransitionImpl::*mmClearTransition)();
+
+ /** When this method is not NULL, it is called in display method to display the slides.
+ ** We might later replace this by cleaner derived class.
+ */
+ void (OGLTransitionImpl::*mmDisplaySlides)( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale );
+
+ void displaySlides( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale );
+ void displaySlide( double nTime, ::sal_Int32 glSlideTex, std::vector<Primitive>& primitives, double SlideWidthScale, double SlideHeightScale );
+ void displayScene( double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight);
+ void applyOverallOperations( double nTime, double SlideWidthScale, double SlideHeightScale );
+
+ /** various transitions helper methods
+ */
+ void prepareDiamond( double nTime, double SlideWidth, double SlideHeight,double DispWidth, double DispHeight );
+ void displaySlidesFadeSmoothly( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale );
+ void displaySlidesFadeThroughBlack( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale );
+ void displaySlidesRochade( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale );
+ void displaySlidesShaders( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale );
+ void prepareStatic( ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex );
+ void prepareDissolve( ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex );
+ void preparePermShader();
};
class SceneObject
@@ -147,6 +226,7 @@ public:
Primitive(const Primitive& rvalue);
~Primitive();
+ void applyOperations(double nTime, double SlideWidthScale, double SlideHeightScale);
void display(double nTime, double SlideWidthScale, double SlideHeightScale);
const Primitive& operator=(const Primitive& rvalue);
@@ -409,5 +489,21 @@ private:
double angle;
};
+/** Same as SRotate, except the depth is scaled by the width of the slide divided by the height of the window.
+*/
+class RotateAndScaleDepthByHeight: public Operation
+{
+public:
+ void interpolate(double t,double SlideWidthScale,double SlideHeightScale);
+ RotateAndScaleDepthByHeight* clone();
+
+ RotateAndScaleDepthByHeight(const basegfx::B3DVector& Axis,const basegfx::B3DVector& Origin,double Angle,bool bInter, double T0, double T1);
+ ~RotateAndScaleDepthByHeight(){}
+private:
+ basegfx::B3DVector axis;
+ basegfx::B3DVector origin;
+ double angle;
+};
+
#endif // INCLUDED_SLIDESHOW_TRANSITION_HXX_
diff --git a/slideshow/source/engine/OGLTrans/OGLTrans_TransitionerImpl.cxx b/slideshow/source/engine/OGLTrans/OGLTrans_TransitionerImpl.cxx
index 62da933baa96..6c07065e2904 100644
--- a/slideshow/source/engine/OGLTrans/OGLTrans_TransitionerImpl.cxx
+++ b/slideshow/source/engine/OGLTrans/OGLTrans_TransitionerImpl.cxx
@@ -28,8 +28,10 @@
*
************************************************************************/
+#define GLX_GLXEXT_PROTOTYPES 1
#include "OGLTrans_TransitionImpl.hxx"
+#include <com/sun/star/beans/XFastPropertySet.hpp>
#include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
#include <com/sun/star/rendering/ColorComponentTag.hpp>
#include <com/sun/star/rendering/ColorSpaceType.hpp>
@@ -70,17 +72,88 @@
namespace unx
{
#include <X11/keysym.h>
+#include <X11/X.h>
#include <GL/glx.h>
+#include <GL/glxext.h>
}
#endif
+#ifdef DEBUG
+#include <boost/date_time/posix_time/posix_time.hpp>
+using namespace ::boost::posix_time;
+
+static ptime t1;
+static ptime t2;
+
+#define DBG(x) x
+#else
+#define DBG(x)
+#endif
+
using namespace ::com::sun::star;
+using ::com::sun::star::beans::XFastPropertySet;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
namespace
{
typedef cppu::WeakComponentImplHelper1<presentation::XTransition> OGLTransitionerImplBase;
+namespace
+{
+ struct OGLFormat
+ {
+ GLint nInternalFormat;
+ GLenum eFormat;
+ GLenum eType;
+ };
+
+ /* channel ordering: (0:rgba, 1:bgra, 2:argb, 3:abgr)
+ */
+ int calcComponentOrderIndex(const uno::Sequence<sal_Int8>& rTags)
+ {
+ using namespace rendering::ColorComponentTag;
+
+ static const sal_Int8 aOrderTable[] =
+ {
+ RGB_RED, RGB_GREEN, RGB_BLUE, ALPHA,
+ RGB_BLUE, RGB_GREEN, RGB_RED, ALPHA,
+ ALPHA, RGB_RED, RGB_GREEN, RGB_BLUE,
+ ALPHA, RGB_BLUE, RGB_GREEN, RGB_RED,
+ };
+
+ const sal_Int32 nNumComps(rTags.getLength());
+ const sal_Int8* pLine=aOrderTable;
+ for(int i=0; i<4; ++i)
+ {
+ int j=0;
+ while( j<4 && j<nNumComps && pLine[j] == rTags[j] )
+ ++j;
+
+ // all of the line passed, this is a match!
+ if( j==nNumComps )
+ return i;
+
+ pLine+=4;
+ }
+
+ return -1;
+ }
+}
+
+// not thread safe
+static bool errorTriggered;
+int oglErrorHandler( unx::Display* /*dpy*/, unx::XErrorEvent* /*evnt*/ )
+{
+ errorTriggered = true;
+
+ return 0;
+}
+
/** This is the Transitioner class for OpenGL 3D transitions in
* slideshow. At the moment, it's Linux only. This class is implicitly
* constructed from XTransitionFactory.
@@ -89,13 +162,22 @@ class OGLTransitionerImpl : private cppu::BaseMutex, private boost::noncopyable,
{
public:
explicit OGLTransitionerImpl(OGLTransitionImpl* pOGLTransition);
- void initWindowFromSlideShowView( const uno::Reference< presentation::XSlideShowView >& xView, double, double);
- void setSlides( const uno::Reference< rendering::XBitmap >& xLeavingSlide , const uno::Reference< rendering::XBitmap >& xEnteringSlide );
+ bool initWindowFromSlideShowView( const uno::Reference< presentation::XSlideShowView >& xView );
+ void setSlides( const Reference< rendering::XBitmap >& xLeavingSlide , const uno::Reference< rendering::XBitmap >& xEnteringSlide );
+ static bool initialize( const Reference< presentation::XSlideShowView >& xView );
// XTransition
- virtual void SAL_CALL update( double nTime ) throw (uno::RuntimeException);
+ virtual void SAL_CALL update( double nTime )
+ throw (uno::RuntimeException);
+ virtual void SAL_CALL viewChanged( const Reference< presentation::XSlideShowView >& rView,
+ const Reference< rendering::XBitmap >& rLeavingBitmap,
+ const Reference< rendering::XBitmap >& rEnteringBitmap )
+ throw (uno::RuntimeException);
protected:
+ void disposeContextAndWindow();
+ void disposeTextures();
+
// WeakComponentImplHelperBase
virtual void SAL_CALL disposing();
@@ -104,6 +186,18 @@ protected:
return (rBHelper.bDisposed || rBHelper.bInDispose);
}
+ bool createWindow( Window* pPWindow );
+ void createTexture( unsigned int* texID,
+#if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
+ unx::GLXPixmap pixmap,
+ bool usePixmap,
+#endif
+ bool useMipmap,
+ uno::Sequence<sal_Int8>& data,
+ const OGLFormat* pFormat );
+ void prepareEnvironment ();
+ const OGLFormat* chooseFormats();
+
private:
/** After the window has been created, and the slides have been set, we'll initialize the slides with OpenGL.
*/
@@ -114,20 +208,29 @@ private:
struct GLWindow
{
#if defined( WNT )
- HWND hWnd;
- HDC hDC;
- HGLRC hRC;
+ HWND hWnd;
+ HDC hDC;
+ HGLRC hRC;
#elif defined( OS2 )
#elif defined( QUARTZ )
#elif defined( UNX )
- unx::Display* dpy;
- int screen;
- unx::Window win;
- unx::GLXContext ctx;
+ unx::Display* dpy;
+ int screen;
+ unx::Window win;
+#if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
+ unx::GLXFBConfig fbc;
+#endif
+ unx::XVisualInfo* vi;
+ unx::GLXContext ctx;
#endif
unsigned int bpp;
unsigned int Width;
unsigned int Height;
+ const char* GLXExtensions;
+ const GLubyte* GLExtensions;
+
+ bool HasGLXExtension( const char* name ) { return gluCheckExtension( (const GLubyte*) name, (const GLubyte*) GLXExtensions ); }
+ bool HasGLExtension( const char* name ) { return gluCheckExtension( (const GLubyte*) name, GLExtensions ); }
} GLWin;
/** OpenGL handle to the leaving slide's texture
@@ -141,6 +244,10 @@ private:
*/
class SystemChildWindow* pWindow;
+ Reference< presentation::XSlideShowView > mxView;
+ Reference< rendering::XIntegerBitmap > mxLeavingBitmap;
+ Reference< rendering::XIntegerBitmap > mxEnteringBitmap;
+
/** raw bytes of the entering bitmap
*/
uno::Sequence<sal_Int8> EnteringBytes;
@@ -149,6 +256,18 @@ private:
*/
uno::Sequence<sal_Int8> LeavingBytes;
+#if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
+ unx::GLXPixmap LeavingPixmap;
+ unx::GLXPixmap EnteringPixmap;
+#endif
+ bool mbRestoreSync;
+ bool mbUseLeavingPixmap;
+ bool mbUseEnteringPixmap;
+ bool mbFreeLeavingPixmap;
+ bool mbFreeEnteringPixmap;
+ unx::Pixmap maLeavingPixmap;
+ unx::Pixmap maEnteringPixmap;
+
/** the form the raw bytes are in for the bitmaps
*/
rendering::IntegerBitmapLayout SlideBitmapLayout;
@@ -160,38 +279,124 @@ private:
/** Our Transition to be used.
*/
OGLTransitionImpl* pTransition;
+
+public:
+ /** whether we are running on ATI fglrx with bug related to textures
+ */
+ static bool cbBrokenTexturesATI;
+
+ /** GL version
+ */
+ static float cnGLVersion;
+ float mnGLXVersion;
+
+ /** Whether Mesa is the OpenGL vendor
+ */
+ static bool cbMesa;
+
+ /**
+ whether the display has GLX extension
+ */
+ static bool cbGLXPresent;
+
+ /**
+ whether texture from pixmap extension is available
+ */
+ bool mbTextureFromPixmap;
+
+ /**
+ whether to generate mipmaped textures
+ */
+ bool mbGenerateMipmap;
+
+ /**
+ whether we have visual which can be used for texture_from_pixmap extension
+ */
+ bool mbHasTFPVisual;
+
+#ifdef DEBUG
+ ptime t3;
+ ptime t4;
+ ptime t5;
+ ptime t6;
+ time_duration total_update;
+ int frame_count;
+#endif
};
-void OGLTransitionerImpl::initWindowFromSlideShowView( const uno::Reference< presentation::XSlideShowView >& xView, double, double)
-{
- osl::MutexGuard const guard( m_aMutex );
+// declare the static variables as some gcc versions have problems declaring them automaticaly
+bool OGLTransitionerImpl::cbBrokenTexturesATI;
+float OGLTransitionerImpl::cnGLVersion;
+bool OGLTransitionerImpl::cbMesa;
+bool OGLTransitionerImpl::cbGLXPresent;
- if (isDisposed())
- return;
+bool OGLTransitionerImpl::initialize( const Reference< presentation::XSlideShowView >& xView )
+{
+ // not thread safe
+ static bool initialized = false;
+
+ if( !initialized ) {
+ OGLTransitionerImpl *instance;
+
+ instance = new OGLTransitionerImpl( NULL );
+ if( instance->initWindowFromSlideShowView( xView ) ) {
+
+ const GLubyte* version = glGetString( GL_VERSION );
+ if( version && version[0] ) {
+ cnGLVersion = version[0] - '0';
+ if( version[1] == '.' && version[2] )
+ cnGLVersion += (version[2] - '0')/10.0;
+ } else
+ cnGLVersion = 1.0;
+ OSL_TRACE("GL version: %s parsed: %f", version, cnGLVersion );
+
+ const GLubyte* vendor = glGetString( GL_VENDOR );
+ cbMesa = ( vendor && strstr( (const char *) vendor, "Mesa" ) );
+ OSL_TRACE("GL vendor: %s identified as Mesa: %d", vendor, cbMesa );
+
+ /* TODO: check for version once the bug in fglrx driver is fixed */
+ cbBrokenTexturesATI = (vendor && strcmp( (const char *) vendor, "ATI Technologies Inc." ) == 0 );
+
+ instance->disposing();
+ cbGLXPresent = true;
+ } else
+ cbGLXPresent = false;
+
+ delete instance;
+ initialized = true;
+ }
- /// take the XSlideShowView and extract the parent window from it. see viewmediashape.cxx
- uno::Reference< rendering::XCanvas > xCanvas(xView->getCanvas(), uno::UNO_QUERY_THROW);
- uno::Sequence< uno::Any > aDeviceParams;
- ::canvas::tools::getDeviceInfo( xCanvas, aDeviceParams );
- ::rtl::OUString aImplName;
- aDeviceParams[ 0 ] >>= aImplName;
- sal_Int64 aVal = 0;
- aDeviceParams[1] >>= aVal;
- Window* pPWindow = reinterpret_cast< Window* >( aVal );
- GLWin.Width = pPWindow->GetSizePixel().Width();
- GLWin.Height = pPWindow->GetSizePixel().Height();
+ return cbGLXPresent;
+}
+bool OGLTransitionerImpl::createWindow( Window* pPWindow )
+{
const SystemEnvData* sysData(pPWindow->GetSystemData());
#if defined( WNT )
GLWin.hWnd = sysData->hWnd;
#elif defined( UNX )
GLWin.dpy = reinterpret_cast<unx::Display*>(sysData->pDisplay);
+
+ if( unx::glXQueryExtension( GLWin.dpy, NULL, NULL ) == false )
+ return false;
+
GLWin.win = sysData->aWindow;
- GLWin.screen = unx::XDefaultScreen(GLWin.dpy);
+
+ OSL_TRACE("parent window: %d", GLWin.win);
+
+ unx::XWindowAttributes xattr;
+ unx::XGetWindowAttributes( GLWin.dpy, GLWin.win, &xattr );
+
+ GLWin.screen = XScreenNumberOfScreen( xattr.screen );
+
unx::XVisualInfo* vi( NULL );
+#if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
+ unx::XVisualInfo* visinfo;
+ unx::XVisualInfo* firstVisual( NULL );
+#endif
static int attrList3[] =
{
- GLX_RGBA,//only TrueColor or DirectColor
+ GLX_RGBA,//only TrueColor or DirectColor
//single buffered
GLX_RED_SIZE,4,//use the maximum red bits, with a minimum of 4 bits
GLX_GREEN_SIZE,4,//use the maximum green bits, with a minimum of 4 bits
@@ -200,8 +405,8 @@ void OGLTransitionerImpl::initWindowFromSlideShowView( const uno::Reference< pre
None
};
static int attrList2[] =
- {
- GLX_RGBA,/// only TrueColor or DirectColor
+ {
+ GLX_RGBA,//only TrueColor or DirectColor
/// single buffered
GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits
GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits
@@ -211,7 +416,7 @@ void OGLTransitionerImpl::initWindowFromSlideShowView( const uno::Reference< pre
};
static int attrList1[] =
{
- GLX_RGBA,/// only TrueColor or DirectColor
+ GLX_RGBA,//only TrueColor or DirectColor
GLX_DOUBLEBUFFER,/// only double buffer
GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits
GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits
@@ -221,7 +426,7 @@ void OGLTransitionerImpl::initWindowFromSlideShowView( const uno::Reference< pre
};
static int attrList0[] =
{
- GLX_RGBA,/// only TrueColor or DirectColor
+ GLX_RGBA,//only TrueColor or DirectColor
GLX_DOUBLEBUFFER,/// only double buffer
GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits
GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits
@@ -241,6 +446,12 @@ void OGLTransitionerImpl::initWindowFromSlideShowView( const uno::Reference< pre
const SystemEnvData* pChildSysData = NULL;
delete pWindow;
pWindow=NULL;
+
+#if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
+ unx::GLXFBConfig* fbconfigs = NULL;
+ int nfbconfigs, value, i = 0;
+#endif
+
while( *pAttributeTable )
{
// try to find a visual for the current set of attributes
@@ -248,59 +459,154 @@ void OGLTransitionerImpl::initWindowFromSlideShowView( const uno::Reference< pre
GLWin.screen,
*pAttributeTable );
- if( vi )
- {
- SystemWindowData winData;
- winData.nSize = sizeof(winData);
- winData.pVisual = (void*)(vi->visual);
- pWindow=new SystemChildWindow(pPWindow, 0, &winData, FALSE);
- pChildSysData = pWindow->GetSystemData();
- if( pChildSysData )
- {
- break;
- }
- else
- {
- delete pWindow, pWindow=NULL;
- }
- }
+#if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
+ if( vi ) {
+ if( !firstVisual )
+ firstVisual = vi;
+ OSL_TRACE("trying VisualID %08X", vi->visualid);
+ fbconfigs = glXGetFBConfigs (GLWin.dpy, GLWin.screen, &nfbconfigs);
+ for ( ; i < nfbconfigs; i++)
+ {
+ visinfo = glXGetVisualFromFBConfig (GLWin.dpy, fbconfigs[i]);
+ if( !visinfo || visinfo->visualid != vi->visualid )
+ continue;
+
+ glXGetFBConfigAttrib (GLWin.dpy, fbconfigs[i], GLX_DRAWABLE_TYPE, &value);
+ if (!(value & GLX_PIXMAP_BIT))
+ continue;
+
+ glXGetFBConfigAttrib (GLWin.dpy, fbconfigs[i],
+ GLX_BIND_TO_TEXTURE_TARGETS_EXT,
+ &value);
+ if (!(value & GLX_TEXTURE_2D_BIT_EXT))
+ continue;
+
+ glXGetFBConfigAttrib (GLWin.dpy, fbconfigs[i],
+ GLX_BIND_TO_TEXTURE_RGB_EXT,
+ &value);
+ if (value == FALSE)
+ continue;
+
+ glXGetFBConfigAttrib (GLWin.dpy, fbconfigs[i],
+ GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
+ &value);
+ if (value == FALSE)
+ continue;
+
+ /* TODO: handle non Y inverted cases */
+ break;
+ }
+
+ if( i != nfbconfigs || ( firstVisual && pAttributeTable[1] == NULL ) ) {
+ if( i != nfbconfigs ) {
+ vi = glXGetVisualFromFBConfig( GLWin.dpy, fbconfigs[i] );
+ mbHasTFPVisual = true;
+ OSL_TRACE("found visual suitable for texture_from_pixmap");
+ } else {
+ vi = firstVisual;
+ mbHasTFPVisual = false;
+ OSL_TRACE("did not find visual suitable for texture_from_pixmap, using %08X", vi->visualid);
+ }
+#else
+ if( vi ) {
+#endif
+ SystemWindowData winData;
+ winData.nSize = sizeof(winData);
+ OSL_TRACE("using VisualID %08X", vi->visualid);
+ winData.pVisual = (void*)(vi->visual);
+ pWindow=new SystemChildWindow(pPWindow, 0, &winData, FALSE);
+ pChildSysData = pWindow->GetSystemData();
+ if( pChildSysData ) {
+ break;
+ } else {
+ delete pWindow, pWindow=NULL;
+ }
+ }
+#if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
+ }
+#endif
+
++pAttributeTable;
- }
+ }
#endif
#if defined( WNT )
- const SystemEnvData* pChildSysData = NULL;
- SystemWindowData winData;
- winData.nSize = sizeof(winData);
- pWindow=new SystemChildWindow(pPWindow, 0, &winData, FALSE);
- pChildSysData = pWindow->GetSystemData();
+ const SystemEnvData* pChildSysData = NULL;
+ SystemWindowData winData;
+ winData.nSize = sizeof(winData);
+ pWindow=new SystemChildWindow(pPWindow, 0, &winData, FALSE);
+ pChildSysData = pWindow->GetSystemData();
#endif
- if( pWindow )
- {
- pWindow->SetMouseTransparent( TRUE );
- pWindow->SetParentClipMode( PARENTCLIPMODE_NOCLIP );
- pWindow->EnableEraseBackground( FALSE );
- pWindow->SetControlForeground();
- pWindow->SetControlBackground();
- pWindow->EnablePaint(FALSE);
- pWindow->SetPosSizePixel(pPWindow->GetPosPixel(),pPWindow->GetSizePixel());
-
+ if( pWindow )
+ {
+ pWindow->SetMouseTransparent( TRUE );
+ pWindow->SetParentClipMode( PARENTCLIPMODE_NOCLIP );
+ pWindow->EnableEraseBackground( FALSE );
+ pWindow->SetControlForeground();
+ pWindow->SetControlBackground();
+ pWindow->EnablePaint(FALSE);
#if defined( WNT )
GLWin.hWnd = sysData->hWnd;
#elif defined( UNX )
GLWin.dpy = reinterpret_cast<unx::Display*>(pChildSysData->pDisplay);
GLWin.win = pChildSysData->aWindow;
+#if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
+ if( mbHasTFPVisual )
+ GLWin.fbc = fbconfigs[i];
#endif
+ GLWin.vi = vi;
+ GLWin.GLXExtensions = unx::glXQueryExtensionsString( GLWin.dpy, GLWin.screen );
+ OSL_TRACE("available GLX extensions: %s", GLWin.GLXExtensions);
+#endif
+
+ return true;
}
+ return false;
+}
+
+bool OGLTransitionerImpl::initWindowFromSlideShowView( const Reference< presentation::XSlideShowView >& xView )
+{
+ osl::MutexGuard const guard( m_aMutex );
+
+ if (isDisposed())
+ return false;
+
+ mxView.set( xView, UNO_QUERY );
+ if( !mxView.is() )
+ return false;
+
+ /// take the XSlideShowView and extract the parent window from it. see viewmediashape.cxx
+ uno::Reference< rendering::XCanvas > xCanvas(mxView->getCanvas(), uno::UNO_QUERY_THROW);
+ uno::Sequence< uno::Any > aDeviceParams;
+ ::canvas::tools::getDeviceInfo( xCanvas, aDeviceParams );
+
+ ::rtl::OUString aImplName;
+ aDeviceParams[ 0 ] >>= aImplName;
+
+ sal_Int64 aVal = 0;
+ aDeviceParams[1] >>= aVal;
+ if( !createWindow( reinterpret_cast< Window* >( aVal ) ) )
+ return false;
+
+ awt::Rectangle aCanvasArea = mxView->getCanvasArea();
+ pWindow->SetPosSizePixel(aCanvasArea.X, aCanvasArea.Y, aCanvasArea.Width, aCanvasArea.Height);
+ GLWin.Width = aCanvasArea.Width;
+ GLWin.Height = aCanvasArea.Height;
+ OSL_TRACE("canvas area: %d,%d - %dx%d", aCanvasArea.X, aCanvasArea.Y, aCanvasArea.Width, aCanvasArea.Height);
+
#if defined( WNT )
GLWin.hDC = GetDC(GLWin.hWnd);
#elif defined( UNX )
GLWin.ctx = glXCreateContext(GLWin.dpy,
- vi,
+ GLWin.vi,
0,
GL_TRUE);
+ if( GLWin.ctx == NULL ) {
+ OSL_TRACE("unable to create GLX context");
+ return false;
+ }
#endif
#if defined( WNT )
@@ -330,8 +636,52 @@ void OGLTransitionerImpl::initWindowFromSlideShowView( const uno::Reference< pre
GLWin.hRC = wglCreateContext(GLWin.hDC);
wglMakeCurrent(GLWin.hDC,GLWin.hRC);
#elif defined( UNX )
- glXMakeCurrent( GLWin.dpy, GLWin.win, GLWin.ctx );
+ if( !glXMakeCurrent( GLWin.dpy, GLWin.win, GLWin.ctx ) ) {
+ OSL_TRACE("unable to select current GLX context");
+ return false;
+ }
+
+ int glxMinor, glxMajor;
+ mnGLXVersion = 0;
+ if( glXQueryVersion( GLWin.dpy, &glxMajor, &glxMinor ) )
+ mnGLXVersion = glxMajor + 0.1*glxMinor;
+ OSL_TRACE("available GLX version: %f", mnGLXVersion);
+
+ GLWin.GLExtensions = glGetString( GL_EXTENSIONS );
+ OSL_TRACE("available GL extensions: %s", GLWin.GLExtensions);
+
+ mbTextureFromPixmap = GLWin.HasGLXExtension( "GLX_EXT_texture_from_pixmap" );
+ mbGenerateMipmap = GLWin.HasGLExtension( "GL_SGIS_generate_mipmap" );
+
+ if( GLWin.HasGLXExtension("GLX_SGI_swap_control" ) ) {
+ // enable vsync
+ typedef GLint (*glXSwapIntervalProc)(GLint);
+ glXSwapIntervalProc glXSwapInterval = (glXSwapIntervalProc) unx::glXGetProcAddress( (const GLubyte*) "glXSwapIntervalSGI" );
+ if( glXSwapInterval ) {
+ int (*oldHandler)(unx::Display* /*dpy*/, unx::XErrorEvent* /*evnt*/);
+
+ // replace error handler temporarily
+ oldHandler = unx::XSetErrorHandler( oglErrorHandler );
+
+ errorTriggered = false;
+
+ glXSwapInterval( 1 );
+
+ // sync so that we possibly get an XError
+ unx::glXWaitGL();
+ XSync(GLWin.dpy, false);
+
+ if( errorTriggered )
+ OSL_TRACE("error when trying to set swap interval, NVIDIA or Mesa bug?");
+ else
+ OSL_TRACE("set swap interval to 1 (enable vsync)");
+
+ // restore the error handler
+ unx::XSetErrorHandler( oldHandler );
+ }
+ }
#endif
+
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glClearColor (0, 0, 0, 0);
@@ -353,8 +703,10 @@ void OGLTransitionerImpl::initWindowFromSlideShowView( const uno::Reference< pre
if( LeavingBytes.hasElements() && EnteringBytes.hasElements())
GLInitSlides();//we already have uninitialized slides, let's initialize
- if (pTransition)
- pTransition->prepare ();
+ if( pTransition && pTransition->mnRequiredGLVersion <= cnGLVersion )
+ pTransition->prepare( GLleavingSlide, GLenteringSlide );
+
+ return true;
}
void OGLTransitionerImpl::setSlides( const uno::Reference< rendering::XBitmap >& xLeavingSlide,
@@ -365,75 +717,213 @@ void OGLTransitionerImpl::setSlides( const uno::Reference< rendering::XBitmap >&
if (isDisposed())
return;
- uno::Reference< rendering::XIntegerBitmap > LeavingSlideIntBitmap( xLeavingSlide , uno::UNO_QUERY_THROW );
- uno::Reference< rendering::XIntegerBitmap > EnteringSlideIntBitmap( xEnteringSlide , uno::UNO_QUERY_THROW );
+ mxLeavingBitmap.set( xLeavingSlide , UNO_QUERY_THROW );
+ mxEnteringBitmap.set( xEnteringSlide , UNO_QUERY_THROW );
+ Reference< XFastPropertySet > xLeavingSet( xLeavingSlide , UNO_QUERY );
+ Reference< XFastPropertySet > xEnteringSet( xEnteringSlide , UNO_QUERY );
geometry::IntegerRectangle2D SlideRect;
- SlideSize = LeavingSlideIntBitmap->getSize();
+ SlideSize = mxLeavingBitmap->getSize();
SlideRect.X1 = 0;
SlideRect.X2 = SlideSize.Width;
SlideRect.Y1 = 0;
SlideRect.Y2 = SlideSize.Height;
- LeavingBytes = LeavingSlideIntBitmap->getData(SlideBitmapLayout,SlideRect);
- EnteringBytes = EnteringSlideIntBitmap->getData(SlideBitmapLayout,SlideRect);
+ OSL_TRACE("leaving bitmap area: %dx%d", SlideSize.Width, SlideSize.Height);
+ SlideSize = mxEnteringBitmap->getSize();
+ OSL_TRACE("entering bitmap area: %dx%d", SlideSize.Width, SlideSize.Height);
-// TODO if(GLWin.ctx)//if we have a rendering context, let's init the slides
- GLInitSlides();
+#ifdef UNX
+ unx::glXWaitGL();
+ XSync(GLWin.dpy, false);
+#endif
- OSL_ENSURE(SlideBitmapLayout.PlaneStride == 0,"only handle no plane stride now");
-}
+#ifdef DEBUG
+ t1 = microsec_clock::local_time();
+#endif
-namespace
-{
- struct OGLFormat
- {
- GLint nInternalFormat;
- GLenum eFormat;
- GLenum eType;
- };
+ mbUseLeavingPixmap = false;
+ mbUseEnteringPixmap = false;
- /* channel ordering: (0:rgba, 1:bgra, 2:argb, 3:abgr)
- */
- int calcComponentOrderIndex(const uno::Sequence<sal_Int8>& rTags)
- {
- using namespace rendering::ColorComponentTag;
+#ifdef UNX
+#if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
- static const sal_Int8 aOrderTable[] =
- {
- RGB_RED, RGB_GREEN, RGB_BLUE, ALPHA,
- RGB_BLUE, RGB_GREEN, RGB_RED, ALPHA,
- ALPHA, RGB_RED, RGB_GREEN, RGB_BLUE,
- ALPHA, RGB_BLUE, RGB_GREEN, RGB_RED,
- };
+ if( mnGLXVersion >= 1.2999 && mbTextureFromPixmap && xLeavingSet.is() && xEnteringSet.is() && mbHasTFPVisual ) {
+ Sequence< Any > leaveArgs;
+ Sequence< Any > enterArgs;
+ if( (xLeavingSet->getFastPropertyValue( 1 ) >>= leaveArgs) &&
+ (xEnteringSet->getFastPropertyValue( 1 ) >>= enterArgs) ) {
+ OSL_TRACE ("pixmaps available");
- const sal_Int32 nNumComps(rTags.getLength());
- const sal_Int8* pLine=aOrderTable;
- for(int i=0; i<4; ++i)
- {
- int j=0;
- while( j<4 && j<nNumComps && pLine[j] == rTags[j] )
- ++j;
+ sal_Int32 depth;
- // all of the line passed, this is a match!
- if( j==nNumComps )
- return i;
+ leaveArgs[0] >>= mbFreeLeavingPixmap;
+ enterArgs[0] >>= mbFreeEnteringPixmap;
+ leaveArgs[1] >>= maLeavingPixmap;
+ enterArgs[1] >>= maEnteringPixmap;
+ leaveArgs[2] >>= depth;
- pLine+=4;
+ int pixmapAttribs[] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
+ GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
+ GLX_MIPMAP_TEXTURE_EXT, True,
+ None };
+
+
+ // sync so that we possibly get an pending XError, before we set our handler.
+ // this way we will not miss any error from other code
+ unx::glXWaitGL();
+ XSync(GLWin.dpy, false);
+
+ int (*oldHandler)(unx::Display* /*dpy*/, unx::XErrorEvent* /*evnt*/);
+
+ // replace error handler temporarily
+ oldHandler = unx::XSetErrorHandler( oglErrorHandler );
+
+ errorTriggered = false;
+ LeavingPixmap = glXCreatePixmap( GLWin.dpy, GLWin.fbc, maLeavingPixmap, pixmapAttribs );
+
+ // sync so that we possibly get an XError
+ unx::glXWaitGL();
+ XSync(GLWin.dpy, false);
+
+ if( !errorTriggered )
+ mbUseLeavingPixmap = true;
+ else {
+ OSL_TRACE("XError triggered");
+ if( mbFreeLeavingPixmap ) {
+ unx::XFreePixmap( GLWin.dpy, maLeavingPixmap );
+ mbFreeLeavingPixmap = false;
+ }
+ errorTriggered = false;
}
- return -1;
+ EnteringPixmap = glXCreatePixmap( GLWin.dpy, GLWin.fbc, maEnteringPixmap, pixmapAttribs );
+
+ // sync so that we possibly get an XError
+ unx::glXWaitGL();
+ XSync(GLWin.dpy, false);
+
+ OSL_TRACE("created glx pixmap %p and %p depth: %d", LeavingPixmap, EnteringPixmap, depth);
+ if( !errorTriggered )
+ mbUseEnteringPixmap = true;
+ else {
+ OSL_TRACE("XError triggered");
+ if( mbFreeEnteringPixmap ) {
+ unx::XFreePixmap( GLWin.dpy, maEnteringPixmap );
+ mbFreeEnteringPixmap = false;
+ }
+ }
+
+ // restore the error handler
+ unx::XSetErrorHandler( oldHandler );
+ }
}
-}
+#endif
+#endif
+ if( !mbUseLeavingPixmap )
+ LeavingBytes = mxLeavingBitmap->getData(SlideBitmapLayout,SlideRect);
+ if( !mbUseEnteringPixmap )
+ EnteringBytes = mxEnteringBitmap->getData(SlideBitmapLayout,SlideRect);
+
+// TODO
+#ifdef UNX
+ if(GLWin.ctx)//if we have a rendering context, let's init the slides
+#endif
+ GLInitSlides();
-void OGLTransitionerImpl::GLInitSlides()
+ OSL_ENSURE(SlideBitmapLayout.PlaneStride == 0,"only handle no plane stride now");
+
+#ifdef UNX
+ /* flush & sync */
+ unx::glXWaitGL();
+ XSync( GLWin.dpy, false );
+
+ // synchronized X still gives us much smoother play
+ // I suspect some issues in above code in slideshow
+ // synchronize whole transition for now
+ XSynchronize( GLWin.dpy, true );
+ mbRestoreSync = true;
+#endif
+}
+
+void OGLTransitionerImpl::createTexture( unsigned int* texID,
+#if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
+ unx::GLXPixmap pixmap,
+ bool usePixmap,
+#endif
+ bool useMipmap,
+ uno::Sequence<sal_Int8>& data,
+ const OGLFormat* pFormat )
{
- osl::MutexGuard const guard( m_aMutex );
+ glDeleteTextures( 1, texID );
+ glGenTextures( 1, texID );
+ glBindTexture( GL_TEXTURE_2D, *texID );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
+
+#if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
+ unx::PFNGLXBINDTEXIMAGEEXTPROC myglXBindTexImageEXT = (unx::PFNGLXBINDTEXIMAGEEXTPROC) unx::glXGetProcAddress( (const GLubyte*) "glXBindTexImageEXT" );
+
+ if( usePixmap ) {
+ if( mbGenerateMipmap )
+ glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, True);
+ myglXBindTexImageEXT (GLWin.dpy, pixmap, GLX_FRONT_LEFT_EXT, NULL);
+ if( mbGenerateMipmap && useMipmap ) {
+ OSL_TRACE("use mipmaps");
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); //TRILINEAR FILTERING
+ } else {
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
+ }
+ } else {
+#endif
+ if( !pFormat )
+ {
+ // force-convert color to ARGB8888 int color space
+ uno::Sequence<sal_Int8> tempBytes(
+ SlideBitmapLayout.ColorSpace->convertToIntegerColorSpace(
+ data,
+ canvas::tools::getStdColorSpace()));
+ gluBuild2DMipmaps(GL_TEXTURE_2D,
+ 4,
+ SlideSize.Width,
+ SlideSize.Height,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ &tempBytes[0]);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); //TRILINEAR FILTERING
- if (isDisposed())
- return;
+ //anistropic filtering (to make texturing not suck when looking at polygons from oblique angles)
+ GLfloat largest_supported_anisotropy;
+ glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy);
+ } else {
+ if( pTransition && !cbBrokenTexturesATI && !useMipmap) {
+ glTexImage2D( GL_TEXTURE_2D, 0, pFormat->nInternalFormat, SlideSize.Width, SlideSize.Height, 0, pFormat->eFormat, pFormat->eType, &data[0] );
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
+ } else {
+ gluBuild2DMipmaps( GL_TEXTURE_2D, pFormat->nInternalFormat, SlideSize.Width, SlideSize.Height, pFormat->eFormat, pFormat->eType, &data[0] );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); //TRILINEAR FILTERING
+
+ //anistropic filtering (to make texturing not suck when looking at polygons from oblique angles)
+ GLfloat largest_supported_anisotropy;
+ glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy );
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy );
+ }
+ }
+#if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
+ }
+#endif
+ OSL_ENSURE(glIsTexture(*texID), "Can't generate Leaving slide textures in OpenGL");
+}
+void OGLTransitionerImpl::prepareEnvironment()
+{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double EyePos(10.0);
@@ -457,7 +947,10 @@ void OGLTransitionerImpl::GLInitSlides()
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslated(0,0,-EyePos);
+}
+const OGLFormat* OGLTransitionerImpl::chooseFormats()
+{
const OGLFormat* pDetectedFormat=NULL;
uno::Reference<rendering::XIntegerBitmapColorSpace> xIntColorSpace(
SlideBitmapLayout.ColorSpace);
@@ -473,10 +966,10 @@ void OGLTransitionerImpl::GLInitSlides()
static const OGLFormat lcl_RGB24[] =
{
// 24 bit RGB
+ {3, GL_BGR, GL_UNSIGNED_BYTE},
{3, GL_RGB, GL_UNSIGNED_BYTE},
-// {3, GL_BGR, GL_UNSIGNED_BYTE},
- {3, GL_RGB, GL_UNSIGNED_BYTE},
- // {3, GL_BGR, GL_UNSIGNED_BYTE}
+ {3, GL_BGR, GL_UNSIGNED_BYTE},
+ {3, GL_RGB, GL_UNSIGNED_BYTE}
};
#if defined(GL_VERSION_1_2) && defined(GLU_VERSION_1_3)
@@ -484,37 +977,37 @@ void OGLTransitionerImpl::GLInitSlides()
static const OGLFormat lcl_RGB16[] =
{
// 16 bit RGB
- {3, GL_RGB, GL_UNSIGNED_SHORT_5_6_5},
{3, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV},
{3, GL_RGB, GL_UNSIGNED_SHORT_5_6_5},
- {3, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV}
+ {3, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV},
+ {3, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}
};
static const OGLFormat lcl_ARGB16_4[] =
{
// 16 bit ARGB
- {4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4},
-// {4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4},
- // {4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV},
- {4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV}
+ {4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV},
+ {4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV},
+ {4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4},
+ {4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4}
};
static const OGLFormat lcl_ARGB16_5[] =
{
// 16 bit ARGB
- {4, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1},
- // {4, GL_BGRA, GL_UNSIGNED_SHORT_5_5_5_1},
- // {4, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV},
- {4, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV}
+ {4, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV},
+ {4, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV},
+ {4, GL_BGRA, GL_UNSIGNED_SHORT_5_5_5_1},
+ {4, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}
};
static const OGLFormat lcl_ARGB32[] =
{
// 32 bit ARGB
- {4, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8},
-// {4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8},
- // {4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV},
- {4, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV}
+ {4, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV},
+ {4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV},
+ {4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8},
+ {4, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8}
};
const uno::Sequence<sal_Int8> aComponentTags(
@@ -572,95 +1065,78 @@ void OGLTransitionerImpl::GLInitSlides()
#endif
}
- glDeleteTextures(1,&GLleavingSlide);
+ return pDetectedFormat;
+}
- glGenTextures(1, &GLleavingSlide);
- glBindTexture(GL_TEXTURE_2D, GLleavingSlide);
- if( !pDetectedFormat )
- {
- // force-convert color to ARGB8888 int color space
- uno::Sequence<sal_Int8> tempBytes(
- SlideBitmapLayout.ColorSpace->convertToIntegerColorSpace(
- LeavingBytes,
- canvas::tools::getStdColorSpace()));
- gluBuild2DMipmaps(GL_TEXTURE_2D,
- 4,
- SlideSize.Width,
- SlideSize.Height,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- &tempBytes[0]);
- }
- else
- {
- gluBuild2DMipmaps(GL_TEXTURE_2D,
- pDetectedFormat->nInternalFormat,
- SlideSize.Width,
- SlideSize.Height,
- pDetectedFormat->eFormat,
- pDetectedFormat->eType,
- &LeavingBytes[0]);
- }
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);//TRILINEAR FILTERING
- GLfloat largest_supported_anisotropy;
- glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy);//anistropic filtering (to make texturing not suck when looking at polygons from oblique angles)
+void OGLTransitionerImpl::GLInitSlides()
+{
+ osl::MutexGuard const guard( m_aMutex );
- OSL_ENSURE(glIsTexture(GLleavingSlide), "Can't generate Leaving slide textures in OpenGL");
+ if (isDisposed() || pTransition->mnRequiredGLVersion > cnGLVersion)
+ return;
- glDeleteTextures(1,&GLenteringSlide);
+ prepareEnvironment();
- glGenTextures(1, &GLenteringSlide);
- glBindTexture(GL_TEXTURE_2D, GLenteringSlide);
- if( !pDetectedFormat )
- {
- // force-convert color to ARGB8888 int color space
- uno::Sequence<sal_Int8> tempBytes(
- SlideBitmapLayout.ColorSpace->convertToIntegerColorSpace(
- EnteringBytes,
- canvas::tools::getStdColorSpace()));
- gluBuild2DMipmaps(GL_TEXTURE_2D,
- 4,
- SlideSize.Width,
- SlideSize.Height,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- &tempBytes[0]);
- }
- else
- {
- gluBuild2DMipmaps(GL_TEXTURE_2D,
- pDetectedFormat->nInternalFormat,
- SlideSize.Width,
- SlideSize.Height,
- pDetectedFormat->eFormat,
- pDetectedFormat->eType,
- &EnteringBytes[0]);
- }
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);//TRILINEAR FILTERING
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy);//anistropic filtering (to make texturing not suck when looking at polygons from oblique angles)
+ const OGLFormat* pFormat = NULL;
+ if( !mbUseLeavingPixmap || !mbUseEnteringPixmap )
+ pFormat = chooseFormats();
+
+ createTexture( &GLleavingSlide,
+#if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
+ LeavingPixmap,
+ mbUseLeavingPixmap,
+#endif
+ pTransition->mbUseMipMapLeaving,
+ LeavingBytes,
+ pFormat );
+
+ createTexture( &GLenteringSlide,
+#if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
+ EnteringPixmap,
+ mbUseEnteringPixmap,
+#endif
+ pTransition->mbUseMipMapEntering,
+ EnteringBytes,
+ pFormat );
+
+#ifdef UNX
+ unx::glXWaitGL();
+ XSync(GLWin.dpy, false);
+#endif
- OSL_ENSURE( glIsTexture(GLenteringSlide), "Can't generate entering slide textures in OpenGL" );
+#ifdef DEBUG
+ t2 = microsec_clock::local_time();
+ OSL_TRACE("textures created in: %s", to_simple_string( t2 - t1 ).c_str());
+#endif
}
void SAL_CALL OGLTransitionerImpl::update( double nTime ) throw (uno::RuntimeException)
{
+#ifdef DEBUG
+ frame_count ++;
+ t3 = microsec_clock::local_time();
+ if( frame_count == 1 ) {
+ t5 = t3;
+ total_update = seconds (0);
+ }
+#endif
osl::MutexGuard const guard( m_aMutex );
- if (isDisposed())
+ if (isDisposed() || !cbGLXPresent || pTransition->mnRequiredGLVersion > cnGLVersion)
return;
+#ifdef WNT
+ wglMakeCurrent(GLWin.hDC,GLWin.hRC);
+#endif
+#ifdef UNX
+ glXMakeCurrent( GLWin.dpy, GLWin.win, GLWin.ctx );
+#endif
+
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(pTransition)
- pTransition->display( nTime , GLleavingSlide , GLenteringSlide ,
+ pTransition->display( nTime, GLleavingSlide, GLenteringSlide,
SlideSize.Width, SlideSize.Height,
static_cast<double>(GLWin.Width),
static_cast<double>(GLWin.Height) );
@@ -672,38 +1148,153 @@ void SAL_CALL OGLTransitionerImpl::update( double nTime ) throw (uno::RuntimeExc
#endif
if( pWindow )
pWindow->Show();
+
+#ifdef UNX
+ /* flush & sync */
+ unx::glXWaitGL();
+ XSync( GLWin.dpy, false );
+#endif
+
+#ifdef DEBUG
+ t4 = microsec_clock::local_time();
+
+ OSL_TRACE("update time: %f", nTime);
+ OSL_TRACE("update took: %s", to_simple_string( t4 - t3 ).c_str());
+ total_update += (t4 - t3);
+#endif
}
-// we are about to be disposed (someone call dispose() on us)
-void OGLTransitionerImpl::disposing()
+void SAL_CALL OGLTransitionerImpl::viewChanged( const Reference< presentation::XSlideShowView >& rView,
+ const Reference< rendering::XBitmap >& rLeavingBitmap,
+ const Reference< rendering::XBitmap >& rEnteringBitmap )
+ throw (uno::RuntimeException)
{
- osl::MutexGuard const guard( m_aMutex );
- glDeleteTextures(1,&GLleavingSlide);
- glDeleteTextures(1,&GLenteringSlide);
+ OSL_TRACE("transitioner: view changed");
- if (pTransition)
- pTransition->finish();
+ disposeTextures();
+ disposeContextAndWindow();
+ initWindowFromSlideShowView( rView );
+ setSlides( rLeavingBitmap, rEnteringBitmap );
+}
+void OGLTransitionerImpl::disposeContextAndWindow()
+{
#if defined( WNT )
if (GLWin.hRC)
{
- wglMakeCurrent( GLWin.hDC, 0 ); // kill Device Context
- wglDeleteContext( GLWin.hRC ); // Kill Render Context
- ReleaseDC( GLWin.hWnd, GLWin.hDC );// Release Window
+ wglMakeCurrent( GLWin.hDC, 0 ); // kill Device Context
+ wglDeleteContext( GLWin.hRC ); // Kill Render Context
+ ReleaseDC( GLWin.hWnd, GLWin.hDC ); // Release Window
}
#elif defined( UNX )
if(GLWin.ctx)
{
- OSL_ENSURE( glXMakeCurrent(GLWin.dpy, None, NULL) , "Error releasing glX context" );
- glXDestroyContext(GLWin.dpy, GLWin.ctx);
- GLWin.ctx = NULL;
+ glXMakeCurrent(GLWin.dpy, None, NULL);
+ if( glGetError() != GL_NO_ERROR ) {
+ OSL_TRACE("glError: %s", (char *)gluErrorString(glGetError()));
+ }
+ glXDestroyContext(GLWin.dpy, GLWin.ctx);
+ GLWin.ctx = NULL;
+ }
+#endif
+ if( pWindow ) {
+ delete pWindow;
+ pWindow = NULL;
+ GLWin.win = 0;
+ }
+}
+
+void OGLTransitionerImpl::disposeTextures()
+{
+#ifdef WNT
+ wglMakeCurrent(GLWin.hDC,GLWin.hRC);
+#endif
+#ifdef UNX
+ glXMakeCurrent( GLWin.dpy, GLWin.win, GLWin.ctx );
+#endif
+
+#if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
+ unx::PFNGLXRELEASETEXIMAGEEXTPROC myglXReleaseTexImageEXT = (unx::PFNGLXRELEASETEXIMAGEEXTPROC) unx::glXGetProcAddress( (const GLubyte*) "glXReleaseTexImageEXT" );
+ if( mbUseLeavingPixmap ) {
+
+ myglXReleaseTexImageEXT( GLWin.dpy, LeavingPixmap, GLX_FRONT_LEFT_EXT );
+ glXDestroyGLXPixmap( GLWin.dpy, LeavingPixmap );
+ LeavingPixmap = 0;
+ if( mbFreeLeavingPixmap ) {
+ unx::XFreePixmap( GLWin.dpy, maLeavingPixmap );
+ mbFreeLeavingPixmap = false;
+ maLeavingPixmap = 0;
+ }
+ }
+ if( mbUseEnteringPixmap ) {
+ myglXReleaseTexImageEXT( GLWin.dpy, EnteringPixmap, GLX_FRONT_LEFT_EXT );
+ glXDestroyGLXPixmap( GLWin.dpy, EnteringPixmap );
+ EnteringPixmap = 0;
+ if( mbFreeEnteringPixmap ) {
+ unx::XFreePixmap( GLWin.dpy, maEnteringPixmap );
+ mbFreeEnteringPixmap = false;
+ maEnteringPixmap = 0;
+ }
+ }
+#endif
+
+ if( !mbUseLeavingPixmap ) {
+ glDeleteTextures(1,&GLleavingSlide);
+ GLleavingSlide = 0;
+ }
+ if( !mbUseEnteringPixmap ) {
+ glDeleteTextures(1,&GLenteringSlide);
+ GLleavingSlide = 0;
+ }
+
+ mbUseLeavingPixmap = false;
+ mbUseEnteringPixmap = false;
+}
+
+// we are about to be disposed (someone call dispose() on us)
+void OGLTransitionerImpl::disposing()
+{
+ osl::MutexGuard const guard( m_aMutex );
+
+#ifdef DEBUG
+ OSL_TRACE("dispose %p\n", this);
+ if( frame_count ) {
+ t6 = microsec_clock::local_time();
+ time_duration duration = t6 - t5;
+ OSL_TRACE("whole transition (frames: %d) took: %s fps: %f time spent in updates: %s percentage of transition time: %f%%",
+ frame_count, to_simple_string( duration ).c_str(),
+ ((double)frame_count*1000000000.0)/duration.total_nanoseconds(),
+ to_simple_string( total_update ).c_str(),
+ 100*(((double)total_update.total_nanoseconds())/((double)duration.total_nanoseconds()))
+ );
+ }
+#endif
+
+ if( pWindow ) {
+
+ disposeTextures();
+
+ if (pTransition)
+ pTransition->finish();
+
+#ifdef UNX
+ if( mbRestoreSync ) {
+ // try to reestablish synchronize state
+ char* sal_synchronize = getenv("SAL_SYNCHRONIZE");
+ XSynchronize( GLWin.dpy, sal_synchronize && *sal_synchronize == '1' );
}
#endif
- if (pWindow)
- delete pWindow;
+
+ disposeContextAndWindow();
+ }
+
if (pTransition)
delete pTransition;
+
+ mxLeavingBitmap.clear();
+ mxEnteringBitmap.clear();
+ mxView.clear();
}
OGLTransitionerImpl::OGLTransitionerImpl(OGLTransitionImpl* pOGLTransition) :
@@ -712,8 +1303,12 @@ OGLTransitionerImpl::OGLTransitionerImpl(OGLTransitionImpl* pOGLTransition) :
GLleavingSlide( 0 ),
GLenteringSlide( 0 ),
pWindow( NULL ),
+ mxView(),
EnteringBytes(),
LeavingBytes(),
+ mbRestoreSync( false ),
+ mbUseLeavingPixmap( false ),
+ mbUseEnteringPixmap( false ),
SlideBitmapLayout(),
SlideSize(),
pTransition(pOGLTransition)
@@ -723,6 +1318,8 @@ OGLTransitionerImpl::OGLTransitionerImpl(OGLTransitionImpl* pOGLTransition) :
#elif defined( UNX )
GLWin.ctx = 0;
#endif
+
+ DBG(frame_count = 0);
}
typedef cppu::WeakComponentImplHelper1<presentation::XTransitionFactory> OGLTransitionFactoryImplBase;
@@ -737,26 +1334,38 @@ public:
// XTransitionFactory
virtual ::sal_Bool SAL_CALL hasTransition( ::sal_Int16 transitionType, ::sal_Int16 transitionSubType ) throw (uno::RuntimeException)
{
- if( transitionType != animations::TransitionType::MISCSHAPEWIPE )
+ if( transitionType == animations::TransitionType::MISCSHAPEWIPE ) {
+ switch( transitionSubType )
+ {
+ case animations::TransitionSubType::ACROSS:
+ case animations::TransitionSubType::CORNERSOUT:
+ case animations::TransitionSubType::CIRCLE:
+ case animations::TransitionSubType::FANOUTHORIZONTAL:
+ case animations::TransitionSubType::CORNERSIN:
+ case animations::TransitionSubType::LEFTTORIGHT:
+ case animations::TransitionSubType::TOPTOBOTTOM:
+ case animations::TransitionSubType::TOPRIGHT:
+ case animations::TransitionSubType::TOPLEFT:
+ case animations::TransitionSubType::BOTTOMRIGHT:
+ case animations::TransitionSubType::BOTTOMLEFT:
+ case animations::TransitionSubType::TOPCENTER:
+ case animations::TransitionSubType::RIGHTCENTER:
+ case animations::TransitionSubType::BOTTOMCENTER:
+ return sal_True;
+
+ default:
+ return sal_False;
+ }
+ } else if( transitionType == animations::TransitionType::FADE && transitionSubType == animations::TransitionSubType::CROSSFADE ) {
+ return sal_True;
+ } else if( transitionType == animations::TransitionType::FADE && transitionSubType == animations::TransitionSubType::FADEOVERCOLOR ) {
+ return sal_True;
+ } else if( transitionType == animations::TransitionType::IRISWIPE && transitionSubType == animations::TransitionSubType::DIAMOND ) {
+ return sal_True;
+ } else if( transitionType == animations::TransitionType::ZOOM && transitionSubType == animations::TransitionSubType::ROTATEIN ) {
+ return sal_True;
+ } else
return sal_False;
-
- switch( transitionSubType )
- {
- case animations::TransitionSubType::ACROSS:
- case animations::TransitionSubType::CORNERSOUT:
- case animations::TransitionSubType::CIRCLE:
- case animations::TransitionSubType::FANOUTHORIZONTAL:
- case animations::TransitionSubType::CORNERSIN:
- case animations::TransitionSubType::LEFTTORIGHT:
- case animations::TransitionSubType::TOPTOBOTTOM:
- case animations::TransitionSubType::TOPRIGHT:
- case animations::TransitionSubType::TOPLEFT:
- case animations::TransitionSubType::BOTTOMRIGHT:
- return sal_True;
-
- default:
- return sal_False;
- }
}
virtual uno::Reference< presentation::XTransition > SAL_CALL createTransition(
@@ -764,53 +1373,91 @@ public:
::sal_Int16 transitionSubType,
const uno::Reference< presentation::XSlideShowView >& view,
const uno::Reference< rendering::XBitmap >& leavingBitmap,
- const uno::Reference< rendering::XBitmap >& enteringBitmap,
- const geometry::RealPoint2D& slideOffset ) throw (uno::RuntimeException)
+ const uno::Reference< rendering::XBitmap >& enteringBitmap )
+ throw (uno::RuntimeException)
{
- if( transitionType != animations::TransitionType::MISCSHAPEWIPE )
+ if( !hasTransition( transitionType, transitionSubType ) )
return uno::Reference< presentation::XTransition >();
- OGLTransitionImpl* pTransition = new OGLTransitionImpl();
- switch( transitionSubType )
- {
- case animations::TransitionSubType::ACROSS:
- pTransition->makeNByMTileFlip(8,6);
- break;
- case animations::TransitionSubType::CORNERSOUT:
- pTransition->makeOutsideCubeFaceToLeft();
- break;
- case animations::TransitionSubType::CIRCLE:
- pTransition->makeRevolvingCircles(8,128);
- break;
- case animations::TransitionSubType::FANOUTHORIZONTAL:
- pTransition->makeHelix(20);
- break;
- case animations::TransitionSubType::CORNERSIN:
- pTransition->makeInsideCubeFaceToLeft();
- break;
- case animations::TransitionSubType::LEFTTORIGHT:
- pTransition->makeFallLeaving();
- break;
- case animations::TransitionSubType::TOPTOBOTTOM:
- pTransition->makeTurnAround();
- break;
- case animations::TransitionSubType::TOPRIGHT:
- pTransition->makeTurnDown();
- break;
- case animations::TransitionSubType::TOPLEFT:
- pTransition->makeIris();
- break;
- case animations::TransitionSubType::BOTTOMRIGHT:
- pTransition->makeRochade();
- break;
- default:
- return uno::Reference< presentation::XTransition >();
+ bool bGLXPresent = OGLTransitionerImpl::initialize( view );
+
+ if( OGLTransitionerImpl::cbMesa && (
+ ( transitionType == animations::TransitionType::FADE && transitionSubType == animations::TransitionSubType::CROSSFADE ) ||
+ ( transitionType == animations::TransitionType::FADE && transitionSubType == animations::TransitionSubType::FADEOVERCOLOR ) ||
+ ( transitionType == animations::TransitionType::IRISWIPE && transitionSubType == animations::TransitionSubType::DIAMOND ) ) )
+ return uno::Reference< presentation::XTransition >();
+
+
+ OGLTransitionImpl* pTransition = NULL;
+
+ if( transitionType == animations::TransitionType::MISCSHAPEWIPE ) {
+ pTransition = new OGLTransitionImpl();
+ switch( transitionSubType )
+ {
+ case animations::TransitionSubType::ACROSS:
+ pTransition->makeNByMTileFlip(8,6);
+ break;
+ case animations::TransitionSubType::CORNERSOUT:
+ pTransition->makeOutsideCubeFaceToLeft();
+ break;
+ case animations::TransitionSubType::CIRCLE:
+ pTransition->makeRevolvingCircles(8,128);
+ break;
+ case animations::TransitionSubType::FANOUTHORIZONTAL:
+ pTransition->makeHelix(20);
+ break;
+ case animations::TransitionSubType::CORNERSIN:
+ pTransition->makeInsideCubeFaceToLeft();
+ break;
+ case animations::TransitionSubType::LEFTTORIGHT:
+ pTransition->makeFallLeaving();
+ break;
+ case animations::TransitionSubType::TOPTOBOTTOM:
+ pTransition->makeTurnAround();
+ break;
+ case animations::TransitionSubType::TOPRIGHT:
+ pTransition->makeTurnDown();
+ break;
+ case animations::TransitionSubType::TOPLEFT:
+ pTransition->makeIris();
+ break;
+ case animations::TransitionSubType::BOTTOMRIGHT:
+ pTransition->makeRochade();
+ break;
+ case animations::TransitionSubType::BOTTOMLEFT:
+ pTransition->makeVenetianBlinds( true, 8 );
+ break;
+ case animations::TransitionSubType::TOPCENTER:
+ pTransition->makeVenetianBlinds( false, 6 );
+ break;
+ case animations::TransitionSubType::RIGHTCENTER:
+ pTransition->makeStatic();
+ break;
+ case animations::TransitionSubType::BOTTOMCENTER:
+ pTransition->makeDissolve();
+ break;
+ }
+ } else if( transitionType == animations::TransitionType::FADE && transitionSubType == animations::TransitionSubType::CROSSFADE ) {
+ pTransition = new OGLTransitionImpl();
+ pTransition->makeFadeSmoothly();
+ } else if( transitionType == animations::TransitionType::FADE && transitionSubType == animations::TransitionSubType::FADEOVERCOLOR ) {
+ pTransition = new OGLTransitionImpl();
+ pTransition->makeFadeThroughBlack();
+ } else if( transitionType == animations::TransitionType::IRISWIPE && transitionSubType == animations::TransitionSubType::DIAMOND ) {
+ pTransition = new OGLTransitionImpl();
+ pTransition->makeDiamond();
+ } else if( transitionType == animations::TransitionType::ZOOM && transitionSubType == animations::TransitionSubType::ROTATEIN ) {
+ pTransition = new OGLTransitionImpl();
+ pTransition->makeNewsflash();
}
rtl::Reference<OGLTransitionerImpl> xRes(
new OGLTransitionerImpl(pTransition) );
- xRes->initWindowFromSlideShowView(view,slideOffset.X,slideOffset.Y);
- xRes->setSlides(leavingBitmap,enteringBitmap);
+ if( bGLXPresent ) {
+ if( !xRes->initWindowFromSlideShowView(view))
+ return uno::Reference< presentation::XTransition >();
+ xRes->setSlides(leavingBitmap,enteringBitmap);
+ }
return uno::Reference<presentation::XTransition>(xRes.get());
}
diff --git a/slideshow/source/engine/OGLTrans/makefile.mk b/slideshow/source/engine/OGLTrans/makefile.mk
index 25792849530a..3e5f818923dc 100644
--- a/slideshow/source/engine/OGLTrans/makefile.mk
+++ b/slideshow/source/engine/OGLTrans/makefile.mk
@@ -51,8 +51,10 @@ ENABLE_EXCEPTIONS=TRUE
SLOFILES = \
$(SLO)$/OGLTrans_TransitionImpl.obj \
+ $(SLO)$/OGLTrans_Shaders.obj \
$(SLO)$/OGLTrans_TransitionerImpl.obj
-
+
+DLLPRE=
SHL1TARGET=$(TARGET).uno
.IF "$(GUI)"=="UNX"
diff --git a/slideshow/source/engine/slideshowimpl.cxx b/slideshow/source/engine/slideshowimpl.cxx
index 18c834e4dfb0..d89d57d2d7f8 100644
--- a/slideshow/source/engine/slideshowimpl.cxx
+++ b/slideshow/source/engine/slideshowimpl.cxx
@@ -73,6 +73,7 @@
#include <com/sun/star/presentation/XSlideShow.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XServiceName.hpp>
+#include <com/sun/star/loader/CannotActivateFactoryException.hpp>
#include "unoviewcontainer.hxx"
#include "transitionfactory.hxx"
@@ -100,6 +101,7 @@
#include <vector>
#include <iterator>
#include <algorithm>
+#include <stdio.h>
using namespace com::sun::star;
using namespace ::slideshow::internal;
@@ -483,12 +485,18 @@ SlideShowImpl::SlideShowImpl(
if( xFactory.is() )
{
- // #i82460# try to retrieve special transition factory
- mxOptionalTransitionFactory.set(
- xFactory->createInstanceWithContext(
- ::rtl::OUString::createFromAscii( "com.sun.star.presentation.TransitionFactory" ),
- mxComponentContext ),
- uno::UNO_QUERY );
+ try
+ {
+ // #i82460# try to retrieve special transition factory
+ mxOptionalTransitionFactory.set(
+ xFactory->createInstanceWithContext(
+ ::rtl::OUString::createFromAscii( "com.sun.star.presentation.TransitionFactory" ),
+ mxComponentContext ),
+ uno::UNO_QUERY );
+ }
+ catch (loader::CannotActivateFactoryException const&)
+ {
+ }
}
mpListener.reset( new SeparateListenerImpl(
diff --git a/slideshow/source/engine/transitions/slidetransitionfactory.cxx b/slideshow/source/engine/transitions/slidetransitionfactory.cxx
index ddc53d7b085d..6c8f769c2d3a 100644
--- a/slideshow/source/engine/transitions/slidetransitionfactory.cxx
+++ b/slideshow/source/engine/transitions/slidetransitionfactory.cxx
@@ -106,6 +106,28 @@ void fillPage( const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
class PluginSlideChange: public SlideChangeBase
{
+ struct TransitionViewPair {
+ uno::Reference<presentation::XTransition> mxTransition;
+ UnoViewSharedPtr mpView;
+
+ TransitionViewPair( uno::Reference<presentation::XTransition> xTransition, const UnoViewSharedPtr pView )
+ {
+ mxTransition = xTransition;
+ mpView = pView;
+ }
+
+ ~TransitionViewPair()
+ {
+ mxTransition.clear();
+ mpView.reset();;
+ }
+
+ void update( double t )
+ {
+ mxTransition->update( t );
+ }
+ };
+
public:
/** Create a new SlideChanger, for the given leaving and
entering slide bitmaps, which uses super secret OpenGL
@@ -127,47 +149,166 @@ public:
rViewContainer,
rScreenUpdater,
rEventMultiplexer ),
- maTransitions()
+ maTransitions(),
+ mbSuccess( false ),
+ mnTransitionType( nTransitionType ),
+ mnTransitionSubType( nTransitionSubType ),
+ mxFactory( xFactory )
{
// create one transition per view
UnoViewVector::const_iterator aCurrView (rViewContainer.begin());
const UnoViewVector::const_iterator aEnd(rViewContainer.end());
while( aCurrView != aEnd )
{
- const ::basegfx::B2DHomMatrix aViewTransform(
- (*aCurrView)->getCanvas()->getTransformation() );
- const ::basegfx::B2DPoint aOffsetPixel(
- aViewTransform * ::basegfx::B2DPoint() );
+ if(! addTransition( *aCurrView ) )
+ return;
- maTransitions.push_back(
- xFactory->createTransition(
- nTransitionType,
- nTransitionSubType,
- (*aCurrView)->getUnoView(),
- getLeavingBitmap(ViewEntry(*aCurrView))->getXBitmap(),
- getEnteringBitmap(ViewEntry(*aCurrView))->getXBitmap(),
- basegfx::unotools::point2DFromB2DPoint(aOffsetPixel) ) );
-
- ENSURE_OR_THROW(maTransitions.back().is(),
+ ENSURE_OR_THROW(maTransitions.back() && maTransitions.back()->mxTransition.is(),
"Failed to create plugin transition");
++aCurrView;
}
+ mbSuccess = true;
+ }
+
+ ~PluginSlideChange()
+ {
+ mxFactory.clear();
+
+ ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin());
+ ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
+ while( aCurrView != aEnd )
+ {
+ delete (*aCurrView);
+ ++aCurrView;
+ }
+ maTransitions.clear();
+ }
+
+ bool addTransition( const UnoViewSharedPtr& rView )
+ {
+ uno::Reference<presentation::XTransition> rTransition = mxFactory->createTransition(
+ mnTransitionType,
+ mnTransitionSubType,
+ rView->getUnoView(),
+ getLeavingBitmap(ViewEntry(rView))->getXBitmap(),
+ getEnteringBitmap(ViewEntry(rView))->getXBitmap() );
+
+ if( rTransition.is() )
+ maTransitions.push_back( new TransitionViewPair( rTransition, rView ) );
+ else
+ return false;
+
+ return true;
}
virtual bool operator()( double t )
{
std::for_each(maTransitions.begin(),
maTransitions.end(),
- boost::bind( &presentation::XTransition::update,
+ boost::bind( &TransitionViewPair::update,
_1, t) );
return true;
}
+ bool Success()
+ {
+ return mbSuccess;
+ }
+
+ // ViewEventHandler
+ virtual void viewAdded( const UnoViewSharedPtr& rView )
+ {
+ OSL_TRACE("PluginSlideChange viewAdded");
+ SlideChangeBase::viewAdded( rView );
+
+ ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin());
+ ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
+ bool bKnown = false;
+ while( aCurrView != aEnd )
+ {
+ if( (*aCurrView)->mpView == rView ) {
+ bKnown = true;
+ break;
+ }
+ ++aCurrView;
+ }
+
+ if( !bKnown ) {
+ OSL_TRACE("need to be added");
+
+ addTransition( rView );
+ }
+ }
+
+ virtual void viewRemoved( const UnoViewSharedPtr& rView )
+ {
+ OSL_TRACE("PluginSlideChange viewRemoved");
+ SlideChangeBase::viewRemoved( rView );
+
+ ::std::vector< TransitionViewPair* >::iterator aCurrView (maTransitions.begin());
+ ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
+ while( aCurrView != aEnd )
+ {
+ if( (*aCurrView)->mpView == rView ) {
+ OSL_TRACE( "view removed" );
+ delete (*aCurrView);
+ maTransitions.erase( aCurrView );
+ break;
+ }
+ ++aCurrView;
+ }
+ }
+
+ virtual void viewChanged( const UnoViewSharedPtr& rView )
+ {
+ OSL_TRACE("PluginSlideChange viewChanged");
+ SlideChangeBase::viewChanged( rView );
+
+ ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin());
+ ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
+ while( aCurrView != aEnd )
+ {
+ if( (*aCurrView)->mpView == rView ) {
+ OSL_TRACE( "view changed" );
+ (*aCurrView)->mxTransition->viewChanged( rView->getUnoView(),
+ getLeavingBitmap(ViewEntry(rView))->getXBitmap(),
+ getEnteringBitmap(ViewEntry(rView))->getXBitmap() );
+ } else
+ OSL_TRACE( "view did not changed" );
+
+ ++aCurrView;
+ }
+ }
+
+ virtual void viewsChanged()
+ {
+ OSL_TRACE("PluginSlideChange viewsChanged");
+ SlideChangeBase::viewsChanged();
+
+ ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin());
+ ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
+ while( aCurrView != aEnd )
+ {
+ OSL_TRACE( "view changed" );
+ (*aCurrView)->mxTransition->viewChanged( (*aCurrView)->mpView->getUnoView(),
+ getLeavingBitmap(ViewEntry((*aCurrView)->mpView))->getXBitmap(),
+ getEnteringBitmap(ViewEntry((*aCurrView)->mpView))->getXBitmap() );
+ ++aCurrView;
+ }
+ }
+
private:
// One transition object per view
- std::vector< uno::Reference<presentation::XTransition> > maTransitions;
-};
+ std::vector< TransitionViewPair* > maTransitions;
+
+ // bool
+ bool mbSuccess;
+ sal_Int16 mnTransitionType;
+ sal_Int16 mnTransitionSubType;
+
+ uno::Reference<presentation::XTransitionFactory> mxFactory;
+};
class ClippedSlideChange : public SlideChangeBase
{
@@ -688,7 +829,7 @@ NumberAnimationSharedPtr createPluginTransition(
const SoundPlayerSharedPtr& pSoundPlayer,
EventMultiplexer& rEventMultiplexer)
{
- return NumberAnimationSharedPtr(
+ PluginSlideChange* pTransition =
new PluginSlideChange(
nTransitionType,
nTransitionSubType,
@@ -698,7 +839,14 @@ NumberAnimationSharedPtr createPluginTransition(
rScreenUpdater,
xFactory,
pSoundPlayer,
- rEventMultiplexer ));
+ rEventMultiplexer );
+
+ if( pTransition->Success() )
+ return NumberAnimationSharedPtr( pTransition );
+ else {
+ delete pTransition;
+ return NumberAnimationSharedPtr();
+ }
}
} // anon namespace
@@ -736,7 +884,7 @@ NumberAnimationSharedPtr TransitionFactory::createSlideTransition(
xOptionalFactory->hasTransition(nTransitionType, nTransitionSubType) )
{
// #i82460# - optional plugin factory claims this transition. delegate.
- return NumberAnimationSharedPtr(
+ NumberAnimationSharedPtr pTransition(
createPluginTransition(
nTransitionType,
nTransitionSubType,
@@ -747,6 +895,9 @@ NumberAnimationSharedPtr TransitionFactory::createSlideTransition(
xOptionalFactory,
pSoundPlayer,
rEventMultiplexer ));
+
+ if( pTransition.get() )
+ return pTransition;
}
const TransitionInfo* pTransitionInfo(