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