Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*************************************************************************
3 : *
4 : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : *
6 : * Copyright 2008 by Sun Microsystems, Inc.
7 : *
8 : * OpenOffice.org - a multi-platform office productivity suite
9 : *
10 : * This file is part of OpenOffice.org.
11 : *
12 : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : * it under the terms of the GNU Lesser General Public License version 3
14 : * only, as published by the Free Software Foundation.
15 : *
16 : * OpenOffice.org is distributed in the hope that it will be useful,
17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : * GNU Lesser General Public License version 3 for more details
20 : * (a copy is included in the LICENSE file that accompanied this code).
21 : *
22 : * You should have received a copy of the GNU Lesser General Public License
23 : * version 3 along with OpenOffice.org. If not, see
24 : * <http://www.openoffice.org/license.html>
25 : * for a copy of the LGPLv3 License.
26 : *
27 : ************************************************************************/
28 :
29 : #include <utility>
30 :
31 : #include <boost/make_shared.hpp>
32 :
33 : #include "OGLTrans_TransitionImpl.hxx"
34 : #include "OGLTrans_Shaders.hxx"
35 : #include <GL/gl.h>
36 : #include <math.h>
37 :
38 : using boost::make_shared;
39 : using boost::shared_ptr;
40 :
41 : using std::max;
42 : using std::min;
43 : using std::vector;
44 :
45 0 : TransitionScene::TransitionScene(TransitionScene const& rOther)
46 : : maLeavingSlidePrimitives(rOther.maLeavingSlidePrimitives)
47 : , maEnteringSlidePrimitives(rOther.maEnteringSlidePrimitives)
48 : , maOverallOperations(rOther.maOverallOperations)
49 0 : , maSceneObjects(rOther.maSceneObjects)
50 : {
51 0 : }
52 :
53 0 : TransitionScene& TransitionScene::operator=(const TransitionScene& rOther)
54 : {
55 0 : TransitionScene aTmp(rOther);
56 0 : swap(aTmp);
57 0 : return *this;
58 : }
59 :
60 0 : void TransitionScene::swap(TransitionScene& rOther)
61 : {
62 : using std::swap;
63 :
64 0 : swap(maLeavingSlidePrimitives, rOther.maLeavingSlidePrimitives);
65 0 : swap(maEnteringSlidePrimitives, rOther.maEnteringSlidePrimitives);
66 0 : swap(maOverallOperations, rOther.maOverallOperations);
67 0 : swap(maSceneObjects, rOther.maSceneObjects);
68 0 : }
69 :
70 0 : void TransitionScene::clear()
71 : {
72 0 : maLeavingSlidePrimitives.clear();
73 0 : maEnteringSlidePrimitives.clear();
74 0 : maOverallOperations.clear();
75 0 : maSceneObjects.clear();
76 0 : }
77 :
78 0 : OGLTransitionImpl::~OGLTransitionImpl()
79 : {
80 0 : }
81 :
82 0 : void OGLTransitionImpl::setScene(TransitionScene const& rScene)
83 : {
84 0 : maScene = rScene;
85 0 : }
86 :
87 0 : void OGLTransitionImpl::prepare( ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex )
88 : {
89 0 : const SceneObjects_t& rSceneObjects(maScene.getSceneObjects());
90 0 : for(unsigned int i(0); i != rSceneObjects.size(); ++i) {
91 0 : rSceneObjects[i]->prepare();
92 : }
93 :
94 0 : prepareTransition_( glLeavingSlideTex, glEnteringSlideTex );
95 0 : }
96 :
97 0 : void OGLTransitionImpl::finish()
98 : {
99 0 : const SceneObjects_t& rSceneObjects(maScene.getSceneObjects());
100 0 : for(unsigned int i(0); i != rSceneObjects.size(); ++i) {
101 0 : rSceneObjects[i]->finish();
102 : }
103 :
104 0 : finishTransition_();
105 0 : }
106 :
107 0 : static void blendSlide( double depth )
108 : {
109 0 : double showHeight = -1 + depth*2;
110 0 : GLfloat reflectionColor[] = {0, 0, 0, 0.25};
111 :
112 0 : glDisable( GL_DEPTH_TEST );
113 0 : glBegin( GL_QUADS );
114 0 : glColor4fv( reflectionColor );
115 0 : glVertex3f( -1, -1, 0 );
116 0 : glColor4f( 0, 0, 0, 1 );
117 0 : glVertex3f(-1, showHeight, 0 );
118 0 : glVertex3f( 1, showHeight, 0 );
119 0 : glColor4fv( reflectionColor );
120 0 : glVertex3f( 1, -1, 0 );
121 0 : glEnd();
122 :
123 0 : glBegin( GL_QUADS );
124 0 : glColor4f( 0, 0, 0, 1 );
125 0 : glVertex3f( -1, showHeight, 0 );
126 0 : glVertex3f( -1, 1, 0 );
127 0 : glVertex3f( 1, 1, 0 );
128 0 : glVertex3f( 1, showHeight, 0 );
129 0 : glEnd();
130 0 : glEnable( GL_DEPTH_TEST );
131 0 : }
132 :
133 0 : static void slideShadow( double nTime, const Primitive& primitive, double sw, double sh )
134 : {
135 0 : double reflectionDepth = 0.3;
136 :
137 0 : glEnable(GL_BLEND);
138 0 : glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
139 0 : glDisable(GL_LIGHTING);
140 :
141 0 : glPushMatrix();
142 0 : primitive.applyOperations( nTime, sw, sh );
143 0 : blendSlide( reflectionDepth );
144 0 : glPopMatrix();
145 :
146 0 : glDisable(GL_BLEND);
147 0 : glEnable(GL_LIGHTING);
148 0 : }
149 :
150 0 : void OGLTransitionImpl::prepare_( double, double, double, double, double )
151 : {
152 0 : }
153 :
154 0 : void OGLTransitionImpl::prepareTransition_( ::sal_Int32, ::sal_Int32 )
155 : {
156 0 : }
157 :
158 0 : void OGLTransitionImpl::finishTransition_()
159 : {
160 0 : }
161 :
162 0 : void OGLTransitionImpl::displaySlides_( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale )
163 : {
164 0 : applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
165 :
166 0 : glEnable(GL_TEXTURE_2D);
167 0 : displaySlide( nTime, glLeavingSlideTex, maScene.getLeavingSlide(), SlideWidthScale, SlideHeightScale );
168 0 : displaySlide( nTime, glEnteringSlideTex, maScene.getEnteringSlide(), SlideWidthScale, SlideHeightScale );
169 0 : }
170 :
171 0 : void OGLTransitionImpl::display( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex,
172 : double SlideWidth, double SlideHeight, double DispWidth, double DispHeight )
173 : {
174 0 : const double SlideWidthScale = SlideWidth/DispWidth;
175 0 : const double SlideHeightScale = SlideHeight/DispHeight;
176 :
177 0 : prepare_( nTime, SlideWidth, SlideHeight, DispWidth, DispHeight );
178 :
179 0 : glPushMatrix();
180 0 : displaySlides_( nTime, glLeavingSlideTex, glEnteringSlideTex, SlideWidthScale, SlideHeightScale );
181 0 : displayScene( nTime, SlideWidth, SlideHeight, DispWidth, DispHeight );
182 0 : glPopMatrix();
183 0 : }
184 :
185 0 : void OGLTransitionImpl::applyOverallOperations( double nTime, double SlideWidthScale, double SlideHeightScale )
186 : {
187 0 : const Operations_t& rOverallOperations(maScene.getOperations());
188 0 : for(unsigned int i(0); i != rOverallOperations.size(); ++i)
189 0 : rOverallOperations[i]->interpolate(nTime,SlideWidthScale,SlideHeightScale);
190 0 : }
191 :
192 : void
193 0 : OGLTransitionImpl::displaySlide(
194 : const double nTime,
195 : const ::sal_Int32 glSlideTex, const Primitives_t& primitives,
196 : double SlideWidthScale, double SlideHeightScale )
197 : {
198 : //TODO change to foreach
199 0 : glBindTexture(GL_TEXTURE_2D, glSlideTex);
200 :
201 : // display slide reflection
202 : // note that depth test is turned off while blending the shadow
203 : // so the slides has to be rendered in right order, see rochade as example
204 0 : if( maSettings.mbReflectSlides ) {
205 0 : double surfaceLevel = -0.04;
206 :
207 : /* reflected slides */
208 0 : glPushMatrix();
209 :
210 0 : glScaled( 1, -1, 1 );
211 0 : glTranslated( 0, 2 - surfaceLevel, 0 );
212 :
213 0 : glCullFace(GL_FRONT);
214 0 : for(unsigned int i(0); i < primitives.size(); ++i)
215 0 : primitives[i].display(nTime, SlideWidthScale, SlideHeightScale);
216 0 : glCullFace(GL_BACK);
217 :
218 0 : slideShadow( nTime, primitives[0], SlideWidthScale, SlideHeightScale );
219 :
220 0 : glPopMatrix();
221 : }
222 :
223 0 : for(unsigned int i(0); i < primitives.size(); ++i)
224 0 : primitives[i].display(nTime, SlideWidthScale, SlideHeightScale);
225 0 : }
226 :
227 0 : void OGLTransitionImpl::displayScene( double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight )
228 : {
229 0 : const SceneObjects_t& rSceneObjects(maScene.getSceneObjects());
230 0 : glEnable(GL_TEXTURE_2D);
231 0 : for(unsigned int i(0); i != rSceneObjects.size(); ++i)
232 0 : rSceneObjects[i]->display(nTime, SlideWidth, SlideHeight, DispWidth, DispHeight);
233 0 : }
234 :
235 0 : void Primitive::display(double nTime, double WidthScale, double HeightScale) const
236 : {
237 0 : glPushMatrix();
238 :
239 0 : applyOperations( nTime, WidthScale, HeightScale );
240 :
241 0 : glEnableClientState( GL_VERTEX_ARRAY );
242 0 : if(!Normals.empty())
243 : {
244 0 : glNormalPointer( GL_DOUBLE , 0 , &Normals[0] );
245 0 : glEnableClientState( GL_NORMAL_ARRAY );
246 : }
247 0 : glEnableClientState( GL_TEXTURE_COORD_ARRAY );
248 0 : glTexCoordPointer( 2, GL_DOUBLE, 0, &TexCoords[0] );
249 0 : glVertexPointer( 3, GL_DOUBLE, 0, &Vertices[0] );
250 0 : glDrawArrays( GL_TRIANGLES, 0, Vertices.size() );
251 0 : glPopMatrix();
252 0 : }
253 :
254 0 : void Primitive::applyOperations(double nTime, double WidthScale, double HeightScale) const
255 : {
256 0 : for(unsigned int i(0); i < Operations.size(); ++i)
257 0 : Operations[i]->interpolate( nTime ,WidthScale,HeightScale);
258 0 : glScaled(WidthScale,HeightScale,1);
259 0 : }
260 :
261 0 : void SceneObject::display(double nTime, double /* SlideWidth */, double /* SlideHeight */, double DispWidth, double DispHeight ) const
262 : {
263 0 : for(unsigned int i(0); i < maPrimitives.size(); ++i) {
264 : // fixme: allow various model spaces, now we make it so that
265 : // it is regular -1,-1 to 1,1, where the whole display fits in
266 0 : glPushMatrix();
267 0 : if (DispHeight > DispWidth)
268 0 : glScaled(DispHeight/DispWidth, 1, 1);
269 : else
270 0 : glScaled(1, DispWidth/DispHeight, 1);
271 0 : maPrimitives[i].display(nTime, 1, 1);
272 0 : glPopMatrix();
273 : }
274 0 : }
275 :
276 0 : void SceneObject::pushPrimitive(const Primitive &p)
277 : {
278 0 : maPrimitives.push_back(p);
279 0 : }
280 :
281 0 : SceneObject::SceneObject()
282 0 : : maPrimitives()
283 : {
284 0 : }
285 :
286 0 : SceneObject::~SceneObject()
287 : {
288 0 : }
289 :
290 0 : Iris::Iris()
291 0 : : SceneObject ()
292 : {
293 0 : }
294 :
295 0 : void Iris::display(double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight ) const
296 : {
297 0 : glBindTexture(GL_TEXTURE_2D, maTexture);
298 0 : SceneObject::display(nTime, SlideWidth, SlideHeight, DispWidth, DispHeight);
299 0 : }
300 :
301 0 : void Iris::prepare()
302 : {
303 : static GLubyte img[3] = { 80, 80, 80 };
304 :
305 0 : glGenTextures(1, &maTexture);
306 0 : glBindTexture(GL_TEXTURE_2D, maTexture);
307 0 : glTexImage2D(GL_TEXTURE_2D, 0, 3, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, img);
308 0 : glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
309 0 : glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
310 0 : glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
311 0 : glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
312 0 : }
313 :
314 0 : void Iris::finish()
315 : {
316 0 : glDeleteTextures(1, &maTexture);
317 0 : }
318 :
319 : namespace
320 : {
321 :
322 0 : class SimpleTransition : public OGLTransitionImpl
323 : {
324 : public:
325 0 : SimpleTransition()
326 0 : : OGLTransitionImpl()
327 : {
328 0 : }
329 :
330 0 : SimpleTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
331 0 : : OGLTransitionImpl(rScene, rSettings)
332 : {
333 0 : }
334 : };
335 :
336 : shared_ptr<OGLTransitionImpl>
337 0 : makeSimpleTransition()
338 : {
339 0 : return make_shared<SimpleTransition>();
340 : }
341 :
342 : shared_ptr<OGLTransitionImpl>
343 0 : makeSimpleTransition(
344 : const Primitives_t& rLeavingSlidePrimitives,
345 : const Primitives_t& rEnteringSlidePrimitives,
346 : const Operations_t& rOverallOperations,
347 : const SceneObjects_t& rSceneObjects,
348 : const TransitionSettings& rSettings = TransitionSettings())
349 : {
350 : return make_shared<SimpleTransition>(
351 : TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives, rOverallOperations, rSceneObjects),
352 0 : rSettings)
353 : ;
354 : }
355 :
356 : shared_ptr<OGLTransitionImpl>
357 0 : makeSimpleTransition(
358 : const Primitives_t& rLeavingSlidePrimitives,
359 : const Primitives_t& rEnteringSlidePrimitives,
360 : const Operations_t& rOverallOperations,
361 : const TransitionSettings& rSettings = TransitionSettings())
362 : {
363 0 : return makeSimpleTransition(rLeavingSlidePrimitives, rEnteringSlidePrimitives, rOverallOperations, SceneObjects_t(), rSettings);
364 : }
365 :
366 : shared_ptr<OGLTransitionImpl>
367 0 : makeSimpleTransition(
368 : const Primitives_t& rLeavingSlidePrimitives,
369 : const Primitives_t& rEnteringSlidePrimitives,
370 : const SceneObjects_t& rSceneObjects,
371 : const TransitionSettings& rSettings = TransitionSettings())
372 : {
373 0 : return makeSimpleTransition(rLeavingSlidePrimitives, rEnteringSlidePrimitives, Operations_t(), rSceneObjects, rSettings);
374 : }
375 :
376 : shared_ptr<OGLTransitionImpl>
377 0 : makeSimpleTransition(
378 : const Primitives_t& rLeavingSlidePrimitives,
379 : const Primitives_t& rEnteringSlidePrimitives,
380 : const TransitionSettings& rSettings = TransitionSettings())
381 : {
382 0 : return makeSimpleTransition(rLeavingSlidePrimitives, rEnteringSlidePrimitives, Operations_t(), SceneObjects_t(), rSettings);
383 : }
384 :
385 : }
386 :
387 0 : boost::shared_ptr<OGLTransitionImpl> makeOutsideCubeFaceToLeft()
388 : {
389 0 : Primitive Slide;
390 :
391 0 : Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1));
392 0 : Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1));
393 :
394 0 : Primitives_t aLeavingPrimitives;
395 0 : aLeavingPrimitives.push_back(Slide);
396 :
397 0 : Slide.Operations.push_back(makeRotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,-1),90,false,0.0,1.0));
398 :
399 0 : Primitives_t aEnteringPrimitives;
400 0 : aEnteringPrimitives.push_back(Slide);
401 :
402 0 : Operations_t aOperations;
403 0 : aOperations.push_back(makeRotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,-1),-90,true,0.0,1.0));
404 :
405 0 : return makeSimpleTransition(aLeavingPrimitives, aEnteringPrimitives, aOperations);
406 : }
407 :
408 0 : boost::shared_ptr<OGLTransitionImpl> makeInsideCubeFaceToLeft()
409 : {
410 0 : Primitive Slide;
411 :
412 0 : Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1));
413 0 : Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1));
414 :
415 0 : Primitives_t aLeavingPrimitives;
416 0 : aLeavingPrimitives.push_back(Slide);
417 :
418 0 : Slide.Operations.push_back(makeRotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,1),-90,false,0.0,1.0));
419 :
420 0 : Primitives_t aEnteringPrimitives;
421 0 : aEnteringPrimitives.push_back(Slide);
422 :
423 0 : Operations_t aOperations;
424 0 : aOperations.push_back(makeRotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,1),90,true,0.0,1.0));
425 :
426 0 : return makeSimpleTransition(aLeavingPrimitives, aEnteringPrimitives, aOperations);
427 : }
428 :
429 0 : boost::shared_ptr<OGLTransitionImpl> makeFallLeaving()
430 : {
431 0 : Primitive Slide;
432 :
433 0 : Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1));
434 0 : Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1));
435 :
436 0 : Primitives_t aEnteringPrimitives;
437 0 : aEnteringPrimitives.push_back(Slide);
438 :
439 0 : Slide.Operations.push_back(makeRotateAndScaleDepthByWidth(basegfx::B3DVector(1,0,0),basegfx::B3DVector(0,-1,0), 90,true,0.0,1.0));
440 0 : Primitives_t aLeavingPrimitives;
441 0 : aLeavingPrimitives.push_back(Slide);
442 :
443 0 : TransitionSettings aSettings;
444 0 : aSettings.mbUseMipMapEntering = false;
445 :
446 0 : return makeSimpleTransition(aLeavingPrimitives, aEnteringPrimitives, aSettings);
447 : }
448 :
449 0 : boost::shared_ptr<OGLTransitionImpl> makeTurnAround()
450 : {
451 0 : Primitive Slide;
452 :
453 0 : TransitionSettings aSettings;
454 0 : aSettings.mbReflectSlides = true;
455 :
456 0 : Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1));
457 0 : Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1));
458 0 : Primitives_t aLeavingPrimitives;
459 0 : aLeavingPrimitives.push_back(Slide);
460 :
461 0 : Slide.Operations.push_back(makeRotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,0),-180,false,0.0,1.0));
462 0 : Primitives_t aEnteringPrimitives;
463 0 : aEnteringPrimitives.push_back(Slide);
464 :
465 0 : Operations_t aOperations;
466 0 : aOperations.push_back(makeSTranslate(basegfx::B3DVector(0, 0, -1.5),true, 0, 0.5));
467 0 : aOperations.push_back(makeSTranslate(basegfx::B3DVector(0, 0, 1.5), true, 0.5, 1));
468 0 : aOperations.push_back(makeRotateAndScaleDepthByWidth(basegfx::B3DVector(0, 1, 0),basegfx::B3DVector(0, 0, 0), -180, true, 0.0, 1.0));
469 :
470 0 : return makeSimpleTransition(aLeavingPrimitives, aEnteringPrimitives, aOperations, aSettings);
471 : }
472 :
473 0 : boost::shared_ptr<OGLTransitionImpl> makeTurnDown()
474 : {
475 0 : Primitive Slide;
476 :
477 0 : Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1));
478 0 : Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1));
479 0 : Primitives_t aLeavingPrimitives;
480 0 : aLeavingPrimitives.push_back(Slide);
481 :
482 0 : Slide.Operations.push_back(makeSTranslate(basegfx::B3DVector(0, 0, 0.0001), false, -1.0, 0.0));
483 0 : Slide.Operations.push_back(makeSRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(-1, 1, 0), -90, true, 0.0, 1.0));
484 0 : Slide.Operations.push_back(makeSRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(-1, 1, 0), 90, false, -1.0, 0.0));
485 0 : Primitives_t aEnteringPrimitives;
486 0 : aEnteringPrimitives.push_back(Slide);
487 :
488 0 : TransitionSettings aSettings;
489 0 : aSettings.mbUseMipMapLeaving = false;
490 :
491 0 : return makeSimpleTransition(aLeavingPrimitives, aEnteringPrimitives, aSettings);
492 : }
493 :
494 0 : boost::shared_ptr<OGLTransitionImpl> makeIris()
495 : {
496 0 : Primitive Slide;
497 :
498 0 : Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1));
499 0 : Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1));
500 0 : Primitives_t aEnteringPrimitives;
501 0 : aEnteringPrimitives.push_back (Slide);
502 :
503 0 : Slide.Operations.push_back (makeSTranslate (basegfx::B3DVector (0, 0, 0.000001), false, -1, 0));
504 0 : Slide.Operations.push_back (makeSTranslate (basegfx::B3DVector (0, 0, -0.000002), false, 0.5, 1));
505 0 : Primitives_t aLeavingPrimitives;
506 0 : aLeavingPrimitives.push_back (Slide);
507 :
508 :
509 0 : Primitive irisPart, part;
510 0 : int i, nSteps = 24, nParts = 7;
511 0 : double t = 1.0/nSteps, cx, cy, lcx, lcy, lx = 1, ly = 0, x, y, cxo, cyo, lcxo, lcyo, of=2.2, f=1.42;
512 :
513 0 : for (i=1; i<=nSteps; i++) {
514 0 : x = cos ((3*2*M_PI*t)/nParts);
515 0 : y = -sin ((3*2*M_PI*t)/nParts);
516 0 : cx = (f*x + 1)/2;
517 0 : cy = (f*y + 1)/2;
518 0 : lcx = (f*lx + 1)/2;
519 0 : lcy = (f*ly + 1)/2;
520 0 : cxo = (of*x + 1)/2;
521 0 : cyo = (of*y + 1)/2;
522 0 : lcxo = (of*lx + 1)/2;
523 0 : lcyo = (of*ly + 1)/2;
524 : irisPart.pushTriangle (basegfx::B2DVector (lcx, lcy),
525 : basegfx::B2DVector (lcxo, lcyo),
526 0 : basegfx::B2DVector (cx, cy));
527 : irisPart.pushTriangle (basegfx::B2DVector (cx, cy),
528 : basegfx::B2DVector (lcxo, lcyo),
529 0 : basegfx::B2DVector (cxo, cyo));
530 0 : lx = x;
531 0 : ly = y;
532 0 : t += 1.0/nSteps;
533 : }
534 :
535 0 : shared_ptr<Iris> pIris = make_shared<Iris>();
536 0 : double angle = 87;
537 :
538 0 : for (i = 0; i < nParts; i++) {
539 0 : irisPart.Operations.clear ();
540 : double rx, ry;
541 :
542 0 : rx = cos ((2*M_PI*i)/nParts);
543 0 : ry = sin ((2*M_PI*i)/nParts);
544 0 : irisPart.Operations.push_back (makeSRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(rx, ry, 0), angle, true, 0.0, 0.5));
545 0 : irisPart.Operations.push_back (makeSRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(rx, ry, 0), -angle, true, 0.5, 1));
546 0 : if (i > 0) {
547 0 : irisPart.Operations.push_back (makeSTranslate (basegfx::B3DVector(rx, ry, 0), false, -1, 0));
548 0 : irisPart.Operations.push_back (makeSRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(0, 0, 0), i*360.0/nParts, false, -1, 0));
549 0 : irisPart.Operations.push_back (makeSTranslate (basegfx::B3DVector(-1, 0, 0), false, -1, 0));
550 : }
551 0 : irisPart.Operations.push_back(makeSTranslate(basegfx::B3DVector(0, 0, 1), false, -2, 0.0));
552 0 : irisPart.Operations.push_back (makeSRotate (basegfx::B3DVector(1, .5, 0), basegfx::B3DVector(1, 0, 0), -30, false, -1, 0));
553 0 : pIris->pushPrimitive (irisPart);
554 : }
555 :
556 0 : SceneObjects_t aSceneObjects;
557 0 : aSceneObjects.push_back (pIris);
558 :
559 0 : TransitionSettings aSettings;
560 0 : aSettings.mbUseMipMapLeaving = aSettings.mbUseMipMapEntering = false;
561 :
562 0 : return makeSimpleTransition(aLeavingPrimitives, aEnteringPrimitives, aSceneObjects, aSettings);
563 : }
564 :
565 : namespace
566 : {
567 :
568 0 : class RochadeTransition : public OGLTransitionImpl
569 : {
570 : public:
571 0 : RochadeTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
572 0 : : OGLTransitionImpl(rScene, rSettings)
573 0 : {}
574 :
575 : private:
576 : virtual void displaySlides_( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale );
577 : };
578 :
579 0 : void RochadeTransition::displaySlides_( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale )
580 : {
581 0 : applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
582 :
583 0 : glEnable(GL_TEXTURE_2D);
584 :
585 0 : if( nTime > .5) {
586 0 : displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale );
587 0 : displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale );
588 : } else {
589 0 : displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale );
590 0 : displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale );
591 : }
592 0 : }
593 :
594 : shared_ptr<OGLTransitionImpl>
595 0 : makeRochadeTransition(
596 : const Primitives_t& rLeavingSlidePrimitives,
597 : const Primitives_t& rEnteringSlidePrimitives,
598 : const TransitionSettings& rSettings)
599 : {
600 : return make_shared<RochadeTransition>(
601 : TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives),
602 0 : rSettings)
603 : ;
604 :
605 : }
606 : }
607 :
608 0 : boost::shared_ptr<OGLTransitionImpl> makeRochade()
609 : {
610 0 : Primitive Slide;
611 :
612 0 : TransitionSettings aSettings;
613 0 : aSettings.mbReflectSlides = true;
614 :
615 : double w, h;
616 :
617 0 : w = 2.2;
618 0 : h = 10;
619 :
620 0 : Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1));
621 0 : Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1));
622 :
623 0 : Slide.Operations.push_back(makeSEllipseTranslate(w, h, 0.25, -0.25, true, 0, 1));
624 0 : Slide.Operations.push_back(makeRotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,0), -45, true, 0, 1));
625 0 : Primitives_t aLeavingSlide;
626 0 : aLeavingSlide.push_back(Slide);
627 :
628 0 : Slide.Operations.clear();
629 0 : Slide.Operations.push_back(makeSEllipseTranslate(w, h, 0.75, 0.25, true, 0, 1));
630 0 : Slide.Operations.push_back(makeSTranslate(basegfx::B3DVector(0, 0, -h), false, -1, 0));
631 0 : Slide.Operations.push_back(makeRotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,0), -45, true, 0, 1));
632 0 : Slide.Operations.push_back(makeRotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,0), 45, false, -1, 0));
633 0 : Primitives_t aEnteringSlide;
634 0 : aEnteringSlide.push_back(Slide);
635 :
636 0 : return makeRochadeTransition(aLeavingSlide, aEnteringSlide, aSettings);
637 : }
638 :
639 : // TODO(Q3): extract to basegfx
640 0 : inline basegfx::B2DVector clamp(const basegfx::B2DVector& v)
641 : {
642 0 : return basegfx::B2DVector(min(max(v.getX(),-1.0),1.0),
643 0 : min(max(v.getY(),-1.0),1.0));
644 : }
645 :
646 : // TODO(Q3): extract to basegfx
647 : inline basegfx::B3DVector clamp(const basegfx::B3DVector& v)
648 : {
649 : return basegfx::B3DVector(min(max(v.getX(),-1.0),1.0),
650 : min(max(v.getY(),-1.0),1.0),
651 : min(max(v.getZ(),-1.0),1.0));
652 : }
653 :
654 0 : inline double randFromNeg1to1()
655 : {
656 0 : return ( ( static_cast<double>( rand() ) / static_cast<double>( RAND_MAX ) ) * 2.0 ) - 1.0;
657 : }
658 :
659 : // TODO(Q3): extract to basegfx
660 0 : inline basegfx::B3DVector randNormVectorInXYPlane()
661 : {
662 0 : basegfx::B3DVector toReturn(randFromNeg1to1(),randFromNeg1to1(),0.0);
663 0 : return toReturn/toReturn.getLength();
664 : }
665 :
666 0 : boost::shared_ptr<OGLTransitionImpl> makeRevolvingCircles( ::sal_uInt16 nCircles , ::sal_uInt16 nPointsOnCircles )
667 : {
668 0 : double dAngle(2*3.1415926/static_cast<double>( nPointsOnCircles ));
669 0 : if(nCircles < 2 || nPointsOnCircles < 4)
670 : {
671 0 : makeNByMTileFlip(1,1);
672 0 : return makeSimpleTransition();
673 : }
674 0 : double Radius(1.0/static_cast<double>( nCircles ));
675 0 : double dRadius(Radius);
676 0 : double LastRadius(0.0);
677 0 : double NextRadius(2*Radius);
678 :
679 : /// now we know there is at least two circles
680 : /// the first will always be a full circle
681 : /// the last will always be the outer shell of the slide with a circle hole
682 :
683 : //add the full circle
684 0 : vector<basegfx::B2DVector> unScaledTexCoords;
685 0 : double TempAngle(0.0);
686 0 : for(unsigned int Point(0); Point < nPointsOnCircles; ++Point)
687 : {
688 0 : unScaledTexCoords.push_back( basegfx::B2DVector( cos(TempAngle - 3.1415926/2.0) , sin(TempAngle- 3.1415926/2.0) ) );
689 :
690 0 : TempAngle += dAngle;
691 : }
692 :
693 0 : Primitives_t aLeavingSlide;
694 0 : Primitives_t aEnteringSlide;
695 : {
696 0 : Primitive EnteringSlide;
697 0 : Primitive LeavingSlide;
698 0 : for(int Point(0); Point + 1 < nPointsOnCircles; ++Point)
699 : {
700 0 : 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 ) );
701 0 : 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) );
702 : }
703 0 : 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 ) );
704 0 : 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) );
705 :
706 0 : basegfx::B3DVector axis(randNormVectorInXYPlane());
707 0 : EnteringSlide.Operations.push_back( makeSRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) );
708 0 : LeavingSlide.Operations.push_back( makeSRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) );
709 0 : EnteringSlide.Operations.push_back( makeSRotate( axis , basegfx::B3DVector(0,0,0) , -180, false,0.0,1.0) );
710 :
711 0 : aEnteringSlide.push_back(EnteringSlide);
712 0 : aLeavingSlide.push_back(LeavingSlide);
713 0 : LastRadius = Radius;
714 0 : Radius = NextRadius;
715 0 : NextRadius += dRadius;
716 : }
717 :
718 0 : for(int i(1); i < nCircles - 1; ++i)
719 : {
720 0 : Primitive LeavingSlide;
721 0 : Primitive EnteringSlide;
722 0 : for(int Side(0); Side < nPointsOnCircles - 1; ++Side)
723 : {
724 0 : 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) );
725 0 : 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) );
726 :
727 0 : 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) );
728 0 : 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) );
729 : }
730 :
731 0 : 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) );
732 0 : 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) );
733 :
734 0 : 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) );
735 0 : 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) );
736 :
737 0 : basegfx::B3DVector axis(randNormVectorInXYPlane());
738 0 : EnteringSlide.Operations.push_back( makeSRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) );
739 0 : LeavingSlide.Operations.push_back( makeSRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) );
740 0 : EnteringSlide.Operations.push_back( makeSRotate( axis , basegfx::B3DVector(0,0,0) , -180, false,0.0,1.0) );
741 :
742 0 : aEnteringSlide.push_back(EnteringSlide);
743 0 : aLeavingSlide.push_back(LeavingSlide);
744 :
745 0 : LastRadius = Radius;
746 0 : Radius = NextRadius;
747 0 : NextRadius += dRadius;
748 0 : }
749 : {
750 0 : Radius = sqrt(2.0);
751 0 : Primitive LeavingSlide;
752 0 : Primitive EnteringSlide;
753 0 : for(int Side(0); Side < nPointsOnCircles - 1; ++Side)
754 : {
755 :
756 0 : 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) );
757 0 : 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) );
758 :
759 0 : 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) );
760 0 : 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) );
761 : }
762 :
763 0 : 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) );
764 0 : 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) );
765 :
766 0 : 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) );
767 0 : 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) );
768 :
769 0 : basegfx::B3DVector axis(randNormVectorInXYPlane());
770 0 : EnteringSlide.Operations.push_back( makeSRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, (LastRadius + dRadius)/2.0 , 1.0 ) );
771 0 : LeavingSlide.Operations.push_back( makeSRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, (LastRadius + dRadius)/2.0 , 1.0 ) );
772 0 : EnteringSlide.Operations.push_back( makeSRotate( axis , basegfx::B3DVector(0,0,0) , -180, false,0.0,1.0) );
773 :
774 0 : aEnteringSlide.push_back(EnteringSlide);
775 0 : aLeavingSlide.push_back(LeavingSlide);
776 : }
777 :
778 0 : return makeSimpleTransition(aLeavingSlide, aEnteringSlide);
779 : }
780 :
781 0 : boost::shared_ptr<OGLTransitionImpl> makeHelix( ::sal_uInt16 nRows )
782 : {
783 0 : double invN(1.0/static_cast<double>(nRows));
784 0 : double iDn = 0.0;
785 0 : double iPDn = invN;
786 0 : Primitives_t aLeavingSlide;
787 0 : Primitives_t aEnteringSlide;
788 0 : for(unsigned int i(0); i < nRows; ++i)
789 : {
790 0 : Primitive Tile;
791 :
792 0 : Tile.pushTriangle(basegfx::B2DVector( 1.0 , iDn ) , basegfx::B2DVector( 0.0 , iDn ) , basegfx::B2DVector( 0.0 , iPDn ));
793 :
794 0 : Tile.pushTriangle(basegfx::B2DVector( 1.0 , iPDn ) , basegfx::B2DVector( 1.0 , iDn ) , basegfx::B2DVector( 0.0 , iPDn ));
795 :
796 0 : Tile.Operations.push_back( makeSRotate( basegfx::B3DVector( 0 , 1 , 0 ) , ( Tile.getVertices()[1] + Tile.getVertices()[3] )/2.0 , 180 ,
797 0 : true,min(max(static_cast<double>(i - nRows/2.0)*invN/2.0,0.0),1.0),
798 0 : min(max(static_cast<double>(i + nRows/2.0)*invN/2.0,0.0),1.0) ) );
799 :
800 0 : aLeavingSlide.push_back(Tile);
801 :
802 0 : Tile.Operations.push_back( makeSRotate( basegfx::B3DVector( 0 , 1 , 0 ) , ( Tile.getVertices()[1] + Tile.getVertices()[3] )/2.0 , -180 , false,0.0,1.0) );
803 :
804 0 : aEnteringSlide.push_back(Tile);
805 :
806 0 : iDn += invN;
807 0 : iPDn += invN;
808 0 : }
809 :
810 0 : return makeSimpleTransition(aLeavingSlide, aEnteringSlide);
811 : }
812 :
813 0 : boost::shared_ptr<OGLTransitionImpl> makeNByMTileFlip( ::sal_uInt16 n, ::sal_uInt16 m )
814 : {
815 0 : double invN(1.0/static_cast<double>(n));
816 0 : double invM(1.0/static_cast<double>(m));
817 0 : double iDn = 0.0;
818 0 : double iPDn = invN;
819 0 : Primitives_t aLeavingSlide;
820 0 : Primitives_t aEnteringSlide;
821 0 : for(unsigned int i(0); i < n; ++i)
822 : {
823 0 : double jDm = 0.0;
824 0 : double jPDm = invM;
825 0 : for(unsigned int j(0); j < m; ++j)
826 : {
827 0 : Primitive Tile;
828 :
829 0 : Tile.pushTriangle(basegfx::B2DVector( iPDn , jDm ) , basegfx::B2DVector( iDn , jDm ) , basegfx::B2DVector( iDn , jPDm ));
830 :
831 0 : Tile.pushTriangle(basegfx::B2DVector( iPDn , jPDm ) , basegfx::B2DVector( iPDn , jDm ) , basegfx::B2DVector( iDn , jPDm ));//bottom left corner of tile
832 :
833 0 : Tile.Operations.push_back( makeSRotate( 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 ) );
834 0 : aLeavingSlide.push_back(Tile);
835 0 : Tile.Operations.push_back( makeSRotate( 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 ) );
836 :
837 0 : aEnteringSlide.push_back(Tile);
838 :
839 0 : jDm += invM;
840 0 : jPDm += invM;
841 0 : }
842 0 : iDn += invN;
843 0 : iPDn += invN;
844 : }
845 :
846 0 : return makeSimpleTransition(aLeavingSlide, aEnteringSlide);
847 : }
848 :
849 0 : SRotate::SRotate(const basegfx::B3DVector& Axis,const basegfx::B3DVector& Origin,double Angle, bool bInter, double T0, double T1):axis(Axis),origin(Origin),angle(Angle)
850 : {
851 0 : nT0 = T0;
852 0 : nT1 = T1;
853 0 : bInterpolate = bInter;
854 0 : }
855 :
856 0 : SScale::SScale(const basegfx::B3DVector& Scale,const basegfx::B3DVector& Origin, bool bInter, double T0, double T1):scale(Scale),origin(Origin)
857 : {
858 0 : nT0 = T0;
859 0 : nT1 = T1;
860 0 : bInterpolate = bInter;
861 0 : }
862 :
863 0 : RotateAndScaleDepthByWidth::RotateAndScaleDepthByWidth(const basegfx::B3DVector& Axis,const basegfx::B3DVector& Origin,double Angle, bool bInter, double T0, double T1):axis(Axis),origin(Origin),angle(Angle)
864 : {
865 0 : nT0 = T0;
866 0 : nT1 = T1;
867 0 : bInterpolate = bInter;
868 0 : }
869 :
870 0 : RotateAndScaleDepthByHeight::RotateAndScaleDepthByHeight(const basegfx::B3DVector& Axis,const basegfx::B3DVector& Origin,double Angle, bool bInter, double T0, double T1):axis(Axis),origin(Origin),angle(Angle)
871 : {
872 0 : nT0 = T0;
873 0 : nT1 = T1;
874 0 : bInterpolate = bInter;
875 0 : }
876 :
877 :
878 0 : STranslate::STranslate(const basegfx::B3DVector& Vector, bool bInter, double T0, double T1):vector(Vector)
879 : {
880 0 : nT0 = T0;
881 0 : nT1 = T1;
882 0 : bInterpolate = bInter;
883 0 : }
884 :
885 : boost::shared_ptr<SRotate>
886 0 : makeSRotate(const basegfx::B3DVector& Axis,const basegfx::B3DVector& Origin,double Angle,bool bInter, double T0, double T1)
887 : {
888 0 : return make_shared<SRotate>(Axis, Origin, Angle, bInter, T0, T1);
889 : }
890 :
891 : boost::shared_ptr<SScale>
892 0 : makeSScale(const basegfx::B3DVector& Scale, const basegfx::B3DVector& Origin,bool bInter, double T0, double T1)
893 : {
894 0 : return make_shared<SScale>(Scale, Origin, bInter, T0, T1);
895 : }
896 :
897 : boost::shared_ptr<STranslate>
898 0 : makeSTranslate(const basegfx::B3DVector& Vector,bool bInter, double T0, double T1)
899 : {
900 0 : return make_shared<STranslate>(Vector, bInter, T0, T1);
901 : }
902 :
903 : boost::shared_ptr<SEllipseTranslate>
904 0 : makeSEllipseTranslate(double dWidth, double dHeight, double dStartPosition, double dEndPosition, bool bInter, double T0, double T1)
905 : {
906 0 : return make_shared<SEllipseTranslate>(dWidth, dHeight, dStartPosition, dEndPosition, bInter, T0, T1);
907 : }
908 :
909 : boost::shared_ptr<RotateAndScaleDepthByWidth>
910 0 : makeRotateAndScaleDepthByWidth(const basegfx::B3DVector& Axis,const basegfx::B3DVector& Origin,double Angle,bool bInter, double T0, double T1)
911 : {
912 0 : return make_shared<RotateAndScaleDepthByWidth>(Axis, Origin, Angle, bInter, T0, T1);
913 : }
914 :
915 : boost::shared_ptr<RotateAndScaleDepthByHeight>
916 0 : makeRotateAndScaleDepthByHeight(const basegfx::B3DVector& Axis,const basegfx::B3DVector& Origin,double Angle,bool bInter, double T0, double T1)
917 : {
918 0 : return make_shared<RotateAndScaleDepthByHeight>(Axis, Origin, Angle, bInter, T0, T1);
919 : }
920 :
921 0 : inline double intervalInter(double t, double T0, double T1)
922 : {
923 0 : return ( t - T0 ) / ( T1 - T0 );
924 : }
925 :
926 0 : void STranslate::interpolate(double t,double SlideWidthScale,double SlideHeightScale) const
927 : {
928 0 : if(t <= nT0)
929 0 : return;
930 0 : if(!bInterpolate || t > nT1)
931 0 : t = nT1;
932 0 : t = intervalInter(t,nT0,nT1);
933 0 : glTranslated(SlideWidthScale*t*vector.getX(),SlideHeightScale*t*vector.getY(),t*vector.getZ());
934 : }
935 :
936 0 : void SRotate::interpolate(double t,double SlideWidthScale,double SlideHeightScale) const
937 : {
938 0 : if(t <= nT0)
939 0 : return;
940 0 : if(!bInterpolate || t > nT1)
941 0 : t = nT1;
942 0 : t = intervalInter(t,nT0,nT1);
943 0 : glTranslated(SlideWidthScale*origin.getX(),SlideHeightScale*origin.getY(),origin.getZ());
944 0 : glScaled(SlideWidthScale,SlideHeightScale,1);
945 0 : glRotated(t*angle,axis.getX(),axis.getY(),axis.getZ());
946 0 : glScaled(1/SlideWidthScale,1/SlideHeightScale,1);
947 0 : glTranslated(-SlideWidthScale*origin.getX(),-SlideHeightScale*origin.getY(),-origin.getZ());
948 : }
949 :
950 0 : void SScale::interpolate(double t,double SlideWidthScale,double SlideHeightScale) const
951 : {
952 0 : if(t <= nT0)
953 0 : return;
954 0 : if(!bInterpolate || t > nT1)
955 0 : t = nT1;
956 0 : t = intervalInter(t,nT0,nT1);
957 0 : glTranslated(SlideWidthScale*origin.getX(),SlideHeightScale*origin.getY(),origin.getZ());
958 0 : glScaled((1-t) + t*scale.getX(),(1-t) + t*scale.getY(),(1-t) + t*scale.getZ());
959 0 : glTranslated(-SlideWidthScale*origin.getX(),-SlideHeightScale*origin.getY(),-origin.getZ());
960 : }
961 :
962 0 : void RotateAndScaleDepthByWidth::interpolate(double t,double SlideWidthScale,double SlideHeightScale) const
963 : {
964 0 : if(t <= nT0)
965 0 : return;
966 0 : if(!bInterpolate || t > nT1)
967 0 : t = nT1;
968 0 : t = intervalInter(t,nT0,nT1);
969 0 : glTranslated(SlideWidthScale*origin.getX(),SlideHeightScale*origin.getY(),SlideWidthScale*origin.getZ());
970 0 : glRotated(t*angle,axis.getX(),axis.getY(),axis.getZ());
971 0 : glTranslated(-SlideWidthScale*origin.getX(),-SlideHeightScale*origin.getY(),-SlideWidthScale*origin.getZ());
972 : }
973 :
974 0 : void RotateAndScaleDepthByHeight::interpolate(double t,double SlideWidthScale,double SlideHeightScale) const
975 : {
976 0 : if(t <= nT0)
977 0 : return;
978 0 : if(!bInterpolate || t > nT1)
979 0 : t = nT1;
980 0 : t = intervalInter(t,nT0,nT1);
981 0 : glTranslated(SlideWidthScale*origin.getX(),SlideHeightScale*origin.getY(),SlideHeightScale*origin.getZ());
982 0 : glRotated(t*angle,axis.getX(),axis.getY(),axis.getZ());
983 0 : glTranslated(-SlideWidthScale*origin.getX(),-SlideHeightScale*origin.getY(),-SlideHeightScale*origin.getZ());
984 : }
985 :
986 0 : SEllipseTranslate::SEllipseTranslate(double dWidth, double dHeight, double dStartPosition, double dEndPosition, bool bInter, double T0, double T1)
987 : {
988 0 : nT0 = T0;
989 0 : nT1 = T1;
990 0 : bInterpolate = bInter;
991 0 : width = dWidth;
992 0 : height = dHeight;
993 0 : startPosition = dStartPosition;
994 0 : endPosition = dEndPosition;
995 0 : }
996 :
997 0 : void SEllipseTranslate::interpolate(double t,double /* SlideWidthScale */,double /* SlideHeightScale */) const
998 : {
999 0 : if(t <= nT0)
1000 0 : return;
1001 0 : if(!bInterpolate || t > nT1)
1002 0 : t = nT1;
1003 0 : t = intervalInter(t,nT0,nT1);
1004 :
1005 : double a1, a2, x, y;
1006 0 : a1 = startPosition*2*M_PI;
1007 0 : a2 = (startPosition + t*(endPosition - startPosition))*2*M_PI;
1008 0 : x = width*(cos (a2) - cos (a1))/2;
1009 0 : y = height*(sin (a2) - sin (a1))/2;
1010 :
1011 0 : glTranslated(x, 0, y);
1012 : }
1013 :
1014 0 : const Primitive& Primitive::operator=(const Primitive& rvalue)
1015 : {
1016 0 : Primitive aTmp(rvalue);
1017 0 : swap(aTmp);
1018 0 : return *this;
1019 : }
1020 :
1021 0 : Primitive::Primitive(const Primitive& rvalue)
1022 : : Operations(rvalue.Operations)
1023 : , Vertices(rvalue.Vertices)
1024 : , Normals(rvalue.Normals)
1025 0 : , TexCoords(rvalue.TexCoords)
1026 : {
1027 0 : }
1028 :
1029 0 : void Primitive::swap(Primitive& rOther)
1030 : {
1031 : using std::swap;
1032 :
1033 0 : swap(Operations, rOther.Operations);
1034 0 : swap(Vertices, rOther.Vertices);
1035 0 : swap(Normals, rOther.Normals);
1036 0 : swap(TexCoords, rOther.TexCoords);
1037 0 : }
1038 :
1039 0 : void Primitive::pushTriangle(const basegfx::B2DVector& SlideLocation0,const basegfx::B2DVector& SlideLocation1,const basegfx::B2DVector& SlideLocation2)
1040 : {
1041 0 : vector<basegfx::B3DVector> Verts;
1042 0 : vector<basegfx::B2DVector> Texs;
1043 0 : Verts.reserve(3);
1044 0 : Texs.reserve(3);
1045 :
1046 0 : Verts.push_back(basegfx::B3DVector( 2*SlideLocation0.getX() - 1, -2*SlideLocation0.getY() + 1 , 0.0 ));
1047 0 : Verts.push_back(basegfx::B3DVector( 2*SlideLocation1.getX() - 1, -2*SlideLocation1.getY() + 1 , 0.0 ));
1048 0 : Verts.push_back(basegfx::B3DVector( 2*SlideLocation2.getX() - 1, -2*SlideLocation2.getY() + 1 , 0.0 ));
1049 :
1050 : //figure out if they're facing the correct way, and make them face the correct way.
1051 0 : basegfx::B3DVector Normal( basegfx::cross( Verts[0] - Verts[1] , Verts[1] - Verts[2] ) );
1052 0 : if(Normal.getZ() >= 0.0)//if the normal is facing us
1053 : {
1054 0 : Texs.push_back(SlideLocation0);
1055 0 : Texs.push_back(SlideLocation1);
1056 0 : Texs.push_back(SlideLocation2);
1057 : }
1058 : else // if the normal is facing away from us, make it face us
1059 : {
1060 0 : Texs.push_back(SlideLocation0);
1061 0 : Texs.push_back(SlideLocation2);
1062 0 : Texs.push_back(SlideLocation1);
1063 0 : Verts.clear();
1064 0 : Verts.push_back(basegfx::B3DVector( 2*SlideLocation0.getX() - 1, -2*SlideLocation0.getY() + 1 , 0.0 ));
1065 0 : Verts.push_back(basegfx::B3DVector( 2*SlideLocation2.getX() - 1, -2*SlideLocation2.getY() + 1 , 0.0 ));
1066 0 : Verts.push_back(basegfx::B3DVector( 2*SlideLocation1.getX() - 1, -2*SlideLocation1.getY() + 1 , 0.0 ));
1067 : }
1068 :
1069 0 : Vertices.push_back(Verts[0]);
1070 0 : Vertices.push_back(Verts[1]);
1071 0 : Vertices.push_back(Verts[2]);
1072 :
1073 0 : TexCoords.push_back(Texs[0]);
1074 0 : TexCoords.push_back(Texs[1]);
1075 0 : TexCoords.push_back(Texs[2]);
1076 :
1077 0 : Normals.push_back(basegfx::B3DVector(0,0,1));//all normals always face the screen when untransformed.
1078 0 : Normals.push_back(basegfx::B3DVector(0,0,1));//all normals always face the screen when untransformed.
1079 0 : Normals.push_back(basegfx::B3DVector(0,0,1));//all normals always face the screen when untransformed.
1080 0 : }
1081 :
1082 : namespace
1083 : {
1084 :
1085 0 : class DiamondTransition : public OGLTransitionImpl
1086 : {
1087 : public:
1088 0 : DiamondTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1089 0 : : OGLTransitionImpl(rScene, rSettings)
1090 0 : {}
1091 :
1092 : private:
1093 : virtual void prepare_( double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight );
1094 : // mmPrepare = &OGLTransitionImpl::prepareDiamond;
1095 : };
1096 :
1097 0 : void DiamondTransition::prepare_( double nTime, double /* SlideWidth */, double /* SlideHeight */, double /* DispWidth */, double /* DispHeight */ )
1098 : {
1099 0 : Primitive Slide1, Slide2;
1100 :
1101 0 : Slide1.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1));
1102 0 : Slide1.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1));
1103 0 : Primitives_t aEnteringSlidePrimitives;
1104 0 : aEnteringSlidePrimitives.push_back (Slide1);
1105 :
1106 0 : if( nTime >= 0.5 ) {
1107 0 : double m = 1 - nTime;
1108 :
1109 0 : Slide2.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (m,0), basegfx::B2DVector (0,m));
1110 0 : Slide2.pushTriangle (basegfx::B2DVector (nTime,0), basegfx::B2DVector (1,0), basegfx::B2DVector (1,m));
1111 0 : Slide2.pushTriangle (basegfx::B2DVector (1,nTime), basegfx::B2DVector (1,1), basegfx::B2DVector (nTime,1));
1112 0 : Slide2.pushTriangle (basegfx::B2DVector (0,nTime), basegfx::B2DVector (m,1), basegfx::B2DVector (0,1));
1113 : } else {
1114 0 : double l = 0.5 - nTime;
1115 0 : double h = 0.5 + nTime;
1116 :
1117 0 : Slide2.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0.5,l));
1118 0 : Slide2.pushTriangle (basegfx::B2DVector (0.5,l), basegfx::B2DVector (1,0), basegfx::B2DVector (h,0.5));
1119 0 : Slide2.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (1,1), basegfx::B2DVector (h,0.5));
1120 0 : Slide2.pushTriangle (basegfx::B2DVector (h,0.5), basegfx::B2DVector (1,1), basegfx::B2DVector (0.5,h));
1121 0 : Slide2.pushTriangle (basegfx::B2DVector (0.5,h), basegfx::B2DVector (1,1), basegfx::B2DVector (0,1));
1122 0 : Slide2.pushTriangle (basegfx::B2DVector (l,0.5), basegfx::B2DVector (0.5,h), basegfx::B2DVector (0,1));
1123 0 : Slide2.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (l,0.5), basegfx::B2DVector (0,1));
1124 0 : Slide2.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (0.5,l), basegfx::B2DVector (l,0.5));
1125 : }
1126 0 : Slide2.Operations.push_back (makeSTranslate (basegfx::B3DVector (0, 0, 0.00000001), false, -1, 0));
1127 0 : Primitives_t aLeavingSlidePrimitives;
1128 0 : aLeavingSlidePrimitives.push_back (Slide2);
1129 :
1130 0 : setScene(TransitionScene(aLeavingSlidePrimitives, aEnteringSlidePrimitives));
1131 0 : }
1132 :
1133 : shared_ptr<OGLTransitionImpl>
1134 0 : makeDiamondTransition(const TransitionSettings& rSettings)
1135 : {
1136 0 : return make_shared<DiamondTransition>(TransitionScene(), rSettings);
1137 : }
1138 :
1139 : }
1140 :
1141 0 : boost::shared_ptr<OGLTransitionImpl> makeDiamond()
1142 : {
1143 0 : TransitionSettings aSettings;
1144 0 : aSettings.mbUseMipMapLeaving = aSettings.mbUseMipMapEntering = false;
1145 :
1146 0 : return makeDiamondTransition(aSettings);
1147 : }
1148 :
1149 0 : boost::shared_ptr<OGLTransitionImpl> makeVenetianBlinds( bool vertical, int parts )
1150 : {
1151 : static double t30 = tan( M_PI/6.0 );
1152 0 : double n, ln = 0;
1153 0 : double p = 1.0/parts;
1154 :
1155 0 : Primitives_t aLeavingSlide;
1156 0 : Primitives_t aEnteringSlide;
1157 0 : for( int i=0; i<parts; i++ ) {
1158 0 : Primitive Slide;
1159 0 : n = (i + 1)/(double)parts;
1160 0 : if( vertical ) {
1161 0 : Slide.pushTriangle (basegfx::B2DVector (ln,0), basegfx::B2DVector (n,0), basegfx::B2DVector (ln,1));
1162 0 : Slide.pushTriangle (basegfx::B2DVector (n,0), basegfx::B2DVector (ln,1), basegfx::B2DVector (n,1));
1163 0 : Slide.Operations.push_back(makeRotateAndScaleDepthByWidth(basegfx::B3DVector(0, 1, 0), basegfx::B3DVector(n + ln - 1, 0, -t30*p), -120, true, 0.0, 1.0));
1164 : } else {
1165 0 : Slide.pushTriangle (basegfx::B2DVector (0,ln), basegfx::B2DVector (1,ln), basegfx::B2DVector (0,n));
1166 0 : Slide.pushTriangle (basegfx::B2DVector (1,ln), basegfx::B2DVector (0,n), basegfx::B2DVector (1,n));
1167 0 : Slide.Operations.push_back(makeRotateAndScaleDepthByHeight(basegfx::B3DVector(1, 0, 0), basegfx::B3DVector(0, 1 - n - ln, -t30*p), -120, true, 0.0, 1.0));
1168 : }
1169 0 : aLeavingSlide.push_back (Slide);
1170 :
1171 0 : if( vertical ) {
1172 0 : Slide.Operations.push_back(makeSRotate(basegfx::B3DVector(0, 1, 0), basegfx::B3DVector(2*n - 1, 0, 0), -60, false, -1, 0));
1173 0 : Slide.Operations.push_back(makeSRotate(basegfx::B3DVector(0, 1, 0), basegfx::B3DVector(n + ln - 1, 0, 0), 180, false, -1, 0));
1174 : } else {
1175 0 : Slide.Operations.push_back(makeSRotate(basegfx::B3DVector(1, 0, 0), basegfx::B3DVector(0, 1 - 2*n, 0), -60, false, -1, 0));
1176 0 : Slide.Operations.push_back(makeSRotate(basegfx::B3DVector(1, 0, 0), basegfx::B3DVector(0, 1 - n - ln, 0), 180, false, -1, 0));
1177 : }
1178 0 : aEnteringSlide.push_back (Slide);
1179 0 : ln = n;
1180 0 : }
1181 :
1182 0 : return makeSimpleTransition(aLeavingSlide, aEnteringSlide);
1183 : }
1184 :
1185 : namespace
1186 : {
1187 :
1188 0 : class FadeSmoothlyTransition : public OGLTransitionImpl
1189 : {
1190 : public:
1191 0 : FadeSmoothlyTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1192 0 : : OGLTransitionImpl(rScene, rSettings)
1193 0 : {}
1194 :
1195 : private:
1196 : virtual void displaySlides_( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale );
1197 : };
1198 :
1199 0 : void FadeSmoothlyTransition::displaySlides_( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale )
1200 : {
1201 0 : applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
1202 :
1203 0 : glDisable(GL_DEPTH_TEST);
1204 :
1205 0 : displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale );
1206 :
1207 0 : glDisable(GL_LIGHTING);
1208 0 : glEnable(GL_BLEND);
1209 0 : glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1210 0 : glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1211 0 : glColor4f( 1, 1, 1, nTime );
1212 0 : displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale );
1213 0 : glDisable(GL_BLEND);
1214 0 : glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1215 0 : glEnable(GL_LIGHTING);
1216 :
1217 0 : glEnable(GL_DEPTH_TEST);
1218 0 : }
1219 :
1220 : shared_ptr<OGLTransitionImpl>
1221 0 : makeFadeSmoothlyTransition(
1222 : const Primitives_t& rLeavingSlidePrimitives,
1223 : const Primitives_t& rEnteringSlidePrimitives,
1224 : const TransitionSettings& rSettings)
1225 : {
1226 : return make_shared<FadeSmoothlyTransition>(
1227 : TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives),
1228 0 : rSettings)
1229 : ;
1230 : }
1231 :
1232 : }
1233 :
1234 0 : boost::shared_ptr<OGLTransitionImpl> makeFadeSmoothly()
1235 : {
1236 0 : Primitive Slide;
1237 :
1238 0 : Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1));
1239 0 : Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1));
1240 0 : Primitives_t aLeavingSlide;
1241 0 : aLeavingSlide.push_back (Slide);
1242 0 : Primitives_t aEnteringSlide;
1243 0 : aEnteringSlide.push_back (Slide);
1244 :
1245 0 : TransitionSettings aSettings;
1246 0 : aSettings.mbUseMipMapLeaving = aSettings.mbUseMipMapEntering = false;
1247 :
1248 0 : return makeFadeSmoothlyTransition(aLeavingSlide, aEnteringSlide, aSettings);
1249 : }
1250 :
1251 : namespace
1252 : {
1253 :
1254 0 : class FadeThroughBlackTransition : public OGLTransitionImpl
1255 : {
1256 : public:
1257 0 : FadeThroughBlackTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1258 0 : : OGLTransitionImpl(rScene, rSettings)
1259 0 : {}
1260 :
1261 : private:
1262 : virtual void displaySlides_( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale );
1263 : };
1264 :
1265 0 : void FadeThroughBlackTransition::displaySlides_( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale )
1266 : {
1267 0 : applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
1268 :
1269 0 : glDisable(GL_DEPTH_TEST);
1270 :
1271 0 : glDisable(GL_LIGHTING);
1272 0 : glEnable(GL_BLEND);
1273 0 : glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1274 0 : glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1275 0 : if( nTime < 0.5 ) {
1276 0 : glColor4f( 1, 1, 1, 1 - nTime*2 );
1277 0 : displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale );
1278 : } else {
1279 0 : glColor4f( 1, 1, 1, (nTime - 0.5)*2 );
1280 0 : displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale );
1281 : }
1282 0 : glDisable(GL_BLEND);
1283 0 : glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1284 0 : glEnable(GL_LIGHTING);
1285 :
1286 0 : glEnable(GL_DEPTH_TEST);
1287 0 : }
1288 :
1289 : shared_ptr<OGLTransitionImpl>
1290 0 : makeFadeThroughBlackTransition(
1291 : const Primitives_t& rLeavingSlidePrimitives,
1292 : const Primitives_t& rEnteringSlidePrimitives,
1293 : const TransitionSettings& rSettings)
1294 : {
1295 : return make_shared<FadeThroughBlackTransition>(
1296 : TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives),
1297 0 : rSettings)
1298 : ;
1299 : }
1300 :
1301 : }
1302 :
1303 0 : boost::shared_ptr<OGLTransitionImpl> makeFadeThroughBlack()
1304 : {
1305 0 : Primitive Slide;
1306 :
1307 0 : Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1));
1308 0 : Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1));
1309 0 : Primitives_t aLeavingSlide;
1310 0 : aLeavingSlide.push_back (Slide);
1311 0 : Primitives_t aEnteringSlide;
1312 0 : aEnteringSlide.push_back (Slide);
1313 :
1314 0 : TransitionSettings aSettings;
1315 0 : aSettings.mbUseMipMapLeaving = aSettings.mbUseMipMapEntering = false;
1316 :
1317 0 : return makeFadeThroughBlackTransition(aLeavingSlide, aEnteringSlide, aSettings);
1318 : }
1319 :
1320 : static const char* basicVertexShader = "\n\
1321 : varying vec2 v_texturePosition;\n\
1322 : \n\
1323 : void main( void )\n\
1324 : {\n\
1325 : gl_Position = ftransform();\n\
1326 : v_texturePosition = gl_MultiTexCoord0.xy;\n\
1327 : }\n\
1328 : ";
1329 :
1330 : static const char* staticFragmentShader = "\n\
1331 : uniform sampler2D leavingSlideTexture;\n\
1332 : uniform sampler2D enteringSlideTexture;\n\
1333 : uniform sampler2D permTexture;\n\
1334 : uniform float time;\n\
1335 : varying vec2 v_texturePosition;\n\
1336 : \n\
1337 : float snoise(vec2 P) {\n\
1338 : \n\
1339 : return texture2D(permTexture, P).r;\n\
1340 : }\n\
1341 : \n\
1342 : \n\
1343 : #define PART 0.5\n\
1344 : #define START 0.4\n\
1345 : #define END 0.9\n\
1346 : \n\
1347 : void main() {\n\
1348 : float sn = snoise(10.0*v_texturePosition+time*0.07);\n\
1349 : if( time < PART ) {\n\
1350 : float sn1 = snoise(vec2(time*15.0, 20.0*v_texturePosition.y));\n\
1351 : float sn2 = snoise(v_texturePosition);\n\
1352 : if (sn1 > 1.0 - time*time && sn2 < 2.0*time+0.1)\n\
1353 : gl_FragColor = vec4(sn, sn, sn, 1.0);\n\
1354 : else if (time > START )\n\
1355 : gl_FragColor = ((time-START)/(PART - START))*vec4(sn, sn, sn, 1.0) + (1.0 - (time - START)/(PART - START))*texture2D(leavingSlideTexture, v_texturePosition);\n\
1356 : else\n\
1357 : gl_FragColor = texture2D(leavingSlideTexture, v_texturePosition);\n\
1358 : } else if ( time < PART ) {\n\
1359 : gl_FragColor = texture2D(leavingSlideTexture, v_texturePosition);\n\
1360 : } else if ( time > END ) {\n\
1361 : gl_FragColor = ((1.0 - time)/(1.0 - END))*vec4(sn, sn, sn, 1.0) + ((time - END)/(1.0 - END))*texture2D(enteringSlideTexture, v_texturePosition);\n\
1362 : } else \n\
1363 : gl_FragColor = vec4(sn, sn, sn, 1.0);\n\
1364 : }\n\
1365 : ";
1366 :
1367 : static const char* dissolveFragmentShader = "\n\
1368 : uniform sampler2D leavingSlideTexture;\n\
1369 : uniform sampler2D enteringSlideTexture;\n\
1370 : uniform sampler2D permTexture;\n\
1371 : uniform float time;\n\
1372 : varying vec2 v_texturePosition;\n\
1373 : \n\
1374 : float snoise(vec2 P) {\n\
1375 : \n\
1376 : return texture2D(permTexture, P).r;\n\
1377 : }\n\
1378 : \n\
1379 : void main() {\n\
1380 : float sn = snoise(10.0*v_texturePosition);\n\
1381 : if( sn < time)\n\
1382 : gl_FragColor = texture2D(enteringSlideTexture, v_texturePosition);\n\
1383 : else\n\
1384 : gl_FragColor = texture2D(leavingSlideTexture, v_texturePosition);\n\
1385 : }\n\
1386 : ";
1387 :
1388 : namespace
1389 : {
1390 :
1391 0 : class ShaderTransition : public OGLTransitionImpl
1392 : {
1393 : protected:
1394 0 : ShaderTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1395 : : OGLTransitionImpl(rScene, rSettings)
1396 : , m_nProgramObject(0)
1397 0 : , m_nHelperTexture(0)
1398 0 : {}
1399 :
1400 : private:
1401 : virtual void displaySlides_( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale );
1402 : virtual void prepareTransition_( ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex );
1403 : virtual void finishTransition_();
1404 : virtual GLuint makeShader_() = 0;
1405 :
1406 : void impl_preparePermShader();
1407 :
1408 : private:
1409 : /** GLSL program object
1410 : */
1411 : GLuint m_nProgramObject;
1412 :
1413 : /** various data */
1414 : GLuint m_nHelperTexture;
1415 : };
1416 :
1417 0 : void ShaderTransition::displaySlides_( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex,
1418 : double SlideWidthScale, double SlideHeightScale )
1419 : {
1420 0 : applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
1421 :
1422 : #ifdef GL_VERSION_2_0
1423 0 : if( m_nProgramObject ) {
1424 0 : GLint location = OGLShaders::glGetUniformLocation( m_nProgramObject, "time" );
1425 0 : if( location != -1 ) {
1426 0 : OGLShaders::glUniform1f( location, nTime );
1427 : }
1428 : }
1429 :
1430 0 : glActiveTexture( GL_TEXTURE2 );
1431 0 : glBindTexture( GL_TEXTURE_2D, glEnteringSlideTex );
1432 0 : glActiveTexture( GL_TEXTURE0 );
1433 : #endif
1434 :
1435 0 : displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale );
1436 0 : }
1437 :
1438 0 : void ShaderTransition::prepareTransition_( ::sal_Int32 /* glLeavingSlideTex */, ::sal_Int32 /* glEnteringSlideTex */ )
1439 : {
1440 0 : m_nProgramObject = makeShader_();
1441 :
1442 0 : impl_preparePermShader();
1443 0 : }
1444 :
1445 0 : void ShaderTransition::finishTransition_()
1446 : {
1447 : #ifdef GL_VERSION_2_0
1448 0 : if( m_nProgramObject ) {
1449 0 : OGLShaders::glDeleteProgram( m_nProgramObject );
1450 0 : m_nProgramObject = 0;
1451 : }
1452 0 : if ( m_nHelperTexture )
1453 : {
1454 0 : glDeleteTextures( 1, &m_nHelperTexture );
1455 0 : m_nHelperTexture = 0;
1456 : }
1457 : #endif
1458 0 : }
1459 :
1460 : int permutation256 [256]= {
1461 : 215, 100, 200, 204, 233, 50, 85, 196,
1462 : 71, 141, 122, 160, 93, 131, 243, 234,
1463 : 162, 183, 36, 155, 4, 62, 35, 205,
1464 : 40, 102, 33, 27, 255, 55, 214, 156,
1465 : 75, 163, 134, 126, 249, 74, 197, 228,
1466 : 72, 90, 206, 235, 17, 22, 49, 169,
1467 : 227, 89, 16, 5, 117, 60, 248, 230,
1468 : 217, 68, 138, 96, 194, 170, 136, 10,
1469 : 112, 238, 184, 189, 176, 42, 225, 212,
1470 : 84, 58, 175, 244, 150, 168, 219, 236,
1471 : 101, 208, 123, 37, 164, 110, 158, 201,
1472 : 78, 114, 57, 48, 70, 142, 106, 43,
1473 : 232, 26, 32, 252, 239, 98, 191, 94,
1474 : 59, 149, 39, 187, 203, 190, 19, 13,
1475 : 133, 45, 61, 247, 23, 34, 20, 52,
1476 : 118, 209, 146, 193, 222, 18, 1, 152,
1477 : 46, 41, 91, 148, 115, 25, 135, 77,
1478 : 254, 147, 224, 161, 9, 213, 223, 250,
1479 : 231, 251, 127, 166, 63, 179, 81, 130,
1480 : 139, 28, 120, 151, 241, 86, 111, 0,
1481 : 88, 153, 172, 182, 159, 105, 178, 47,
1482 : 51, 167, 65, 66, 92, 73, 198, 211,
1483 : 245, 195, 31, 220, 140, 76, 221, 186,
1484 : 154, 185, 56, 83, 38, 165, 109, 67,
1485 : 124, 226, 132, 53, 229, 29, 12, 181,
1486 : 121, 24, 207, 199, 177, 113, 30, 80,
1487 : 3, 97, 188, 79, 216, 173, 8, 145,
1488 : 87, 128, 180, 237, 240, 137, 125, 104,
1489 : 15, 242, 119, 246, 103, 143, 95, 144,
1490 : 2, 44, 69, 157, 192, 174, 14, 54,
1491 : 218, 82, 64, 210, 11, 6, 129, 21,
1492 : 116, 171, 99, 202, 7, 107, 253, 108
1493 : };
1494 :
1495 0 : void initPermTexture(GLuint *texID)
1496 : {
1497 0 : glGenTextures(1, texID);
1498 0 : glBindTexture(GL_TEXTURE_2D, *texID);
1499 :
1500 : static bool initialized = false;
1501 : static unsigned char permutation2D[256*256*4];
1502 0 : if( !initialized ) {
1503 : int x, y;
1504 :
1505 0 : for( y=0; y < 256; y++ )
1506 0 : for( x=0; x < 256; x++ )
1507 0 : permutation2D[x*4 + y*1024] = permutation256[(y + permutation256[x]) & 0xff];
1508 :
1509 0 : initialized = true;
1510 : }
1511 :
1512 0 : glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, permutation2D );
1513 0 : glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
1514 0 : glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
1515 0 : }
1516 :
1517 0 : void ShaderTransition::impl_preparePermShader()
1518 : {
1519 : #ifdef GL_VERSION_2_0
1520 0 : if( m_nProgramObject ) {
1521 0 : OGLShaders::glUseProgram( m_nProgramObject );
1522 :
1523 0 : GLint location = OGLShaders::glGetUniformLocation( m_nProgramObject, "leavingSlideTexture" );
1524 0 : if( location != -1 ) {
1525 0 : OGLShaders::glUniform1i( location, 0 ); // texture unit 0
1526 : }
1527 :
1528 0 : glActiveTexture(GL_TEXTURE1);
1529 0 : if( !m_nHelperTexture )
1530 0 : initPermTexture( &m_nHelperTexture );
1531 0 : glActiveTexture(GL_TEXTURE0);
1532 :
1533 0 : location = OGLShaders::glGetUniformLocation( m_nProgramObject, "permTexture" );
1534 0 : if( location != -1 ) {
1535 0 : OGLShaders::glUniform1i( location, 1 ); // texture unit 1
1536 : }
1537 :
1538 0 : location = OGLShaders::glGetUniformLocation( m_nProgramObject, "enteringSlideTexture" );
1539 0 : if( location != -1 ) {
1540 0 : OGLShaders::glUniform1i( location, 2 ); // texture unit 2
1541 : }
1542 : }
1543 : #endif
1544 0 : }
1545 :
1546 : }
1547 :
1548 : namespace
1549 : {
1550 :
1551 0 : class StaticNoiseTransition : public ShaderTransition
1552 : {
1553 : public:
1554 0 : StaticNoiseTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1555 0 : : ShaderTransition(rScene, rSettings)
1556 0 : {}
1557 :
1558 : private:
1559 : virtual GLuint makeShader_();
1560 : };
1561 :
1562 0 : GLuint StaticNoiseTransition::makeShader_()
1563 : {
1564 0 : return OGLShaders::LinkProgram( basicVertexShader, staticFragmentShader );
1565 : }
1566 :
1567 : shared_ptr<OGLTransitionImpl>
1568 0 : makeStaticNoiseTransition(
1569 : const Primitives_t& rLeavingSlidePrimitives,
1570 : const Primitives_t& rEnteringSlidePrimitives,
1571 : const TransitionSettings& rSettings)
1572 : {
1573 : return make_shared<StaticNoiseTransition>(
1574 : TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives),
1575 0 : rSettings)
1576 : ;
1577 : }
1578 :
1579 : }
1580 :
1581 0 : boost::shared_ptr<OGLTransitionImpl> makeStatic()
1582 : {
1583 0 : Primitive Slide;
1584 :
1585 0 : Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1));
1586 0 : Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1));
1587 0 : Primitives_t aLeavingSlide;
1588 0 : aLeavingSlide.push_back (Slide);
1589 0 : Primitives_t aEnteringSlide;
1590 0 : aEnteringSlide.push_back (Slide);
1591 :
1592 0 : TransitionSettings aSettings;
1593 0 : aSettings.mbUseMipMapLeaving = aSettings.mbUseMipMapEntering = false;
1594 0 : aSettings.mnRequiredGLVersion = 2.0;
1595 :
1596 0 : return makeStaticNoiseTransition(aLeavingSlide, aEnteringSlide, aSettings);
1597 : }
1598 :
1599 : namespace
1600 : {
1601 :
1602 0 : class DissolveTransition : public ShaderTransition
1603 : {
1604 : public:
1605 0 : DissolveTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1606 0 : : ShaderTransition(rScene, rSettings)
1607 0 : {}
1608 :
1609 : private:
1610 : virtual GLuint makeShader_();
1611 : };
1612 :
1613 0 : GLuint DissolveTransition::makeShader_()
1614 : {
1615 0 : return OGLShaders::LinkProgram( basicVertexShader, dissolveFragmentShader );
1616 : }
1617 :
1618 : shared_ptr<OGLTransitionImpl>
1619 0 : makeDissolveTransition(
1620 : const Primitives_t& rLeavingSlidePrimitives,
1621 : const Primitives_t& rEnteringSlidePrimitives,
1622 : const TransitionSettings& rSettings)
1623 : {
1624 : return make_shared<DissolveTransition>(
1625 : TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives),
1626 0 : rSettings)
1627 : ;
1628 : }
1629 :
1630 : }
1631 :
1632 0 : boost::shared_ptr<OGLTransitionImpl> makeDissolve()
1633 : {
1634 0 : Primitive Slide;
1635 :
1636 0 : Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1));
1637 0 : Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1));
1638 0 : Primitives_t aLeavingSlide;
1639 0 : aLeavingSlide.push_back (Slide);
1640 0 : Primitives_t aEnteringSlide;
1641 0 : aEnteringSlide.push_back (Slide);
1642 :
1643 0 : TransitionSettings aSettings;
1644 0 : aSettings.mbUseMipMapLeaving = aSettings.mbUseMipMapEntering = false;
1645 0 : aSettings.mnRequiredGLVersion = 2.0;
1646 :
1647 0 : return makeDissolveTransition(aLeavingSlide, aEnteringSlide, aSettings);
1648 : }
1649 :
1650 0 : boost::shared_ptr<OGLTransitionImpl> makeNewsflash()
1651 : {
1652 0 : Primitive Slide;
1653 :
1654 0 : Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1));
1655 0 : Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1));
1656 0 : Slide.Operations.push_back(makeSRotate(basegfx::B3DVector(0,0,1),basegfx::B3DVector(0,0,0),3000,true,0,0.5));
1657 0 : Slide.Operations.push_back(makeSScale(basegfx::B3DVector(0.01,0.01,0.01),basegfx::B3DVector(0,0,0),true,0,0.5));
1658 0 : Slide.Operations.push_back(makeSTranslate(basegfx::B3DVector(-10000, 0, 0),false, 0.5, 2));
1659 0 : Primitives_t aLeavingSlide;
1660 0 : aLeavingSlide.push_back(Slide);
1661 :
1662 0 : Slide.Operations.clear();
1663 0 : Slide.Operations.push_back(makeSRotate(basegfx::B3DVector(0,0,1),basegfx::B3DVector(0,0,0),-3000,true,0.5,1));
1664 0 : Slide.Operations.push_back(makeSTranslate(basegfx::B3DVector(-100, 0, 0),false, -1, 1));
1665 0 : Slide.Operations.push_back(makeSTranslate(basegfx::B3DVector(100, 0, 0),false, 0.5, 1));
1666 0 : Slide.Operations.push_back(makeSScale(basegfx::B3DVector(0.01,0.01,0.01),basegfx::B3DVector(0,0,0),false,-1,1));
1667 0 : Slide.Operations.push_back(makeSScale(basegfx::B3DVector(100,100,100),basegfx::B3DVector(0,0,0),true,0.5,1));
1668 0 : Primitives_t aEnteringSlide;
1669 0 : aEnteringSlide.push_back(Slide);
1670 :
1671 0 : Operations_t aOverallOperations;
1672 0 : aOverallOperations.push_back(makeSRotate(basegfx::B3DVector(0,0,1),basegfx::B3DVector(0.2,0.2,0),1080,true,0,1));
1673 :
1674 0 : return makeSimpleTransition(aLeavingSlide, aEnteringSlide, aOverallOperations);
1675 : }
1676 :
1677 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|