1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 #ifndef INCLUDED_OGLTRANS_TRANSITIONIMPL_HXX_
28 #define INCLUDED_OGLTRANS_TRANSITIONIMPL_HXX_
29 
30 #include <basegfx/vector/b2dvector.hxx>
31 #include <basegfx/vector/b3dvector.hxx>
32 
33 #include <tools/prewin.h>
34 #include <tools/postwin.h>
35 
36 #if defined( WNT )
37 #include <tools/prewin.h>
38 #include <tools/postwin.h>
39 #elif defined( OS2 )
40 #elif defined( QUARTZ )
41 #elif defined( UNX )
42 #endif
43 
44 #include <vector>
45 #include <GL/gl.h>
46 
47 using namespace std;
48 
49 class Primitive;
50 class Operation;
51 class SceneObject;
52 
53 
54 /** OpenGL 3D Transition class. It implicitly is constructed from XOGLTransition
55 
56 	This class is capable of making itself into many difference transitions. It holds Primitives and Operations on those primitives.
57 */
58 class OGLTransitionImpl
59 {
60 public:
61     OGLTransitionImpl() :
62         mbUseMipMapLeaving( true ),
63         mbUseMipMapEntering( true ),
64         mnRequiredGLVersion( 1.0 ),
65         maLeavingSlidePrimitives(),
66         maEnteringSlidePrimitives(),
67         maSceneObjects(),
68         mbReflectSlides( false ),
69         mVertexObject( 0 ),
70         mFragmentObject( 0 ),
71         mProgramObject( 0 ),
72         maHelperTexture( 0 ),
73         mmPrepare( NULL ),
74         mmPrepareTransition( NULL ),
75         mmClearTransition( NULL ),
76         mmDisplaySlides( NULL )
77     {}
78 
79     ~OGLTransitionImpl();
80 
81     void prepare( ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex );
82     void display( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight );
83     void finish();
84 
85     void makeOutsideCubeFaceToLeft();
86     void makeInsideCubeFaceToLeft();
87     void makeNByMTileFlip( ::sal_uInt16 n, ::sal_uInt16 m );
88     void makeRevolvingCircles( ::sal_uInt16 nCircles , ::sal_uInt16 nPointsOnCircles );
89     void makeHelix( ::sal_uInt16 nRows );
90     void makeFallLeaving();
91     void makeTurnAround();
92     void makeTurnDown();
93     void makeIris();
94     void makeRochade();
95     void makeVenetianBlinds( bool vertical, int parts );
96     void makeStatic();
97     void makeDissolve();
98     void makeNewsflash();
99 
100     /** 2D replacements
101      */
102     void makeDiamond();
103     void makeFadeSmoothly();
104     void makeFadeThroughBlack();
105 
106     /** Whether to use mipmaping for slides textures
107      */
108     bool mbUseMipMapLeaving;
109     bool mbUseMipMapEntering;
110 
111     /** which GL version does the transition require
112      */
113     float mnRequiredGLVersion;
114 
115 private:
116     /** clears all the primitives and operations
117 	*/
118     void clear();
119 
120     /** All the primitives that use the leaving slide texture
121 	*/
122     vector<Primitive> maLeavingSlidePrimitives;
123 
124     /** All the primitives that use the leaving slide texture
125 	*/
126     vector<Primitive> maEnteringSlidePrimitives;
127 
128     /** All the surrounding scene objects
129 	*/
130     vector<SceneObject*> maSceneObjects;
131 
132     /** All the operations that should be applied to both leaving and entering slide primitives. These operations will be called in the order they were pushed back in. In OpenGL this effectively uses the operations in the opposite order they were pushed back.
133 	*/
134 	vector<Operation*> OverallOperations;
135 
136 	/** Whether to reflect slides, the reflection happens on flat surface beneath the slides.
137 	 ** Now it only works with slides which keep their rectangular shape together.
138 	 */
139 	bool mbReflectSlides;
140 
141 	/** GLSL objects, shaders and program
142 	 */
143 	GLuint mVertexObject, mFragmentObject, mProgramObject;
144 
145 	/** various data */
146 	GLuint maHelperTexture;
147 
148 	/** When this method is not NULL, it is called in display method to prepare the slides, scene, etc.
149 	 ** We might later replace this by cleaner derived class.
150 	 */
151 	void (OGLTransitionImpl::*mmPrepare)( double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight );
152 
153 	/** When this method is not NULL, it is called after glx context is ready to let the transition prepare GL related things, like GLSL program.
154 	 ** We might later replace this by cleaner derived class.
155 	 */
156 	void (OGLTransitionImpl::*mmPrepareTransition)( ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex );
157 
158 	/** When this method is not NULL, it is called when the transition needs to clear after itself, like delete own textures etc.
159 	 ** We might later replace this by cleaner derived class.
160 	 */
161 	void (OGLTransitionImpl::*mmClearTransition)();
162 
163 	/** When this method is not NULL, it is called in display method to display the slides.
164 	 ** We might later replace this by cleaner derived class.
165 	 */
166 	void (OGLTransitionImpl::*mmDisplaySlides)( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale );
167 
168 	void displaySlides( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale );
169 	void displaySlide( double nTime, ::sal_Int32 glSlideTex, std::vector<Primitive>& primitives, double SlideWidthScale, double SlideHeightScale );
170 	void displayScene( double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight);
171 	void applyOverallOperations( double nTime, double SlideWidthScale, double SlideHeightScale );
172 
173 	/** various transitions helper methods
174 	 */
175 	void prepareDiamond( double nTime, double SlideWidth, double SlideHeight,double DispWidth, double DispHeight );
176 	void displaySlidesFadeSmoothly( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale );
177         void displaySlidesFadeThroughBlack( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale );
178         void displaySlidesRochade( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale );
179 	void displaySlidesShaders( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale );
180 	void prepareStatic( ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex );
181 	void prepareDissolve( ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex );
182 	void preparePermShader();
183 };
184 
185 class SceneObject
186 {
187 public:
188     SceneObject();
189 
190     virtual void prepare() {};
191     virtual void display(double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight);
192     virtual void finish() {};
193 
194     void pushPrimitive (const Primitive &p);
195 
196 protected:
197     /** All the surrounding scene primitives
198 	*/
199     vector<Primitive> maPrimitives;
200 };
201 
202 class Iris : public SceneObject
203 {
204 public:
205     Iris ();
206 
207     virtual void prepare();
208     virtual void display(double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight);
209     virtual void finish();
210 
211 private:
212 
213     GLuint maTexture;
214 };
215 
216 /** This class is a list of Triangles that will share Operations, and could possibly share
217 */
218 class Primitive
219 {
220 public:
221     Primitive() {}
222 	// making copy constructor explicit makes the class un-suitable for use with stl containers
223     Primitive(const Primitive& rvalue);
224 	~Primitive();
225 
226     void applyOperations(double nTime, double SlideWidthScale, double SlideHeightScale);
227     void display(double nTime, double SlideWidthScale, double SlideHeightScale);
228     const Primitive& operator=(const Primitive& rvalue);
229 
230     /** PushBack a vertex,normal, and tex coord. Each SlideLocation is where on the slide is mapped to this location ( from (0,0) to (1,1)  ). This will make sure the correct aspect ratio is used, and helps to make slides begin and end at the correct position. (0,0) is the top left of the slide, and (1,1) is the bottom right.
231 
232     @param SlideLocation0
233     Location of first Vertex on slide
234 
235     @param SlideLocation1
236     Location of second Vertex on slide
237 
238     @param SlideLocation2
239     Location of third Vertex on slide
240 
241     */
242     void pushTriangle(const basegfx::B2DVector& SlideLocation0,const basegfx::B2DVector& SlideLocation1,const basegfx::B2DVector& SlideLocation2);
243 
244     /** clear all the vertices, normals, tex coordinates, and normals
245     */
246     void clearTriangles();
247 
248     /** guards against directly changing the vertices
249 
250         @return
251         the list of vertices
252     */
253     const vector<basegfx::B3DVector>& getVertices() const {return Vertices;}
254 
255     /** guards against directly changing the vertices
256     */
257     const vector<basegfx::B3DVector>& getNormals() const {return Normals;}
258 
259     /** guards against directly changing the vertices
260 
261         @return
262         the list of Texture Coordinates
263 
264     */
265     const vector<basegfx::B2DVector>& getTexCoords() const {return TexCoords;}
266 
267     /** list of Operations to be performed on this primitive.These operations will be called in the order they were pushed back in. In OpenGL this effectively uses the operations in the opposite order they were pushed back.
268 
269         @return
270         the list of Operations
271 
272     */
273     vector<Operation*> Operations;
274 
275 private:
276     /** list of vertices
277     */
278 	vector<basegfx::B3DVector> Vertices;
279 
280 	/** list of Normals
281     */
282 	vector<basegfx::B3DVector> Normals;
283 
284 	/** list of Texture Coordinates
285     */
286 	vector<basegfx::B2DVector> TexCoords;
287 };
288 
289 /** This class is to be derived to make any operation (tranform) you may need in order to construct your transitions
290 */
291 class Operation
292 {
293 public:
294 	Operation(){}
295 	virtual ~Operation(){}
296 
297 	/** Should this operation be interpolated . If TRUE, the transform will smoothly move from making no difference from t = 0.0 to nT0 to being completely transformed from t = nT1 to 1. If FALSE, the transform will be inneffectual from t = 0 to nT0, and completely transformed from t = nT0 to 1.
298 	*/
299 	bool bInterpolate;
300 
301 	/** time to begin the transformation
302 	*/
303 	double nT0;
304 
305 	/** time to finish the transformation
306 	*/
307 	double nT1;
308 public:
309     /** this is the function that is called to give the Operation to OpenGL.
310 
311         @param t
312         time from t = 0 to t = 1
313 
314         @param SlideWidthScale
315         width of slide divided by width of window
316 
317         @param SlideHeightScale
318         height of slide divided by height of window
319 
320     */
321 	virtual void interpolate(double t,double SlideWidthScale,double SlideHeightScale) = 0;
322 
323 	/** return a copy of this operation
324 	*/
325     virtual Operation* clone() = 0;
326 };
327 
328 /** this class is a generic CounterClockWise(CCW) rotation with an axis angle
329 */
330 class SRotate: public Operation
331 {
332 public:
333 	void interpolate(double t,double SlideWidthScale,double SlideHeightScale);
334     virtual SRotate* clone();
335 
336 	/** Constructor
337 
338 	    @param Axis
339 	    axis to rotate about
340 
341 	    @param Origin
342 	    position that rotation axis runs through
343 
344 	    @param Angle
345 	    angle in radians of CCW rotation
346 
347 	    @param bInter
348 	    see Operation
349 
350 	    @param T0
351 	    transformation starting time
352 
353 	    @param T1
354 	    transformation ending time
355 
356 	*/
357 	SRotate(const basegfx::B3DVector& Axis,const basegfx::B3DVector& Origin,double Angle,bool bInter, double T0, double T1);
358 	~SRotate(){}
359 private:
360     /** axis to rotate CCW about
361     */
362 	basegfx::B3DVector axis;
363 
364 	/** position that rotation axis runs through
365 	*/
366     basegfx::B3DVector origin;
367 
368     /** angle in radians of CCW rotation
369     */
370 	double angle;
371 };
372 
373 /** scaling transformation
374 */
375 class SScale: public Operation
376 {
377 public:
378 	void interpolate(double t,double SlideWidthScale,double SlideHeightScale);
379     SScale* clone();
380 
381 	/** Constructor
382 
383         @param Scale
384 	    amount to scale by
385 
386 	    @param Origin
387 	    position that rotation axis runs through
388 
389 	    @param bInter
390 	    see Operation
391 
392 	    @param T0
393 	    transformation starting time
394 
395 	    @param T1
396 	    transformation ending time
397 
398 	*/
399 	SScale(const basegfx::B3DVector& Scale, const basegfx::B3DVector& Origin,bool bInter, double T0, double T1);
400 	~SScale(){}
401 private:
402 	basegfx::B3DVector scale;
403 	basegfx::B3DVector origin;
404 };
405 
406 /** translation transformation
407 */
408 class STranslate: public Operation
409 {
410 public:
411 	void interpolate(double t,double SlideWidthScale,double SlideHeightScale);
412     STranslate* clone();
413 
414 	/** Constructor
415 
416 	    @param Vector
417 	    vector to translate
418 
419 	    @param bInter
420 	    see Operation
421 
422 	    @param T0
423 	    transformation starting time
424 
425 	    @param T1
426 	    transformation ending time
427 
428 	*/
429 	STranslate(const basegfx::B3DVector& Vector,bool bInter, double T0, double T1);
430 	~STranslate(){}
431 private:
432     /** vector to translate by
433     */
434 	basegfx::B3DVector vector;
435 };
436 
437 /** translation transformation
438 */
439 class SEllipseTranslate: public Operation
440 {
441 public:
442 	void interpolate(double t,double SlideWidthScale,double SlideHeightScale);
443     SEllipseTranslate* clone();
444 
445 	/** Constructor
446 
447 	    @param Vector
448 	    vector to translate
449 
450 	    @param bInter
451 	    see Operation
452 
453 	    @param T0
454 	    transformation starting time
455 
456 	    @param T1
457 	    transformation ending time
458 
459 	*/
460 	SEllipseTranslate(double dWidth, double dHeight, double dStartPosition, double dEndPosition, bool bInter, double T0, double T1);
461 	~SEllipseTranslate(){}
462 private:
463     /** width and length of the ellipse
464      */
465     double width, height;
466 
467     /** start and end position on the ellipse <0,1>
468      */
469     double startPosition;
470     double endPosition;
471 };
472 
473 /** Same as SRotate, except the depth is scaled by the width of the slide divided by the width of the window.
474 */
475 class RotateAndScaleDepthByWidth: public Operation
476 {
477 public:
478 	void interpolate(double t,double SlideWidthScale,double SlideHeightScale);
479     RotateAndScaleDepthByWidth* clone();
480 
481 	RotateAndScaleDepthByWidth(const basegfx::B3DVector& Axis,const basegfx::B3DVector& Origin,double Angle,bool bInter, double T0, double T1);
482 	~RotateAndScaleDepthByWidth(){}
483 private:
484 	basegfx::B3DVector axis;
485     basegfx::B3DVector origin;
486 	double angle;
487 };
488 
489 /** Same as SRotate, except the depth is scaled by the width of the slide divided by the height of the window.
490 */
491 class RotateAndScaleDepthByHeight: public Operation
492 {
493 public:
494 	void interpolate(double t,double SlideWidthScale,double SlideHeightScale);
495     RotateAndScaleDepthByHeight* clone();
496 
497 	RotateAndScaleDepthByHeight(const basegfx::B3DVector& Axis,const basegfx::B3DVector& Origin,double Angle,bool bInter, double T0, double T1);
498 	~RotateAndScaleDepthByHeight(){}
499 private:
500 	basegfx::B3DVector axis;
501     basegfx::B3DVector origin;
502 	double angle;
503 };
504 
505 #endif // INCLUDED_SLIDESHOW_TRANSITION_HXX_
506 
507