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