1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2008 by Sun Microsystems, Inc.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
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.
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).
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.
27 ************************************************************************/
29 #include <glm/gtc/matrix_transform.hpp>
30 #include <glm/gtc/type_ptr.hpp>
31 #include <vcl/opengl/OpenGLHelper.hxx>
32 #include <vcl/opengl/OpenGLContext.hxx>
33 #include <sal/log.hxx>
38 #include <comphelper/random.hxx>
40 #include "Operation.hxx"
41 #include "TransitionImpl.hxx"
44 TransitionScene::TransitionScene(TransitionScene
const& rOther
)
45 : maLeavingSlidePrimitives(rOther
.maLeavingSlidePrimitives
)
46 , maEnteringSlidePrimitives(rOther
.maEnteringSlidePrimitives
)
47 , maOverallOperations(rOther
.maOverallOperations
)
48 , maSceneObjects(rOther
.maSceneObjects
)
52 TransitionScene
& TransitionScene::operator=(const TransitionScene
& rOther
)
54 TransitionScene
aTmp(rOther
);
59 void TransitionScene::swap(TransitionScene
& rOther
)
63 swap(maLeavingSlidePrimitives
, rOther
.maLeavingSlidePrimitives
);
64 swap(maEnteringSlidePrimitives
, rOther
.maEnteringSlidePrimitives
);
65 swap(maOverallOperations
, rOther
.maOverallOperations
);
66 swap(maSceneObjects
, rOther
.maSceneObjects
);
69 OGLTransitionImpl::~OGLTransitionImpl()
73 void OGLTransitionImpl::uploadModelViewProjectionMatrices()
76 double const RealF(1.0);
77 double const RealN(-1.0);
78 double const RealL(-1.0);
80 double const RealB(-1.0);
82 double ClipN(EyePos
+5.0*RealN
);
83 double ClipF(EyePos
+15.0*RealF
);
84 double ClipL(RealL
*8.0);
85 double ClipR(RealR
*8.0);
86 double ClipB(RealB
*8.0);
87 double ClipT(RealT
*8.0);
89 glm::mat4 projection
= glm::frustum
<float>(ClipL
, ClipR
, ClipB
, ClipT
, ClipN
, ClipF
);
90 //This scaling is to take the plane with BottomLeftCorner(-1,-1,0) and TopRightCorner(1,1,0) and map it to the screen after the perspective division.
91 glm::vec3
scale(1.0 / (((RealR
* 2.0 * ClipN
) / (EyePos
* (ClipR
- ClipL
))) - ((ClipR
+ ClipL
) / (ClipR
- ClipL
))),
92 1.0 / (((RealT
* 2.0 * ClipN
) / (EyePos
* (ClipT
- ClipB
))) - ((ClipT
+ ClipB
) / (ClipT
- ClipB
))),
94 projection
= glm::scale(projection
, scale
);
95 glm::mat4 modelview
= glm::translate(glm::mat4(), glm::vec3(0, 0, -EyePos
));
97 GLint location
= glGetUniformLocation( m_nProgramObject
, "u_projectionMatrix" );
98 if( location
!= -1 ) {
99 glUniformMatrix4fv(location
, 1, false, glm::value_ptr(projection
));
103 location
= glGetUniformLocation( m_nProgramObject
, "u_modelViewMatrix" );
104 if( location
!= -1 ) {
105 glUniformMatrix4fv(location
, 1, false, glm::value_ptr(modelview
));
110 static std::vector
<int> uploadPrimitives(const Primitives_t
& primitives
)
113 for (const Primitive
& primitive
: primitives
)
114 size
+= primitive
.getVerticesByteSize();
117 glBufferData(GL_ARRAY_BUFFER
, size
, nullptr, GL_STATIC_DRAW
);
119 Vertex
*buf
= static_cast<Vertex
*>(glMapBuffer(GL_ARRAY_BUFFER
, GL_WRITE_ONLY
));
121 std::vector
<int> indices
;
123 for (const Primitive
& primitive
: primitives
) {
124 indices
.push_back(last_pos
);
125 int num
= primitive
.writeVertices(buf
);
131 glUnmapBuffer(GL_ARRAY_BUFFER
);
136 bool OGLTransitionImpl::prepare( sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, OpenGLContext
*pContext
)
138 m_nProgramObject
= makeShader();
139 if (!m_nProgramObject
)
143 glUseProgram( m_nProgramObject
);
146 const SceneObjects_t
& rSceneObjects(maScene
.getSceneObjects());
147 for(size_t i(0); i
!= rSceneObjects
.size(); ++i
) {
148 rSceneObjects
[i
]->prepare(m_nProgramObject
);
151 GLint location
= glGetUniformLocation( m_nProgramObject
, "leavingSlideTexture" );
152 if( location
!= -1 ) {
153 glUniform1i( location
, 0 ); // texture unit 0
157 location
= glGetUniformLocation( m_nProgramObject
, "enteringSlideTexture" );
158 if( location
!= -1 ) {
159 glUniform1i( location
, 2 ); // texture unit 2
163 uploadModelViewProjectionMatrices();
165 m_nPrimitiveTransformLocation
= glGetUniformLocation( m_nProgramObject
, "u_primitiveTransformMatrix" );
166 m_nSceneTransformLocation
= glGetUniformLocation( m_nProgramObject
, "u_sceneTransformMatrix" );
167 m_nOperationsTransformLocation
= glGetUniformLocation( m_nProgramObject
, "u_operationsTransformMatrix" );
168 m_nTimeLocation
= glGetUniformLocation( m_nProgramObject
, "time" );
170 glGenVertexArrays(1, &m_nVertexArrayObject
);
171 glBindVertexArray(m_nVertexArrayObject
);
173 glGenBuffers(1, &m_nVertexBufferObject
);
174 glBindBuffer(GL_ARRAY_BUFFER
, m_nVertexBufferObject
);
176 // In practice both leaving and entering slides share the same primitives.
177 m_nFirstIndices
= uploadPrimitives(getScene().getLeavingSlide());
179 // Attribute bindings
180 m_nPositionLocation
= glGetAttribLocation(m_nProgramObject
, "a_position");
181 if (m_nPositionLocation
!= -1) {
182 glEnableVertexAttribArray(m_nPositionLocation
);
183 glVertexAttribPointer( m_nPositionLocation
, 3, GL_FLOAT
, false, sizeof(Vertex
), reinterpret_cast<void*>(offsetof(Vertex
, position
)) );
187 m_nNormalLocation
= glGetAttribLocation(m_nProgramObject
, "a_normal");
188 if (m_nNormalLocation
!= -1) {
189 glEnableVertexAttribArray(m_nNormalLocation
);
190 glVertexAttribPointer( m_nNormalLocation
, 3, GL_FLOAT
, false, sizeof(Vertex
), reinterpret_cast<void*>(offsetof(Vertex
, normal
)) );
194 m_nTexCoordLocation
= glGetAttribLocation(m_nProgramObject
, "a_texCoord");
195 if (m_nTexCoordLocation
!= -1) {
196 glEnableVertexAttribArray(m_nTexCoordLocation
);
197 glVertexAttribPointer( m_nTexCoordLocation
, 2, GL_FLOAT
, false, sizeof(Vertex
), reinterpret_cast<void*>(offsetof(Vertex
, texcoord
)) );
201 glBindBuffer(GL_ARRAY_BUFFER
, 0);
204 prepareTransition( glLeavingSlideTex
, glEnteringSlideTex
, pContext
);
208 void OGLTransitionImpl::finish()
210 const SceneObjects_t
& rSceneObjects(maScene
.getSceneObjects());
211 for(size_t i(0); i
!= rSceneObjects
.size(); ++i
) {
212 rSceneObjects
[i
]->finish();
218 if( m_nProgramObject
) {
219 glDeleteBuffers(1, &m_nVertexBufferObject
);
220 m_nVertexBufferObject
= 0;
221 glDeleteVertexArrays(1, &m_nVertexArrayObject
);
222 m_nVertexArrayObject
= 0;
223 glDeleteProgram( m_nProgramObject
);
224 m_nProgramObject
= 0;
229 void OGLTransitionImpl::prepare( double, double )
233 void OGLTransitionImpl::cleanup()
237 void OGLTransitionImpl::prepareTransition( sal_Int32
, sal_Int32
, OpenGLContext
* )
241 void OGLTransitionImpl::finishTransition()
245 void OGLTransitionImpl::displaySlides_( double nTime
, sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, double SlideWidthScale
, double SlideHeightScale
, OpenGLContext
* )
248 applyOverallOperations( nTime
, SlideWidthScale
, SlideHeightScale
);
250 glUniform1f( m_nTimeLocation
, nTime
);
252 glActiveTexture( GL_TEXTURE2
);
253 glBindTexture( GL_TEXTURE_2D
, glEnteringSlideTex
);
254 glActiveTexture( GL_TEXTURE0
);
256 displaySlide( nTime
, glLeavingSlideTex
, getScene().getLeavingSlide(), SlideWidthScale
, SlideHeightScale
);
260 void OGLTransitionImpl::display( double nTime
, sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
,
261 double SlideWidth
, double SlideHeight
, double DispWidth
, double DispHeight
, OpenGLContext
*pContext
)
263 const double SlideWidthScale
= SlideWidth
/DispWidth
;
264 const double SlideHeightScale
= SlideHeight
/DispHeight
;
267 glBindVertexArray(m_nVertexArrayObject
);
268 prepare( SlideWidth
, SlideHeight
);
271 displaySlides_( nTime
, glLeavingSlideTex
, glEnteringSlideTex
, SlideWidthScale
, SlideHeightScale
, pContext
);
273 displayScene( nTime
, SlideWidth
, SlideHeight
, DispWidth
, DispHeight
);
277 void OGLTransitionImpl::applyOverallOperations( double nTime
, double SlideWidthScale
, double SlideHeightScale
)
279 const Operations_t
& rOverallOperations(maScene
.getOperations());
281 for(size_t i(0); i
!= rOverallOperations
.size(); ++i
)
282 rOverallOperations
[i
]->interpolate(matrix
, nTime
, SlideWidthScale
, SlideHeightScale
);
284 if (m_nOperationsTransformLocation
!= -1) {
285 glUniformMatrix4fv(m_nOperationsTransformLocation
, 1, false, glm::value_ptr(matrix
));
290 static void displayPrimitives(const Primitives_t
& primitives
, GLint primitiveTransformLocation
, double nTime
, double WidthScale
, double HeightScale
, std::vector
<int>::const_iterator first
)
292 for (const Primitive
& primitive
: primitives
)
293 primitive
.display(primitiveTransformLocation
, nTime
, WidthScale
, HeightScale
, *first
++);
297 OGLTransitionImpl::displaySlide(
299 const sal_Int32 glSlideTex
, const Primitives_t
& primitives
,
300 double SlideWidthScale
, double SlideHeightScale
)
303 glBindTexture(GL_TEXTURE_2D
, glSlideTex
);
305 if (m_nSceneTransformLocation
!= -1) {
306 glUniformMatrix4fv(m_nSceneTransformLocation
, 1, false, glm::value_ptr(glm::mat4()));
309 displayPrimitives(primitives
, m_nPrimitiveTransformLocation
, nTime
, SlideWidthScale
, SlideHeightScale
, m_nFirstIndices
.cbegin());
314 OGLTransitionImpl::displayUnbufferedSlide(
316 const sal_Int32 glSlideTex
, const Primitives_t
& primitives
,
317 double SlideWidthScale
, double SlideHeightScale
)
320 glBindTexture(GL_TEXTURE_2D
, glSlideTex
);
322 glBindVertexArray(0);
324 glBindBuffer(GL_ARRAY_BUFFER
, 0);
326 if (m_nSceneTransformLocation
!= -1) {
327 glUniformMatrix4fv(m_nSceneTransformLocation
, 1, false, glm::value_ptr(glm::mat4()));
330 for (const Primitive
& primitive
: primitives
)
331 primitive
.display(m_nPrimitiveTransformLocation
, nTime
, SlideWidthScale
, SlideHeightScale
);
333 glBindVertexArray(m_nVertexArrayObject
);
335 glBindBuffer(GL_ARRAY_BUFFER
, m_nVertexBufferObject
);
339 void OGLTransitionImpl::displayScene( double nTime
, double SlideWidth
, double SlideHeight
, double DispWidth
, double DispHeight
)
341 const SceneObjects_t
& rSceneObjects(maScene
.getSceneObjects());
343 for(size_t i(0); i
!= rSceneObjects
.size(); ++i
)
344 rSceneObjects
[i
]->display(m_nSceneTransformLocation
, m_nPrimitiveTransformLocation
, nTime
, SlideWidth
, SlideHeight
, DispWidth
, DispHeight
);
348 void Primitive::display(GLint primitiveTransformLocation
, double nTime
, double WidthScale
, double HeightScale
) const
351 applyOperations( matrix
, nTime
, WidthScale
, HeightScale
);
354 if (primitiveTransformLocation
!= -1) {
355 glUniformMatrix4fv(primitiveTransformLocation
, 1, false, glm::value_ptr(matrix
));
359 GLuint nVertexArrayObject
;
360 glGenVertexArrays(1, &nVertexArrayObject
);
362 glBindVertexArray(nVertexArrayObject
);
366 glGenBuffers(1, &nBuffer
);
368 glBindBuffer(GL_ARRAY_BUFFER
, nBuffer
);
370 glBufferData(GL_ARRAY_BUFFER
, getVerticesByteSize(), Vertices
.data(), GL_STATIC_DRAW
);
372 glEnableVertexAttribArray(0);
374 glVertexAttribPointer(0, 3, GL_FLOAT
, GL_FALSE
, sizeof(Vertex
), nullptr);
376 glDrawArrays( GL_TRIANGLES
, 0, Vertices
.size() );
379 glDeleteBuffers(1, &nBuffer
);
382 glDeleteVertexArrays(1, &nVertexArrayObject
);
386 void Primitive::display(GLint primitiveTransformLocation
, double nTime
, double WidthScale
, double HeightScale
, int first
) const
389 applyOperations( matrix
, nTime
, WidthScale
, HeightScale
);
392 if (primitiveTransformLocation
!= -1) {
393 glUniformMatrix4fv(primitiveTransformLocation
, 1, false, glm::value_ptr(matrix
));
396 glDrawArrays( GL_TRIANGLES
, first
, Vertices
.size() );
401 void Primitive::applyOperations(glm::mat4
& matrix
, double nTime
, double WidthScale
, double HeightScale
) const
403 for(const auto & rOperation
: Operations
)
404 rOperation
->interpolate(matrix
, nTime
, WidthScale
, HeightScale
);
405 matrix
= glm::scale(matrix
, glm::vec3(WidthScale
, HeightScale
, 1));
408 void SceneObject::display(GLint sceneTransformLocation
, GLint primitiveTransformLocation
, double nTime
, double /* SlideWidth */, double /* SlideHeight */, double DispWidth
, double DispHeight
) const
410 // fixme: allow various model spaces, now we make it so that
411 // it is regular -1,-1 to 1,1, where the whole display fits in
413 if (DispHeight
> DispWidth
)
414 matrix
= glm::scale(matrix
, glm::vec3(DispHeight
/DispWidth
, 1, 1));
416 matrix
= glm::scale(matrix
, glm::vec3(1, DispWidth
/DispHeight
, 1));
418 if (sceneTransformLocation
!= -1) {
419 glUniformMatrix4fv(sceneTransformLocation
, 1, false, glm::value_ptr(matrix
));
422 displayPrimitives(maPrimitives
, primitiveTransformLocation
, nTime
, 1, 1, maFirstIndices
.cbegin());
426 void SceneObject::pushPrimitive(const Primitive
&p
)
428 maPrimitives
.push_back(p
);
431 SceneObject::SceneObject()
436 SceneObject::~SceneObject()
443 class Iris
: public SceneObject
448 virtual void prepare(GLuint program
) override
;
449 virtual void display(GLint sceneTransformLocation
, GLint primitiveTransformLocation
, double nTime
, double SlideWidth
, double SlideHeight
, double DispWidth
, double DispHeight
) const override
;
450 virtual void finish() override
;
453 GLuint maTexture
= 0;
455 GLuint maVertexArray
= 0;
458 void Iris::display(GLint sceneTransformLocation
, GLint primitiveTransformLocation
, double nTime
, double SlideWidth
, double SlideHeight
, double DispWidth
, double DispHeight
) const
460 glBindVertexArray(maVertexArray
);
462 glBindTexture(GL_TEXTURE_2D
, maTexture
);
464 SceneObject::display(sceneTransformLocation
, primitiveTransformLocation
, nTime
, SlideWidth
, SlideHeight
, DispWidth
, DispHeight
);
467 void Iris::prepare(GLuint program
)
470 static const GLubyte img
[3] = { 80, 80, 80 };
472 glGenTextures(1, &maTexture
);
473 glBindTexture(GL_TEXTURE_2D
, maTexture
);
474 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGB
, 1, 1, 0, GL_RGB
, GL_UNSIGNED_BYTE
, img
);
475 glTexParameteri(GL_TEXTURE_2D
,GL_TEXTURE_WRAP_S
,GL_REPEAT
);
476 glTexParameteri(GL_TEXTURE_2D
,GL_TEXTURE_WRAP_T
,GL_REPEAT
);
477 glTexParameteri(GL_TEXTURE_2D
,GL_TEXTURE_MAG_FILTER
,GL_NEAREST
);
478 glTexParameteri(GL_TEXTURE_2D
,GL_TEXTURE_MIN_FILTER
,GL_NEAREST
);
481 glGenVertexArrays(1, &maVertexArray
);
482 glBindVertexArray(maVertexArray
);
484 glGenBuffers(1, &maBuffer
);
485 glBindBuffer(GL_ARRAY_BUFFER
, maBuffer
);
486 maFirstIndices
= uploadPrimitives(maPrimitives
);
488 // Attribute bindings
489 GLint location
= glGetAttribLocation(program
, "a_position");
490 if (location
!= -1) {
491 glEnableVertexAttribArray(location
);
492 glVertexAttribPointer( location
, 3, GL_FLOAT
, false, sizeof(Vertex
), reinterpret_cast<void*>(offsetof(Vertex
, position
)) );
496 location
= glGetAttribLocation(program
, "a_normal");
497 if (location
!= -1) {
498 glEnableVertexAttribArray(location
);
499 glVertexAttribPointer( location
, 3, GL_FLOAT
, false, sizeof(Vertex
), reinterpret_cast<void*>(offsetof(Vertex
, normal
)) );
503 location
= glGetAttribLocation(program
, "a_texCoord");
504 if (location
!= -1) {
505 glEnableVertexAttribArray(location
);
506 glVertexAttribPointer( location
, 2, GL_FLOAT
, false, sizeof(Vertex
), reinterpret_cast<void*>(offsetof(Vertex
, texcoord
)) );
510 glBindBuffer(GL_ARRAY_BUFFER
, 0);
516 glDeleteBuffers(1, &maBuffer
);
518 glDeleteVertexArrays(1, &maVertexArray
);
520 glDeleteTextures(1, &maTexture
);
529 class ReflectionTransition
: public OGLTransitionImpl
532 ReflectionTransition(const TransitionScene
& rScene
, const TransitionSettings
& rSettings
)
533 : OGLTransitionImpl(rScene
, rSettings
)
537 virtual GLuint
makeShader() const override
;
538 virtual void displaySlides_( double nTime
, sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, double SlideWidthScale
, double SlideHeightScale
, OpenGLContext
*pContext
) override
;
540 virtual void prepareTransition( sal_Int32
, sal_Int32
, OpenGLContext
* ) override
{
541 glDisable(GL_CULL_FACE
);
544 virtual void finishTransition() override
{
545 glEnable(GL_CULL_FACE
);
549 GLuint
ReflectionTransition::makeShader() const
551 return OpenGLHelper::LoadShaders( "reflectionVertexShader", "reflectionFragmentShader" );
554 void ReflectionTransition::displaySlides_( double nTime
, sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
,
555 double SlideWidthScale
, double SlideHeightScale
, OpenGLContext
* )
558 applyOverallOperations( nTime
, SlideWidthScale
, SlideHeightScale
);
563 texture
= glLeavingSlideTex
;
564 slide
= getScene().getLeavingSlide();
566 texture
= glEnteringSlideTex
;
567 slide
= getScene().getEnteringSlide();
570 displaySlide( nTime
, texture
, slide
, SlideWidthScale
, SlideHeightScale
);
574 std::shared_ptr
<OGLTransitionImpl
>
575 makeReflectionTransition(
576 const Primitives_t
& rLeavingSlidePrimitives
,
577 const Primitives_t
& rEnteringSlidePrimitives
,
578 const Operations_t
& rOverallOperations
,
579 const TransitionSettings
& rSettings
)
581 return std::make_shared
<ReflectionTransition
>(
582 TransitionScene(rLeavingSlidePrimitives
, rEnteringSlidePrimitives
, rOverallOperations
, SceneObjects_t()),
591 class SimpleTransition
: public OGLTransitionImpl
594 SimpleTransition(const TransitionScene
& rScene
, const TransitionSettings
& rSettings
)
595 : OGLTransitionImpl(rScene
, rSettings
)
600 virtual GLuint
makeShader() const override
;
602 virtual void displaySlides_( double nTime
, sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, double SlideWidthScale
, double SlideHeightScale
, OpenGLContext
*pContext
) override
;
605 GLuint
SimpleTransition::makeShader() const
607 return OpenGLHelper::LoadShaders( "basicVertexShader", "basicFragmentShader" );
610 void SimpleTransition::displaySlides_( double nTime
, sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
,
611 double SlideWidthScale
, double SlideHeightScale
, OpenGLContext
* )
614 applyOverallOperations( nTime
, SlideWidthScale
, SlideHeightScale
);
617 displaySlide( nTime
, glLeavingSlideTex
, getScene().getLeavingSlide(), SlideWidthScale
, SlideHeightScale
);
618 displaySlide( nTime
, glEnteringSlideTex
, getScene().getEnteringSlide(), SlideWidthScale
, SlideHeightScale
);
622 std::shared_ptr
<OGLTransitionImpl
>
623 makeSimpleTransition(
624 const Primitives_t
& rLeavingSlidePrimitives
,
625 const Primitives_t
& rEnteringSlidePrimitives
,
626 const Operations_t
& rOverallOperations
,
627 const SceneObjects_t
& rSceneObjects
,
628 const TransitionSettings
& rSettings
)
630 return std::make_shared
<SimpleTransition
>(
631 TransitionScene(rLeavingSlidePrimitives
, rEnteringSlidePrimitives
, rOverallOperations
, rSceneObjects
),
635 std::shared_ptr
<OGLTransitionImpl
>
636 makeSimpleTransition(
637 const Primitives_t
& rLeavingSlidePrimitives
,
638 const Primitives_t
& rEnteringSlidePrimitives
,
639 const Operations_t
& rOverallOperations
,
640 const TransitionSettings
& rSettings
= TransitionSettings())
642 return makeSimpleTransition(rLeavingSlidePrimitives
, rEnteringSlidePrimitives
, rOverallOperations
, SceneObjects_t(), rSettings
);
645 std::shared_ptr
<OGLTransitionImpl
>
646 makeSimpleTransition(
647 const Primitives_t
& rLeavingSlidePrimitives
,
648 const Primitives_t
& rEnteringSlidePrimitives
,
649 const SceneObjects_t
& rSceneObjects
,
650 const TransitionSettings
& rSettings
)
652 return makeSimpleTransition(rLeavingSlidePrimitives
, rEnteringSlidePrimitives
, Operations_t(), rSceneObjects
, rSettings
);
655 std::shared_ptr
<OGLTransitionImpl
>
656 makeSimpleTransition(
657 const Primitives_t
& rLeavingSlidePrimitives
,
658 const Primitives_t
& rEnteringSlidePrimitives
,
659 const TransitionSettings
& rSettings
= TransitionSettings())
661 return makeSimpleTransition(rLeavingSlidePrimitives
, rEnteringSlidePrimitives
, Operations_t(), SceneObjects_t(), rSettings
);
666 std::shared_ptr
<OGLTransitionImpl
> makeOutsideCubeFaceToLeft()
670 Slide
.pushTriangle(glm::vec2(0,0),glm::vec2(1,0),glm::vec2(0,1));
671 Slide
.pushTriangle(glm::vec2(1,0),glm::vec2(0,1),glm::vec2(1,1));
673 Primitives_t aLeavingPrimitives
;
674 aLeavingPrimitives
.push_back(Slide
);
676 Slide
.Operations
.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0,1,0),glm::vec3(0,0,-1),90,false,false,0.0,1.0));
678 Primitives_t aEnteringPrimitives
;
679 aEnteringPrimitives
.push_back(Slide
);
681 Operations_t aOperations
;
682 aOperations
.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0,1,0),glm::vec3(0,0,-1),-90,false,true,0.0,1.0));
684 return makeSimpleTransition(aLeavingPrimitives
, aEnteringPrimitives
, aOperations
);
687 std::shared_ptr
<OGLTransitionImpl
> makeInsideCubeFaceToLeft()
691 Slide
.pushTriangle(glm::vec2(0,0),glm::vec2(1,0),glm::vec2(0,1));
692 Slide
.pushTriangle(glm::vec2(1,0),glm::vec2(0,1),glm::vec2(1,1));
694 Primitives_t aLeavingPrimitives
;
695 aLeavingPrimitives
.push_back(Slide
);
697 Slide
.Operations
.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0,1,0),glm::vec3(0,0,1),-90,false,false,0.0,1.0));
699 Primitives_t aEnteringPrimitives
;
700 aEnteringPrimitives
.push_back(Slide
);
702 Operations_t aOperations
;
703 aOperations
.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0,1,0),glm::vec3(0,0,1),90,false,true,0.0,1.0));
705 return makeSimpleTransition(aLeavingPrimitives
, aEnteringPrimitives
, aOperations
);
708 std::shared_ptr
<OGLTransitionImpl
> makeFallLeaving()
712 Slide
.pushTriangle(glm::vec2(0,0),glm::vec2(1,0),glm::vec2(0,1));
713 Slide
.pushTriangle(glm::vec2(1,0),glm::vec2(0,1),glm::vec2(1,1));
715 Primitives_t aEnteringPrimitives
;
716 aEnteringPrimitives
.push_back(Slide
);
718 Slide
.Operations
.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(1,0,0),glm::vec3(0,-1,0), 90,true,true,0.0,1.0));
719 Primitives_t aLeavingPrimitives
;
720 aLeavingPrimitives
.push_back(Slide
);
722 TransitionSettings aSettings
;
723 aSettings
.mbUseMipMapEntering
= false;
725 return makeSimpleTransition(aLeavingPrimitives
, aEnteringPrimitives
, aSettings
);
728 std::shared_ptr
<OGLTransitionImpl
> makeTurnAround()
731 TransitionSettings aSettings
;
733 Slide
.pushTriangle(glm::vec2(0,0),glm::vec2(1,0),glm::vec2(0,1));
734 Slide
.pushTriangle(glm::vec2(1,0),glm::vec2(0,1),glm::vec2(1,1));
735 Primitives_t aLeavingPrimitives
;
736 aLeavingPrimitives
.push_back(Slide
);
738 Slide
.Operations
.push_back(makeSScale(glm::vec3(1, -1, 1), glm::vec3(0, -1.02, 0), false, -1, 0));
739 aLeavingPrimitives
.push_back(Slide
);
741 Slide
.Operations
.clear();
742 Slide
.Operations
.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0,1,0),glm::vec3(0,0,0),-180,true,false,0.0,1.0));
743 Primitives_t aEnteringPrimitives
;
744 aEnteringPrimitives
.push_back(Slide
);
746 Slide
.Operations
.push_back(makeSScale(glm::vec3(1, -1, 1), glm::vec3(0, -1.02, 0), false, -1, 0));
747 aEnteringPrimitives
.push_back(Slide
);
749 Operations_t aOperations
;
750 aOperations
.push_back(makeSTranslate(glm::vec3(0, 0, -1.5),true, 0, 0.5));
751 aOperations
.push_back(makeSTranslate(glm::vec3(0, 0, 1.5), true, 0.5, 1));
752 aOperations
.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0, 1, 0),glm::vec3(0, 0, 0), -180, true, true, 0.0, 1.0));
754 return makeReflectionTransition(aLeavingPrimitives
, aEnteringPrimitives
, aOperations
, aSettings
);
757 std::shared_ptr
<OGLTransitionImpl
> makeTurnDown()
761 Slide
.pushTriangle(glm::vec2(0,0),glm::vec2(1,0),glm::vec2(0,1));
762 Slide
.pushTriangle(glm::vec2(1,0),glm::vec2(0,1),glm::vec2(1,1));
763 Primitives_t aLeavingPrimitives
;
764 aLeavingPrimitives
.push_back(Slide
);
766 Slide
.Operations
.push_back(makeSTranslate(glm::vec3(0, 0, 0.0001), false, -1.0, 0.0));
767 Slide
.Operations
.push_back(makeSRotate (glm::vec3(0, 0, 1), glm::vec3(-1, 1, 0), -90, true, 0.0, 1.0));
768 Slide
.Operations
.push_back(makeSRotate (glm::vec3(0, 0, 1), glm::vec3(-1, 1, 0), 90, false, -1.0, 0.0));
769 Primitives_t aEnteringPrimitives
;
770 aEnteringPrimitives
.push_back(Slide
);
772 TransitionSettings aSettings
;
773 aSettings
.mbUseMipMapLeaving
= false;
775 return makeSimpleTransition(aLeavingPrimitives
, aEnteringPrimitives
, aSettings
);
778 std::shared_ptr
<OGLTransitionImpl
> makeIris()
782 Slide
.pushTriangle (glm::vec2 (0,0), glm::vec2 (1,0), glm::vec2 (0,1));
783 Slide
.pushTriangle (glm::vec2 (1,0), glm::vec2 (0,1), glm::vec2 (1,1));
784 Primitives_t aEnteringPrimitives
;
785 aEnteringPrimitives
.push_back (Slide
);
787 Slide
.Operations
.push_back (makeSTranslate (glm::vec3 (0, 0, 0.000001), false, -1, 0));
788 Slide
.Operations
.push_back (makeSTranslate (glm::vec3 (0, 0, -0.000002), false, 0.5, 1));
789 Primitives_t aLeavingPrimitives
;
790 aLeavingPrimitives
.push_back (Slide
);
794 int i
, nSteps
= 24, nParts
= 7;
795 double t
= 1.0/nSteps
, lx
= 1, ly
= 0, of
=2.2, f
=1.42;
797 for (i
=1; i
<=nSteps
; i
++) {
798 double x
= cos ((3*2*M_PI
*t
)/nParts
);
799 double y
= -sin ((3*2*M_PI
*t
)/nParts
);
800 double cx
= (f
*x
+ 1)/2;
801 double cy
= (f
*y
+ 1)/2;
802 double lcx
= (f
*lx
+ 1)/2;
803 double lcy
= (f
*ly
+ 1)/2;
804 double cxo
= (of
*x
+ 1)/2;
805 double cyo
= (of
*y
+ 1)/2;
806 double lcxo
= (of
*lx
+ 1)/2;
807 double lcyo
= (of
*ly
+ 1)/2;
808 irisPart
.pushTriangle (glm::vec2 (lcx
, lcy
),
809 glm::vec2 (lcxo
, lcyo
),
811 irisPart
.pushTriangle (glm::vec2 (cx
, cy
),
812 glm::vec2 (lcxo
, lcyo
),
813 glm::vec2 (cxo
, cyo
));
819 std::shared_ptr
<Iris
> pIris
= std::make_shared
<Iris
>();
822 for (i
= 0; i
< nParts
; i
++) {
823 irisPart
.Operations
.clear ();
826 rx
= cos ((2*M_PI
*i
)/nParts
);
827 ry
= sin ((2*M_PI
*i
)/nParts
);
828 irisPart
.Operations
.push_back (makeSRotate (glm::vec3(0, 0, 1), glm::vec3(rx
, ry
, 0), angle
, true, 0.0, 0.5));
829 irisPart
.Operations
.push_back (makeSRotate (glm::vec3(0, 0, 1), glm::vec3(rx
, ry
, 0), -angle
, true, 0.5, 1));
831 irisPart
.Operations
.push_back (makeSTranslate (glm::vec3(rx
, ry
, 0), false, -1, 0));
832 irisPart
.Operations
.push_back (makeSRotate (glm::vec3(0, 0, 1), glm::vec3(0, 0, 0), i
*360.0/nParts
, false, -1, 0));
833 irisPart
.Operations
.push_back (makeSTranslate (glm::vec3(-1, 0, 0), false, -1, 0));
835 irisPart
.Operations
.push_back(makeSTranslate(glm::vec3(0, 0, 1), false, -2, 0.0));
836 irisPart
.Operations
.push_back (makeSRotate (glm::vec3(1, .5, 0), glm::vec3(1, 0, 0), -30, false, -1, 0));
837 pIris
->pushPrimitive (irisPart
);
840 SceneObjects_t aSceneObjects
;
841 aSceneObjects
.push_back (pIris
);
843 TransitionSettings aSettings
;
844 aSettings
.mbUseMipMapLeaving
= aSettings
.mbUseMipMapEntering
= false;
846 return makeSimpleTransition(aLeavingPrimitives
, aEnteringPrimitives
, aSceneObjects
, aSettings
);
852 class RochadeTransition
: public ReflectionTransition
855 RochadeTransition(const TransitionScene
& rScene
, const TransitionSettings
& rSettings
)
856 : ReflectionTransition(rScene
, rSettings
)
860 virtual void displaySlides_(double nTime
, sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, double SlideWidthScale
, double SlideHeightScale
, OpenGLContext
*pContext
) override
;
863 void RochadeTransition::displaySlides_( double nTime
, sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, double SlideWidthScale
, double SlideHeightScale
, OpenGLContext
* )
865 applyOverallOperations( nTime
, SlideWidthScale
, SlideHeightScale
);
868 displaySlide( nTime
, glLeavingSlideTex
, getScene().getLeavingSlide(), SlideWidthScale
, SlideHeightScale
);
869 displaySlide( nTime
, glEnteringSlideTex
, getScene().getEnteringSlide(), SlideWidthScale
, SlideHeightScale
);
871 displaySlide( nTime
, glEnteringSlideTex
, getScene().getEnteringSlide(), SlideWidthScale
, SlideHeightScale
);
872 displaySlide( nTime
, glLeavingSlideTex
, getScene().getLeavingSlide(), SlideWidthScale
, SlideHeightScale
);
876 std::shared_ptr
<OGLTransitionImpl
>
877 makeRochadeTransition(
878 const Primitives_t
& rLeavingSlidePrimitives
,
879 const Primitives_t
& rEnteringSlidePrimitives
,
880 const TransitionSettings
& rSettings
)
882 return std::make_shared
<RochadeTransition
>(
883 TransitionScene(rLeavingSlidePrimitives
, rEnteringSlidePrimitives
),
890 std::shared_ptr
<OGLTransitionImpl
> makeRochade()
893 TransitionSettings aSettings
;
900 Slide
.pushTriangle(glm::vec2(0,0),glm::vec2(1,0),glm::vec2(0,1));
901 Slide
.pushTriangle(glm::vec2(1,0),glm::vec2(0,1),glm::vec2(1,1));
903 Slide
.Operations
.push_back(makeSEllipseTranslate(w
, h
, 0.25, -0.25, true, 0, 1));
904 Slide
.Operations
.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0,1,0),glm::vec3(0,0,0), -45, true, true, 0, 1));
905 Primitives_t aLeavingSlide
;
906 aLeavingSlide
.push_back(Slide
);
908 Slide
.Operations
.push_back(makeSScale(glm::vec3(1, -1, 1), glm::vec3(0, -1.02, 0), false, -1, 0));
909 aLeavingSlide
.push_back(Slide
);
911 Slide
.Operations
.clear();
912 Slide
.Operations
.push_back(makeSEllipseTranslate(w
, h
, 0.75, 0.25, true, 0, 1));
913 Slide
.Operations
.push_back(makeSTranslate(glm::vec3(0, 0, -h
), false, -1, 0));
914 Slide
.Operations
.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0,1,0),glm::vec3(0,0,0), -45, true, true, 0, 1));
915 Slide
.Operations
.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0,1,0),glm::vec3(0,0,0), 45, true, false, -1, 0));
916 Primitives_t aEnteringSlide
;
917 aEnteringSlide
.push_back(Slide
);
919 Slide
.Operations
.push_back(makeSScale(glm::vec3(1, -1, 1), glm::vec3(0, -1.02, 0), false, -1, 0));
920 aEnteringSlide
.push_back(Slide
);
922 return makeRochadeTransition(aLeavingSlide
, aEnteringSlide
, aSettings
);
925 static double randFromNeg1to1()
927 return comphelper::rng::uniform_real_distribution(-1.0, std::nextafter(1.0, DBL_MAX
));
930 // TODO(Q3): extract to basegfx
931 static glm::vec3
randNormVectorInXYPlane()
933 glm::vec3
toReturn(randFromNeg1to1(),randFromNeg1to1(),0.0);
934 return glm::normalize(toReturn
);
938 static T
clamp(const T
& rIn
)
940 return glm::clamp(rIn
, T(-1.0), T(1.0));
943 std::shared_ptr
<OGLTransitionImpl
> makeRevolvingCircles( sal_uInt16 nCircles
, sal_uInt16 nPointsOnCircles
)
945 double dAngle(2*3.1415926/static_cast<double>( nPointsOnCircles
));
946 if(nCircles
< 2 || nPointsOnCircles
< 4)
947 return makeNByMTileFlip(1,1);
948 float Radius(1.0/static_cast<double>( nCircles
));
949 float dRadius(Radius
);
950 float LastRadius(0.0);
951 float NextRadius(2*Radius
);
953 /// now we know there is at least two circles
954 /// the first will always be a full circle
955 /// the last will always be the outer shell of the slide with a circle hole
957 //add the full circle
958 std::vector
<glm::vec2
> unScaledTexCoords
;
959 float TempAngle(0.0);
960 for(unsigned int Point(0); Point
< nPointsOnCircles
; ++Point
)
962 unScaledTexCoords
.emplace_back( cos(TempAngle
- 3.1415926/2.0) , sin(TempAngle
- 3.1415926/2.0) );
967 Primitives_t aLeavingSlide
;
968 Primitives_t aEnteringSlide
;
970 Primitive EnteringSlide
;
971 Primitive LeavingSlide
;
972 for(int Point(0); Point
+ 1 < nPointsOnCircles
; ++Point
)
974 EnteringSlide
.pushTriangle( glm::vec2( 0.5 , 0.5 ) , Radius
* unScaledTexCoords
[ Point
+ 1 ] / 2.0f
+ glm::vec2( 0.5 , 0.5 ) , Radius
* unScaledTexCoords
[ Point
] / 2.0f
+ glm::vec2( 0.5 , 0.5 ) );
975 LeavingSlide
.pushTriangle( glm::vec2( 0.5 , 0.5 ) , Radius
* unScaledTexCoords
[ Point
+ 1 ] / 2.0f
+ glm::vec2( 0.5 , 0.5 ) , Radius
* unScaledTexCoords
[ Point
] / 2.0f
+ glm::vec2( 0.5, 0.5) );
977 EnteringSlide
.pushTriangle( glm::vec2(0.5,0.5) , Radius
* unScaledTexCoords
[ 0 ] / 2.0f
+ glm::vec2( 0.5 , 0.5 ) , Radius
* unScaledTexCoords
[ nPointsOnCircles
- 1 ] / 2.0f
+ glm::vec2( 0.5 , 0.5 ) );
978 LeavingSlide
.pushTriangle( glm::vec2(0.5,0.5) , Radius
*unScaledTexCoords
[0]/2.0f
+ glm::vec2(0.5,0.5) , Radius
*unScaledTexCoords
[nPointsOnCircles
- 1]/2.0f
+ glm::vec2(0.5,0.5) );
980 glm::vec3
axis(randNormVectorInXYPlane());
981 EnteringSlide
.Operations
.push_back( makeSRotate( axis
, glm::vec3(0,0,0) , 180, true, Radius
/2.0 , (NextRadius
+ 1)/2.0 ) );
982 LeavingSlide
.Operations
.push_back( makeSRotate( axis
, glm::vec3(0,0,0) , 180, true, Radius
/2.0 , (NextRadius
+ 1)/2.0 ) );
983 EnteringSlide
.Operations
.push_back( makeSRotate( axis
, glm::vec3(0,0,0) , -180, false,0.0,1.0) );
985 aEnteringSlide
.push_back(EnteringSlide
);
986 aLeavingSlide
.push_back(LeavingSlide
);
989 NextRadius
+= dRadius
;
992 for(int i(1); i
< nCircles
- 1; ++i
)
994 Primitive LeavingSlide
;
995 Primitive EnteringSlide
;
996 for(int Side(0); Side
< nPointsOnCircles
- 1; ++Side
)
998 EnteringSlide
.pushTriangle(Radius
*unScaledTexCoords
[Side
]/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[Side
]/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[Side
+ 1]/2.0f
+ glm::vec2(0.5,0.5) );
999 EnteringSlide
.pushTriangle(Radius
*unScaledTexCoords
[Side
]/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[Side
+ 1]/2.0f
+ glm::vec2(0.5,0.5) , Radius
*unScaledTexCoords
[Side
+ 1]/2.0f
+ glm::vec2(0.5,0.5) );
1001 LeavingSlide
.pushTriangle(Radius
*unScaledTexCoords
[Side
]/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[Side
]/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[Side
+ 1]/2.0f
+ glm::vec2(0.5,0.5) );
1002 LeavingSlide
.pushTriangle(Radius
*unScaledTexCoords
[Side
]/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[Side
+ 1]/2.0f
+ glm::vec2(0.5,0.5) , Radius
*unScaledTexCoords
[Side
+ 1]/2.0f
+ glm::vec2(0.5,0.5) );
1005 EnteringSlide
.pushTriangle(Radius
*unScaledTexCoords
[nPointsOnCircles
- 1]/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[nPointsOnCircles
- 1]/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[0]/2.0f
+ glm::vec2(0.5,0.5) );
1006 EnteringSlide
.pushTriangle(Radius
*unScaledTexCoords
[nPointsOnCircles
- 1]/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[0]/2.0f
+ glm::vec2(0.5,0.5) , Radius
*unScaledTexCoords
[0]/2.0f
+ glm::vec2(0.5,0.5) );
1008 LeavingSlide
.pushTriangle(Radius
*unScaledTexCoords
[nPointsOnCircles
- 1]/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[nPointsOnCircles
- 1]/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[0]/2.0f
+ glm::vec2(0.5,0.5) );
1009 LeavingSlide
.pushTriangle(Radius
*unScaledTexCoords
[nPointsOnCircles
- 1]/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[0]/2.0f
+ glm::vec2(0.5,0.5) , Radius
*unScaledTexCoords
[0]/2.0f
+ glm::vec2(0.5,0.5) );
1011 glm::vec3
axis(randNormVectorInXYPlane());
1012 EnteringSlide
.Operations
.push_back( makeSRotate( axis
, glm::vec3(0,0,0) , 180, true, Radius
/2.0 , (NextRadius
+ 1)/2.0 ) );
1013 LeavingSlide
.Operations
.push_back( makeSRotate( axis
, glm::vec3(0,0,0) , 180, true, Radius
/2.0 , (NextRadius
+ 1)/2.0 ) );
1014 EnteringSlide
.Operations
.push_back( makeSRotate( axis
, glm::vec3(0,0,0) , -180, false,0.0,1.0) );
1016 aEnteringSlide
.push_back(EnteringSlide
);
1017 aLeavingSlide
.push_back(LeavingSlide
);
1019 LastRadius
= Radius
;
1020 Radius
= NextRadius
;
1021 NextRadius
+= dRadius
;
1025 Primitive LeavingSlide
;
1026 Primitive EnteringSlide
;
1027 for(int Side(0); Side
< nPointsOnCircles
- 1; ++Side
)
1030 EnteringSlide
.pushTriangle(clamp(Radius
*unScaledTexCoords
[Side
])/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[Side
]/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[Side
+ 1]/2.0f
+ glm::vec2(0.5,0.5) );
1031 EnteringSlide
.pushTriangle(clamp(Radius
*unScaledTexCoords
[Side
])/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[Side
+ 1]/2.0f
+ glm::vec2(0.5,0.5) , clamp(Radius
*unScaledTexCoords
[Side
+ 1])/2.0f
+ glm::vec2(0.5,0.5) );
1033 LeavingSlide
.pushTriangle(clamp(Radius
*unScaledTexCoords
[Side
])/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[Side
]/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[Side
+ 1]/2.0f
+ glm::vec2(0.5,0.5) );
1034 LeavingSlide
.pushTriangle(clamp(Radius
*unScaledTexCoords
[Side
])/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[Side
+ 1]/2.0f
+ glm::vec2(0.5,0.5) , clamp(Radius
*unScaledTexCoords
[Side
+ 1])/2.0f
+ glm::vec2(0.5,0.5) );
1037 EnteringSlide
.pushTriangle(clamp(Radius
*unScaledTexCoords
[nPointsOnCircles
- 1])/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[nPointsOnCircles
- 1]/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[0]/2.0f
+ glm::vec2(0.5,0.5) );
1038 EnteringSlide
.pushTriangle(clamp(Radius
*unScaledTexCoords
[nPointsOnCircles
- 1])/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[0]/2.0f
+ glm::vec2(0.5,0.5) , clamp(Radius
*unScaledTexCoords
[0])/2.0f
+ glm::vec2(0.5,0.5) );
1040 LeavingSlide
.pushTriangle(clamp(Radius
*unScaledTexCoords
[nPointsOnCircles
- 1])/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[nPointsOnCircles
- 1]/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[0]/2.0f
+ glm::vec2(0.5,0.5) );
1041 LeavingSlide
.pushTriangle(clamp(Radius
*unScaledTexCoords
[nPointsOnCircles
- 1])/2.0f
+ glm::vec2(0.5,0.5) , LastRadius
*unScaledTexCoords
[0]/2.0f
+ glm::vec2(0.5,0.5) , clamp(Radius
*unScaledTexCoords
[0])/2.0f
+ glm::vec2(0.5,0.5) );
1043 glm::vec3
axis(randNormVectorInXYPlane());
1044 EnteringSlide
.Operations
.push_back( makeSRotate( axis
, glm::vec3(0,0,0) , 180, true, (LastRadius
+ dRadius
)/2.0 , 1.0 ) );
1045 LeavingSlide
.Operations
.push_back( makeSRotate( axis
, glm::vec3(0,0,0) , 180, true, (LastRadius
+ dRadius
)/2.0 , 1.0 ) );
1046 EnteringSlide
.Operations
.push_back( makeSRotate( axis
, glm::vec3(0,0,0) , -180, false,0.0,1.0) );
1048 aEnteringSlide
.push_back(EnteringSlide
);
1049 aLeavingSlide
.push_back(LeavingSlide
);
1052 return makeSimpleTransition(aLeavingSlide
, aEnteringSlide
);
1055 std::shared_ptr
<OGLTransitionImpl
> makeHelix( sal_uInt16 nRows
)
1057 double invN(1.0/static_cast<double>(nRows
));
1060 Primitives_t aLeavingSlide
;
1061 Primitives_t aEnteringSlide
;
1062 for(unsigned int i(0); i
< nRows
; ++i
)
1066 Tile
.pushTriangle(glm::vec2( 1.0 , iDn
) , glm::vec2( 0.0 , iDn
) , glm::vec2( 0.0 , iPDn
));
1068 Tile
.pushTriangle(glm::vec2( 1.0 , iPDn
) , glm::vec2( 1.0 , iDn
) , glm::vec2( 0.0 , iPDn
));
1070 Tile
.Operations
.push_back( makeSRotate( glm::vec3( 0 , 1 , 0 ) , ( Tile
.getVertex(1) + Tile
.getVertex(3) )/2.0f
, 180 ,
1071 true, std::min(std::max(static_cast<double>(i
- nRows
/2.0)*invN
/2.0,0.0),1.0),
1072 std::min(std::max(static_cast<double>(i
+ nRows
/2.0)*invN
/2.0,0.0),1.0) ) );
1074 aLeavingSlide
.push_back(Tile
);
1076 Tile
.Operations
.push_back( makeSRotate( glm::vec3( 0 , 1 , 0 ) , ( Tile
.getVertex(1) + Tile
.getVertex(3) )/2.0f
, -180 , false,0.0,1.0) );
1078 aEnteringSlide
.push_back(Tile
);
1084 return makeSimpleTransition(aLeavingSlide
, aEnteringSlide
);
1087 static float fdiv(int a
, int b
)
1089 return static_cast<float>(a
)/b
;
1092 static glm::vec2
vec(float x
, float y
, float nx
, float ny
)
1094 x
= x
< 0.0 ? 0.0 : x
;
1095 x
= std::min(x
, nx
);
1096 y
= y
< 0.0 ? 0.0 : y
;
1097 y
= std::min(y
, ny
);
1098 return glm::vec2(fdiv(x
, nx
), fdiv(y
, ny
));
1101 std::shared_ptr
<OGLTransitionImpl
> makeNByMTileFlip( sal_uInt16 n
, sal_uInt16 m
)
1103 Primitives_t aLeavingSlide
;
1104 Primitives_t aEnteringSlide
;
1106 for (int x
= 0; x
< n
; x
++)
1108 for (int y
= 0; y
< n
; y
++)
1111 glm::vec2 x11
= vec(x
, y
, n
, m
);
1112 glm::vec2 x12
= vec(x
, y
+1, n
, m
);
1113 glm::vec2 x21
= vec(x
+1, y
, n
, m
);
1114 glm::vec2 x22
= vec(x
+1, y
+1, n
, m
);
1116 aTile
.pushTriangle(x21
, x11
, x12
);
1117 aTile
.pushTriangle(x22
, x21
, x12
);
1119 aTile
.Operations
.push_back(makeSRotate( glm::vec3(0 , 1, 0), (aTile
.getVertex(1) + aTile
.getVertex(3)) / 2.0f
, 180 , true, x11
.x
* x11
.y
/ 2.0f
, ((x22
.x
* x22
.y
) + 1.0f
) / 2.0f
));
1120 aLeavingSlide
.push_back(aTile
);
1122 aTile
.Operations
.push_back(makeSRotate( glm::vec3(0 , 1, 0), (aTile
.getVertex(1) + aTile
.getVertex(3)) / 2.0f
, -180, false, x11
.x
* x11
.y
/ 2.0f
, ((x22
.x
* x22
.y
) + 1.0f
) / 2.0f
));
1123 aEnteringSlide
.push_back(aTile
);
1127 return makeSimpleTransition(aLeavingSlide
, aEnteringSlide
);
1130 Primitive
& Primitive::operator=(const Primitive
& rvalue
)
1132 Primitive
aTmp(rvalue
);
1137 Primitive::Primitive(const Primitive
& rvalue
)
1138 : Operations(rvalue
.Operations
)
1139 , Vertices(rvalue
.Vertices
)
1143 void Primitive::swap(Primitive
& rOther
)
1147 swap(Operations
, rOther
.Operations
);
1148 swap(Vertices
, rOther
.Vertices
);
1151 void Primitive::pushTriangle(const glm::vec2
& SlideLocation0
,const glm::vec2
& SlideLocation1
,const glm::vec2
& SlideLocation2
)
1153 std::vector
<glm::vec3
> Verts
;
1154 std::vector
<glm::vec2
> Texs
;
1158 Verts
.emplace_back( 2*SlideLocation0
.x
- 1, -2*SlideLocation0
.y
+ 1 , 0.0 );
1159 Verts
.emplace_back( 2*SlideLocation1
.x
- 1, -2*SlideLocation1
.y
+ 1 , 0.0 );
1160 Verts
.emplace_back( 2*SlideLocation2
.x
- 1, -2*SlideLocation2
.y
+ 1 , 0.0 );
1162 //figure out if they're facing the correct way, and make them face the correct way.
1163 glm::vec3
Normal( glm::cross( Verts
[0] - Verts
[1] , Verts
[1] - Verts
[2] ) );
1164 if(Normal
.z
>= 0.0)//if the normal is facing us
1166 Texs
.push_back(SlideLocation0
);
1167 Texs
.push_back(SlideLocation1
);
1168 Texs
.push_back(SlideLocation2
);
1170 else // if the normal is facing away from us, make it face us
1172 Texs
.push_back(SlideLocation0
);
1173 Texs
.push_back(SlideLocation2
);
1174 Texs
.push_back(SlideLocation1
);
1176 Verts
.emplace_back( 2*SlideLocation0
.x
- 1, -2*SlideLocation0
.y
+ 1 , 0.0 );
1177 Verts
.emplace_back( 2*SlideLocation2
.x
- 1, -2*SlideLocation2
.y
+ 1 , 0.0 );
1178 Verts
.emplace_back( 2*SlideLocation1
.x
- 1, -2*SlideLocation1
.y
+ 1 , 0.0 );
1181 Vertices
.push_back({Verts
[0], glm::vec3(0, 0, 1), Texs
[0]}); //all normals always face the screen when untransformed.
1182 Vertices
.push_back({Verts
[1], glm::vec3(0, 0, 1), Texs
[1]}); //all normals always face the screen when untransformed.
1183 Vertices
.push_back({Verts
[2], glm::vec3(0, 0, 1), Texs
[2]}); //all normals always face the screen when untransformed.
1189 class DiamondTransition
: public SimpleTransition
1192 DiamondTransition(const TransitionScene
& rScene
, const TransitionSettings
& rSettings
)
1193 : SimpleTransition(rScene
, rSettings
)
1197 virtual void displaySlides_( double nTime
, sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, double SlideWidthScale
, double SlideHeightScale
, OpenGLContext
*pContext
) override
;
1200 Primitives_t
makeLeavingSlide(double nTime
)
1203 if( nTime
>= 0.5 ) {
1204 double m
= 1 - nTime
;
1206 Slide2
.pushTriangle (glm::vec2 (0,0), glm::vec2 (m
,0), glm::vec2 (0,m
));
1207 Slide2
.pushTriangle (glm::vec2 (nTime
,0), glm::vec2 (1,0), glm::vec2 (1,m
));
1208 Slide2
.pushTriangle (glm::vec2 (1,nTime
), glm::vec2 (1,1), glm::vec2 (nTime
,1));
1209 Slide2
.pushTriangle (glm::vec2 (0,nTime
), glm::vec2 (m
,1), glm::vec2 (0,1));
1211 double l
= 0.5 - nTime
;
1212 double h
= 0.5 + nTime
;
1214 Slide2
.pushTriangle (glm::vec2 (0,0), glm::vec2 (1,0), glm::vec2 (0.5,l
));
1215 Slide2
.pushTriangle (glm::vec2 (0.5,l
), glm::vec2 (1,0), glm::vec2 (h
,0.5));
1216 Slide2
.pushTriangle (glm::vec2 (1,0), glm::vec2 (1,1), glm::vec2 (h
,0.5));
1217 Slide2
.pushTriangle (glm::vec2 (h
,0.5), glm::vec2 (1,1), glm::vec2 (0.5,h
));
1218 Slide2
.pushTriangle (glm::vec2 (0.5,h
), glm::vec2 (1,1), glm::vec2 (0,1));
1219 Slide2
.pushTriangle (glm::vec2 (l
,0.5), glm::vec2 (0.5,h
), glm::vec2 (0,1));
1220 Slide2
.pushTriangle (glm::vec2 (0,0), glm::vec2 (l
,0.5), glm::vec2 (0,1));
1221 Slide2
.pushTriangle (glm::vec2 (0,0), glm::vec2 (0.5,l
), glm::vec2 (l
,0.5));
1223 Slide2
.Operations
.push_back (makeSTranslate (glm::vec3 (0, 0, 0.00000001), false, -1, 0));
1224 Primitives_t aLeavingSlidePrimitives
;
1225 aLeavingSlidePrimitives
.push_back (Slide2
);
1227 return aLeavingSlidePrimitives
;
1230 void DiamondTransition::displaySlides_( double nTime
, sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
,
1231 double SlideWidthScale
, double SlideHeightScale
, OpenGLContext
* )
1234 applyOverallOperations( nTime
, SlideWidthScale
, SlideHeightScale
);
1237 displayUnbufferedSlide( nTime
, glLeavingSlideTex
, makeLeavingSlide(nTime
), SlideWidthScale
, SlideHeightScale
);
1238 displaySlide( nTime
, glEnteringSlideTex
, getScene().getEnteringSlide(), SlideWidthScale
, SlideHeightScale
);
1242 std::shared_ptr
<OGLTransitionImpl
>
1243 makeDiamondTransition(const TransitionSettings
& rSettings
)
1246 Slide1
.pushTriangle (glm::vec2 (0,0), glm::vec2 (1,0), glm::vec2 (0,1));
1247 Slide1
.pushTriangle (glm::vec2 (1,0), glm::vec2 (0,1), glm::vec2 (1,1));
1248 Primitives_t aEnteringSlidePrimitives
;
1249 aEnteringSlidePrimitives
.push_back (Slide1
);
1250 Primitives_t aLeavingSlidePrimitives
;
1251 aLeavingSlidePrimitives
.push_back (Slide1
);
1252 return std::make_shared
<DiamondTransition
>(TransitionScene(aLeavingSlidePrimitives
, aEnteringSlidePrimitives
), rSettings
);
1257 std::shared_ptr
<OGLTransitionImpl
> makeDiamond()
1259 TransitionSettings aSettings
;
1260 aSettings
.mbUseMipMapLeaving
= aSettings
.mbUseMipMapEntering
= false;
1262 return makeDiamondTransition(aSettings
);
1265 std::shared_ptr
<OGLTransitionImpl
> makeVenetianBlinds( bool vertical
, int parts
)
1267 static double t30
= tan( M_PI
/6.0 );
1269 double p
= 1.0/parts
;
1271 Primitives_t aLeavingSlide
;
1272 Primitives_t aEnteringSlide
;
1273 for( int i
=0; i
<parts
; i
++ ) {
1275 double n
= (i
+ 1)/static_cast<double>(parts
);
1277 Slide
.pushTriangle (glm::vec2 (ln
,0), glm::vec2 (n
,0), glm::vec2 (ln
,1));
1278 Slide
.pushTriangle (glm::vec2 (n
,0), glm::vec2 (ln
,1), glm::vec2 (n
,1));
1279 Slide
.Operations
.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0, 1, 0), glm::vec3(n
+ ln
- 1, 0, -t30
*p
), -120, true, true, 0.0, 1.0));
1281 Slide
.pushTriangle (glm::vec2 (0,ln
), glm::vec2 (1,ln
), glm::vec2 (0,n
));
1282 Slide
.pushTriangle (glm::vec2 (1,ln
), glm::vec2 (0,n
), glm::vec2 (1,n
));
1283 Slide
.Operations
.push_back(makeRotateAndScaleDepthByHeight(glm::vec3(1, 0, 0), glm::vec3(0, 1 - n
- ln
, -t30
*p
), -120, true, true, 0.0, 1.0));
1285 aLeavingSlide
.push_back (Slide
);
1288 Slide
.Operations
.push_back(makeSRotate(glm::vec3(0, 1, 0), glm::vec3(2*n
- 1, 0, 0), -60, false, -1, 0));
1289 Slide
.Operations
.push_back(makeSRotate(glm::vec3(0, 1, 0), glm::vec3(n
+ ln
- 1, 0, 0), 180, false, -1, 0));
1291 Slide
.Operations
.push_back(makeSRotate(glm::vec3(1, 0, 0), glm::vec3(0, 1 - 2*n
, 0), -60, false, -1, 0));
1292 Slide
.Operations
.push_back(makeSRotate(glm::vec3(1, 0, 0), glm::vec3(0, 1 - n
- ln
, 0), 180, false, -1, 0));
1294 aEnteringSlide
.push_back (Slide
);
1298 return makeSimpleTransition(aLeavingSlide
, aEnteringSlide
);
1304 class FadeSmoothlyTransition
: public OGLTransitionImpl
1307 FadeSmoothlyTransition(const TransitionScene
& rScene
, const TransitionSettings
& rSettings
)
1308 : OGLTransitionImpl(rScene
, rSettings
)
1312 virtual GLuint
makeShader() const override
;
1315 GLuint
FadeSmoothlyTransition::makeShader() const
1317 return OpenGLHelper::LoadShaders( "basicVertexShader", "fadeFragmentShader" );
1320 std::shared_ptr
<OGLTransitionImpl
>
1321 makeFadeSmoothlyTransition(
1322 const Primitives_t
& rLeavingSlidePrimitives
,
1323 const Primitives_t
& rEnteringSlidePrimitives
,
1324 const TransitionSettings
& rSettings
)
1326 return std::make_shared
<FadeSmoothlyTransition
>(
1327 TransitionScene(rLeavingSlidePrimitives
, rEnteringSlidePrimitives
),
1334 std::shared_ptr
<OGLTransitionImpl
> makeFadeSmoothly()
1338 Slide
.pushTriangle (glm::vec2 (0,0), glm::vec2 (1,0), glm::vec2 (0,1));
1339 Slide
.pushTriangle (glm::vec2 (1,0), glm::vec2 (0,1), glm::vec2 (1,1));
1340 Primitives_t aLeavingSlide
;
1341 aLeavingSlide
.push_back (Slide
);
1342 Primitives_t aEnteringSlide
;
1343 aEnteringSlide
.push_back (Slide
);
1345 TransitionSettings aSettings
;
1346 aSettings
.mbUseMipMapLeaving
= aSettings
.mbUseMipMapEntering
= false;
1348 return makeFadeSmoothlyTransition(aLeavingSlide
, aEnteringSlide
, aSettings
);
1354 class FadeThroughColorTransition
: public OGLTransitionImpl
1357 FadeThroughColorTransition(const TransitionScene
& rScene
, const TransitionSettings
& rSettings
, bool white
)
1358 : OGLTransitionImpl(rScene
, rSettings
), useWhite( white
)
1362 virtual GLuint
makeShader() const override
;
1366 GLuint
FadeThroughColorTransition::makeShader() const
1368 return OpenGLHelper::LoadShaders( "basicVertexShader", "fadeBlackFragmentShader",
1369 useWhite
? "#define use_white" : "", "" );
1372 std::shared_ptr
<OGLTransitionImpl
>
1373 makeFadeThroughColorTransition(
1374 const Primitives_t
& rLeavingSlidePrimitives
,
1375 const Primitives_t
& rEnteringSlidePrimitives
,
1376 const TransitionSettings
& rSettings
,
1379 return std::make_shared
<FadeThroughColorTransition
>(
1380 TransitionScene(rLeavingSlidePrimitives
, rEnteringSlidePrimitives
),
1387 std::shared_ptr
<OGLTransitionImpl
> makeFadeThroughColor( bool white
)
1391 Slide
.pushTriangle (glm::vec2 (0,0), glm::vec2 (1,0), glm::vec2 (0,1));
1392 Slide
.pushTriangle (glm::vec2 (1,0), glm::vec2 (0,1), glm::vec2 (1,1));
1393 Primitives_t aLeavingSlide
;
1394 aLeavingSlide
.push_back (Slide
);
1395 Primitives_t aEnteringSlide
;
1396 aEnteringSlide
.push_back (Slide
);
1398 TransitionSettings aSettings
;
1399 aSettings
.mbUseMipMapLeaving
= aSettings
.mbUseMipMapEntering
= false;
1401 return makeFadeThroughColorTransition(aLeavingSlide
, aEnteringSlide
, aSettings
, white
);
1407 class PermTextureTransition
: public OGLTransitionImpl
1410 PermTextureTransition(const TransitionScene
& rScene
, const TransitionSettings
& rSettings
)
1411 : OGLTransitionImpl(rScene
, rSettings
)
1412 , m_nHelperTexture(0)
1415 virtual void finishTransition() override
;
1416 virtual void prepareTransition( sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, OpenGLContext
*pContext
) override
;
1420 GLuint m_nHelperTexture
;
1423 void PermTextureTransition::finishTransition()
1426 if ( m_nHelperTexture
)
1428 glDeleteTextures( 1, &m_nHelperTexture
);
1429 m_nHelperTexture
= 0;
1434 int permutation256
[256]= {
1435 215, 100, 200, 204, 233, 50, 85, 196,
1436 71, 141, 122, 160, 93, 131, 243, 234,
1437 162, 183, 36, 155, 4, 62, 35, 205,
1438 40, 102, 33, 27, 255, 55, 214, 156,
1439 75, 163, 134, 126, 249, 74, 197, 228,
1440 72, 90, 206, 235, 17, 22, 49, 169,
1441 227, 89, 16, 5, 117, 60, 248, 230,
1442 217, 68, 138, 96, 194, 170, 136, 10,
1443 112, 238, 184, 189, 176, 42, 225, 212,
1444 84, 58, 175, 244, 150, 168, 219, 236,
1445 101, 208, 123, 37, 164, 110, 158, 201,
1446 78, 114, 57, 48, 70, 142, 106, 43,
1447 232, 26, 32, 252, 239, 98, 191, 94,
1448 59, 149, 39, 187, 203, 190, 19, 13,
1449 133, 45, 61, 247, 23, 34, 20, 52,
1450 118, 209, 146, 193, 222, 18, 1, 152,
1451 46, 41, 91, 148, 115, 25, 135, 77,
1452 254, 147, 224, 161, 9, 213, 223, 250,
1453 231, 251, 127, 166, 63, 179, 81, 130,
1454 139, 28, 120, 151, 241, 86, 111, 0,
1455 88, 153, 172, 182, 159, 105, 178, 47,
1456 51, 167, 65, 66, 92, 73, 198, 211,
1457 245, 195, 31, 220, 140, 76, 221, 186,
1458 154, 185, 56, 83, 38, 165, 109, 67,
1459 124, 226, 132, 53, 229, 29, 12, 181,
1460 121, 24, 207, 199, 177, 113, 30, 80,
1461 3, 97, 188, 79, 216, 173, 8, 145,
1462 87, 128, 180, 237, 240, 137, 125, 104,
1463 15, 242, 119, 246, 103, 143, 95, 144,
1464 2, 44, 69, 157, 192, 174, 14, 54,
1465 218, 82, 64, 210, 11, 6, 129, 21,
1466 116, 171, 99, 202, 7, 107, 253, 108
1469 void initPermTexture(GLuint
*texID
)
1472 glGenTextures(1, texID
);
1473 glBindTexture(GL_TEXTURE_2D
, *texID
);
1475 static bool initialized
= false;
1476 static unsigned char permutation2D
[256*256*4];
1477 if( !initialized
) {
1480 for( y
=0; y
< 256; y
++ )
1481 for( x
=0; x
< 256; x
++ )
1482 permutation2D
[x
*4 + y
*1024] = permutation256
[(y
+ permutation256
[x
]) & 0xff];
1487 glTexImage2D( GL_TEXTURE_2D
, 0, GL_RGBA
, 256, 256, 0, GL_RGBA
, GL_UNSIGNED_BYTE
, permutation2D
);
1488 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
1489 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
1493 void PermTextureTransition::prepareTransition( sal_Int32
, sal_Int32
, OpenGLContext
* )
1496 GLint location
= glGetUniformLocation( m_nProgramObject
, "permTexture" );
1497 if( location
!= -1 ) {
1498 glActiveTexture(GL_TEXTURE1
);
1500 if( !m_nHelperTexture
)
1501 initPermTexture( &m_nHelperTexture
);
1503 glActiveTexture(GL_TEXTURE0
);
1506 glUniform1i( location
, 1 ); // texture unit 1
1517 class StaticNoiseTransition
: public PermTextureTransition
1520 StaticNoiseTransition(const TransitionScene
& rScene
, const TransitionSettings
& rSettings
)
1521 : PermTextureTransition(rScene
, rSettings
)
1525 virtual GLuint
makeShader() const override
;
1528 GLuint
StaticNoiseTransition::makeShader() const
1530 return OpenGLHelper::LoadShaders( "basicVertexShader", "staticFragmentShader" );
1533 std::shared_ptr
<OGLTransitionImpl
>
1534 makeStaticNoiseTransition(
1535 const Primitives_t
& rLeavingSlidePrimitives
,
1536 const Primitives_t
& rEnteringSlidePrimitives
,
1537 const TransitionSettings
& rSettings
)
1539 return std::make_shared
<StaticNoiseTransition
>(
1540 TransitionScene(rLeavingSlidePrimitives
, rEnteringSlidePrimitives
),
1547 std::shared_ptr
<OGLTransitionImpl
> makeStatic()
1551 Slide
.pushTriangle (glm::vec2 (0,0), glm::vec2 (1,0), glm::vec2 (0,1));
1552 Slide
.pushTriangle (glm::vec2 (1,0), glm::vec2 (0,1), glm::vec2 (1,1));
1553 Primitives_t aLeavingSlide
;
1554 aLeavingSlide
.push_back (Slide
);
1555 Primitives_t aEnteringSlide
;
1556 aEnteringSlide
.push_back (Slide
);
1558 TransitionSettings aSettings
;
1559 aSettings
.mbUseMipMapLeaving
= aSettings
.mbUseMipMapEntering
= false;
1561 return makeStaticNoiseTransition(aLeavingSlide
, aEnteringSlide
, aSettings
);
1567 class DissolveTransition
: public PermTextureTransition
1570 DissolveTransition(const TransitionScene
& rScene
, const TransitionSettings
& rSettings
)
1571 : PermTextureTransition(rScene
, rSettings
)
1575 virtual GLuint
makeShader() const override
;
1578 GLuint
DissolveTransition::makeShader() const
1580 return OpenGLHelper::LoadShaders( "basicVertexShader", "dissolveFragmentShader" );
1583 std::shared_ptr
<OGLTransitionImpl
>
1584 makeDissolveTransition(
1585 const Primitives_t
& rLeavingSlidePrimitives
,
1586 const Primitives_t
& rEnteringSlidePrimitives
,
1587 const TransitionSettings
& rSettings
)
1589 return std::make_shared
<DissolveTransition
>(
1590 TransitionScene(rLeavingSlidePrimitives
, rEnteringSlidePrimitives
),
1597 std::shared_ptr
<OGLTransitionImpl
> makeDissolve()
1601 Slide
.pushTriangle (glm::vec2 (0,0), glm::vec2 (1,0), glm::vec2 (0,1));
1602 Slide
.pushTriangle (glm::vec2 (1,0), glm::vec2 (0,1), glm::vec2 (1,1));
1603 Primitives_t aLeavingSlide
;
1604 aLeavingSlide
.push_back (Slide
);
1605 Primitives_t aEnteringSlide
;
1606 aEnteringSlide
.push_back (Slide
);
1608 TransitionSettings aSettings
;
1609 aSettings
.mbUseMipMapLeaving
= aSettings
.mbUseMipMapEntering
= false;
1611 return makeDissolveTransition(aLeavingSlide
, aEnteringSlide
, aSettings
);
1617 class VortexTransition
: public PermTextureTransition
1620 VortexTransition(const TransitionScene
& rScene
, const TransitionSettings
& rSettings
, int nNX
, int nNY
)
1621 : PermTextureTransition(rScene
, rSettings
)
1622 , maNumTiles(nNX
,nNY
)
1624 mvTileInfo
.resize(6*maNumTiles
.x
*maNumTiles
.y
);
1625 mnFramebuffers
[0] = 0;
1626 mnFramebuffers
[1] = 0;
1627 mnDepthTextures
[0] = 0;
1628 mnDepthTextures
[1] = 0;
1632 virtual void finishTransition() override
;
1633 virtual GLuint
makeShader() const override
;
1634 virtual void prepareTransition( sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, OpenGLContext
*pContext
) override
;
1635 virtual void displaySlides_( double nTime
, sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, double SlideWidthScale
, double SlideHeightScale
, OpenGLContext
*pContext
) override
;
1637 GLint mnSlideLocation
= -1;
1638 GLint mnTileInfoLocation
= -1;
1639 GLuint mnTileInfoBuffer
= 0u;
1640 GLint mnShadowLocation
= -1;
1641 std::array
<GLuint
, 2> mnFramebuffers
;
1642 std::array
<GLuint
, 2> mnDepthTextures
;
1644 glm::ivec2 maNumTiles
;
1646 std::vector
<GLfloat
> mvTileInfo
;
1649 void VortexTransition::finishTransition()
1651 PermTextureTransition::finishTransition();
1654 glDeleteTextures(2, mnDepthTextures
.data());
1655 mnDepthTextures
= {0u, 0u};
1657 glDeleteFramebuffers(2, mnFramebuffers
.data());
1658 mnFramebuffers
= {0u, 0u};
1659 glDeleteBuffers(1, &mnTileInfoBuffer
);
1660 mnTileInfoBuffer
= 0u;
1661 mnSlideLocation
= -1;
1662 mnTileInfoLocation
= -1;
1663 mnShadowLocation
= -1;
1667 GLuint
VortexTransition::makeShader() const
1669 return OpenGLHelper::LoadShaders( "vortexVertexShader", "vortexFragmentShader", "vortexGeometryShader" );
1672 glm::mat4
lookAt(const glm::vec3
& eye
, const glm::vec3
& center
, const glm::vec3
& up
) {
1673 glm::vec3 f
= glm::normalize(center
- eye
);
1674 glm::vec3 u
= glm::normalize(up
);
1675 glm::vec3 s
= glm::normalize(glm::cross(f
, u
));
1676 u
= glm::cross(s
, f
);
1678 return glm::mat4(s
.x
, u
.x
, -f
.x
, 0,
1681 -glm::dot(s
, eye
), -glm::dot(u
, eye
), glm::dot(f
, eye
), 1);
1684 void VortexTransition::prepareTransition( sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, OpenGLContext
*pContext
)
1687 PermTextureTransition::prepareTransition( glLeavingSlideTex
, glEnteringSlideTex
, pContext
);
1690 mnSlideLocation
= glGetUniformLocation(m_nProgramObject
, "slide");
1691 mnTileInfoLocation
= glGetAttribLocation(m_nProgramObject
, "tileInfo");
1692 GLint nNumTilesLocation
= glGetUniformLocation(m_nProgramObject
, "numTiles");
1693 mnShadowLocation
= glGetUniformLocation(m_nProgramObject
, "shadow");
1694 GLint nOrthoProjectionMatrix
= glGetUniformLocation(m_nProgramObject
, "orthoProjectionMatrix");
1695 GLint nOrthoViewMatrix
= glGetUniformLocation(m_nProgramObject
, "orthoViewMatrix");
1696 GLint location
= glGetUniformLocation(m_nProgramObject
, "leavingShadowTexture");
1697 glUniform1i(location
, 2);
1698 location
= glGetUniformLocation(m_nProgramObject
, "enteringShadowTexture");
1699 glUniform1i(location
, 3);
1702 glUniform2iv(nNumTilesLocation
, 1, glm::value_ptr(maNumTiles
));
1705 glGenBuffers(1, &mnTileInfoBuffer
);
1708 // We store the (x,y) indexes of the tile each vertex belongs to in a float, so they must fit.
1709 assert(maNumTiles
.x
< 256);
1710 assert(maNumTiles
.y
< 256);
1712 // Two triangles, i.e. six vertices, per tile
1715 for (int x
= 0; x
< maNumTiles
.x
; x
++)
1717 for (int y
= 0; y
< maNumTiles
.y
; y
++)
1719 for (int v
= 0; v
< 6; v
++)
1721 mvTileInfo
[n
] = x
+ (y
<< 8) + (v
<< 16);
1728 glBindBuffer(GL_ARRAY_BUFFER
, mnTileInfoBuffer
);
1730 glEnableVertexAttribArray(mnTileInfoLocation
);
1732 glVertexAttribPointer(mnTileInfoLocation
, 1, GL_FLOAT
, GL_FALSE
, 0, nullptr);
1734 glBufferData(GL_ARRAY_BUFFER
, mvTileInfo
.size()*sizeof(GLfloat
), mvTileInfo
.data(), GL_STATIC_DRAW
);
1737 glBindBuffer(GL_ARRAY_BUFFER
, 0);
1740 double EyePos(10.0);
1741 double const RealF(1.0);
1742 double const RealN(-1.0);
1743 double const RealL(-2.0);
1745 double const RealB(-2.0);
1747 double ClipN(EyePos
+5.0*RealN
);
1748 double ClipF(EyePos
+15.0*RealF
);
1749 double ClipL(RealL
*8.0);
1750 double ClipR(RealR
*8.0);
1751 double ClipB(RealB
*8.0);
1752 double ClipT(RealT
*8.0);
1754 glm::mat4 projection
= glm::ortho
<float>(ClipL
, ClipR
, ClipB
, ClipT
, ClipN
, ClipF
);
1755 //This scaling is to take the plane with BottomLeftCorner(-1,-1,0) and TopRightCorner(1,1,0) and map it to the screen after the perspective division.
1756 glm::vec3
scale(1.0 / (((RealR
* 2.0 * ClipN
) / (EyePos
* (ClipR
- ClipL
))) - ((ClipR
+ ClipL
) / (ClipR
- ClipL
))),
1757 1.0 / (((RealT
* 2.0 * ClipN
) / (EyePos
* (ClipT
- ClipB
))) - ((ClipT
+ ClipB
) / (ClipT
- ClipB
))),
1759 projection
= glm::scale(projection
, scale
);
1760 glUniformMatrix4fv(nOrthoProjectionMatrix
, 1, false, glm::value_ptr(projection
));
1762 glm::mat4 view
= lookAt(glm::vec3(-1, 1, EyePos
), glm::vec3(-0.5, 0.5, 0), glm::vec3(0, 1, 0));
1763 glUniformMatrix4fv(nOrthoViewMatrix
, 1, false, glm::value_ptr(view
));
1765 // Generate the framebuffers and textures for the shadows.
1766 glGenTextures(2, mnDepthTextures
.data());
1767 glGenFramebuffers(2, mnFramebuffers
.data());
1769 for (int i
: {0, 1}) {
1770 glBindTexture(GL_TEXTURE_2D
, mnDepthTextures
[i
]);
1771 glTexImage2D(GL_TEXTURE_2D
, 0, GL_DEPTH_COMPONENT16
, 2048, 2048, 0, GL_DEPTH_COMPONENT
, GL_FLOAT
, nullptr);
1772 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
1773 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
1774 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
1775 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
1777 glBindFramebuffer(GL_FRAMEBUFFER
, mnFramebuffers
[i
]);
1778 glFramebufferTexture(GL_FRAMEBUFFER
, GL_DEPTH_ATTACHMENT
, mnDepthTextures
[i
], 0);
1779 glDrawBuffer(GL_NONE
); // No color buffer is drawn to.
1781 // Always check that our framebuffer is ok
1782 if(glCheckFramebufferStatus(GL_FRAMEBUFFER
) != GL_FRAMEBUFFER_COMPLETE
) {
1783 SAL_WARN("slideshow.opengl", "Wrong framebuffer!");
1788 pContext
->restoreDefaultFramebuffer();
1789 glBindTexture(GL_TEXTURE_2D
, 0);
1791 glActiveTexture( GL_TEXTURE2
);
1792 glBindTexture( GL_TEXTURE_2D
, mnDepthTextures
[0] );
1793 glActiveTexture( GL_TEXTURE3
);
1794 glBindTexture( GL_TEXTURE_2D
, mnDepthTextures
[1] );
1795 glActiveTexture( GL_TEXTURE0
);
1798 void VortexTransition::displaySlides_( double nTime
, sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, double SlideWidthScale
, double SlideHeightScale
, OpenGLContext
* pContext
)
1801 applyOverallOperations( nTime
, SlideWidthScale
, SlideHeightScale
);
1802 glUniform1f( m_nTimeLocation
, nTime
);
1803 glUniform1f( mnShadowLocation
, 1.0 );
1805 std::array
<GLint
, 4> viewport
;
1806 glGetIntegerv(GL_VIEWPORT
, viewport
.data());
1807 glViewport(0, 0, 2048, 2048);
1809 glBindFramebuffer(GL_FRAMEBUFFER
, mnFramebuffers
[0]);
1810 glClear(GL_DEPTH_BUFFER_BIT
);
1811 glUniform1f( mnSlideLocation
, 0.0 );
1812 displaySlide( nTime
, glLeavingSlideTex
, getScene().getLeavingSlide(), SlideWidthScale
, SlideHeightScale
);
1814 glBindFramebuffer(GL_FRAMEBUFFER
, mnFramebuffers
[1]);
1815 glClear(GL_DEPTH_BUFFER_BIT
);
1816 glUniform1f( mnSlideLocation
, 1.0 );
1817 displaySlide( nTime
, glEnteringSlideTex
, getScene().getEnteringSlide(), SlideWidthScale
, SlideHeightScale
);
1819 glViewport(viewport
[0], viewport
[1], viewport
[2], viewport
[3]);
1820 pContext
->restoreDefaultFramebuffer();
1821 glUniform1f( mnShadowLocation
, 0.0 );
1822 glUniform1f( mnSlideLocation
, 0.0 );
1823 displaySlide( nTime
, glLeavingSlideTex
, getScene().getLeavingSlide(), SlideWidthScale
, SlideHeightScale
);
1824 glUniform1f( mnSlideLocation
, 1.0 );
1825 displaySlide( nTime
, glEnteringSlideTex
, getScene().getEnteringSlide(), SlideWidthScale
, SlideHeightScale
);
1829 std::shared_ptr
<OGLTransitionImpl
>
1830 makeVortexTransition(const Primitives_t
& rLeavingSlidePrimitives
,
1831 const Primitives_t
& rEnteringSlidePrimitives
,
1832 const TransitionSettings
& rSettings
,
1836 return std::make_shared
<VortexTransition
>(TransitionScene(rLeavingSlidePrimitives
, rEnteringSlidePrimitives
),
1843 std::shared_ptr
<OGLTransitionImpl
> makeVortex()
1845 const int NX
= 96, NY
= 96;
1848 for (int x
= 0; x
< NX
; x
++)
1850 for (int y
= 0; y
< NY
; y
++)
1852 Slide
.pushTriangle (glm::vec2 (fdiv(x
,NX
),fdiv(y
,NY
)), glm::vec2 (fdiv(x
+1,NX
),fdiv(y
,NY
)), glm::vec2 (fdiv(x
,NX
),fdiv(y
+1,NY
)));
1853 Slide
.pushTriangle (glm::vec2 (fdiv(x
+1,NX
),fdiv(y
,NY
)), glm::vec2 (fdiv(x
,NX
),fdiv(y
+1,NY
)), glm::vec2 (fdiv(x
+1,NX
),fdiv(y
+1,NY
)));
1856 Primitives_t aLeavingSlide
;
1857 aLeavingSlide
.push_back (Slide
);
1858 Primitives_t aEnteringSlide
;
1859 aEnteringSlide
.push_back (Slide
);
1861 TransitionSettings aSettings
;
1862 aSettings
.mbUseMipMapLeaving
= aSettings
.mbUseMipMapEntering
= false;
1863 aSettings
.mnRequiredGLVersion
= 3.2f
;
1865 return makeVortexTransition(aLeavingSlide
, aEnteringSlide
, aSettings
, NX
, NY
);
1871 class RippleTransition
: public OGLTransitionImpl
1874 RippleTransition(const TransitionScene
& rScene
, const TransitionSettings
& rSettings
, const glm::vec2
& rCenter
)
1875 : OGLTransitionImpl(rScene
, rSettings
),
1881 virtual GLuint
makeShader() const override
;
1882 virtual void prepareTransition( sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, OpenGLContext
*pContext
) override
;
1883 virtual void prepare( double SlideWidth
, double SlideHeight
) override
;
1886 GLint maSlideRatioLocation
= -1;
1889 GLuint
RippleTransition::makeShader() const
1891 return OpenGLHelper::LoadShaders( "basicVertexShader", "rippleFragmentShader" );
1894 void RippleTransition::prepareTransition( sal_Int32
, sal_Int32
, OpenGLContext
* )
1896 GLint nCenterLocation
= glGetUniformLocation(m_nProgramObject
, "center");
1899 glUniform2fv(nCenterLocation
, 1, glm::value_ptr(maCenter
));
1902 maSlideRatioLocation
= glGetUniformLocation(m_nProgramObject
, "slideRatio");
1906 void RippleTransition::prepare( double SlideWidth
, double SlideHeight
)
1908 if( maSlideRatioLocation
!= -1 )
1909 glUniform1f( maSlideRatioLocation
, SlideWidth
/ SlideHeight
);
1912 std::shared_ptr
<OGLTransitionImpl
>
1913 makeRippleTransition(const Primitives_t
& rLeavingSlidePrimitives
,
1914 const Primitives_t
& rEnteringSlidePrimitives
,
1915 const TransitionSettings
& rSettings
)
1917 // The center point should be adjustable by the user, but we have no way to do that in the UI
1918 return std::make_shared
<RippleTransition
>(TransitionScene(rLeavingSlidePrimitives
, rEnteringSlidePrimitives
),
1920 glm::vec2(0.5, 0.5));
1925 std::shared_ptr
<OGLTransitionImpl
> makeRipple()
1929 Slide
.pushTriangle (glm::vec2 (0,0), glm::vec2 (1,0), glm::vec2 (0,1));
1930 Slide
.pushTriangle (glm::vec2 (1,0), glm::vec2 (0,1), glm::vec2 (1,1));
1932 Primitives_t aLeavingSlide
;
1933 aLeavingSlide
.push_back (Slide
);
1935 Primitives_t aEnteringSlide
;
1936 aEnteringSlide
.push_back (Slide
);
1938 TransitionSettings aSettings
;
1939 aSettings
.mbUseMipMapLeaving
= aSettings
.mbUseMipMapEntering
= false;
1941 return makeRippleTransition(aLeavingSlide
, aEnteringSlide
, aSettings
);
1944 static void createHexagon(Primitive
& aHexagon
, const int x
, const int y
, const int NX
, const int NY
)
1948 aHexagon
.pushTriangle(vec(x
-1, y
-1, NX
, NY
), vec(x
, y
-2, NX
, NY
), vec(x
, y
+0.5, NX
, NY
));
1949 aHexagon
.pushTriangle(vec(x
, y
-2, NX
, NY
), vec(x
+1, y
-1, NX
, NY
), vec(x
, y
+0.5, NX
, NY
));
1950 aHexagon
.pushTriangle(vec(x
+1, y
-1, NX
, NY
), vec(x
+1, y
, NX
, NY
), vec(x
, y
+0.5, NX
, NY
));
1951 aHexagon
.pushTriangle(vec(x
+1, y
, NX
, NY
), vec(x
, y
+1, NX
, NY
), vec(x
, y
+0.5, NX
, NY
));
1952 aHexagon
.pushTriangle(vec(x
, y
+1, NX
, NY
), vec(x
-1, y
, NX
, NY
), vec(x
, y
+0.5, NX
, NY
));
1953 aHexagon
.pushTriangle(vec(x
-1, y
, NX
, NY
), vec(x
-1, y
-1, NX
, NY
), vec(x
, y
+0.5, NX
, NY
));
1957 aHexagon
.pushTriangle(vec(x
-2, y
-1, NX
, NY
), vec(x
-1, y
-2, NX
, NY
), vec(x
, y
+0.5, NX
, NY
));
1958 aHexagon
.pushTriangle(vec(x
-1, y
-2, NX
, NY
), vec(x
, y
-1, NX
, NY
), vec(x
, y
+0.5, NX
, NY
));
1959 aHexagon
.pushTriangle(vec(x
, y
-1, NX
, NY
), vec(x
, y
, NX
, NY
), vec(x
, y
+0.5, NX
, NY
));
1960 aHexagon
.pushTriangle(vec(x
, y
, NX
, NY
), vec(x
-1, y
+1, NX
, NY
), vec(x
, y
+0.5, NX
, NY
));
1961 aHexagon
.pushTriangle(vec(x
-1, y
+1, NX
, NY
), vec(x
-2, y
, NX
, NY
), vec(x
, y
+0.5, NX
, NY
));
1962 aHexagon
.pushTriangle(vec(x
-2, y
, NX
, NY
), vec(x
-2, y
-1, NX
, NY
), vec(x
, y
+0.5, NX
, NY
));
1969 class GlitterTransition
: public PermTextureTransition
1972 GlitterTransition(const TransitionScene
& rScene
, const TransitionSettings
& rSettings
)
1973 : PermTextureTransition(rScene
, rSettings
)
1978 virtual GLuint
makeShader() const override
;
1979 virtual void prepareTransition( sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, OpenGLContext
*pContext
) override
;
1980 virtual void cleanup() override
;
1982 GLuint maBuffer
= 0;
1985 GLuint
GlitterTransition::makeShader() const
1987 return OpenGLHelper::LoadShaders( "glitterVertexShader", "glitterFragmentShader" );
1995 void GlitterTransition::prepareTransition( sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, OpenGLContext
*pContext
)
1998 PermTextureTransition::prepareTransition( glLeavingSlideTex
, glEnteringSlideTex
, pContext
);
2001 GLint nNumTilesLocation
= glGetUniformLocation(m_nProgramObject
, "numTiles");
2002 if (nNumTilesLocation
!= -1) {
2003 glUniform2iv(nNumTilesLocation
, 1, glm::value_ptr(glm::ivec2(41, 41 * 4 / 3)));
2007 glGenBuffers(1, &maBuffer
);
2008 glBindBuffer(GL_ARRAY_BUFFER
, maBuffer
);
2010 // Upload the center of each hexagon.
2011 const Primitive
& primitive
= getScene().getLeavingSlide()[0];
2012 std::vector
<ThreeFloats
> vertices
;
2013 for (int i
= 2; i
< primitive
.getVerticesCount(); i
+= 18) {
2014 const glm::vec3
& center
= primitive
.getVertex(i
);
2015 for (int j
= 0; j
< 18; ++j
)
2016 vertices
.push_back({center
.x
, center
.y
, center
.z
});
2018 glBufferData(GL_ARRAY_BUFFER
, vertices
.size() * 3 * sizeof(GLfloat
), vertices
.data(), GL_STATIC_DRAW
);
2020 GLint location
= glGetAttribLocation(m_nProgramObject
, "center");
2021 if (location
!= -1) {
2022 glEnableVertexAttribArray(location
);
2023 glVertexAttribPointer( location
, 3, GL_FLOAT
, false, 0, nullptr );
2027 glBindBuffer(GL_ARRAY_BUFFER
, 0);
2030 void GlitterTransition::cleanup()
2033 glDeleteBuffers(1, &maBuffer
);
2037 std::shared_ptr
<OGLTransitionImpl
>
2038 makeGlitterTransition(const Primitives_t
& rLeavingSlidePrimitives
,
2039 const Primitives_t
& rEnteringSlidePrimitives
,
2040 const TransitionSettings
& rSettings
)
2042 return std::make_shared
<GlitterTransition
>(TransitionScene(rLeavingSlidePrimitives
, rEnteringSlidePrimitives
),
2048 std::shared_ptr
<OGLTransitionImpl
> makeGlitter()
2051 const int NY
= NX
* 4 / 3;
2053 Primitives_t aSlide
;
2054 Primitives_t aEmptySlide
;
2057 for (int y
= 0; y
< NY
+2; y
+=2)
2058 for (int x
= 0; x
< NX
+2; x
+=2)
2059 createHexagon(aHexagon
, x
, y
, NX
, NY
);
2061 aSlide
.push_back(aHexagon
);
2063 return makeGlitterTransition(aSlide
, aEmptySlide
, TransitionSettings());
2069 class HoneycombTransition
: public PermTextureTransition
2072 HoneycombTransition(const TransitionScene
& rScene
, const TransitionSettings
& rSettings
)
2073 : PermTextureTransition(rScene
, rSettings
)
2075 mnDepthTextures
[0] = 0;
2076 mnDepthTextures
[1] = 0;
2080 virtual void finishTransition() override
;
2081 virtual GLuint
makeShader() const override
;
2082 virtual void prepareTransition( sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, OpenGLContext
*pContext
) override
;
2083 virtual void displaySlides_( double nTime
, sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, double SlideWidthScale
, double SlideHeightScale
, OpenGLContext
*pContext
) override
;
2085 GLint maHexagonSizeLocation
= -1;
2086 GLint maSelectedTextureLocation
= -1;
2087 GLint mnShadowLocation
= -1;
2088 GLuint mnFramebuffer
= 0u;
2089 std::array
<GLuint
, 2> mnDepthTextures
;
2092 void HoneycombTransition::finishTransition()
2094 PermTextureTransition::finishTransition();
2097 glActiveTexture( GL_TEXTURE2
);
2098 glBindTexture( GL_TEXTURE_2D
, 0 );
2099 glActiveTexture( GL_TEXTURE3
);
2100 glBindTexture( GL_TEXTURE_2D
, 0 );
2101 glActiveTexture( GL_TEXTURE0
);
2103 glDeleteTextures(2, mnDepthTextures
.data());
2104 mnDepthTextures
= {0u, 0u};
2106 glDeleteFramebuffers(1, &mnFramebuffer
);
2111 GLuint
HoneycombTransition::makeShader() const
2113 return OpenGLHelper::LoadShaders( "honeycombVertexShader", "honeycombFragmentShader", "honeycombGeometryShader" );
2116 void HoneycombTransition::prepareTransition( sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
, OpenGLContext
*pContext
)
2119 PermTextureTransition::prepareTransition( glLeavingSlideTex
, glEnteringSlideTex
, pContext
);
2122 maHexagonSizeLocation
= glGetUniformLocation(m_nProgramObject
, "hexagonSize");
2123 maSelectedTextureLocation
= glGetUniformLocation( m_nProgramObject
, "selectedTexture" );
2124 mnShadowLocation
= glGetUniformLocation(m_nProgramObject
, "shadow");
2125 GLint nOrthoProjectionMatrix
= glGetUniformLocation(m_nProgramObject
, "orthoProjectionMatrix");
2126 GLint nOrthoViewMatrix
= glGetUniformLocation(m_nProgramObject
, "orthoViewMatrix");
2127 GLint location
= glGetUniformLocation(m_nProgramObject
, "colorShadowTexture");
2128 glUniform1i(location
, 2);
2129 location
= glGetUniformLocation(m_nProgramObject
, "depthShadowTexture");
2130 glUniform1i(location
, 3);
2133 // We want to see the entering slide behind the leaving one.
2135 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
2138 double EyePos(10.0);
2139 double const RealF(1.0);
2140 double const RealN(-1.0);
2141 double const RealL(-4.0);
2143 double const RealB(-4.0);
2145 double ClipN(EyePos
+5.0*RealN
);
2146 double ClipF(EyePos
+15.0*RealF
);
2147 double ClipL(RealL
*8.0);
2148 double ClipR(RealR
*8.0);
2149 double ClipB(RealB
*8.0);
2150 double ClipT(RealT
*8.0);
2152 glm::mat4 projection
= glm::ortho
<float>(ClipL
, ClipR
, ClipB
, ClipT
, ClipN
, ClipF
);
2153 //This scaling is to take the plane with BottomLeftCorner(-1,-1,0) and TopRightCorner(1,1,0) and map it to the screen after the perspective division.
2154 glm::vec3
scale(1.0 / (((RealR
* 2.0 * ClipN
) / (EyePos
* (ClipR
- ClipL
))) - ((ClipR
+ ClipL
) / (ClipR
- ClipL
))),
2155 1.0 / (((RealT
* 2.0 * ClipN
) / (EyePos
* (ClipT
- ClipB
))) - ((ClipT
+ ClipB
) / (ClipT
- ClipB
))),
2157 projection
= glm::scale(projection
, scale
);
2158 glUniformMatrix4fv(nOrthoProjectionMatrix
, 1, false, glm::value_ptr(projection
));
2160 glm::mat4 view
= lookAt(glm::vec3(0, 0, EyePos
), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
2161 glUniformMatrix4fv(nOrthoViewMatrix
, 1, false, glm::value_ptr(view
));
2163 // Generate the framebuffer and textures for the shadows.
2164 glGenTextures(2, mnDepthTextures
.data());
2165 glActiveTexture(GL_TEXTURE2
);
2166 glBindTexture(GL_TEXTURE_2D
, mnDepthTextures
[0]);
2167 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, 2048, 2048, 0, GL_RGBA
, GL_FLOAT
, nullptr);
2168 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
2169 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
2170 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
2171 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
2173 glActiveTexture(GL_TEXTURE3
);
2174 glBindTexture(GL_TEXTURE_2D
, mnDepthTextures
[1]);
2175 glTexImage2D(GL_TEXTURE_2D
, 0, GL_DEPTH_COMPONENT16
, 2048, 2048, 0, GL_DEPTH_COMPONENT
, GL_FLOAT
, nullptr);
2176 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
2177 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
2178 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
2179 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
2181 glActiveTexture(GL_TEXTURE0
);
2182 glGenFramebuffers(1, &mnFramebuffer
);
2183 glBindFramebuffer(GL_FRAMEBUFFER
, mnFramebuffer
);
2184 glFramebufferTexture(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, mnDepthTextures
[0], 0);
2185 glFramebufferTexture(GL_FRAMEBUFFER
, GL_DEPTH_ATTACHMENT
, mnDepthTextures
[1], 0);
2187 // Always check that our framebuffer is ok
2188 if(glCheckFramebufferStatus(GL_FRAMEBUFFER
) != GL_FRAMEBUFFER_COMPLETE
) {
2189 SAL_WARN("slideshow.opengl", "Wrong framebuffer!");
2193 pContext
->restoreDefaultFramebuffer();
2196 void HoneycombTransition::displaySlides_( double nTime
, sal_Int32 glLeavingSlideTex
, sal_Int32 glEnteringSlideTex
,
2197 double SlideWidthScale
, double SlideHeightScale
, OpenGLContext
*pContext
)
2200 applyOverallOperations(nTime
, SlideWidthScale
, SlideHeightScale
);
2201 glUniform1f(m_nTimeLocation
, nTime
);
2202 glUniform1f(mnShadowLocation
, 1.0);
2205 const float borderSize
= 0.15f
;
2207 std::array
<GLint
, 4> viewport
;
2208 glGetIntegerv(GL_VIEWPORT
, viewport
.data());
2209 glViewport(0, 0, 2048, 2048);
2210 glBindFramebuffer(GL_FRAMEBUFFER
, mnFramebuffer
);
2211 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
2212 glUniform1f(mnShadowLocation
, 1.0);
2213 glUniform1f(maSelectedTextureLocation
, 1.0);
2214 glUniform1f(maHexagonSizeLocation
, 1.0f
- borderSize
);
2215 displaySlide(nTime
, glLeavingSlideTex
, getScene().getLeavingSlide(), SlideWidthScale
, SlideHeightScale
);
2216 glUniform1f(maHexagonSizeLocation
, 1.0f
+ borderSize
);
2217 displaySlide(nTime
, glLeavingSlideTex
, getScene().getLeavingSlide(), SlideWidthScale
, SlideHeightScale
);
2219 // The back (entering) slide needs to be drawn before the front (leaving) one in order for blending to work.
2220 glViewport(viewport
[0], viewport
[1], viewport
[2], viewport
[3]);
2221 pContext
->restoreDefaultFramebuffer();
2222 glUniform1f(mnShadowLocation
, 0.0);
2223 glUniform1f(maSelectedTextureLocation
, 0.0);
2224 glUniform1f(maHexagonSizeLocation
, 1.0f
- borderSize
);
2225 displaySlide(nTime
, glEnteringSlideTex
, getScene().getEnteringSlide(), SlideWidthScale
, SlideHeightScale
);
2226 glUniform1f(maHexagonSizeLocation
, 1.0f
+ borderSize
);
2227 displaySlide(nTime
, glEnteringSlideTex
, getScene().getEnteringSlide(), SlideWidthScale
, SlideHeightScale
);
2228 glUniform1f(maSelectedTextureLocation
, 1.0);
2229 glUniform1f(maHexagonSizeLocation
, 1.0f
- borderSize
);
2230 displaySlide(nTime
, glLeavingSlideTex
, getScene().getLeavingSlide(), SlideWidthScale
, SlideHeightScale
);
2231 glUniform1f(maHexagonSizeLocation
, 1.0f
+ borderSize
);
2232 displaySlide(nTime
, glLeavingSlideTex
, getScene().getLeavingSlide(), SlideWidthScale
, SlideHeightScale
);
2236 std::shared_ptr
<OGLTransitionImpl
>
2237 makeHoneycombTransition(const Primitives_t
& rLeavingSlidePrimitives
,
2238 const Primitives_t
& rEnteringSlidePrimitives
,
2239 const TransitionSettings
& rSettings
)
2241 // The center point should be adjustable by the user, but we have no way to do that in the UI
2242 return std::make_shared
<HoneycombTransition
>(TransitionScene(rLeavingSlidePrimitives
, rEnteringSlidePrimitives
),
2248 std::shared_ptr
<OGLTransitionImpl
> makeHoneycomb()
2253 TransitionSettings aSettings
;
2254 aSettings
.mnRequiredGLVersion
= 3.2f
;
2256 Primitives_t aSlide
;
2258 for (int y
= 0; y
< NY
+2; y
+=2)
2259 for (int x
= 0; x
< NX
+2; x
+=2)
2260 aHexagon
.pushTriangle(glm::vec2((y
% 4) ? fdiv(x
, NX
) : fdiv(x
+ 1, NX
), fdiv(y
, NY
)), glm::vec2(1, 0), glm::vec2(0, 0));
2261 aSlide
.push_back(aHexagon
);
2263 return makeHoneycombTransition(aSlide
, aSlide
, aSettings
);
2266 std::shared_ptr
<OGLTransitionImpl
> makeNewsflash()
2270 Slide
.pushTriangle(glm::vec2(0,0),glm::vec2(1,0),glm::vec2(0,1));
2271 Slide
.pushTriangle(glm::vec2(1,0),glm::vec2(0,1),glm::vec2(1,1));
2272 Slide
.Operations
.push_back(makeSRotate(glm::vec3(0,0,1),glm::vec3(0,0,0),3000,true,0,0.5));
2273 Slide
.Operations
.push_back(makeSScale(glm::vec3(0.01,0.01,0.01),glm::vec3(0,0,0),true,0,0.5));
2274 Slide
.Operations
.push_back(makeSTranslate(glm::vec3(-10000, 0, 0),false, 0.5, 2));
2275 Primitives_t aLeavingSlide
;
2276 aLeavingSlide
.push_back(Slide
);
2278 Slide
.Operations
.clear();
2279 Slide
.Operations
.push_back(makeSRotate(glm::vec3(0,0,1),glm::vec3(0,0,0),-3000,true,0.5,1));
2280 Slide
.Operations
.push_back(makeSTranslate(glm::vec3(-100, 0, 0),false, -1, 1));
2281 Slide
.Operations
.push_back(makeSTranslate(glm::vec3(100, 0, 0),false, 0.5, 1));
2282 Slide
.Operations
.push_back(makeSScale(glm::vec3(0.01,0.01,0.01),glm::vec3(0,0,0),false,-1,1));
2283 Slide
.Operations
.push_back(makeSScale(glm::vec3(100,100,100),glm::vec3(0,0,0),true,0.5,1));
2284 Primitives_t aEnteringSlide
;
2285 aEnteringSlide
.push_back(Slide
);
2287 Operations_t aOverallOperations
;
2288 aOverallOperations
.push_back(makeSRotate(glm::vec3(0,0,1),glm::vec3(0.2,0.2,0),1080,true,0,1));
2290 return makeSimpleTransition(aLeavingSlide
, aEnteringSlide
, aOverallOperations
);
2293 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */