nss: upgrade to release 3.73
[LibreOffice.git] / slideshow / source / engine / opengl / TransitionImpl.cxx
blob98d6778fd1976e0945b3f98cfe1931c93c956f1b
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>
35 #include <algorithm>
36 #include <array>
38 #include <comphelper/random.hxx>
40 #include "Operation.hxx"
41 #include "TransitionImpl.hxx"
42 #include <math.h>
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);
55 swap(aTmp);
56 return *this;
59 void TransitionScene::swap(TransitionScene& rOther)
61 using std::swap;
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()
75 double EyePos(10.0);
76 double const RealF(1.0);
77 double const RealN(-1.0);
78 double const RealL(-1.0);
79 double RealR(1.0);
80 double const RealB(-1.0);
81 double RealT(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))),
93 1.0);
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));
100 CHECK_GL_ERROR();
103 location = glGetUniformLocation( m_nProgramObject, "u_modelViewMatrix" );
104 if( location != -1 ) {
105 glUniformMatrix4fv(location, 1, false, glm::value_ptr(modelview));
106 CHECK_GL_ERROR();
110 static std::vector<int> uploadPrimitives(const Primitives_t& primitives)
112 int size = 0;
113 for (const Primitive& primitive: primitives)
114 size += primitive.getVerticesByteSize();
116 CHECK_GL_ERROR();
117 glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_STATIC_DRAW);
118 CHECK_GL_ERROR();
119 Vertex *buf = static_cast<Vertex*>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
121 std::vector<int> indices;
122 int last_pos = 0;
123 for (const Primitive& primitive: primitives) {
124 indices.push_back(last_pos);
125 int num = primitive.writeVertices(buf);
126 buf += num;
127 last_pos += num;
130 CHECK_GL_ERROR();
131 glUnmapBuffer(GL_ARRAY_BUFFER);
132 CHECK_GL_ERROR();
133 return indices;
136 bool OGLTransitionImpl::prepare( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext )
138 m_nProgramObject = makeShader();
139 if (!m_nProgramObject)
140 return false;
142 CHECK_GL_ERROR();
143 glUseProgram( m_nProgramObject );
144 CHECK_GL_ERROR();
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
154 CHECK_GL_ERROR();
157 location = glGetUniformLocation( m_nProgramObject, "enteringSlideTexture" );
158 if( location != -1 ) {
159 glUniform1i( location, 2 ); // texture unit 2
160 CHECK_GL_ERROR();
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)) );
184 CHECK_GL_ERROR();
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)) );
191 CHECK_GL_ERROR();
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)) );
198 CHECK_GL_ERROR();
201 glBindBuffer(GL_ARRAY_BUFFER, 0);
202 CHECK_GL_ERROR();
204 prepareTransition( glLeavingSlideTex, glEnteringSlideTex, pContext );
205 return true;
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();
215 finishTransition();
217 CHECK_GL_ERROR();
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;
226 CHECK_GL_ERROR();
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 * )
247 CHECK_GL_ERROR();
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 );
257 CHECK_GL_ERROR();
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;
266 CHECK_GL_ERROR();
267 glBindVertexArray(m_nVertexArrayObject);
268 prepare( SlideWidth, SlideHeight );
270 CHECK_GL_ERROR();
271 displaySlides_( nTime, glLeavingSlideTex, glEnteringSlideTex, SlideWidthScale, SlideHeightScale, pContext );
272 CHECK_GL_ERROR();
273 displayScene( nTime, SlideWidth, SlideHeight, DispWidth, DispHeight );
274 CHECK_GL_ERROR();
277 void OGLTransitionImpl::applyOverallOperations( double nTime, double SlideWidthScale, double SlideHeightScale )
279 const Operations_t& rOverallOperations(maScene.getOperations());
280 glm::mat4 matrix;
281 for(size_t i(0); i != rOverallOperations.size(); ++i)
282 rOverallOperations[i]->interpolate(matrix, nTime, SlideWidthScale, SlideHeightScale);
283 CHECK_GL_ERROR();
284 if (m_nOperationsTransformLocation != -1) {
285 glUniformMatrix4fv(m_nOperationsTransformLocation, 1, false, glm::value_ptr(matrix));
286 CHECK_GL_ERROR();
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++);
296 void
297 OGLTransitionImpl::displaySlide(
298 const double nTime,
299 const sal_Int32 glSlideTex, const Primitives_t& primitives,
300 double SlideWidthScale, double SlideHeightScale )
302 CHECK_GL_ERROR();
303 glBindTexture(GL_TEXTURE_2D, glSlideTex);
304 CHECK_GL_ERROR();
305 if (m_nSceneTransformLocation != -1) {
306 glUniformMatrix4fv(m_nSceneTransformLocation, 1, false, glm::value_ptr(glm::mat4()));
307 CHECK_GL_ERROR();
309 displayPrimitives(primitives, m_nPrimitiveTransformLocation, nTime, SlideWidthScale, SlideHeightScale, m_nFirstIndices.cbegin());
310 CHECK_GL_ERROR();
313 void
314 OGLTransitionImpl::displayUnbufferedSlide(
315 const double nTime,
316 const sal_Int32 glSlideTex, const Primitives_t& primitives,
317 double SlideWidthScale, double SlideHeightScale )
319 CHECK_GL_ERROR();
320 glBindTexture(GL_TEXTURE_2D, glSlideTex);
321 CHECK_GL_ERROR();
322 glBindVertexArray(0);
323 CHECK_GL_ERROR();
324 glBindBuffer(GL_ARRAY_BUFFER, 0);
325 CHECK_GL_ERROR();
326 if (m_nSceneTransformLocation != -1) {
327 glUniformMatrix4fv(m_nSceneTransformLocation, 1, false, glm::value_ptr(glm::mat4()));
328 CHECK_GL_ERROR();
330 for (const Primitive& primitive: primitives)
331 primitive.display(m_nPrimitiveTransformLocation, nTime, SlideWidthScale, SlideHeightScale);
332 CHECK_GL_ERROR();
333 glBindVertexArray(m_nVertexArrayObject);
334 CHECK_GL_ERROR();
335 glBindBuffer(GL_ARRAY_BUFFER, m_nVertexBufferObject);
336 CHECK_GL_ERROR();
339 void OGLTransitionImpl::displayScene( double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight )
341 const SceneObjects_t& rSceneObjects(maScene.getSceneObjects());
342 CHECK_GL_ERROR();
343 for(size_t i(0); i != rSceneObjects.size(); ++i)
344 rSceneObjects[i]->display(m_nSceneTransformLocation, m_nPrimitiveTransformLocation, nTime, SlideWidth, SlideHeight, DispWidth, DispHeight);
345 CHECK_GL_ERROR();
348 void Primitive::display(GLint primitiveTransformLocation, double nTime, double WidthScale, double HeightScale) const
350 glm::mat4 matrix;
351 applyOperations( matrix, nTime, WidthScale, HeightScale );
353 CHECK_GL_ERROR();
354 if (primitiveTransformLocation != -1) {
355 glUniformMatrix4fv(primitiveTransformLocation, 1, false, glm::value_ptr(matrix));
356 CHECK_GL_ERROR();
359 GLuint nVertexArrayObject;
360 glGenVertexArrays(1, &nVertexArrayObject);
361 CHECK_GL_ERROR();
362 glBindVertexArray(nVertexArrayObject);
363 CHECK_GL_ERROR();
365 GLuint nBuffer;
366 glGenBuffers(1, &nBuffer);
367 CHECK_GL_ERROR();
368 glBindBuffer(GL_ARRAY_BUFFER, nBuffer);
369 CHECK_GL_ERROR();
370 glBufferData(GL_ARRAY_BUFFER, getVerticesByteSize(), Vertices.data(), GL_STATIC_DRAW);
372 glEnableVertexAttribArray(0);
373 CHECK_GL_ERROR();
374 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), nullptr);
375 CHECK_GL_ERROR();
376 glDrawArrays( GL_TRIANGLES, 0, Vertices.size() );
377 CHECK_GL_ERROR();
379 glDeleteBuffers(1, &nBuffer);
380 CHECK_GL_ERROR();
382 glDeleteVertexArrays(1, &nVertexArrayObject);
383 CHECK_GL_ERROR();
386 void Primitive::display(GLint primitiveTransformLocation, double nTime, double WidthScale, double HeightScale, int first) const
388 glm::mat4 matrix;
389 applyOperations( matrix, nTime, WidthScale, HeightScale );
391 CHECK_GL_ERROR();
392 if (primitiveTransformLocation != -1) {
393 glUniformMatrix4fv(primitiveTransformLocation, 1, false, glm::value_ptr(matrix));
394 CHECK_GL_ERROR();
396 glDrawArrays( GL_TRIANGLES, first, Vertices.size() );
398 CHECK_GL_ERROR();
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
412 glm::mat4 matrix;
413 if (DispHeight > DispWidth)
414 matrix = glm::scale(matrix, glm::vec3(DispHeight/DispWidth, 1, 1));
415 else
416 matrix = glm::scale(matrix, glm::vec3(1, DispWidth/DispHeight, 1));
417 CHECK_GL_ERROR();
418 if (sceneTransformLocation != -1) {
419 glUniformMatrix4fv(sceneTransformLocation, 1, false, glm::value_ptr(matrix));
420 CHECK_GL_ERROR();
422 displayPrimitives(maPrimitives, primitiveTransformLocation, nTime, 1, 1, maFirstIndices.cbegin());
423 CHECK_GL_ERROR();
426 void SceneObject::pushPrimitive(const Primitive &p)
428 maPrimitives.push_back(p);
431 SceneObject::SceneObject()
432 : maPrimitives()
436 SceneObject::~SceneObject()
440 namespace
443 class Iris : public SceneObject
445 public:
446 Iris() = default;
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;
452 private:
453 GLuint maTexture = 0;
454 GLuint maBuffer = 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);
461 CHECK_GL_ERROR();
462 glBindTexture(GL_TEXTURE_2D, maTexture);
463 CHECK_GL_ERROR();
464 SceneObject::display(sceneTransformLocation, primitiveTransformLocation, nTime, SlideWidth, SlideHeight, DispWidth, DispHeight);
467 void Iris::prepare(GLuint program)
469 CHECK_GL_ERROR();
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);
479 CHECK_GL_ERROR();
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)) );
493 CHECK_GL_ERROR();
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)) );
500 CHECK_GL_ERROR();
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)) );
507 CHECK_GL_ERROR();
510 glBindBuffer(GL_ARRAY_BUFFER, 0);
513 void Iris::finish()
515 CHECK_GL_ERROR();
516 glDeleteBuffers(1, &maBuffer);
517 CHECK_GL_ERROR();
518 glDeleteVertexArrays(1, &maVertexArray);
519 CHECK_GL_ERROR();
520 glDeleteTextures(1, &maTexture);
521 CHECK_GL_ERROR();
526 namespace
529 class ReflectionTransition : public OGLTransitionImpl
531 public:
532 ReflectionTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
533 : OGLTransitionImpl(rScene, rSettings)
536 private:
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 * )
557 CHECK_GL_ERROR();
558 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
560 sal_Int32 texture;
561 Primitives_t slide;
562 if (nTime < 0.5) {
563 texture = glLeavingSlideTex;
564 slide = getScene().getLeavingSlide();
565 } else {
566 texture = glEnteringSlideTex;
567 slide = getScene().getEnteringSlide();
570 displaySlide( nTime, texture, slide, SlideWidthScale, SlideHeightScale );
571 CHECK_GL_ERROR();
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()),
583 rSettings);
588 namespace
591 class SimpleTransition : public OGLTransitionImpl
593 public:
594 SimpleTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
595 : OGLTransitionImpl(rScene, rSettings)
599 private:
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 * )
613 CHECK_GL_ERROR();
614 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
616 CHECK_GL_ERROR();
617 displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale );
618 displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale );
619 CHECK_GL_ERROR();
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),
632 rSettings);
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()
668 Primitive Slide;
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()
689 Primitive Slide;
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()
710 Primitive Slide;
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()
730 Primitive Slide;
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()
759 Primitive Slide;
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()
780 Primitive Slide;
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);
793 Primitive irisPart;
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),
810 glm::vec2 (cx, cy));
811 irisPart.pushTriangle (glm::vec2 (cx, cy),
812 glm::vec2 (lcxo, lcyo),
813 glm::vec2 (cxo, cyo));
814 lx = x;
815 ly = y;
816 t += 1.0/nSteps;
819 std::shared_ptr<Iris> pIris = std::make_shared<Iris>();
820 double angle = 87;
822 for (i = 0; i < nParts; i++) {
823 irisPart.Operations.clear ();
824 double rx, ry;
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));
830 if (i > 0) {
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);
849 namespace
852 class RochadeTransition : public ReflectionTransition
854 public:
855 RochadeTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
856 : ReflectionTransition(rScene, rSettings)
859 private:
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 );
867 if( nTime > .5) {
868 displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale );
869 displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale );
870 } else {
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),
884 rSettings)
890 std::shared_ptr<OGLTransitionImpl> makeRochade()
892 Primitive Slide;
893 TransitionSettings aSettings;
895 double w, h;
897 w = 2.2;
898 h = 10;
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);
937 template<typename T>
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) );
964 TempAngle += dAngle;
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);
987 LastRadius = Radius;
988 Radius = NextRadius;
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;
1024 Radius = sqrt(2.0);
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));
1058 double iDn = 0.0;
1059 double iPDn = invN;
1060 Primitives_t aLeavingSlide;
1061 Primitives_t aEnteringSlide;
1062 for(unsigned int i(0); i < nRows; ++i)
1064 Primitive Tile;
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);
1080 iDn += invN;
1081 iPDn += invN;
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++)
1110 Primitive aTile;
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);
1133 swap(aTmp);
1134 return *this;
1137 Primitive::Primitive(const Primitive& rvalue)
1138 : Operations(rvalue.Operations)
1139 , Vertices(rvalue.Vertices)
1143 void Primitive::swap(Primitive& rOther)
1145 using std::swap;
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;
1155 Verts.reserve(3);
1156 Texs.reserve(3);
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);
1175 Verts.clear();
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.
1186 namespace
1189 class DiamondTransition : public SimpleTransition
1191 public:
1192 DiamondTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1193 : SimpleTransition(rScene, rSettings)
1196 private:
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)
1202 Primitive Slide2;
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));
1210 } else {
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 * )
1233 CHECK_GL_ERROR();
1234 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
1236 CHECK_GL_ERROR();
1237 displayUnbufferedSlide( nTime, glLeavingSlideTex, makeLeavingSlide(nTime), SlideWidthScale, SlideHeightScale );
1238 displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale );
1239 CHECK_GL_ERROR();
1242 std::shared_ptr<OGLTransitionImpl>
1243 makeDiamondTransition(const TransitionSettings& rSettings)
1245 Primitive Slide1;
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 );
1268 double ln = 0;
1269 double p = 1.0/parts;
1271 Primitives_t aLeavingSlide;
1272 Primitives_t aEnteringSlide;
1273 for( int i=0; i<parts; i++ ) {
1274 Primitive Slide;
1275 double n = (i + 1)/static_cast<double>(parts);
1276 if( vertical ) {
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));
1280 } else {
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);
1287 if( vertical ) {
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));
1290 } else {
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);
1295 ln = n;
1298 return makeSimpleTransition(aLeavingSlide, aEnteringSlide);
1301 namespace
1304 class FadeSmoothlyTransition : public OGLTransitionImpl
1306 public:
1307 FadeSmoothlyTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1308 : OGLTransitionImpl(rScene, rSettings)
1311 private:
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),
1328 rSettings)
1334 std::shared_ptr<OGLTransitionImpl> makeFadeSmoothly()
1336 Primitive Slide;
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);
1351 namespace
1354 class FadeThroughColorTransition : public OGLTransitionImpl
1356 public:
1357 FadeThroughColorTransition(const TransitionScene& rScene, const TransitionSettings& rSettings, bool white)
1358 : OGLTransitionImpl(rScene, rSettings), useWhite( white )
1361 private:
1362 virtual GLuint makeShader() const override;
1363 bool useWhite;
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,
1377 bool white)
1379 return std::make_shared<FadeThroughColorTransition>(
1380 TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives),
1381 rSettings, white)
1387 std::shared_ptr<OGLTransitionImpl> makeFadeThroughColor( bool white )
1389 Primitive Slide;
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);
1404 namespace
1407 class PermTextureTransition : public OGLTransitionImpl
1409 protected:
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;
1418 private:
1419 /** various data */
1420 GLuint m_nHelperTexture;
1423 void PermTextureTransition::finishTransition()
1425 CHECK_GL_ERROR();
1426 if ( m_nHelperTexture )
1428 glDeleteTextures( 1, &m_nHelperTexture );
1429 m_nHelperTexture = 0;
1431 CHECK_GL_ERROR();
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)
1471 CHECK_GL_ERROR();
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 ) {
1478 int x, y;
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];
1484 initialized = true;
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 );
1490 CHECK_GL_ERROR();
1493 void PermTextureTransition::prepareTransition( sal_Int32, sal_Int32, OpenGLContext* )
1495 CHECK_GL_ERROR();
1496 GLint location = glGetUniformLocation( m_nProgramObject, "permTexture" );
1497 if( location != -1 ) {
1498 glActiveTexture(GL_TEXTURE1);
1499 CHECK_GL_ERROR();
1500 if( !m_nHelperTexture )
1501 initPermTexture( &m_nHelperTexture );
1503 glActiveTexture(GL_TEXTURE0);
1504 CHECK_GL_ERROR();
1506 glUniform1i( location, 1 ); // texture unit 1
1507 CHECK_GL_ERROR();
1509 CHECK_GL_ERROR();
1514 namespace
1517 class StaticNoiseTransition : public PermTextureTransition
1519 public:
1520 StaticNoiseTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1521 : PermTextureTransition(rScene, rSettings)
1524 private:
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),
1541 rSettings)
1547 std::shared_ptr<OGLTransitionImpl> makeStatic()
1549 Primitive Slide;
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);
1564 namespace
1567 class DissolveTransition : public PermTextureTransition
1569 public:
1570 DissolveTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1571 : PermTextureTransition(rScene, rSettings)
1574 private:
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),
1591 rSettings)
1597 std::shared_ptr<OGLTransitionImpl> makeDissolve()
1599 Primitive Slide;
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);
1614 namespace
1617 class VortexTransition : public PermTextureTransition
1619 public:
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;
1631 private:
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();
1653 CHECK_GL_ERROR();
1654 glDeleteTextures(2, mnDepthTextures.data());
1655 mnDepthTextures = {0u, 0u};
1656 CHECK_GL_ERROR();
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;
1664 CHECK_GL_ERROR();
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,
1679 s.y, u.y, -f.y, 0,
1680 s.z, u.z, -f.z, 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 )
1686 CHECK_GL_ERROR();
1687 PermTextureTransition::prepareTransition( glLeavingSlideTex, glEnteringSlideTex, pContext );
1688 CHECK_GL_ERROR();
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);
1700 CHECK_GL_ERROR();
1702 glUniform2iv(nNumTilesLocation, 1, glm::value_ptr(maNumTiles));
1703 CHECK_GL_ERROR();
1705 glGenBuffers(1, &mnTileInfoBuffer);
1706 CHECK_GL_ERROR();
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
1714 int n = 0;
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);
1722 n++;
1728 glBindBuffer(GL_ARRAY_BUFFER, mnTileInfoBuffer);
1729 CHECK_GL_ERROR();
1730 glEnableVertexAttribArray(mnTileInfoLocation);
1731 CHECK_GL_ERROR();
1732 glVertexAttribPointer(mnTileInfoLocation, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
1733 CHECK_GL_ERROR();
1734 glBufferData(GL_ARRAY_BUFFER, mvTileInfo.size()*sizeof(GLfloat), mvTileInfo.data(), GL_STATIC_DRAW);
1735 CHECK_GL_ERROR();
1737 glBindBuffer(GL_ARRAY_BUFFER, 0);
1738 CHECK_GL_ERROR();
1740 double EyePos(10.0);
1741 double const RealF(1.0);
1742 double const RealN(-1.0);
1743 double const RealL(-2.0);
1744 double RealR(2.0);
1745 double const RealB(-2.0);
1746 double RealT(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))),
1758 1.0);
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!");
1784 return;
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 )
1800 CHECK_GL_ERROR();
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 );
1826 CHECK_GL_ERROR();
1829 std::shared_ptr<OGLTransitionImpl>
1830 makeVortexTransition(const Primitives_t& rLeavingSlidePrimitives,
1831 const Primitives_t& rEnteringSlidePrimitives,
1832 const TransitionSettings& rSettings,
1833 int NX,
1834 int NY)
1836 return std::make_shared<VortexTransition>(TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives),
1837 rSettings,
1838 NX, NY);
1843 std::shared_ptr<OGLTransitionImpl> makeVortex()
1845 const int NX = 96, NY = 96;
1846 Primitive Slide;
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);
1868 namespace
1871 class RippleTransition : public OGLTransitionImpl
1873 public:
1874 RippleTransition(const TransitionScene& rScene, const TransitionSettings& rSettings, const glm::vec2& rCenter)
1875 : OGLTransitionImpl(rScene, rSettings),
1876 maCenter(rCenter)
1880 private:
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;
1885 glm::vec2 maCenter;
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");
1897 CHECK_GL_ERROR();
1899 glUniform2fv(nCenterLocation, 1, glm::value_ptr(maCenter));
1900 CHECK_GL_ERROR();
1902 maSlideRatioLocation = glGetUniformLocation(m_nProgramObject, "slideRatio");
1903 CHECK_GL_ERROR();
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),
1919 rSettings,
1920 glm::vec2(0.5, 0.5));
1925 std::shared_ptr<OGLTransitionImpl> makeRipple()
1927 Primitive Slide;
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)
1946 if (y % 4 == 0)
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));
1955 else
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));
1966 namespace
1969 class GlitterTransition : public PermTextureTransition
1971 public:
1972 GlitterTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1973 : PermTextureTransition(rScene, rSettings)
1977 private:
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" );
1990 struct ThreeFloats
1992 GLfloat x, y, z;
1995 void GlitterTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext )
1997 CHECK_GL_ERROR();
1998 PermTextureTransition::prepareTransition( glLeavingSlideTex, glEnteringSlideTex, pContext );
1999 CHECK_GL_ERROR();
2001 GLint nNumTilesLocation = glGetUniformLocation(m_nProgramObject, "numTiles");
2002 if (nNumTilesLocation != -1) {
2003 glUniform2iv(nNumTilesLocation, 1, glm::value_ptr(glm::ivec2(41, 41 * 4 / 3)));
2004 CHECK_GL_ERROR();
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 );
2024 CHECK_GL_ERROR();
2027 glBindBuffer(GL_ARRAY_BUFFER, 0);
2030 void GlitterTransition::cleanup()
2032 CHECK_GL_ERROR();
2033 glDeleteBuffers(1, &maBuffer);
2034 CHECK_GL_ERROR();
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),
2043 rSettings);
2048 std::shared_ptr<OGLTransitionImpl> makeGlitter()
2050 const int NX = 80;
2051 const int NY = NX * 4 / 3;
2053 Primitives_t aSlide;
2054 Primitives_t aEmptySlide;
2055 Primitive aHexagon;
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());
2066 namespace
2069 class HoneycombTransition : public PermTextureTransition
2071 public:
2072 HoneycombTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
2073 : PermTextureTransition(rScene, rSettings)
2075 mnDepthTextures[0] = 0;
2076 mnDepthTextures[1] = 0;
2079 private:
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();
2096 CHECK_GL_ERROR();
2097 glActiveTexture( GL_TEXTURE2 );
2098 glBindTexture( GL_TEXTURE_2D, 0 );
2099 glActiveTexture( GL_TEXTURE3 );
2100 glBindTexture( GL_TEXTURE_2D, 0 );
2101 glActiveTexture( GL_TEXTURE0 );
2102 CHECK_GL_ERROR();
2103 glDeleteTextures(2, mnDepthTextures.data());
2104 mnDepthTextures = {0u, 0u};
2105 CHECK_GL_ERROR();
2106 glDeleteFramebuffers(1, &mnFramebuffer);
2107 mnFramebuffer = 0u;
2108 CHECK_GL_ERROR();
2111 GLuint HoneycombTransition::makeShader() const
2113 return OpenGLHelper::LoadShaders( "honeycombVertexShader", "honeycombFragmentShader", "honeycombGeometryShader" );
2116 void HoneycombTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext )
2118 CHECK_GL_ERROR();
2119 PermTextureTransition::prepareTransition( glLeavingSlideTex, glEnteringSlideTex, pContext );
2121 CHECK_GL_ERROR();
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);
2131 CHECK_GL_ERROR();
2133 // We want to see the entering slide behind the leaving one.
2134 glEnable(GL_BLEND);
2135 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2136 CHECK_GL_ERROR();
2138 double EyePos(10.0);
2139 double const RealF(1.0);
2140 double const RealN(-1.0);
2141 double const RealL(-4.0);
2142 double RealR(4.0);
2143 double const RealB(-4.0);
2144 double RealT(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))),
2156 1.0);
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!");
2190 return;
2193 pContext->restoreDefaultFramebuffer();
2196 void HoneycombTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex,
2197 double SlideWidthScale, double SlideHeightScale, OpenGLContext *pContext )
2199 CHECK_GL_ERROR();
2200 applyOverallOperations(nTime, SlideWidthScale, SlideHeightScale);
2201 glUniform1f(m_nTimeLocation, nTime);
2202 glUniform1f(mnShadowLocation, 1.0);
2203 CHECK_GL_ERROR();
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);
2233 CHECK_GL_ERROR();
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),
2243 rSettings);
2248 std::shared_ptr<OGLTransitionImpl> makeHoneycomb()
2250 const int NX = 21;
2251 const int NY = 21;
2253 TransitionSettings aSettings;
2254 aSettings.mnRequiredGLVersion = 3.2f;
2256 Primitives_t aSlide;
2257 Primitive aHexagon;
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()
2268 Primitive Slide;
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: */