| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include "OGLTrans_TransitionImpl.hxx" |
| #include "OGLTrans_Shaders.hxx" |
| #include <GL/gl.h> |
| #include <math.h> |
| |
| |
| void OGLTransitionImpl::clear() |
| { |
| for(unsigned int i( 0 ); i < OverallOperations.size(); ++i) |
| delete OverallOperations[i]; |
| OverallOperations.clear(); |
| maLeavingSlidePrimitives.clear(); |
| maEnteringSlidePrimitives.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() |
| { |
| clear(); |
| } |
| |
| 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() |
| { |
| for(unsigned int i(0); i < maSceneObjects.size(); ++i) { |
| maSceneObjects[i]->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 ) |
| { |
| double SlideWidthScale, SlideHeightScale; |
| |
| SlideWidthScale = SlideWidth/DispWidth; |
| SlideHeightScale = SlideHeight/DispHeight; |
| |
| if( mmPrepare ) { |
| clear(); |
| (this->*mmPrepare)( nTime, SlideWidth, SlideHeight, DispWidth, DispHeight ); |
| } |
| |
| glPushMatrix(); |
| 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); |
| } |
| |
| 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; |
| |
| /* 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(); |
| |
| applyOperations( nTime, WidthScale, HeightScale ); |
| |
| glEnableClientState( GL_VERTEX_ARRAY ); |
| if(!Normals.empty()) |
| { |
| glNormalPointer( GL_DOUBLE , 0 , &Normals[0] ); |
| glEnableClientState( GL_NORMAL_ARRAY ); |
| } |
| glEnableClientState( GL_TEXTURE_COORD_ARRAY ); |
| glTexCoordPointer( 2, GL_DOUBLE, 0, &TexCoords[0] ); |
| glVertexPointer( 3, GL_DOUBLE, 0, &Vertices[0] ); |
| glDrawArrays( GL_TRIANGLES, 0, Vertices.size() ); |
| 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) |
| delete Operations[i]; |
| } |
| |
| |
| void SceneObject::display(double nTime, double /* SlideWidth */, double /* SlideHeight */, double DispWidth, double DispHeight ) |
| { |
| for(unsigned int i(0); i < maPrimitives.size(); ++i) { |
| // fixme: allow various model spaces, now we make it so that |
| // it is regular -1,-1 to 1,1, where the whole display fits in |
| glPushMatrix(); |
| if (DispHeight > DispWidth) |
| glScaled(DispHeight/DispWidth, 1, 1); |
| else |
| glScaled(1, DispWidth/DispHeight, 1); |
| maPrimitives[i].display(nTime, 1, 1); |
| glPopMatrix(); |
| } |
| } |
| |
| void SceneObject::pushPrimitive(const Primitive &p) |
| { |
| maPrimitives.push_back(p); |
| } |
| |
| SceneObject::SceneObject() |
| : maPrimitives() |
| { |
| } |
| |
| Iris::Iris() |
| : SceneObject () |
| { |
| } |
| |
| void Iris::display(double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight ) |
| { |
| glBindTexture(GL_TEXTURE_2D, maTexture); |
| SceneObject::display(nTime, SlideWidth, SlideHeight, DispWidth, DispHeight); |
| } |
| |
| void Iris::prepare() |
| { |
| static GLubyte img[3] = { 80, 80, 80 }; |
| |
| glGenTextures(1, &maTexture); |
| glBindTexture(GL_TEXTURE_2D, maTexture); |
| glTexImage2D(GL_TEXTURE_2D, 0, 3, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, img); |
| 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); |
| } |
| |
| void Iris::finish() |
| { |
| glDeleteTextures(1, &maTexture); |
| } |
| |
| void OGLTransitionImpl::makeOutsideCubeFaceToLeft() |
| { |
| clear(); |
| 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); |
| |
| Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,-1),90,false,0.0,1.0)); |
| |
| maEnteringSlidePrimitives.push_back(Slide); |
| |
| OverallOperations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,-1),-90,true,0.0,1.0)); |
| } |
| |
| void OGLTransitionImpl::makeInsideCubeFaceToLeft() |
| { |
| clear(); |
| 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); |
| |
| Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,1),-90,false,0.0,1.0)); |
| |
| maEnteringSlidePrimitives.push_back(Slide); |
| |
| OverallOperations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,1),90,true,0.0,1.0)); |
| } |
| |
| void OGLTransitionImpl::makeFallLeaving() |
| { |
| clear(); |
| 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)); |
| maEnteringSlidePrimitives.push_back(Slide); |
| |
| 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() |
| { |
| 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); |
| |
| Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,0),-180,false,0.0,1.0)); |
| maEnteringSlidePrimitives.push_back(Slide); |
| |
| OverallOperations.push_back(new STranslate(basegfx::B3DVector(0, 0, -1.5),true, 0, 0.5)); |
| OverallOperations.push_back(new STranslate(basegfx::B3DVector(0, 0, 1.5), true, 0.5, 1)); |
| OverallOperations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0, 1, 0),basegfx::B3DVector(0, 0, 0), -180, true, 0.0, 1.0)); |
| } |
| |
| void OGLTransitionImpl::makeTurnDown() |
| { |
| clear(); |
| 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); |
| |
| Slide.Operations.push_back(new STranslate(basegfx::B3DVector(0, 0, 0.0001), false, -1.0, 0.0)); |
| 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() |
| { |
| clear(); |
| 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)); |
| maEnteringSlidePrimitives.push_back (Slide); |
| |
| 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); |
| |
| |
| Primitive irisPart, part; |
| int i, nSteps = 24, nParts = 7; |
| double lt = 0, t = 1.0/nSteps, cx, cy, lcx, lcy, lx = 1, ly = 0, x, y, cxo, cyo, lcxo, lcyo, of=2.2, f=1.42; |
| |
| for (i=1; i<=nSteps; i++) { |
| x = cos ((3*2*M_PI*t)/nParts); |
| y = -sin ((3*2*M_PI*t)/nParts); |
| cx = (f*x + 1)/2; |
| cy = (f*y + 1)/2; |
| lcx = (f*lx + 1)/2; |
| lcy = (f*ly + 1)/2; |
| cxo = (of*x + 1)/2; |
| cyo = (of*y + 1)/2; |
| lcxo = (of*lx + 1)/2; |
| lcyo = (of*ly + 1)/2; |
| irisPart.pushTriangle (basegfx::B2DVector (lcx, lcy), |
| basegfx::B2DVector (lcxo, lcyo), |
| basegfx::B2DVector (cx, cy)); |
| irisPart.pushTriangle (basegfx::B2DVector (cx, cy), |
| basegfx::B2DVector (lcxo, lcyo), |
| basegfx::B2DVector (cxo, cyo)); |
| lx = x; |
| ly = y; |
| lt = t; |
| t += 1.0/nSteps; |
| } |
| |
| Iris* pIris = new Iris(); |
| double angle = 87; |
| |
| for (i = 0; i < nParts; i++) { |
| irisPart.Operations.clear (); |
| double rx, ry; |
| |
| rx = cos ((2*M_PI*i)/nParts); |
| ry = sin ((2*M_PI*i)/nParts); |
| irisPart.Operations.push_back (new SRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(rx, ry, 0), angle, true, 0.0, 0.5)); |
| irisPart.Operations.push_back (new SRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(rx, ry, 0), -angle, true, 0.5, 1)); |
| if (i > 0) { |
| irisPart.Operations.push_back (new STranslate (basegfx::B3DVector(rx, ry, 0), false, -1, 0)); |
| irisPart.Operations.push_back (new SRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(0, 0, 0), i*360.0/nParts, false, -1, 0)); |
| irisPart.Operations.push_back (new STranslate (basegfx::B3DVector(-1, 0, 0), false, -1, 0)); |
| } |
| irisPart.Operations.push_back(new STranslate(basegfx::B3DVector(0, 0, 1), false, -2, 0.0)); |
| irisPart.Operations.push_back (new SRotate (basegfx::B3DVector(1, .5, 0), basegfx::B3DVector(1, 0, 0), -30, false, -1, 0)); |
| pIris->pushPrimitive (irisPart); |
| } |
| |
| 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() |
| { |
| clear(); |
| Primitive Slide; |
| |
| mbReflectSlides = true; |
| mmDisplaySlides = &OGLTransitionImpl::displaySlidesRochade; |
| |
| double w, h; |
| |
| w = 2.2; |
| 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)); |
| |
| Slide.Operations.push_back(new SEllipseTranslate(w, h, 0.25, -0.25, true, 0, 1)); |
| Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,0), -45, true, 0, 1)); |
| maLeavingSlidePrimitives.push_back(Slide); |
| |
| Slide.Operations.clear(); |
| Slide.Operations.push_back(new SEllipseTranslate(w, h, 0.75, 0.25, true, 0, 1)); |
| Slide.Operations.push_back(new STranslate(basegfx::B3DVector(0, 0, -h), false, -1, 0)); |
| Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,0), -45, true, 0, 1)); |
| Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,0), 45, false, -1, 0)); |
| maEnteringSlidePrimitives.push_back(Slide); |
| |
| // OverallOperations.push_back(new SEllipseTranslate(0.5, 2, 0, 1, true, 0, 1)); |
| // push_back(new STranslate(basegfx::B3DVector(0, 0, -2), true, 0, 0.5)); |
| // OverallOperations.push_back(new STranslate(basegfx::B3DVector(0, 0, 2), true, 0.5, 1)); |
| } |
| |
| // TODO(Q3): extract to basegfx |
| inline basegfx::B2DVector clamp(const basegfx::B2DVector& v) |
| { |
| return basegfx::B2DVector(min(max(v.getX(),-1.0),1.0), |
| min(max(v.getY(),-1.0),1.0)); |
| } |
| |
| // TODO(Q3): extract to basegfx |
| inline basegfx::B3DVector clamp(const basegfx::B3DVector& v) |
| { |
| return basegfx::B3DVector(min(max(v.getX(),-1.0),1.0), |
| min(max(v.getY(),-1.0),1.0), |
| min(max(v.getZ(),-1.0),1.0)); |
| } |
| |
| inline double randFromNeg1to1() |
| { |
| return ( ( static_cast<double>( rand() ) / static_cast<double>( RAND_MAX ) ) * 2.0 ) - 1.0; |
| } |
| |
| // TODO(Q3): extract to basegfx |
| inline basegfx::B3DVector randNormVectorInXYPlane() |
| { |
| basegfx::B3DVector toReturn(randFromNeg1to1(),randFromNeg1to1(),0.0); |
| return toReturn/toReturn.getLength(); |
| } |
| |
| void OGLTransitionImpl::makeRevolvingCircles( ::sal_uInt16 nCircles , ::sal_uInt16 nPointsOnCircles ) |
| { |
| clear(); |
| double dAngle(2*3.1415926/static_cast<double>( nPointsOnCircles )); |
| if(nCircles < 2 || nPointsOnCircles < 4) |
| { |
| makeNByMTileFlip(1,1); |
| return; |
| } |
| double Radius(1.0/static_cast<double>( nCircles )); |
| double dRadius(Radius); |
| double LastRadius(0.0); |
| double NextRadius(2*Radius); |
| |
| /// now we know there is at least two circles |
| /// the first will always be a full circle |
| /// the last will always be the outer shell of the slide with a circle hole |
| |
| //add the full circle |
| vector<basegfx::B2DVector> unScaledTexCoords; |
| double TempAngle(0.0); |
| for(unsigned int Point(0); Point < nPointsOnCircles; ++Point) |
| { |
| unScaledTexCoords.push_back( basegfx::B2DVector( cos(TempAngle - 3.1415926/2.0) , sin(TempAngle- 3.1415926/2.0) ) ); |
| |
| TempAngle += dAngle; |
| } |
| |
| { |
| //double angle(0.0); |
| Primitive EnteringSlide; |
| Primitive LeavingSlide; |
| for(int Point(0); Point + 1 < nPointsOnCircles; ++Point) |
| { |
| EnteringSlide.pushTriangle( basegfx::B2DVector( 0.5 , 0.5 ) , Radius * unScaledTexCoords[ Point + 1 ] / 2.0 + basegfx::B2DVector( 0.5 , 0.5 ) , Radius * unScaledTexCoords[ Point ] / 2.0 + basegfx::B2DVector( 0.5 , 0.5 ) ); |
| LeavingSlide.pushTriangle( basegfx::B2DVector( 0.5 , 0.5 ) , Radius * unScaledTexCoords[ Point + 1 ] / 2.0 + basegfx::B2DVector( 0.5 , 0.5 ) , Radius * unScaledTexCoords[ Point ] / 2.0 + basegfx::B2DVector( 0.5, 0.5) ); |
| } |
| EnteringSlide.pushTriangle( basegfx::B2DVector(0.5,0.5) , Radius * unScaledTexCoords[ 0 ] / 2.0 + basegfx::B2DVector( 0.5 , 0.5 ) , Radius * unScaledTexCoords[ nPointsOnCircles - 1 ] / 2.0 + basegfx::B2DVector( 0.5 , 0.5 ) ); |
| LeavingSlide.pushTriangle( basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); |
| |
| basegfx::B3DVector axis(randNormVectorInXYPlane()); |
| EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) ); |
| LeavingSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) ); |
| EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , -180, false,0.0,1.0) ); |
| |
| maEnteringSlidePrimitives.push_back(EnteringSlide); |
| maLeavingSlidePrimitives.push_back(LeavingSlide); |
| LastRadius = Radius; |
| Radius = NextRadius; |
| NextRadius += dRadius; |
| } |
| |
| for(int i(1); i < nCircles - 1; ++i) |
| { |
| Primitive LeavingSlide; |
| Primitive EnteringSlide; |
| for(int Side(0); Side < nPointsOnCircles - 1; ++Side) |
| { |
| EnteringSlide.pushTriangle(Radius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); |
| EnteringSlide.pushTriangle(Radius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); |
| |
| LeavingSlide.pushTriangle(Radius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); |
| LeavingSlide.pushTriangle(Radius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); |
| } |
| |
| EnteringSlide.pushTriangle(Radius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); |
| EnteringSlide.pushTriangle(Radius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); |
| |
| LeavingSlide.pushTriangle(Radius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); |
| LeavingSlide.pushTriangle(Radius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); |
| |
| basegfx::B3DVector axis(randNormVectorInXYPlane()); |
| EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) ); |
| LeavingSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) ); |
| EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , -180, false,0.0,1.0) ); |
| |
| maEnteringSlidePrimitives.push_back(EnteringSlide); |
| maLeavingSlidePrimitives.push_back(LeavingSlide); |
| |
| LastRadius = Radius; |
| Radius = NextRadius; |
| NextRadius += dRadius; |
| } |
| { |
| Radius = sqrt(2.0); |
| Primitive LeavingSlide; |
| Primitive EnteringSlide; |
| for(int Side(0); Side < nPointsOnCircles - 1; ++Side) |
| { |
| |
| EnteringSlide.pushTriangle(clamp(Radius*unScaledTexCoords[Side])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); |
| EnteringSlide.pushTriangle(clamp(Radius*unScaledTexCoords[Side])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) , clamp(Radius*unScaledTexCoords[Side + 1])/2.0 + basegfx::B2DVector(0.5,0.5) ); |
| |
| LeavingSlide.pushTriangle(clamp(Radius*unScaledTexCoords[Side])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); |
| LeavingSlide.pushTriangle(clamp(Radius*unScaledTexCoords[Side])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) , clamp(Radius*unScaledTexCoords[Side + 1])/2.0 + basegfx::B2DVector(0.5,0.5) ); |
| } |
| |
| EnteringSlide.pushTriangle(clamp(Radius*unScaledTexCoords[nPointsOnCircles - 1])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); |
| EnteringSlide.pushTriangle(clamp(Radius*unScaledTexCoords[nPointsOnCircles - 1])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) , clamp(Radius*unScaledTexCoords[0])/2.0 + basegfx::B2DVector(0.5,0.5) ); |
| |
| LeavingSlide.pushTriangle(clamp(Radius*unScaledTexCoords[nPointsOnCircles - 1])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); |
| LeavingSlide.pushTriangle(clamp(Radius*unScaledTexCoords[nPointsOnCircles - 1])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) , clamp(Radius*unScaledTexCoords[0])/2.0 + basegfx::B2DVector(0.5,0.5) ); |
| |
| basegfx::B3DVector axis(randNormVectorInXYPlane()); |
| EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, (LastRadius + dRadius)/2.0 , 1.0 ) ); |
| LeavingSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, (LastRadius + dRadius)/2.0 , 1.0 ) ); |
| EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , -180, false,0.0,1.0) ); |
| |
| maEnteringSlidePrimitives.push_back(EnteringSlide); |
| maLeavingSlidePrimitives.push_back(LeavingSlide); |
| } |
| } |
| |
| void OGLTransitionImpl::makeHelix( ::sal_uInt16 nRows ) |
| { |
| clear(); |
| double invN(1.0/static_cast<double>(nRows)); |
| double iDn = 0.0; |
| double iPDn = invN; |
| for(unsigned int i(0); i < nRows; ++i) |
| { |
| Primitive Tile; |
| |
| Tile.pushTriangle(basegfx::B2DVector( 1.0 , iDn ) , basegfx::B2DVector( 0.0 , iDn ) , basegfx::B2DVector( 0.0 , iPDn )); |
| |
| Tile.pushTriangle(basegfx::B2DVector( 1.0 , iPDn ) , basegfx::B2DVector( 1.0 , iDn ) , basegfx::B2DVector( 0.0 , iPDn )); |
| |
| Tile.Operations.push_back( new SRotate( basegfx::B3DVector( 0 , 1 , 0 ) , ( Tile.getVertices()[1] + Tile.getVertices()[3] )/2.0 , 180 , |
| true,min(max(static_cast<double>(i - nRows/2.0)*invN/2.0,0.0),1.0), |
| min(max(static_cast<double>(i + nRows/2.0)*invN/2.0,0.0),1.0) ) ); |
| |
| maLeavingSlidePrimitives.push_back(Tile); |
| |
| Tile.Operations.push_back( new SRotate( basegfx::B3DVector( 0 , 1 , 0 ) , ( Tile.getVertices()[1] + Tile.getVertices()[3] )/2.0 , -180 , false,0.0,1.0) ); |
| |
| maEnteringSlidePrimitives.push_back(Tile); |
| |
| iDn += invN; |
| iPDn += invN; |
| } |
| } |
| |
| void OGLTransitionImpl::makeNByMTileFlip( ::sal_uInt16 n, ::sal_uInt16 m ) |
| { |
| clear(); |
| double invN(1.0/static_cast<double>(n)); |
| double invM(1.0/static_cast<double>(m)); |
| double iDn = 0.0; |
| double iPDn = invN; |
| for(unsigned int i(0); i < n; ++i) |
| { |
| double jDm = 0.0; |
| double jPDm = invM; |
| for(unsigned int j(0); j < m; ++j) |
| { |
| Primitive Tile; |
| |
| Tile.pushTriangle(basegfx::B2DVector( iPDn , jDm ) , basegfx::B2DVector( iDn , jDm ) , basegfx::B2DVector( iDn , jPDm )); |
| |
| Tile.pushTriangle(basegfx::B2DVector( iPDn , jPDm ) , basegfx::B2DVector( iPDn , jDm ) , basegfx::B2DVector( iDn , jPDm ));//bottom left corner of tile |
| |
| Tile.Operations.push_back( new SRotate( basegfx::B3DVector( 1 , 1 , 0 ) , ( Tile.getVertices()[1] + Tile.getVertices()[3] )/2.0 , 180 , true, iDn*jDm/2.0 , ((iPDn*jPDm)+1.0)/2.0 ) ); |
| maLeavingSlidePrimitives.push_back(Tile); |
| Tile.Operations.push_back( new SRotate( basegfx::B3DVector( 1 , 1 , 0 ) , ( Tile.getVertices()[1] + Tile.getVertices()[3] )/2.0 , -180, false, iDn*jDm/2.0 , ((iPDn*jPDm)+1.0)/2.0 ) ); |
| |
| maEnteringSlidePrimitives.push_back(Tile); |
| |
| jDm += invM; |
| jPDm += invM; |
| } |
| iDn += invN; |
| iPDn += invN; |
| } |
| } |
| |
| SRotate::SRotate(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; |
| } |
| |
| SScale::SScale(const basegfx::B3DVector& Scale,const basegfx::B3DVector& Origin, bool bInter, double T0, double T1):scale(Scale),origin(Origin) |
| { |
| nT0 = T0; |
| nT1 = T1; |
| bInterpolate = bInter; |
| } |
| |
| RotateAndScaleDepthByWidth::RotateAndScaleDepthByWidth(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; |
| } |
| |
| 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) |
| { |
| nT0 = T0; |
| nT1 = T1; |
| bInterpolate = bInter; |
| } |
| |
| inline double intervalInter(double t, double T0, double T1) |
| { |
| return ( t - T0 ) / ( T1 - T0 ); |
| } |
| |
| void STranslate::interpolate(double t,double SlideWidthScale,double SlideHeightScale) |
| { |
| if(t <= nT0) |
| return; |
| if(!bInterpolate || t > nT1) |
| t = nT1; |
| t = intervalInter(t,nT0,nT1); |
| glTranslated(SlideWidthScale*t*vector.getX(),SlideHeightScale*t*vector.getY(),t*vector.getZ()); |
| } |
| |
| void SRotate::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(),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()); |
| } |
| |
| void SScale::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(),origin.getZ()); |
| glScaled((1-t) + t*scale.getX(),(1-t) + t*scale.getY(),(1-t) + t*scale.getZ()); |
| glTranslated(-SlideWidthScale*origin.getX(),-SlideHeightScale*origin.getY(),-origin.getZ()); |
| } |
| |
| void RotateAndScaleDepthByWidth::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(),SlideWidthScale*origin.getZ()); |
| glRotated(t*angle,axis.getX(),axis.getY(),axis.getZ()); |
| 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; |
| nT1 = T1; |
| bInterpolate = bInter; |
| width = dWidth; |
| height = dHeight; |
| startPosition = dStartPosition; |
| endPosition = dEndPosition; |
| } |
| |
| void SEllipseTranslate::interpolate(double t,double /* SlideWidthScale */,double /* SlideHeightScale */) |
| { |
| if(t <= nT0) |
| return; |
| if(!bInterpolate || t > nT1) |
| t = nT1; |
| t = intervalInter(t,nT0,nT1); |
| |
| double a1, a2, x, y; |
| a1 = startPosition*2*M_PI; |
| a2 = (startPosition + t*(endPosition - startPosition))*2*M_PI; |
| x = width*(cos (a2) - cos (a1))/2; |
| y = height*(sin (a2) - sin (a1))/2; |
| |
| glTranslated(x, 0, y); |
| } |
| |
| STranslate* STranslate::clone() |
| { |
| return new STranslate(*this); |
| } |
| SRotate* SRotate::clone() |
| { |
| return new SRotate(*this); |
| } |
| |
| SScale* SScale::clone() |
| { |
| return new SScale(*this); |
| } |
| |
| SEllipseTranslate* SEllipseTranslate::clone() |
| { |
| return new SEllipseTranslate(*this); |
| } |
| |
| 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) |
| Operations.push_back(rvalue.Operations[i]->clone()); |
| for(unsigned int i( 0 ); i < rvalue.Vertices.size(); ++i)//SPEED! use copy or something. this is slow. |
| Vertices.push_back(rvalue.Vertices[i]); |
| for(unsigned int i( 0 ); i < rvalue.TexCoords.size(); ++i)//SPEED! use copy or something. this is slow. |
| TexCoords.push_back(rvalue.TexCoords[i]); |
| for(unsigned int i( 0 ); i < rvalue.Normals.size(); ++i)//SPEED! use copy or something. this is slow. |
| Normals.push_back(rvalue.Normals[i]); |
| return *this; |
| } |
| |
| Primitive::Primitive(const Primitive& rvalue) |
| { |
| for(unsigned int i( 0 ); i < rvalue.Operations.size(); ++i) |
| Operations.push_back(rvalue.Operations[i]->clone()); |
| for(unsigned int i( 0 ); i < rvalue.Vertices.size(); ++i)//SPEED! use copy or something. this is slow. |
| Vertices.push_back(rvalue.Vertices[i]); |
| for(unsigned int i( 0 ); i < rvalue.TexCoords.size(); ++i)//SPEED! use copy or something. this is slow. |
| TexCoords.push_back(rvalue.TexCoords[i]); |
| for(unsigned int i( 0 ); i < rvalue.Normals.size(); ++i)//SPEED! use copy or something. this is slow. |
| Normals.push_back(rvalue.Normals[i]); |
| } |
| |
| void Primitive::pushTriangle(const basegfx::B2DVector& SlideLocation0,const basegfx::B2DVector& SlideLocation1,const basegfx::B2DVector& SlideLocation2) |
| { |
| vector<basegfx::B3DVector> Verts; |
| vector<basegfx::B2DVector> Texs; |
| Verts.reserve(3); |
| Texs.reserve(3); |
| |
| Verts.push_back(basegfx::B3DVector( 2*SlideLocation0.getX() - 1, -2*SlideLocation0.getY() + 1 , 0.0 )); |
| Verts.push_back(basegfx::B3DVector( 2*SlideLocation1.getX() - 1, -2*SlideLocation1.getY() + 1 , 0.0 )); |
| Verts.push_back(basegfx::B3DVector( 2*SlideLocation2.getX() - 1, -2*SlideLocation2.getY() + 1 , 0.0 )); |
| |
| //figure out if they're facing the correct way, and make them face the correct way. |
| basegfx::B3DVector Normal( basegfx::cross( Verts[0] - Verts[1] , Verts[1] - Verts[2] ) ); |
| if(Normal.getZ() >= 0.0)//if the normal is facing us |
| { |
| Texs.push_back(SlideLocation0); |
| Texs.push_back(SlideLocation1); |
| Texs.push_back(SlideLocation2); |
| } |
| else // if the normal is facing away from us, make it face us |
| { |
| Texs.push_back(SlideLocation0); |
| Texs.push_back(SlideLocation2); |
| Texs.push_back(SlideLocation1); |
| Verts.clear(); |
| Verts.push_back(basegfx::B3DVector( 2*SlideLocation0.getX() - 1, -2*SlideLocation0.getY() + 1 , 0.0 )); |
| Verts.push_back(basegfx::B3DVector( 2*SlideLocation2.getX() - 1, -2*SlideLocation2.getY() + 1 , 0.0 )); |
| Verts.push_back(basegfx::B3DVector( 2*SlideLocation1.getX() - 1, -2*SlideLocation1.getY() + 1 , 0.0 )); |
| } |
| |
| Vertices.push_back(Verts[0]); |
| Vertices.push_back(Verts[1]); |
| Vertices.push_back(Verts[2]); |
| |
| TexCoords.push_back(Texs[0]); |
| TexCoords.push_back(Texs[1]); |
| TexCoords.push_back(Texs[2]); |
| |
| 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. |
| 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)); |
| } |
| |