1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
3 *
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * Copyright 2008 by Sun Microsystems, Inc.
7 *
8 * OpenOffice.org - a multi-platform office productivity suite
9 *
10 * This file is part of OpenOffice.org.
11 *
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
15 *
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
21 *
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
26 *
27 ************************************************************************/
28
29 #include <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>
34
35 #include <algorithm>
36 #include <array>
37 #include <utility>
38
39 #include <comphelper/random.hxx>
40
41 #include "TransitionImpl.hxx"
42 #include "Operation.hxx"
43 #include <math.h>
44
TransitionScene(TransitionScene const & rOther)45 TransitionScene::TransitionScene(TransitionScene const& rOther)
46 : maLeavingSlidePrimitives(rOther.maLeavingSlidePrimitives)
47 , maEnteringSlidePrimitives(rOther.maEnteringSlidePrimitives)
48 , maOverallOperations(rOther.maOverallOperations)
49 , maSceneObjects(rOther.maSceneObjects)
50 {
51 }
52
operator =(const TransitionScene & rOther)53 TransitionScene& TransitionScene::operator=(const TransitionScene& rOther)
54 {
55 TransitionScene aTmp(rOther);
56 swap(aTmp);
57 return *this;
58 }
59
swap(TransitionScene & rOther)60 void TransitionScene::swap(TransitionScene& rOther)
61 {
62 using std::swap;
63
64 swap(maLeavingSlidePrimitives, rOther.maLeavingSlidePrimitives);
65 swap(maEnteringSlidePrimitives, rOther.maEnteringSlidePrimitives);
66 swap(maOverallOperations, rOther.maOverallOperations);
67 swap(maSceneObjects, rOther.maSceneObjects);
68 }
69
~OGLTransitionImpl()70 OGLTransitionImpl::~OGLTransitionImpl()
71 {
72 }
73
uploadModelViewProjectionMatrices()74 void OGLTransitionImpl::uploadModelViewProjectionMatrices()
75 {
76 double EyePos(10.0);
77 double const RealF(1.0);
78 double const RealN(-1.0);
79 double const RealL(-1.0);
80 double RealR(1.0);
81 double const RealB(-1.0);
82 double RealT(1.0);
83 double ClipN(EyePos+5.0*RealN);
84 double ClipF(EyePos+15.0*RealF);
85 double ClipL(RealL*8.0);
86 double ClipR(RealR*8.0);
87 double ClipB(RealB*8.0);
88 double ClipT(RealT*8.0);
89
90 glm::mat4 projection = glm::frustum<float>(ClipL, ClipR, ClipB, ClipT, ClipN, ClipF);
91 //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.
92 glm::vec3 scale(1.0 / (((RealR * 2.0 * ClipN) / (EyePos * (ClipR - ClipL))) - ((ClipR + ClipL) / (ClipR - ClipL))),
93 1.0 / (((RealT * 2.0 * ClipN) / (EyePos * (ClipT - ClipB))) - ((ClipT + ClipB) / (ClipT - ClipB))),
94 1.0);
95 projection = glm::scale(projection, scale);
96 glm::mat4 modelview = glm::translate(glm::mat4(), glm::vec3(0, 0, -EyePos));
97
98 GLint location = glGetUniformLocation( m_nProgramObject, "u_projectionMatrix" );
99 if( location != -1 ) {
100 glUniformMatrix4fv(location, 1, false, glm::value_ptr(projection));
101 CHECK_GL_ERROR();
102 }
103
104 location = glGetUniformLocation( m_nProgramObject, "u_modelViewMatrix" );
105 if( location != -1 ) {
106 glUniformMatrix4fv(location, 1, false, glm::value_ptr(modelview));
107 CHECK_GL_ERROR();
108 }
109 }
110
uploadPrimitives(const Primitives_t & primitives)111 static std::vector<int> uploadPrimitives(const Primitives_t& primitives)
112 {
113 int size = 0;
114 for (const Primitive& primitive: primitives)
115 size += primitive.getVerticesByteSize();
116
117 CHECK_GL_ERROR();
118 glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_STATIC_DRAW);
119 CHECK_GL_ERROR();
120 Vertex *buf = static_cast<Vertex*>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
121
122 std::vector<int> indices;
123 int last_pos = 0;
124 for (const Primitive& primitive: primitives) {
125 indices.push_back(last_pos);
126 int num = primitive.writeVertices(buf);
127 buf += num;
128 last_pos += num;
129 }
130
131 CHECK_GL_ERROR();
132 glUnmapBuffer(GL_ARRAY_BUFFER);
133 CHECK_GL_ERROR();
134 return indices;
135 }
136
prepare(sal_Int32 glLeavingSlideTex,sal_Int32 glEnteringSlideTex,OpenGLContext * pContext)137 bool OGLTransitionImpl::prepare( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext )
138 {
139 m_nProgramObject = makeShader();
140 if (!m_nProgramObject)
141 return false;
142
143 CHECK_GL_ERROR();
144 glUseProgram( m_nProgramObject );
145 CHECK_GL_ERROR();
146
147 const SceneObjects_t& rSceneObjects(maScene.getSceneObjects());
148 for(size_t i(0); i != rSceneObjects.size(); ++i) {
149 rSceneObjects[i]->prepare(m_nProgramObject);
150 }
151
152 GLint location = glGetUniformLocation( m_nProgramObject, "leavingSlideTexture" );
153 if( location != -1 ) {
154 glUniform1i( location, 0 ); // texture unit 0
155 CHECK_GL_ERROR();
156 }
157
158 location = glGetUniformLocation( m_nProgramObject, "enteringSlideTexture" );
159 if( location != -1 ) {
160 glUniform1i( location, 2 ); // texture unit 2
161 CHECK_GL_ERROR();
162 }
163
164 uploadModelViewProjectionMatrices();
165
166 m_nPrimitiveTransformLocation = glGetUniformLocation( m_nProgramObject, "u_primitiveTransformMatrix" );
167 m_nSceneTransformLocation = glGetUniformLocation( m_nProgramObject, "u_sceneTransformMatrix" );
168 m_nOperationsTransformLocation = glGetUniformLocation( m_nProgramObject, "u_operationsTransformMatrix" );
169 m_nTimeLocation = glGetUniformLocation( m_nProgramObject, "time" );
170
171 glGenVertexArrays(1, &m_nVertexArrayObject);
172 glBindVertexArray(m_nVertexArrayObject);
173
174 glGenBuffers(1, &m_nVertexBufferObject);
175 glBindBuffer(GL_ARRAY_BUFFER, m_nVertexBufferObject);
176
177 // In practice both leaving and entering slides share the same primitives.
178 m_nFirstIndices = uploadPrimitives(getScene().getLeavingSlide());
179
180 // Attribute bindings
181 m_nPositionLocation = glGetAttribLocation(m_nProgramObject, "a_position");
182 if (m_nPositionLocation != -1) {
183 glEnableVertexAttribArray(m_nPositionLocation);
184 glVertexAttribPointer( m_nPositionLocation, 3, GL_FLOAT, false, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, position)) );
185 CHECK_GL_ERROR();
186 }
187
188 m_nNormalLocation = glGetAttribLocation(m_nProgramObject, "a_normal");
189 if (m_nNormalLocation != -1) {
190 glEnableVertexAttribArray(m_nNormalLocation);
191 glVertexAttribPointer( m_nNormalLocation, 3, GL_FLOAT, false, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, normal)) );
192 CHECK_GL_ERROR();
193 }
194
195 m_nTexCoordLocation = glGetAttribLocation(m_nProgramObject, "a_texCoord");
196 if (m_nTexCoordLocation != -1) {
197 glEnableVertexAttribArray(m_nTexCoordLocation);
198 glVertexAttribPointer( m_nTexCoordLocation, 2, GL_FLOAT, false, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, texcoord)) );
199 CHECK_GL_ERROR();
200 }
201
202 glBindBuffer(GL_ARRAY_BUFFER, 0);
203 CHECK_GL_ERROR();
204
205 prepareTransition( glLeavingSlideTex, glEnteringSlideTex, pContext );
206 return true;
207 }
208
finish()209 void OGLTransitionImpl::finish()
210 {
211 const SceneObjects_t& rSceneObjects(maScene.getSceneObjects());
212 for(size_t i(0); i != rSceneObjects.size(); ++i) {
213 rSceneObjects[i]->finish();
214 }
215
216 finishTransition();
217
218 CHECK_GL_ERROR();
219 if( m_nProgramObject ) {
220 glDeleteBuffers(1, &m_nVertexBufferObject);
221 m_nVertexBufferObject = 0;
222 glDeleteVertexArrays(1, &m_nVertexArrayObject);
223 m_nVertexArrayObject = 0;
224 glDeleteProgram( m_nProgramObject );
225 m_nProgramObject = 0;
226 }
227 CHECK_GL_ERROR();
228 }
229
prepare(double,double)230 void OGLTransitionImpl::prepare( double, double )
231 {
232 }
233
cleanup()234 void OGLTransitionImpl::cleanup()
235 {
236 }
237
prepareTransition(sal_Int32,sal_Int32,OpenGLContext *)238 void OGLTransitionImpl::prepareTransition( sal_Int32, sal_Int32, OpenGLContext* )
239 {
240 }
241
finishTransition()242 void OGLTransitionImpl::finishTransition()
243 {
244 }
245
displaySlides_(double nTime,sal_Int32 glLeavingSlideTex,sal_Int32 glEnteringSlideTex,double SlideWidthScale,double SlideHeightScale,OpenGLContext *)246 void OGLTransitionImpl::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext * )
247 {
248 CHECK_GL_ERROR();
249 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
250
251 glUniform1f( m_nTimeLocation, nTime );
252
253 glActiveTexture( GL_TEXTURE2 );
254 glBindTexture( GL_TEXTURE_2D, glEnteringSlideTex );
255 glActiveTexture( GL_TEXTURE0 );
256
257 displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale );
258 CHECK_GL_ERROR();
259 }
260
display(double nTime,sal_Int32 glLeavingSlideTex,sal_Int32 glEnteringSlideTex,double SlideWidth,double SlideHeight,double DispWidth,double DispHeight,OpenGLContext * pContext)261 void OGLTransitionImpl::display( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex,
262 double SlideWidth, double SlideHeight, double DispWidth, double DispHeight, OpenGLContext *pContext )
263 {
264 const double SlideWidthScale = SlideWidth/DispWidth;
265 const double SlideHeightScale = SlideHeight/DispHeight;
266
267 CHECK_GL_ERROR();
268 glBindVertexArray(m_nVertexArrayObject);
269 prepare( SlideWidth, SlideHeight );
270
271 CHECK_GL_ERROR();
272 displaySlides_( nTime, glLeavingSlideTex, glEnteringSlideTex, SlideWidthScale, SlideHeightScale, pContext );
273 CHECK_GL_ERROR();
274 displayScene( nTime, SlideWidth, SlideHeight, DispWidth, DispHeight );
275 CHECK_GL_ERROR();
276 }
277
applyOverallOperations(double nTime,double SlideWidthScale,double SlideHeightScale)278 void OGLTransitionImpl::applyOverallOperations( double nTime, double SlideWidthScale, double SlideHeightScale )
279 {
280 const Operations_t& rOverallOperations(maScene.getOperations());
281 glm::mat4 matrix;
282 for(size_t i(0); i != rOverallOperations.size(); ++i)
283 rOverallOperations[i]->interpolate(matrix, nTime, SlideWidthScale, SlideHeightScale);
284 CHECK_GL_ERROR();
285 if (m_nOperationsTransformLocation != -1) {
286 glUniformMatrix4fv(m_nOperationsTransformLocation, 1, false, glm::value_ptr(matrix));
287 CHECK_GL_ERROR();
288 }
289 }
290
displayPrimitives(const Primitives_t & primitives,GLint primitiveTransformLocation,double nTime,double WidthScale,double HeightScale,std::vector<int>::const_iterator first)291 static void displayPrimitives(const Primitives_t& primitives, GLint primitiveTransformLocation, double nTime, double WidthScale, double HeightScale, std::vector<int>::const_iterator first)
292 {
293 for (const Primitive& primitive: primitives)
294 primitive.display(primitiveTransformLocation, nTime, WidthScale, HeightScale, *first++);
295 }
296
297 void
displaySlide(const double nTime,const sal_Int32 glSlideTex,const Primitives_t & primitives,double SlideWidthScale,double SlideHeightScale)298 OGLTransitionImpl::displaySlide(
299 const double nTime,
300 const sal_Int32 glSlideTex, const Primitives_t& primitives,
301 double SlideWidthScale, double SlideHeightScale )
302 {
303 CHECK_GL_ERROR();
304 glBindTexture(GL_TEXTURE_2D, glSlideTex);
305 CHECK_GL_ERROR();
306 if (m_nSceneTransformLocation != -1) {
307 glUniformMatrix4fv(m_nSceneTransformLocation, 1, false, glm::value_ptr(glm::mat4()));
308 CHECK_GL_ERROR();
309 }
310 displayPrimitives(primitives, m_nPrimitiveTransformLocation, nTime, SlideWidthScale, SlideHeightScale, m_nFirstIndices.cbegin());
311 CHECK_GL_ERROR();
312 }
313
314 void
displayUnbufferedSlide(const double nTime,const sal_Int32 glSlideTex,const Primitives_t & primitives,double SlideWidthScale,double SlideHeightScale)315 OGLTransitionImpl::displayUnbufferedSlide(
316 const double nTime,
317 const sal_Int32 glSlideTex, const Primitives_t& primitives,
318 double SlideWidthScale, double SlideHeightScale )
319 {
320 CHECK_GL_ERROR();
321 glBindTexture(GL_TEXTURE_2D, glSlideTex);
322 CHECK_GL_ERROR();
323 glBindVertexArray(0);
324 CHECK_GL_ERROR();
325 glBindBuffer(GL_ARRAY_BUFFER, 0);
326 CHECK_GL_ERROR();
327 if (m_nSceneTransformLocation != -1) {
328 glUniformMatrix4fv(m_nSceneTransformLocation, 1, false, glm::value_ptr(glm::mat4()));
329 CHECK_GL_ERROR();
330 }
331 for (const Primitive& primitive: primitives)
332 primitive.display(m_nPrimitiveTransformLocation, nTime, SlideWidthScale, SlideHeightScale);
333 CHECK_GL_ERROR();
334 glBindVertexArray(m_nVertexArrayObject);
335 CHECK_GL_ERROR();
336 glBindBuffer(GL_ARRAY_BUFFER, m_nVertexBufferObject);
337 CHECK_GL_ERROR();
338 }
339
displayScene(double nTime,double SlideWidth,double SlideHeight,double DispWidth,double DispHeight)340 void OGLTransitionImpl::displayScene( double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight )
341 {
342 const SceneObjects_t& rSceneObjects(maScene.getSceneObjects());
343 CHECK_GL_ERROR();
344 for(size_t i(0); i != rSceneObjects.size(); ++i)
345 rSceneObjects[i]->display(m_nSceneTransformLocation, m_nPrimitiveTransformLocation, nTime, SlideWidth, SlideHeight, DispWidth, DispHeight);
346 CHECK_GL_ERROR();
347 }
348
display(GLint primitiveTransformLocation,double nTime,double WidthScale,double HeightScale) const349 void Primitive::display(GLint primitiveTransformLocation, double nTime, double WidthScale, double HeightScale) const
350 {
351 glm::mat4 matrix;
352 applyOperations( matrix, nTime, WidthScale, HeightScale );
353
354 CHECK_GL_ERROR();
355 if (primitiveTransformLocation != -1) {
356 glUniformMatrix4fv(primitiveTransformLocation, 1, false, glm::value_ptr(matrix));
357 CHECK_GL_ERROR();
358 }
359
360 GLuint nVertexArrayObject;
361 glGenVertexArrays(1, &nVertexArrayObject);
362 CHECK_GL_ERROR();
363 glBindVertexArray(nVertexArrayObject);
364 CHECK_GL_ERROR();
365
366 GLuint nBuffer;
367 glGenBuffers(1, &nBuffer);
368 CHECK_GL_ERROR();
369 glBindBuffer(GL_ARRAY_BUFFER, nBuffer);
370 CHECK_GL_ERROR();
371 glBufferData(GL_ARRAY_BUFFER, getVerticesByteSize(), Vertices.data(), GL_STATIC_DRAW);
372
373 glEnableVertexAttribArray(0);
374 CHECK_GL_ERROR();
375 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), nullptr);
376 CHECK_GL_ERROR();
377 glDrawArrays( GL_TRIANGLES, 0, Vertices.size() );
378 CHECK_GL_ERROR();
379
380 glDeleteBuffers(1, &nBuffer);
381 CHECK_GL_ERROR();
382
383 glDeleteVertexArrays(1, &nVertexArrayObject);
384 CHECK_GL_ERROR();
385 }
386
display(GLint primitiveTransformLocation,double nTime,double WidthScale,double HeightScale,int first) const387 void Primitive::display(GLint primitiveTransformLocation, double nTime, double WidthScale, double HeightScale, int first) const
388 {
389 glm::mat4 matrix;
390 applyOperations( matrix, nTime, WidthScale, HeightScale );
391
392 CHECK_GL_ERROR();
393 if (primitiveTransformLocation != -1) {
394 glUniformMatrix4fv(primitiveTransformLocation, 1, false, glm::value_ptr(matrix));
395 CHECK_GL_ERROR();
396 }
397 glDrawArrays( GL_TRIANGLES, first, Vertices.size() );
398
399 CHECK_GL_ERROR();
400 }
401
applyOperations(glm::mat4 & matrix,double nTime,double WidthScale,double HeightScale) const402 void Primitive::applyOperations(glm::mat4& matrix, double nTime, double WidthScale, double HeightScale) const
403 {
404 for(const auto & rOperation : Operations)
405 rOperation->interpolate(matrix, nTime, WidthScale, HeightScale);
406 matrix = glm::scale(matrix, glm::vec3(WidthScale, HeightScale, 1));
407 }
408
display(GLint sceneTransformLocation,GLint primitiveTransformLocation,double nTime,double,double,double DispWidth,double DispHeight) const409 void SceneObject::display(GLint sceneTransformLocation, GLint primitiveTransformLocation, double nTime, double /* SlideWidth */, double /* SlideHeight */, double DispWidth, double DispHeight ) const
410 {
411 // fixme: allow various model spaces, now we make it so that
412 // it is regular -1,-1 to 1,1, where the whole display fits in
413 glm::mat4 matrix;
414 if (DispHeight > DispWidth)
415 matrix = glm::scale(matrix, glm::vec3(DispHeight/DispWidth, 1, 1));
416 else
417 matrix = glm::scale(matrix, glm::vec3(1, DispWidth/DispHeight, 1));
418 CHECK_GL_ERROR();
419 if (sceneTransformLocation != -1) {
420 glUniformMatrix4fv(sceneTransformLocation, 1, false, glm::value_ptr(matrix));
421 CHECK_GL_ERROR();
422 }
423 displayPrimitives(maPrimitives, primitiveTransformLocation, nTime, 1, 1, maFirstIndices.cbegin());
424 CHECK_GL_ERROR();
425 }
426
pushPrimitive(const Primitive & p)427 void SceneObject::pushPrimitive(const Primitive &p)
428 {
429 maPrimitives.push_back(p);
430 }
431
SceneObject()432 SceneObject::SceneObject()
433 : maPrimitives()
434 {
435 }
436
~SceneObject()437 SceneObject::~SceneObject()
438 {
439 }
440
441 namespace
442 {
443
444 class Iris : public SceneObject
445 {
446 public:
447 Iris() = default;
448
449 virtual void prepare(GLuint program) override;
450 virtual void display(GLint sceneTransformLocation, GLint primitiveTransformLocation, double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight) const override;
451 virtual void finish() override;
452
453 private:
454 GLuint maTexture = 0;
455 GLuint maBuffer = 0;
456 GLuint maVertexArray = 0;
457 };
458
display(GLint sceneTransformLocation,GLint primitiveTransformLocation,double nTime,double SlideWidth,double SlideHeight,double DispWidth,double DispHeight) const459 void Iris::display(GLint sceneTransformLocation, GLint primitiveTransformLocation, double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight ) const
460 {
461 glBindVertexArray(maVertexArray);
462 CHECK_GL_ERROR();
463 glBindTexture(GL_TEXTURE_2D, maTexture);
464 CHECK_GL_ERROR();
465 SceneObject::display(sceneTransformLocation, primitiveTransformLocation, nTime, SlideWidth, SlideHeight, DispWidth, DispHeight);
466 }
467
prepare(GLuint program)468 void Iris::prepare(GLuint program)
469 {
470 CHECK_GL_ERROR();
471 static const GLubyte img[3] = { 80, 80, 80 };
472
473 glGenTextures(1, &maTexture);
474 glBindTexture(GL_TEXTURE_2D, maTexture);
475 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, img);
476 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
477 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
478 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
479 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
480 CHECK_GL_ERROR();
481
482 glGenVertexArrays(1, &maVertexArray);
483 glBindVertexArray(maVertexArray);
484
485 glGenBuffers(1, &maBuffer);
486 glBindBuffer(GL_ARRAY_BUFFER, maBuffer);
487 maFirstIndices = uploadPrimitives(maPrimitives);
488
489 // Attribute bindings
490 GLint location = glGetAttribLocation(program, "a_position");
491 if (location != -1) {
492 glEnableVertexAttribArray(location);
493 glVertexAttribPointer( location, 3, GL_FLOAT, false, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, position)) );
494 CHECK_GL_ERROR();
495 }
496
497 location = glGetAttribLocation(program, "a_normal");
498 if (location != -1) {
499 glEnableVertexAttribArray(location);
500 glVertexAttribPointer( location, 3, GL_FLOAT, false, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, normal)) );
501 CHECK_GL_ERROR();
502 }
503
504 location = glGetAttribLocation(program, "a_texCoord");
505 if (location != -1) {
506 glEnableVertexAttribArray(location);
507 glVertexAttribPointer( location, 2, GL_FLOAT, false, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, texcoord)) );
508 CHECK_GL_ERROR();
509 }
510
511 glBindBuffer(GL_ARRAY_BUFFER, 0);
512 }
513
finish()514 void Iris::finish()
515 {
516 CHECK_GL_ERROR();
517 glDeleteBuffers(1, &maBuffer);
518 CHECK_GL_ERROR();
519 glDeleteVertexArrays(1, &maVertexArray);
520 CHECK_GL_ERROR();
521 glDeleteTextures(1, &maTexture);
522 CHECK_GL_ERROR();
523 }
524
525 }
526
527 namespace
528 {
529
530 class ReflectionTransition : public OGLTransitionImpl
531 {
532 public:
ReflectionTransition(const TransitionScene & rScene,const TransitionSettings & rSettings)533 ReflectionTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
534 : OGLTransitionImpl(rScene, rSettings)
535 {}
536
537 private:
538 virtual GLuint makeShader() const override;
539 virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext *pContext ) override;
540
prepareTransition(sal_Int32,sal_Int32,OpenGLContext *)541 virtual void prepareTransition( sal_Int32, sal_Int32, OpenGLContext* ) override {
542 glDisable(GL_CULL_FACE);
543 }
544
finishTransition()545 virtual void finishTransition() override {
546 glEnable(GL_CULL_FACE);
547 }
548 };
549
makeShader() const550 GLuint ReflectionTransition::makeShader() const
551 {
552 return OpenGLHelper::LoadShaders( "reflectionVertexShader", "reflectionFragmentShader" );
553 }
554
displaySlides_(double nTime,sal_Int32 glLeavingSlideTex,sal_Int32 glEnteringSlideTex,double SlideWidthScale,double SlideHeightScale,OpenGLContext *)555 void ReflectionTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex,
556 double SlideWidthScale, double SlideHeightScale, OpenGLContext * )
557 {
558 CHECK_GL_ERROR();
559 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
560
561 sal_Int32 texture;
562 Primitives_t slide;
563 if (nTime < 0.5) {
564 texture = glLeavingSlideTex;
565 slide = getScene().getLeavingSlide();
566 } else {
567 texture = glEnteringSlideTex;
568 slide = getScene().getEnteringSlide();
569 }
570
571 displaySlide( nTime, texture, slide, SlideWidthScale, SlideHeightScale );
572 CHECK_GL_ERROR();
573 }
574
575 std::shared_ptr<OGLTransitionImpl>
makeReflectionTransition(const Primitives_t & rLeavingSlidePrimitives,const Primitives_t & rEnteringSlidePrimitives,const Operations_t & rOverallOperations,const TransitionSettings & rSettings)576 makeReflectionTransition(
577 const Primitives_t& rLeavingSlidePrimitives,
578 const Primitives_t& rEnteringSlidePrimitives,
579 const Operations_t& rOverallOperations,
580 const TransitionSettings& rSettings)
581 {
582 return std::make_shared<ReflectionTransition>(
583 TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives, rOverallOperations, SceneObjects_t()),
584 rSettings);
585 }
586
587 }
588
589 namespace
590 {
591
592 class SimpleTransition : public OGLTransitionImpl
593 {
594 public:
SimpleTransition(const TransitionScene & rScene,const TransitionSettings & rSettings)595 SimpleTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
596 : OGLTransitionImpl(rScene, rSettings)
597 {
598 }
599
600 private:
601 virtual GLuint makeShader() const override;
602
603 virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext *pContext ) override;
604 };
605
makeShader() const606 GLuint SimpleTransition::makeShader() const
607 {
608 return OpenGLHelper::LoadShaders( "basicVertexShader", "basicFragmentShader" );
609 }
610
displaySlides_(double nTime,sal_Int32 glLeavingSlideTex,sal_Int32 glEnteringSlideTex,double SlideWidthScale,double SlideHeightScale,OpenGLContext *)611 void SimpleTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex,
612 double SlideWidthScale, double SlideHeightScale, OpenGLContext * )
613 {
614 CHECK_GL_ERROR();
615 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
616
617 CHECK_GL_ERROR();
618 displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale );
619 displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale );
620 CHECK_GL_ERROR();
621 }
622
623 std::shared_ptr<OGLTransitionImpl>
makeSimpleTransition(const Primitives_t & rLeavingSlidePrimitives,const Primitives_t & rEnteringSlidePrimitives,const Operations_t & rOverallOperations,const SceneObjects_t & rSceneObjects,const TransitionSettings & rSettings)624 makeSimpleTransition(
625 const Primitives_t& rLeavingSlidePrimitives,
626 const Primitives_t& rEnteringSlidePrimitives,
627 const Operations_t& rOverallOperations,
628 const SceneObjects_t& rSceneObjects,
629 const TransitionSettings& rSettings)
630 {
631 return std::make_shared<SimpleTransition>(
632 TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives, rOverallOperations, rSceneObjects),
633 rSettings);
634 }
635
636 std::shared_ptr<OGLTransitionImpl>
makeSimpleTransition(const Primitives_t & rLeavingSlidePrimitives,const Primitives_t & rEnteringSlidePrimitives,const Operations_t & rOverallOperations,const TransitionSettings & rSettings=TransitionSettings ())637 makeSimpleTransition(
638 const Primitives_t& rLeavingSlidePrimitives,
639 const Primitives_t& rEnteringSlidePrimitives,
640 const Operations_t& rOverallOperations,
641 const TransitionSettings& rSettings = TransitionSettings())
642 {
643 return makeSimpleTransition(rLeavingSlidePrimitives, rEnteringSlidePrimitives, rOverallOperations, SceneObjects_t(), rSettings);
644 }
645
646 std::shared_ptr<OGLTransitionImpl>
makeSimpleTransition(const Primitives_t & rLeavingSlidePrimitives,const Primitives_t & rEnteringSlidePrimitives,const SceneObjects_t & rSceneObjects,const TransitionSettings & rSettings)647 makeSimpleTransition(
648 const Primitives_t& rLeavingSlidePrimitives,
649 const Primitives_t& rEnteringSlidePrimitives,
650 const SceneObjects_t& rSceneObjects,
651 const TransitionSettings& rSettings)
652 {
653 return makeSimpleTransition(rLeavingSlidePrimitives, rEnteringSlidePrimitives, Operations_t(), rSceneObjects, rSettings);
654 }
655
656 std::shared_ptr<OGLTransitionImpl>
makeSimpleTransition(const Primitives_t & rLeavingSlidePrimitives,const Primitives_t & rEnteringSlidePrimitives,const TransitionSettings & rSettings=TransitionSettings ())657 makeSimpleTransition(
658 const Primitives_t& rLeavingSlidePrimitives,
659 const Primitives_t& rEnteringSlidePrimitives,
660 const TransitionSettings& rSettings = TransitionSettings())
661 {
662 return makeSimpleTransition(rLeavingSlidePrimitives, rEnteringSlidePrimitives, Operations_t(), SceneObjects_t(), rSettings);
663 }
664
665 }
666
makeOutsideCubeFaceToLeft()667 std::shared_ptr<OGLTransitionImpl> makeOutsideCubeFaceToLeft()
668 {
669 Primitive Slide;
670
671 Slide.pushTriangle(glm::vec2(0,0),glm::vec2(1,0),glm::vec2(0,1));
672 Slide.pushTriangle(glm::vec2(1,0),glm::vec2(0,1),glm::vec2(1,1));
673
674 Primitives_t aLeavingPrimitives;
675 aLeavingPrimitives.push_back(Slide);
676
677 Slide.Operations.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0,1,0),glm::vec3(0,0,-1),90,false,false,0.0,1.0));
678
679 Primitives_t aEnteringPrimitives;
680 aEnteringPrimitives.push_back(Slide);
681
682 Operations_t aOperations;
683 aOperations.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0,1,0),glm::vec3(0,0,-1),-90,false,true,0.0,1.0));
684
685 return makeSimpleTransition(aLeavingPrimitives, aEnteringPrimitives, aOperations);
686 }
687
makeInsideCubeFaceToLeft()688 std::shared_ptr<OGLTransitionImpl> makeInsideCubeFaceToLeft()
689 {
690 Primitive Slide;
691
692 Slide.pushTriangle(glm::vec2(0,0),glm::vec2(1,0),glm::vec2(0,1));
693 Slide.pushTriangle(glm::vec2(1,0),glm::vec2(0,1),glm::vec2(1,1));
694
695 Primitives_t aLeavingPrimitives;
696 aLeavingPrimitives.push_back(Slide);
697
698 Slide.Operations.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0,1,0),glm::vec3(0,0,1),-90,false,false,0.0,1.0));
699
700 Primitives_t aEnteringPrimitives;
701 aEnteringPrimitives.push_back(Slide);
702
703 Operations_t aOperations;
704 aOperations.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0,1,0),glm::vec3(0,0,1),90,false,true,0.0,1.0));
705
706 return makeSimpleTransition(aLeavingPrimitives, aEnteringPrimitives, aOperations);
707 }
708
makeFallLeaving()709 std::shared_ptr<OGLTransitionImpl> makeFallLeaving()
710 {
711 Primitive Slide;
712
713 Slide.pushTriangle(glm::vec2(0,0),glm::vec2(1,0),glm::vec2(0,1));
714 Slide.pushTriangle(glm::vec2(1,0),glm::vec2(0,1),glm::vec2(1,1));
715
716 Primitives_t aEnteringPrimitives;
717 aEnteringPrimitives.push_back(Slide);
718
719 Slide.Operations.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(1,0,0),glm::vec3(0,-1,0), 90,true,true,0.0,1.0));
720 Primitives_t aLeavingPrimitives;
721 aLeavingPrimitives.push_back(Slide);
722
723 TransitionSettings aSettings;
724 aSettings.mbUseMipMapEntering = false;
725
726 return makeSimpleTransition(aLeavingPrimitives, aEnteringPrimitives, aSettings);
727 }
728
makeTurnAround()729 std::shared_ptr<OGLTransitionImpl> makeTurnAround()
730 {
731 Primitive Slide;
732 TransitionSettings aSettings;
733
734 Slide.pushTriangle(glm::vec2(0,0),glm::vec2(1,0),glm::vec2(0,1));
735 Slide.pushTriangle(glm::vec2(1,0),glm::vec2(0,1),glm::vec2(1,1));
736 Primitives_t aLeavingPrimitives;
737 aLeavingPrimitives.push_back(Slide);
738
739 Slide.Operations.push_back(makeSScale(glm::vec3(1, -1, 1), glm::vec3(0, -1.02, 0), false, -1, 0));
740 aLeavingPrimitives.push_back(Slide);
741
742 Slide.Operations.clear();
743 Slide.Operations.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0,1,0),glm::vec3(0,0,0),-180,true,false,0.0,1.0));
744 Primitives_t aEnteringPrimitives;
745 aEnteringPrimitives.push_back(Slide);
746
747 Slide.Operations.push_back(makeSScale(glm::vec3(1, -1, 1), glm::vec3(0, -1.02, 0), false, -1, 0));
748 aEnteringPrimitives.push_back(Slide);
749
750 Operations_t aOperations;
751 aOperations.push_back(makeSTranslate(glm::vec3(0, 0, -1.5),true, 0, 0.5));
752 aOperations.push_back(makeSTranslate(glm::vec3(0, 0, 1.5), true, 0.5, 1));
753 aOperations.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0, 1, 0),glm::vec3(0, 0, 0), -180, true, true, 0.0, 1.0));
754
755 return makeReflectionTransition(aLeavingPrimitives, aEnteringPrimitives, aOperations, aSettings);
756 }
757
makeTurnDown()758 std::shared_ptr<OGLTransitionImpl> makeTurnDown()
759 {
760 Primitive Slide;
761
762 Slide.pushTriangle(glm::vec2(0,0),glm::vec2(1,0),glm::vec2(0,1));
763 Slide.pushTriangle(glm::vec2(1,0),glm::vec2(0,1),glm::vec2(1,1));
764 Primitives_t aLeavingPrimitives;
765 aLeavingPrimitives.push_back(Slide);
766
767 Slide.Operations.push_back(makeSTranslate(glm::vec3(0, 0, 0.0001), false, -1.0, 0.0));
768 Slide.Operations.push_back(makeSRotate (glm::vec3(0, 0, 1), glm::vec3(-1, 1, 0), -90, true, 0.0, 1.0));
769 Slide.Operations.push_back(makeSRotate (glm::vec3(0, 0, 1), glm::vec3(-1, 1, 0), 90, false, -1.0, 0.0));
770 Primitives_t aEnteringPrimitives;
771 aEnteringPrimitives.push_back(Slide);
772
773 TransitionSettings aSettings;
774 aSettings.mbUseMipMapLeaving = false;
775
776 return makeSimpleTransition(aLeavingPrimitives, aEnteringPrimitives, aSettings);
777 }
778
makeIris()779 std::shared_ptr<OGLTransitionImpl> makeIris()
780 {
781 Primitive Slide;
782
783 Slide.pushTriangle (glm::vec2 (0,0), glm::vec2 (1,0), glm::vec2 (0,1));
784 Slide.pushTriangle (glm::vec2 (1,0), glm::vec2 (0,1), glm::vec2 (1,1));
785 Primitives_t aEnteringPrimitives;
786 aEnteringPrimitives.push_back (Slide);
787
788 Slide.Operations.push_back (makeSTranslate (glm::vec3 (0, 0, 0.000001), false, -1, 0));
789 Slide.Operations.push_back (makeSTranslate (glm::vec3 (0, 0, -0.000002), false, 0.5, 1));
790 Primitives_t aLeavingPrimitives;
791 aLeavingPrimitives.push_back (Slide);
792
793
794 Primitive irisPart, part;
795 int i, nSteps = 24, nParts = 7;
796 double t = 1.0/nSteps, lx = 1, ly = 0, of=2.2, f=1.42;
797
798 for (i=1; i<=nSteps; i++) {
799 double x = cos ((3*2*M_PI*t)/nParts);
800 double y = -sin ((3*2*M_PI*t)/nParts);
801 double cx = (f*x + 1)/2;
802 double cy = (f*y + 1)/2;
803 double lcx = (f*lx + 1)/2;
804 double lcy = (f*ly + 1)/2;
805 double cxo = (of*x + 1)/2;
806 double cyo = (of*y + 1)/2;
807 double lcxo = (of*lx + 1)/2;
808 double lcyo = (of*ly + 1)/2;
809 irisPart.pushTriangle (glm::vec2 (lcx, lcy),
810 glm::vec2 (lcxo, lcyo),
811 glm::vec2 (cx, cy));
812 irisPart.pushTriangle (glm::vec2 (cx, cy),
813 glm::vec2 (lcxo, lcyo),
814 glm::vec2 (cxo, cyo));
815 lx = x;
816 ly = y;
817 t += 1.0/nSteps;
818 }
819
820 std::shared_ptr<Iris> pIris = std::make_shared<Iris>();
821 double angle = 87;
822
823 for (i = 0; i < nParts; i++) {
824 irisPart.Operations.clear ();
825 double rx, ry;
826
827 rx = cos ((2*M_PI*i)/nParts);
828 ry = sin ((2*M_PI*i)/nParts);
829 irisPart.Operations.push_back (makeSRotate (glm::vec3(0, 0, 1), glm::vec3(rx, ry, 0), angle, true, 0.0, 0.5));
830 irisPart.Operations.push_back (makeSRotate (glm::vec3(0, 0, 1), glm::vec3(rx, ry, 0), -angle, true, 0.5, 1));
831 if (i > 0) {
832 irisPart.Operations.push_back (makeSTranslate (glm::vec3(rx, ry, 0), false, -1, 0));
833 irisPart.Operations.push_back (makeSRotate (glm::vec3(0, 0, 1), glm::vec3(0, 0, 0), i*360.0/nParts, false, -1, 0));
834 irisPart.Operations.push_back (makeSTranslate (glm::vec3(-1, 0, 0), false, -1, 0));
835 }
836 irisPart.Operations.push_back(makeSTranslate(glm::vec3(0, 0, 1), false, -2, 0.0));
837 irisPart.Operations.push_back (makeSRotate (glm::vec3(1, .5, 0), glm::vec3(1, 0, 0), -30, false, -1, 0));
838 pIris->pushPrimitive (irisPart);
839 }
840
841 SceneObjects_t aSceneObjects;
842 aSceneObjects.push_back (pIris);
843
844 TransitionSettings aSettings;
845 aSettings.mbUseMipMapLeaving = aSettings.mbUseMipMapEntering = false;
846
847 return makeSimpleTransition(aLeavingPrimitives, aEnteringPrimitives, aSceneObjects, aSettings);
848 }
849
850 namespace
851 {
852
853 class RochadeTransition : public ReflectionTransition
854 {
855 public:
RochadeTransition(const TransitionScene & rScene,const TransitionSettings & rSettings)856 RochadeTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
857 : ReflectionTransition(rScene, rSettings)
858 {}
859
860 private:
861 virtual void displaySlides_(double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext *pContext) override;
862 };
863
displaySlides_(double nTime,sal_Int32 glLeavingSlideTex,sal_Int32 glEnteringSlideTex,double SlideWidthScale,double SlideHeightScale,OpenGLContext *)864 void RochadeTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext * )
865 {
866 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
867
868 if( nTime > .5) {
869 displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale );
870 displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale );
871 } else {
872 displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale );
873 displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale );
874 }
875 }
876
877 std::shared_ptr<OGLTransitionImpl>
makeRochadeTransition(const Primitives_t & rLeavingSlidePrimitives,const Primitives_t & rEnteringSlidePrimitives,const TransitionSettings & rSettings)878 makeRochadeTransition(
879 const Primitives_t& rLeavingSlidePrimitives,
880 const Primitives_t& rEnteringSlidePrimitives,
881 const TransitionSettings& rSettings)
882 {
883 return std::make_shared<RochadeTransition>(
884 TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives),
885 rSettings)
886 ;
887
888 }
889 }
890
makeRochade()891 std::shared_ptr<OGLTransitionImpl> makeRochade()
892 {
893 Primitive Slide;
894 TransitionSettings aSettings;
895
896 double w, h;
897
898 w = 2.2;
899 h = 10;
900
901 Slide.pushTriangle(glm::vec2(0,0),glm::vec2(1,0),glm::vec2(0,1));
902 Slide.pushTriangle(glm::vec2(1,0),glm::vec2(0,1),glm::vec2(1,1));
903
904 Slide.Operations.push_back(makeSEllipseTranslate(w, h, 0.25, -0.25, true, 0, 1));
905 Slide.Operations.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0,1,0),glm::vec3(0,0,0), -45, true, true, 0, 1));
906 Primitives_t aLeavingSlide;
907 aLeavingSlide.push_back(Slide);
908
909 Slide.Operations.push_back(makeSScale(glm::vec3(1, -1, 1), glm::vec3(0, -1.02, 0), false, -1, 0));
910 aLeavingSlide.push_back(Slide);
911
912 Slide.Operations.clear();
913 Slide.Operations.push_back(makeSEllipseTranslate(w, h, 0.75, 0.25, true, 0, 1));
914 Slide.Operations.push_back(makeSTranslate(glm::vec3(0, 0, -h), false, -1, 0));
915 Slide.Operations.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0,1,0),glm::vec3(0,0,0), -45, true, true, 0, 1));
916 Slide.Operations.push_back(makeRotateAndScaleDepthByWidth(glm::vec3(0,1,0),glm::vec3(0,0,0), 45, true, false, -1, 0));
917 Primitives_t aEnteringSlide;
918 aEnteringSlide.push_back(Slide);
919
920 Slide.Operations.push_back(makeSScale(glm::vec3(1, -1, 1), glm::vec3(0, -1.02, 0), false, -1, 0));
921 aEnteringSlide.push_back(Slide);
922
923 return makeRochadeTransition(aLeavingSlide, aEnteringSlide, aSettings);
924 }
925
randFromNeg1to1()926 static double randFromNeg1to1()
927 {
928 return comphelper::rng::uniform_real_distribution(-1.0, std::nextafter(1.0, DBL_MAX));
929 }
930
931 // TODO(Q3): extract to basegfx
randNormVectorInXYPlane()932 static glm::vec3 randNormVectorInXYPlane()
933 {
934 glm::vec3 toReturn(randFromNeg1to1(),randFromNeg1to1(),0.0);
935 return glm::normalize(toReturn);
936 }
937
938 template<typename T>
clamp(const T & rIn)939 static T clamp(const T& rIn)
940 {
941 return glm::clamp(rIn, T(-1.0), T(1.0));
942 }
943
makeRevolvingCircles(sal_uInt16 nCircles,sal_uInt16 nPointsOnCircles)944 std::shared_ptr<OGLTransitionImpl> makeRevolvingCircles( sal_uInt16 nCircles , sal_uInt16 nPointsOnCircles )
945 {
946 double dAngle(2*3.1415926/static_cast<double>( nPointsOnCircles ));
947 if(nCircles < 2 || nPointsOnCircles < 4)
948 return makeNByMTileFlip(1,1);
949 float Radius(1.0/static_cast<double>( nCircles ));
950 float dRadius(Radius);
951 float LastRadius(0.0);
952 float NextRadius(2*Radius);
953
954 /// now we know there is at least two circles
955 /// the first will always be a full circle
956 /// the last will always be the outer shell of the slide with a circle hole
957
958 //add the full circle
959 std::vector<glm::vec2> unScaledTexCoords;
960 float TempAngle(0.0);
961 for(unsigned int Point(0); Point < nPointsOnCircles; ++Point)
962 {
963 unScaledTexCoords.emplace_back( cos(TempAngle - 3.1415926/2.0) , sin(TempAngle- 3.1415926/2.0) );
964
965 TempAngle += dAngle;
966 }
967
968 Primitives_t aLeavingSlide;
969 Primitives_t aEnteringSlide;
970 {
971 Primitive EnteringSlide;
972 Primitive LeavingSlide;
973 for(int Point(0); Point + 1 < nPointsOnCircles; ++Point)
974 {
975 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 ) );
976 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 }
978 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 ) );
979 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
981 glm::vec3 axis(randNormVectorInXYPlane());
982 EnteringSlide.Operations.push_back( makeSRotate( axis , glm::vec3(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) );
983 LeavingSlide.Operations.push_back( makeSRotate( axis , glm::vec3(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) );
984 EnteringSlide.Operations.push_back( makeSRotate( axis , glm::vec3(0,0,0) , -180, false,0.0,1.0) );
985
986 aEnteringSlide.push_back(EnteringSlide);
987 aLeavingSlide.push_back(LeavingSlide);
988 LastRadius = Radius;
989 Radius = NextRadius;
990 NextRadius += dRadius;
991 }
992
993 for(int i(1); i < nCircles - 1; ++i)
994 {
995 Primitive LeavingSlide;
996 Primitive EnteringSlide;
997 for(int Side(0); Side < nPointsOnCircles - 1; ++Side)
998 {
999 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) );
1000 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
1002 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) );
1003 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) );
1004 }
1005
1006 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) );
1007 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
1009 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) );
1010 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
1012 glm::vec3 axis(randNormVectorInXYPlane());
1013 EnteringSlide.Operations.push_back( makeSRotate( axis , glm::vec3(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) );
1014 LeavingSlide.Operations.push_back( makeSRotate( axis , glm::vec3(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) );
1015 EnteringSlide.Operations.push_back( makeSRotate( axis , glm::vec3(0,0,0) , -180, false,0.0,1.0) );
1016
1017 aEnteringSlide.push_back(EnteringSlide);
1018 aLeavingSlide.push_back(LeavingSlide);
1019
1020 LastRadius = Radius;
1021 Radius = NextRadius;
1022 NextRadius += dRadius;
1023 }
1024 {
1025 Radius = sqrt(2.0);
1026 Primitive LeavingSlide;
1027 Primitive EnteringSlide;
1028 for(int Side(0); Side < nPointsOnCircles - 1; ++Side)
1029 {
1030
1031 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) );
1032 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
1034 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) );
1035 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) );
1036 }
1037
1038 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) );
1039 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
1041 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) );
1042 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
1044 glm::vec3 axis(randNormVectorInXYPlane());
1045 EnteringSlide.Operations.push_back( makeSRotate( axis , glm::vec3(0,0,0) , 180, true, (LastRadius + dRadius)/2.0 , 1.0 ) );
1046 LeavingSlide.Operations.push_back( makeSRotate( axis , glm::vec3(0,0,0) , 180, true, (LastRadius + dRadius)/2.0 , 1.0 ) );
1047 EnteringSlide.Operations.push_back( makeSRotate( axis , glm::vec3(0,0,0) , -180, false,0.0,1.0) );
1048
1049 aEnteringSlide.push_back(EnteringSlide);
1050 aLeavingSlide.push_back(LeavingSlide);
1051 }
1052
1053 return makeSimpleTransition(aLeavingSlide, aEnteringSlide);
1054 }
1055
makeHelix(sal_uInt16 nRows)1056 std::shared_ptr<OGLTransitionImpl> makeHelix( sal_uInt16 nRows )
1057 {
1058 double invN(1.0/static_cast<double>(nRows));
1059 double iDn = 0.0;
1060 double iPDn = invN;
1061 Primitives_t aLeavingSlide;
1062 Primitives_t aEnteringSlide;
1063 for(unsigned int i(0); i < nRows; ++i)
1064 {
1065 Primitive Tile;
1066
1067 Tile.pushTriangle(glm::vec2( 1.0 , iDn ) , glm::vec2( 0.0 , iDn ) , glm::vec2( 0.0 , iPDn ));
1068
1069 Tile.pushTriangle(glm::vec2( 1.0 , iPDn ) , glm::vec2( 1.0 , iDn ) , glm::vec2( 0.0 , iPDn ));
1070
1071 Tile.Operations.push_back( makeSRotate( glm::vec3( 0 , 1 , 0 ) , ( Tile.getVertex(1) + Tile.getVertex(3) )/2.0f , 180 ,
1072 true, std::min(std::max(static_cast<double>(i - nRows/2.0)*invN/2.0,0.0),1.0),
1073 std::min(std::max(static_cast<double>(i + nRows/2.0)*invN/2.0,0.0),1.0) ) );
1074
1075 aLeavingSlide.push_back(Tile);
1076
1077 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
1079 aEnteringSlide.push_back(Tile);
1080
1081 iDn += invN;
1082 iPDn += invN;
1083 }
1084
1085 return makeSimpleTransition(aLeavingSlide, aEnteringSlide);
1086 }
1087
fdiv(int a,int b)1088 static float fdiv(int a, int b)
1089 {
1090 return static_cast<float>(a)/b;
1091 }
1092
vec(float x,float y,float nx,float ny)1093 static glm::vec2 vec(float x, float y, float nx, float ny)
1094 {
1095 x = x < 0.0 ? 0.0 : x;
1096 x = std::min(x, nx);
1097 y = y < 0.0 ? 0.0 : y;
1098 y = std::min(y, ny);
1099 return glm::vec2(fdiv(x, nx), fdiv(y, ny));
1100 }
1101
makeNByMTileFlip(sal_uInt16 n,sal_uInt16 m)1102 std::shared_ptr<OGLTransitionImpl> makeNByMTileFlip( sal_uInt16 n, sal_uInt16 m )
1103 {
1104 Primitives_t aLeavingSlide;
1105 Primitives_t aEnteringSlide;
1106
1107 for (int x = 0; x < n; x++)
1108 {
1109 for (int y = 0; y < n; y++)
1110 {
1111 Primitive aTile;
1112 glm::vec2 x11 = vec(x, y, n, m);
1113 glm::vec2 x12 = vec(x, y+1, n, m);
1114 glm::vec2 x21 = vec(x+1, y, n, m);
1115 glm::vec2 x22 = vec(x+1, y+1, n, m);
1116
1117 aTile.pushTriangle(x21, x11, x12);
1118 aTile.pushTriangle(x22, x21, x12);
1119
1120 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));
1121 aLeavingSlide.push_back(aTile);
1122
1123 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));
1124 aEnteringSlide.push_back(aTile);
1125 }
1126 }
1127
1128 return makeSimpleTransition(aLeavingSlide, aEnteringSlide);
1129 }
1130
operator =(const Primitive & rvalue)1131 Primitive& Primitive::operator=(const Primitive& rvalue)
1132 {
1133 Primitive aTmp(rvalue);
1134 swap(aTmp);
1135 return *this;
1136 }
1137
Primitive(const Primitive & rvalue)1138 Primitive::Primitive(const Primitive& rvalue)
1139 : Operations(rvalue.Operations)
1140 , Vertices(rvalue.Vertices)
1141 {
1142 }
1143
swap(Primitive & rOther)1144 void Primitive::swap(Primitive& rOther)
1145 {
1146 using std::swap;
1147
1148 swap(Operations, rOther.Operations);
1149 swap(Vertices, rOther.Vertices);
1150 }
1151
pushTriangle(const glm::vec2 & SlideLocation0,const glm::vec2 & SlideLocation1,const glm::vec2 & SlideLocation2)1152 void Primitive::pushTriangle(const glm::vec2& SlideLocation0,const glm::vec2& SlideLocation1,const glm::vec2& SlideLocation2)
1153 {
1154 std::vector<glm::vec3> Verts;
1155 std::vector<glm::vec2> Texs;
1156 Verts.reserve(3);
1157 Texs.reserve(3);
1158
1159 Verts.emplace_back( 2*SlideLocation0.x - 1, -2*SlideLocation0.y + 1 , 0.0 );
1160 Verts.emplace_back( 2*SlideLocation1.x - 1, -2*SlideLocation1.y + 1 , 0.0 );
1161 Verts.emplace_back( 2*SlideLocation2.x - 1, -2*SlideLocation2.y + 1 , 0.0 );
1162
1163 //figure out if they're facing the correct way, and make them face the correct way.
1164 glm::vec3 Normal( glm::cross( Verts[0] - Verts[1] , Verts[1] - Verts[2] ) );
1165 if(Normal.z >= 0.0)//if the normal is facing us
1166 {
1167 Texs.push_back(SlideLocation0);
1168 Texs.push_back(SlideLocation1);
1169 Texs.push_back(SlideLocation2);
1170 }
1171 else // if the normal is facing away from us, make it face us
1172 {
1173 Texs.push_back(SlideLocation0);
1174 Texs.push_back(SlideLocation2);
1175 Texs.push_back(SlideLocation1);
1176 Verts.clear();
1177 Verts.emplace_back( 2*SlideLocation0.x - 1, -2*SlideLocation0.y + 1 , 0.0 );
1178 Verts.emplace_back( 2*SlideLocation2.x - 1, -2*SlideLocation2.y + 1 , 0.0 );
1179 Verts.emplace_back( 2*SlideLocation1.x - 1, -2*SlideLocation1.y + 1 , 0.0 );
1180 }
1181
1182 Vertices.push_back({Verts[0], glm::vec3(0, 0, 1), Texs[0]}); //all normals always face the screen when untransformed.
1183 Vertices.push_back({Verts[1], glm::vec3(0, 0, 1), Texs[1]}); //all normals always face the screen when untransformed.
1184 Vertices.push_back({Verts[2], glm::vec3(0, 0, 1), Texs[2]}); //all normals always face the screen when untransformed.
1185 }
1186
1187 namespace
1188 {
1189
1190 class DiamondTransition : public SimpleTransition
1191 {
1192 public:
DiamondTransition(const TransitionScene & rScene,const TransitionSettings & rSettings)1193 DiamondTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1194 : SimpleTransition(rScene, rSettings)
1195 {}
1196
1197 private:
1198 virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext *pContext ) override;
1199 };
1200
makeLeavingSlide(double nTime)1201 Primitives_t makeLeavingSlide(double nTime)
1202 {
1203 Primitive Slide2;
1204 if( nTime >= 0.5 ) {
1205 double m = 1 - nTime;
1206
1207 Slide2.pushTriangle (glm::vec2 (0,0), glm::vec2 (m,0), glm::vec2 (0,m));
1208 Slide2.pushTriangle (glm::vec2 (nTime,0), glm::vec2 (1,0), glm::vec2 (1,m));
1209 Slide2.pushTriangle (glm::vec2 (1,nTime), glm::vec2 (1,1), glm::vec2 (nTime,1));
1210 Slide2.pushTriangle (glm::vec2 (0,nTime), glm::vec2 (m,1), glm::vec2 (0,1));
1211 } else {
1212 double l = 0.5 - nTime;
1213 double h = 0.5 + nTime;
1214
1215 Slide2.pushTriangle (glm::vec2 (0,0), glm::vec2 (1,0), glm::vec2 (0.5,l));
1216 Slide2.pushTriangle (glm::vec2 (0.5,l), glm::vec2 (1,0), glm::vec2 (h,0.5));
1217 Slide2.pushTriangle (glm::vec2 (1,0), glm::vec2 (1,1), glm::vec2 (h,0.5));
1218 Slide2.pushTriangle (glm::vec2 (h,0.5), glm::vec2 (1,1), glm::vec2 (0.5,h));
1219 Slide2.pushTriangle (glm::vec2 (0.5,h), glm::vec2 (1,1), glm::vec2 (0,1));
1220 Slide2.pushTriangle (glm::vec2 (l,0.5), glm::vec2 (0.5,h), glm::vec2 (0,1));
1221 Slide2.pushTriangle (glm::vec2 (0,0), glm::vec2 (l,0.5), glm::vec2 (0,1));
1222 Slide2.pushTriangle (glm::vec2 (0,0), glm::vec2 (0.5,l), glm::vec2 (l,0.5));
1223 }
1224 Slide2.Operations.push_back (makeSTranslate (glm::vec3 (0, 0, 0.00000001), false, -1, 0));
1225 Primitives_t aLeavingSlidePrimitives;
1226 aLeavingSlidePrimitives.push_back (Slide2);
1227
1228 return aLeavingSlidePrimitives;
1229 }
1230
displaySlides_(double nTime,sal_Int32 glLeavingSlideTex,sal_Int32 glEnteringSlideTex,double SlideWidthScale,double SlideHeightScale,OpenGLContext *)1231 void DiamondTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex,
1232 double SlideWidthScale, double SlideHeightScale, OpenGLContext * )
1233 {
1234 CHECK_GL_ERROR();
1235 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
1236
1237 CHECK_GL_ERROR();
1238 displayUnbufferedSlide( nTime, glLeavingSlideTex, makeLeavingSlide(nTime), SlideWidthScale, SlideHeightScale );
1239 displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale );
1240 CHECK_GL_ERROR();
1241 }
1242
1243 std::shared_ptr<OGLTransitionImpl>
makeDiamondTransition(const TransitionSettings & rSettings)1244 makeDiamondTransition(const TransitionSettings& rSettings)
1245 {
1246 Primitive Slide1;
1247 Slide1.pushTriangle (glm::vec2 (0,0), glm::vec2 (1,0), glm::vec2 (0,1));
1248 Slide1.pushTriangle (glm::vec2 (1,0), glm::vec2 (0,1), glm::vec2 (1,1));
1249 Primitives_t aEnteringSlidePrimitives;
1250 aEnteringSlidePrimitives.push_back (Slide1);
1251 Primitives_t aLeavingSlidePrimitives;
1252 aLeavingSlidePrimitives.push_back (Slide1);
1253 return std::make_shared<DiamondTransition>(TransitionScene(aLeavingSlidePrimitives, aEnteringSlidePrimitives), rSettings);
1254 }
1255
1256 }
1257
makeDiamond()1258 std::shared_ptr<OGLTransitionImpl> makeDiamond()
1259 {
1260 TransitionSettings aSettings;
1261 aSettings.mbUseMipMapLeaving = aSettings.mbUseMipMapEntering = false;
1262
1263 return makeDiamondTransition(aSettings);
1264 }
1265
makeVenetianBlinds(bool vertical,int parts)1266 std::shared_ptr<OGLTransitionImpl> makeVenetianBlinds( bool vertical, int parts )
1267 {
1268 static double t30 = tan( M_PI/6.0 );
1269 double ln = 0;
1270 double p = 1.0/parts;
1271
1272 Primitives_t aLeavingSlide;
1273 Primitives_t aEnteringSlide;
1274 for( int i=0; i<parts; i++ ) {
1275 Primitive Slide;
1276 double n = (i + 1)/static_cast<double>(parts);
1277 if( vertical ) {
1278 Slide.pushTriangle (glm::vec2 (ln,0), glm::vec2 (n,0), glm::vec2 (ln,1));
1279 Slide.pushTriangle (glm::vec2 (n,0), glm::vec2 (ln,1), glm::vec2 (n,1));
1280 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 } else {
1282 Slide.pushTriangle (glm::vec2 (0,ln), glm::vec2 (1,ln), glm::vec2 (0,n));
1283 Slide.pushTriangle (glm::vec2 (1,ln), glm::vec2 (0,n), glm::vec2 (1,n));
1284 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 }
1286 aLeavingSlide.push_back (Slide);
1287
1288 if( vertical ) {
1289 Slide.Operations.push_back(makeSRotate(glm::vec3(0, 1, 0), glm::vec3(2*n - 1, 0, 0), -60, false, -1, 0));
1290 Slide.Operations.push_back(makeSRotate(glm::vec3(0, 1, 0), glm::vec3(n + ln - 1, 0, 0), 180, false, -1, 0));
1291 } else {
1292 Slide.Operations.push_back(makeSRotate(glm::vec3(1, 0, 0), glm::vec3(0, 1 - 2*n, 0), -60, false, -1, 0));
1293 Slide.Operations.push_back(makeSRotate(glm::vec3(1, 0, 0), glm::vec3(0, 1 - n - ln, 0), 180, false, -1, 0));
1294 }
1295 aEnteringSlide.push_back (Slide);
1296 ln = n;
1297 }
1298
1299 return makeSimpleTransition(aLeavingSlide, aEnteringSlide);
1300 }
1301
1302 namespace
1303 {
1304
1305 class FadeSmoothlyTransition : public OGLTransitionImpl
1306 {
1307 public:
FadeSmoothlyTransition(const TransitionScene & rScene,const TransitionSettings & rSettings)1308 FadeSmoothlyTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1309 : OGLTransitionImpl(rScene, rSettings)
1310 {}
1311
1312 private:
1313 virtual GLuint makeShader() const override;
1314 };
1315
makeShader() const1316 GLuint FadeSmoothlyTransition::makeShader() const
1317 {
1318 return OpenGLHelper::LoadShaders( "basicVertexShader", "fadeFragmentShader" );
1319 }
1320
1321 std::shared_ptr<OGLTransitionImpl>
makeFadeSmoothlyTransition(const Primitives_t & rLeavingSlidePrimitives,const Primitives_t & rEnteringSlidePrimitives,const TransitionSettings & rSettings)1322 makeFadeSmoothlyTransition(
1323 const Primitives_t& rLeavingSlidePrimitives,
1324 const Primitives_t& rEnteringSlidePrimitives,
1325 const TransitionSettings& rSettings)
1326 {
1327 return std::make_shared<FadeSmoothlyTransition>(
1328 TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives),
1329 rSettings)
1330 ;
1331 }
1332
1333 }
1334
makeFadeSmoothly()1335 std::shared_ptr<OGLTransitionImpl> makeFadeSmoothly()
1336 {
1337 Primitive Slide;
1338
1339 Slide.pushTriangle (glm::vec2 (0,0), glm::vec2 (1,0), glm::vec2 (0,1));
1340 Slide.pushTriangle (glm::vec2 (1,0), glm::vec2 (0,1), glm::vec2 (1,1));
1341 Primitives_t aLeavingSlide;
1342 aLeavingSlide.push_back (Slide);
1343 Primitives_t aEnteringSlide;
1344 aEnteringSlide.push_back (Slide);
1345
1346 TransitionSettings aSettings;
1347 aSettings.mbUseMipMapLeaving = aSettings.mbUseMipMapEntering = false;
1348
1349 return makeFadeSmoothlyTransition(aLeavingSlide, aEnteringSlide, aSettings);
1350 }
1351
1352 namespace
1353 {
1354
1355 class FadeThroughBlackTransition : public OGLTransitionImpl
1356 {
1357 public:
FadeThroughBlackTransition(const TransitionScene & rScene,const TransitionSettings & rSettings)1358 FadeThroughBlackTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1359 : OGLTransitionImpl(rScene, rSettings)
1360 {}
1361
1362 private:
1363 virtual GLuint makeShader() const override;
1364 };
1365
makeShader() const1366 GLuint FadeThroughBlackTransition::makeShader() const
1367 {
1368 return OpenGLHelper::LoadShaders( "basicVertexShader", "fadeBlackFragmentShader" );
1369 }
1370
1371 std::shared_ptr<OGLTransitionImpl>
makeFadeThroughBlackTransition(const Primitives_t & rLeavingSlidePrimitives,const Primitives_t & rEnteringSlidePrimitives,const TransitionSettings & rSettings)1372 makeFadeThroughBlackTransition(
1373 const Primitives_t& rLeavingSlidePrimitives,
1374 const Primitives_t& rEnteringSlidePrimitives,
1375 const TransitionSettings& rSettings)
1376 {
1377 return std::make_shared<FadeThroughBlackTransition>(
1378 TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives),
1379 rSettings)
1380 ;
1381 }
1382
1383 }
1384
makeFadeThroughBlack()1385 std::shared_ptr<OGLTransitionImpl> makeFadeThroughBlack()
1386 {
1387 Primitive Slide;
1388
1389 Slide.pushTriangle (glm::vec2 (0,0), glm::vec2 (1,0), glm::vec2 (0,1));
1390 Slide.pushTriangle (glm::vec2 (1,0), glm::vec2 (0,1), glm::vec2 (1,1));
1391 Primitives_t aLeavingSlide;
1392 aLeavingSlide.push_back (Slide);
1393 Primitives_t aEnteringSlide;
1394 aEnteringSlide.push_back (Slide);
1395
1396 TransitionSettings aSettings;
1397 aSettings.mbUseMipMapLeaving = aSettings.mbUseMipMapEntering = false;
1398
1399 return makeFadeThroughBlackTransition(aLeavingSlide, aEnteringSlide, aSettings);
1400 }
1401
1402 namespace
1403 {
1404
1405 class PermTextureTransition : public OGLTransitionImpl
1406 {
1407 protected:
PermTextureTransition(const TransitionScene & rScene,const TransitionSettings & rSettings)1408 PermTextureTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1409 : OGLTransitionImpl(rScene, rSettings)
1410 , m_nHelperTexture(0)
1411 {}
1412
1413 virtual void finishTransition() override;
1414 virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext ) override;
1415
1416 private:
1417 /** various data */
1418 GLuint m_nHelperTexture;
1419 };
1420
finishTransition()1421 void PermTextureTransition::finishTransition()
1422 {
1423 CHECK_GL_ERROR();
1424 if ( m_nHelperTexture )
1425 {
1426 glDeleteTextures( 1, &m_nHelperTexture );
1427 m_nHelperTexture = 0;
1428 }
1429 CHECK_GL_ERROR();
1430 }
1431
1432 int permutation256 [256]= {
1433 215, 100, 200, 204, 233, 50, 85, 196,
1434 71, 141, 122, 160, 93, 131, 243, 234,
1435 162, 183, 36, 155, 4, 62, 35, 205,
1436 40, 102, 33, 27, 255, 55, 214, 156,
1437 75, 163, 134, 126, 249, 74, 197, 228,
1438 72, 90, 206, 235, 17, 22, 49, 169,
1439 227, 89, 16, 5, 117, 60, 248, 230,
1440 217, 68, 138, 96, 194, 170, 136, 10,
1441 112, 238, 184, 189, 176, 42, 225, 212,
1442 84, 58, 175, 244, 150, 168, 219, 236,
1443 101, 208, 123, 37, 164, 110, 158, 201,
1444 78, 114, 57, 48, 70, 142, 106, 43,
1445 232, 26, 32, 252, 239, 98, 191, 94,
1446 59, 149, 39, 187, 203, 190, 19, 13,
1447 133, 45, 61, 247, 23, 34, 20, 52,
1448 118, 209, 146, 193, 222, 18, 1, 152,
1449 46, 41, 91, 148, 115, 25, 135, 77,
1450 254, 147, 224, 161, 9, 213, 223, 250,
1451 231, 251, 127, 166, 63, 179, 81, 130,
1452 139, 28, 120, 151, 241, 86, 111, 0,
1453 88, 153, 172, 182, 159, 105, 178, 47,
1454 51, 167, 65, 66, 92, 73, 198, 211,
1455 245, 195, 31, 220, 140, 76, 221, 186,
1456 154, 185, 56, 83, 38, 165, 109, 67,
1457 124, 226, 132, 53, 229, 29, 12, 181,
1458 121, 24, 207, 199, 177, 113, 30, 80,
1459 3, 97, 188, 79, 216, 173, 8, 145,
1460 87, 128, 180, 237, 240, 137, 125, 104,
1461 15, 242, 119, 246, 103, 143, 95, 144,
1462 2, 44, 69, 157, 192, 174, 14, 54,
1463 218, 82, 64, 210, 11, 6, 129, 21,
1464 116, 171, 99, 202, 7, 107, 253, 108
1465 };
1466
initPermTexture(GLuint * texID)1467 void initPermTexture(GLuint *texID)
1468 {
1469 CHECK_GL_ERROR();
1470 glGenTextures(1, texID);
1471 glBindTexture(GL_TEXTURE_2D, *texID);
1472
1473 static bool initialized = false;
1474 static unsigned char permutation2D[256*256*4];
1475 if( !initialized ) {
1476 int x, y;
1477
1478 for( y=0; y < 256; y++ )
1479 for( x=0; x < 256; x++ )
1480 permutation2D[x*4 + y*1024] = permutation256[(y + permutation256[x]) & 0xff];
1481
1482 initialized = true;
1483 }
1484
1485 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, permutation2D );
1486 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
1487 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
1488 CHECK_GL_ERROR();
1489 }
1490
prepareTransition(sal_Int32,sal_Int32,OpenGLContext *)1491 void PermTextureTransition::prepareTransition( sal_Int32, sal_Int32, OpenGLContext* )
1492 {
1493 CHECK_GL_ERROR();
1494 GLint location = glGetUniformLocation( m_nProgramObject, "permTexture" );
1495 if( location != -1 ) {
1496 glActiveTexture(GL_TEXTURE1);
1497 CHECK_GL_ERROR();
1498 if( !m_nHelperTexture )
1499 initPermTexture( &m_nHelperTexture );
1500
1501 glActiveTexture(GL_TEXTURE0);
1502 CHECK_GL_ERROR();
1503
1504 glUniform1i( location, 1 ); // texture unit 1
1505 CHECK_GL_ERROR();
1506 }
1507 CHECK_GL_ERROR();
1508 }
1509
1510 }
1511
1512 namespace
1513 {
1514
1515 class StaticNoiseTransition : public PermTextureTransition
1516 {
1517 public:
StaticNoiseTransition(const TransitionScene & rScene,const TransitionSettings & rSettings)1518 StaticNoiseTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1519 : PermTextureTransition(rScene, rSettings)
1520 {}
1521
1522 private:
1523 virtual GLuint makeShader() const override;
1524 };
1525
makeShader() const1526 GLuint StaticNoiseTransition::makeShader() const
1527 {
1528 return OpenGLHelper::LoadShaders( "basicVertexShader", "staticFragmentShader" );
1529 }
1530
1531 std::shared_ptr<OGLTransitionImpl>
makeStaticNoiseTransition(const Primitives_t & rLeavingSlidePrimitives,const Primitives_t & rEnteringSlidePrimitives,const TransitionSettings & rSettings)1532 makeStaticNoiseTransition(
1533 const Primitives_t& rLeavingSlidePrimitives,
1534 const Primitives_t& rEnteringSlidePrimitives,
1535 const TransitionSettings& rSettings)
1536 {
1537 return std::make_shared<StaticNoiseTransition>(
1538 TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives),
1539 rSettings)
1540 ;
1541 }
1542
1543 }
1544
makeStatic()1545 std::shared_ptr<OGLTransitionImpl> makeStatic()
1546 {
1547 Primitive Slide;
1548
1549 Slide.pushTriangle (glm::vec2 (0,0), glm::vec2 (1,0), glm::vec2 (0,1));
1550 Slide.pushTriangle (glm::vec2 (1,0), glm::vec2 (0,1), glm::vec2 (1,1));
1551 Primitives_t aLeavingSlide;
1552 aLeavingSlide.push_back (Slide);
1553 Primitives_t aEnteringSlide;
1554 aEnteringSlide.push_back (Slide);
1555
1556 TransitionSettings aSettings;
1557 aSettings.mbUseMipMapLeaving = aSettings.mbUseMipMapEntering = false;
1558
1559 return makeStaticNoiseTransition(aLeavingSlide, aEnteringSlide, aSettings);
1560 }
1561
1562 namespace
1563 {
1564
1565 class DissolveTransition : public PermTextureTransition
1566 {
1567 public:
DissolveTransition(const TransitionScene & rScene,const TransitionSettings & rSettings)1568 DissolveTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1569 : PermTextureTransition(rScene, rSettings)
1570 {}
1571
1572 private:
1573 virtual GLuint makeShader() const override;
1574 };
1575
makeShader() const1576 GLuint DissolveTransition::makeShader() const
1577 {
1578 return OpenGLHelper::LoadShaders( "basicVertexShader", "dissolveFragmentShader" );
1579 }
1580
1581 std::shared_ptr<OGLTransitionImpl>
makeDissolveTransition(const Primitives_t & rLeavingSlidePrimitives,const Primitives_t & rEnteringSlidePrimitives,const TransitionSettings & rSettings)1582 makeDissolveTransition(
1583 const Primitives_t& rLeavingSlidePrimitives,
1584 const Primitives_t& rEnteringSlidePrimitives,
1585 const TransitionSettings& rSettings)
1586 {
1587 return std::make_shared<DissolveTransition>(
1588 TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives),
1589 rSettings)
1590 ;
1591 }
1592
1593 }
1594
makeDissolve()1595 std::shared_ptr<OGLTransitionImpl> makeDissolve()
1596 {
1597 Primitive Slide;
1598
1599 Slide.pushTriangle (glm::vec2 (0,0), glm::vec2 (1,0), glm::vec2 (0,1));
1600 Slide.pushTriangle (glm::vec2 (1,0), glm::vec2 (0,1), glm::vec2 (1,1));
1601 Primitives_t aLeavingSlide;
1602 aLeavingSlide.push_back (Slide);
1603 Primitives_t aEnteringSlide;
1604 aEnteringSlide.push_back (Slide);
1605
1606 TransitionSettings aSettings;
1607 aSettings.mbUseMipMapLeaving = aSettings.mbUseMipMapEntering = false;
1608
1609 return makeDissolveTransition(aLeavingSlide, aEnteringSlide, aSettings);
1610 }
1611
1612 namespace
1613 {
1614
1615 class VortexTransition : public PermTextureTransition
1616 {
1617 public:
VortexTransition(const TransitionScene & rScene,const TransitionSettings & rSettings,int nNX,int nNY)1618 VortexTransition(const TransitionScene& rScene, const TransitionSettings& rSettings, int nNX, int nNY)
1619 : PermTextureTransition(rScene, rSettings)
1620 , maNumTiles(nNX,nNY)
1621 {
1622 mvTileInfo.resize(6*maNumTiles.x*maNumTiles.y);
1623 mnFramebuffers[0] = 0;
1624 mnFramebuffers[1] = 0;
1625 mnDepthTextures[0] = 0;
1626 mnDepthTextures[1] = 0;
1627 }
1628
1629 private:
1630 virtual void finishTransition() override;
1631 virtual GLuint makeShader() const override;
1632 virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext ) override;
1633 virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext *pContext ) override;
1634
1635 GLint mnSlideLocation = -1;
1636 GLint mnTileInfoLocation = -1;
1637 GLuint mnTileInfoBuffer = 0u;
1638 GLint mnShadowLocation = -1;
1639 std::array<GLuint, 2> mnFramebuffers;
1640 std::array<GLuint, 2> mnDepthTextures;
1641
1642 glm::ivec2 maNumTiles;
1643
1644 std::vector<GLfloat> mvTileInfo;
1645 };
1646
finishTransition()1647 void VortexTransition::finishTransition()
1648 {
1649 PermTextureTransition::finishTransition();
1650
1651 CHECK_GL_ERROR();
1652 glDeleteTextures(2, mnDepthTextures.data());
1653 mnDepthTextures = {0u, 0u};
1654 CHECK_GL_ERROR();
1655 glDeleteFramebuffers(2, mnFramebuffers.data());
1656 mnFramebuffers = {0u, 0u};
1657 glDeleteBuffers(1, &mnTileInfoBuffer);
1658 mnTileInfoBuffer = 0u;
1659 mnSlideLocation = -1;
1660 mnTileInfoLocation = -1;
1661 mnShadowLocation = -1;
1662 CHECK_GL_ERROR();
1663 }
1664
makeShader() const1665 GLuint VortexTransition::makeShader() const
1666 {
1667 return OpenGLHelper::LoadShaders( "vortexVertexShader", "vortexFragmentShader", "vortexGeometryShader" );
1668 }
1669
lookAt(const glm::vec3 & eye,const glm::vec3 & center,const glm::vec3 & up)1670 glm::mat4 lookAt(const glm::vec3& eye, const glm::vec3& center, const glm::vec3& up) {
1671 glm::vec3 f = glm::normalize(center - eye);
1672 glm::vec3 u = glm::normalize(up);
1673 glm::vec3 s = glm::normalize(glm::cross(f, u));
1674 u = glm::cross(s, f);
1675
1676 return glm::mat4(s.x, u.x, -f.x, 0,
1677 s.y, u.y, -f.y, 0,
1678 s.z, u.z, -f.z, 0,
1679 -glm::dot(s, eye), -glm::dot(u, eye), glm::dot(f, eye), 1);
1680 }
1681
prepareTransition(sal_Int32 glLeavingSlideTex,sal_Int32 glEnteringSlideTex,OpenGLContext * pContext)1682 void VortexTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext )
1683 {
1684 CHECK_GL_ERROR();
1685 PermTextureTransition::prepareTransition( glLeavingSlideTex, glEnteringSlideTex, pContext );
1686 CHECK_GL_ERROR();
1687
1688 mnSlideLocation = glGetUniformLocation(m_nProgramObject, "slide");
1689 mnTileInfoLocation = glGetAttribLocation(m_nProgramObject, "tileInfo");
1690 GLint nNumTilesLocation = glGetUniformLocation(m_nProgramObject, "numTiles");
1691 mnShadowLocation = glGetUniformLocation(m_nProgramObject, "shadow");
1692 GLint nOrthoProjectionMatrix = glGetUniformLocation(m_nProgramObject, "orthoProjectionMatrix");
1693 GLint nOrthoViewMatrix = glGetUniformLocation(m_nProgramObject, "orthoViewMatrix");
1694 GLint location = glGetUniformLocation(m_nProgramObject, "leavingShadowTexture");
1695 glUniform1i(location, 2);
1696 location = glGetUniformLocation(m_nProgramObject, "enteringShadowTexture");
1697 glUniform1i(location, 3);
1698 CHECK_GL_ERROR();
1699
1700 glUniform2iv(nNumTilesLocation, 1, glm::value_ptr(maNumTiles));
1701 CHECK_GL_ERROR();
1702
1703 glGenBuffers(1, &mnTileInfoBuffer);
1704 CHECK_GL_ERROR();
1705
1706 // We store the (x,y) indexes of the tile each vertex belongs to in a float, so they must fit.
1707 assert(maNumTiles.x < 256);
1708 assert(maNumTiles.y < 256);
1709
1710 // Two triangles, i.e. six vertices, per tile
1711 {
1712 int n = 0;
1713 for (int x = 0; x < maNumTiles.x; x++)
1714 {
1715 for (int y = 0; y < maNumTiles.y; y++)
1716 {
1717 for (int v = 0; v < 6; v++)
1718 {
1719 mvTileInfo[n] = x + (y << 8) + (v << 16);
1720 n++;
1721 }
1722 }
1723 }
1724 }
1725
1726 glBindBuffer(GL_ARRAY_BUFFER, mnTileInfoBuffer);
1727 CHECK_GL_ERROR();
1728 glEnableVertexAttribArray(mnTileInfoLocation);
1729 CHECK_GL_ERROR();
1730 glVertexAttribPointer(mnTileInfoLocation, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
1731 CHECK_GL_ERROR();
1732 glBufferData(GL_ARRAY_BUFFER, mvTileInfo.size()*sizeof(GLfloat), mvTileInfo.data(), GL_STATIC_DRAW);
1733 CHECK_GL_ERROR();
1734
1735 glBindBuffer(GL_ARRAY_BUFFER, 0);
1736 CHECK_GL_ERROR();
1737
1738 double EyePos(10.0);
1739 double const RealF(1.0);
1740 double const RealN(-1.0);
1741 double const RealL(-2.0);
1742 double RealR(2.0);
1743 double const RealB(-2.0);
1744 double RealT(2.0);
1745 double ClipN(EyePos+5.0*RealN);
1746 double ClipF(EyePos+15.0*RealF);
1747 double ClipL(RealL*8.0);
1748 double ClipR(RealR*8.0);
1749 double ClipB(RealB*8.0);
1750 double ClipT(RealT*8.0);
1751
1752 glm::mat4 projection = glm::ortho<float>(ClipL, ClipR, ClipB, ClipT, ClipN, ClipF);
1753 //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.
1754 glm::vec3 scale(1.0 / (((RealR * 2.0 * ClipN) / (EyePos * (ClipR - ClipL))) - ((ClipR + ClipL) / (ClipR - ClipL))),
1755 1.0 / (((RealT * 2.0 * ClipN) / (EyePos * (ClipT - ClipB))) - ((ClipT + ClipB) / (ClipT - ClipB))),
1756 1.0);
1757 projection = glm::scale(projection, scale);
1758 glUniformMatrix4fv(nOrthoProjectionMatrix, 1, false, glm::value_ptr(projection));
1759
1760 glm::mat4 view = lookAt(glm::vec3(-1, 1, EyePos), glm::vec3(-0.5, 0.5, 0), glm::vec3(0, 1, 0));
1761 glUniformMatrix4fv(nOrthoViewMatrix, 1, false, glm::value_ptr(view));
1762
1763 // Generate the framebuffers and textures for the shadows.
1764 glGenTextures(2, mnDepthTextures.data());
1765 glGenFramebuffers(2, mnFramebuffers.data());
1766
1767 for (int i : {0, 1}) {
1768 glBindTexture(GL_TEXTURE_2D, mnDepthTextures[i]);
1769 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 2048, 2048, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
1770 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1771 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1772 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1773 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1774
1775 glBindFramebuffer(GL_FRAMEBUFFER, mnFramebuffers[i]);
1776 glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, mnDepthTextures[i], 0);
1777 glDrawBuffer(GL_NONE); // No color buffer is drawn to.
1778
1779 // Always check that our framebuffer is ok
1780 if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
1781 SAL_WARN("slideshow.opengl", "Wrong framebuffer!");
1782 return;
1783 }
1784 }
1785
1786 pContext->restoreDefaultFramebuffer();
1787 glBindTexture(GL_TEXTURE_2D, 0);
1788
1789 glActiveTexture( GL_TEXTURE2 );
1790 glBindTexture( GL_TEXTURE_2D, mnDepthTextures[0] );
1791 glActiveTexture( GL_TEXTURE3 );
1792 glBindTexture( GL_TEXTURE_2D, mnDepthTextures[1] );
1793 glActiveTexture( GL_TEXTURE0 );
1794 }
1795
displaySlides_(double nTime,sal_Int32 glLeavingSlideTex,sal_Int32 glEnteringSlideTex,double SlideWidthScale,double SlideHeightScale,OpenGLContext * pContext)1796 void VortexTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext * pContext )
1797 {
1798 CHECK_GL_ERROR();
1799 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
1800 glUniform1f( m_nTimeLocation, nTime );
1801 glUniform1f( mnShadowLocation, 1.0 );
1802
1803 std::array<GLint, 4> viewport;
1804 glGetIntegerv(GL_VIEWPORT, viewport.data());
1805 glViewport(0, 0, 2048, 2048);
1806
1807 glBindFramebuffer(GL_FRAMEBUFFER, mnFramebuffers[0]);
1808 glClear(GL_DEPTH_BUFFER_BIT);
1809 glUniform1f( mnSlideLocation, 0.0 );
1810 displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale );
1811
1812 glBindFramebuffer(GL_FRAMEBUFFER, mnFramebuffers[1]);
1813 glClear(GL_DEPTH_BUFFER_BIT);
1814 glUniform1f( mnSlideLocation, 1.0 );
1815 displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale );
1816
1817 glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
1818 pContext->restoreDefaultFramebuffer();
1819 glUniform1f( mnShadowLocation, 0.0 );
1820 glUniform1f( mnSlideLocation, 0.0 );
1821 displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale );
1822 glUniform1f( mnSlideLocation, 1.0 );
1823 displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale );
1824 CHECK_GL_ERROR();
1825 }
1826
1827 std::shared_ptr<OGLTransitionImpl>
makeVortexTransition(const Primitives_t & rLeavingSlidePrimitives,const Primitives_t & rEnteringSlidePrimitives,const TransitionSettings & rSettings,int NX,int NY)1828 makeVortexTransition(const Primitives_t& rLeavingSlidePrimitives,
1829 const Primitives_t& rEnteringSlidePrimitives,
1830 const TransitionSettings& rSettings,
1831 int NX,
1832 int NY)
1833 {
1834 return std::make_shared<VortexTransition>(TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives),
1835 rSettings,
1836 NX, NY);
1837 }
1838
1839 }
1840
makeVortex()1841 std::shared_ptr<OGLTransitionImpl> makeVortex()
1842 {
1843 const int NX = 96, NY = 96;
1844 Primitive Slide;
1845
1846 for (int x = 0; x < NX; x++)
1847 {
1848 for (int y = 0; y < NY; y++)
1849 {
1850 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)));
1851 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)));
1852 }
1853 }
1854 Primitives_t aLeavingSlide;
1855 aLeavingSlide.push_back (Slide);
1856 Primitives_t aEnteringSlide;
1857 aEnteringSlide.push_back (Slide);
1858
1859 TransitionSettings aSettings;
1860 aSettings.mbUseMipMapLeaving = aSettings.mbUseMipMapEntering = false;
1861 aSettings.mnRequiredGLVersion = 3.2f;
1862
1863 return makeVortexTransition(aLeavingSlide, aEnteringSlide, aSettings, NX, NY);
1864 }
1865
1866 namespace
1867 {
1868
1869 class RippleTransition : public OGLTransitionImpl
1870 {
1871 public:
RippleTransition(const TransitionScene & rScene,const TransitionSettings & rSettings,const glm::vec2 & rCenter)1872 RippleTransition(const TransitionScene& rScene, const TransitionSettings& rSettings, const glm::vec2& rCenter)
1873 : OGLTransitionImpl(rScene, rSettings),
1874 maCenter(rCenter)
1875 {
1876 }
1877
1878 private:
1879 virtual GLuint makeShader() const override;
1880 virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext ) override;
1881 virtual void prepare( double SlideWidth, double SlideHeight ) override;
1882
1883 glm::vec2 maCenter;
1884 GLint maSlideRatioLocation = -1;
1885 };
1886
makeShader() const1887 GLuint RippleTransition::makeShader() const
1888 {
1889 return OpenGLHelper::LoadShaders( "basicVertexShader", "rippleFragmentShader" );
1890 }
1891
prepareTransition(sal_Int32,sal_Int32,OpenGLContext *)1892 void RippleTransition::prepareTransition( sal_Int32, sal_Int32, OpenGLContext* )
1893 {
1894 GLint nCenterLocation = glGetUniformLocation(m_nProgramObject, "center");
1895 CHECK_GL_ERROR();
1896
1897 glUniform2fv(nCenterLocation, 1, glm::value_ptr(maCenter));
1898 CHECK_GL_ERROR();
1899
1900 maSlideRatioLocation = glGetUniformLocation(m_nProgramObject, "slideRatio");
1901 CHECK_GL_ERROR();
1902 }
1903
prepare(double SlideWidth,double SlideHeight)1904 void RippleTransition::prepare( double SlideWidth, double SlideHeight )
1905 {
1906 if( maSlideRatioLocation != -1 )
1907 glUniform1f( maSlideRatioLocation, SlideWidth / SlideHeight );
1908 }
1909
1910 std::shared_ptr<OGLTransitionImpl>
makeRippleTransition(const Primitives_t & rLeavingSlidePrimitives,const Primitives_t & rEnteringSlidePrimitives,const TransitionSettings & rSettings)1911 makeRippleTransition(const Primitives_t& rLeavingSlidePrimitives,
1912 const Primitives_t& rEnteringSlidePrimitives,
1913 const TransitionSettings& rSettings)
1914 {
1915 // The center point should be adjustable by the user, but we have no way to do that in the UI
1916 return std::make_shared<RippleTransition>(TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives),
1917 rSettings,
1918 glm::vec2(0.5, 0.5));
1919 }
1920
1921 }
1922
makeRipple()1923 std::shared_ptr<OGLTransitionImpl> makeRipple()
1924 {
1925 Primitive Slide;
1926
1927 Slide.pushTriangle (glm::vec2 (0,0), glm::vec2 (1,0), glm::vec2 (0,1));
1928 Slide.pushTriangle (glm::vec2 (1,0), glm::vec2 (0,1), glm::vec2 (1,1));
1929
1930 Primitives_t aLeavingSlide;
1931 aLeavingSlide.push_back (Slide);
1932
1933 Primitives_t aEnteringSlide;
1934 aEnteringSlide.push_back (Slide);
1935
1936 TransitionSettings aSettings;
1937 aSettings.mbUseMipMapLeaving = aSettings.mbUseMipMapEntering = false;
1938
1939 return makeRippleTransition(aLeavingSlide, aEnteringSlide, aSettings);
1940 }
1941
createHexagon(Primitive & aHexagon,const int x,const int y,const int NX,const int NY)1942 static void createHexagon(Primitive& aHexagon, const int x, const int y, const int NX, const int NY)
1943 {
1944 if (y % 4 == 0)
1945 {
1946 aHexagon.pushTriangle(vec(x-1, y-1, NX, NY), vec(x, y-2, NX, NY), vec(x, y+0.5, NX, NY));
1947 aHexagon.pushTriangle(vec(x, y-2, NX, NY), vec(x+1, y-1, NX, NY), vec(x, y+0.5, NX, NY));
1948 aHexagon.pushTriangle(vec(x+1, y-1, NX, NY), vec(x+1, y, NX, NY), vec(x, y+0.5, NX, NY));
1949 aHexagon.pushTriangle(vec(x+1, y, NX, NY), vec(x, y+1, NX, NY), vec(x, y+0.5, NX, NY));
1950 aHexagon.pushTriangle(vec(x, 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-1, y-1, NX, NY), vec(x, y+0.5, NX, NY));
1952 }
1953 else
1954 {
1955 aHexagon.pushTriangle(vec(x-2, y-1, NX, NY), vec(x-1, y-2, NX, NY), vec(x, y+0.5, NX, NY));
1956 aHexagon.pushTriangle(vec(x-1, y-2, NX, NY), vec(x, y-1, NX, NY), vec(x, y+0.5, NX, NY));
1957 aHexagon.pushTriangle(vec(x, y-1, NX, NY), vec(x, y, NX, NY), vec(x, y+0.5, NX, NY));
1958 aHexagon.pushTriangle(vec(x, y, NX, NY), vec(x-1, y+1, NX, NY), vec(x, y+0.5, NX, NY));
1959 aHexagon.pushTriangle(vec(x-1, y+1, NX, NY), vec(x-2, y, NX, NY), vec(x, y+0.5, NX, NY));
1960 aHexagon.pushTriangle(vec(x-2, y, NX, NY), vec(x-2, y-1, NX, NY), vec(x, y+0.5, NX, NY));
1961 }
1962 }
1963
1964 namespace
1965 {
1966
1967 class GlitterTransition : public PermTextureTransition
1968 {
1969 public:
GlitterTransition(const TransitionScene & rScene,const TransitionSettings & rSettings)1970 GlitterTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
1971 : PermTextureTransition(rScene, rSettings)
1972 {
1973 }
1974
1975 private:
1976 virtual GLuint makeShader() const override;
1977 virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext ) override;
1978 virtual void cleanup() override;
1979
1980 GLuint maBuffer = 0;
1981 };
1982
makeShader() const1983 GLuint GlitterTransition::makeShader() const
1984 {
1985 return OpenGLHelper::LoadShaders( "glitterVertexShader", "glitterFragmentShader" );
1986 }
1987
1988 struct ThreeFloats
1989 {
1990 GLfloat x, y, z;
1991 };
1992
prepareTransition(sal_Int32 glLeavingSlideTex,sal_Int32 glEnteringSlideTex,OpenGLContext * pContext)1993 void GlitterTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext )
1994 {
1995 CHECK_GL_ERROR();
1996 PermTextureTransition::prepareTransition( glLeavingSlideTex, glEnteringSlideTex, pContext );
1997 CHECK_GL_ERROR();
1998
1999 GLint nNumTilesLocation = glGetUniformLocation(m_nProgramObject, "numTiles");
2000 if (nNumTilesLocation != -1) {
2001 glUniform2iv(nNumTilesLocation, 1, glm::value_ptr(glm::ivec2(41, 41 * 4 / 3)));
2002 CHECK_GL_ERROR();
2003 }
2004
2005 glGenBuffers(1, &maBuffer);
2006 glBindBuffer(GL_ARRAY_BUFFER, maBuffer);
2007
2008 // Upload the center of each hexagon.
2009 const Primitive& primitive = getScene().getLeavingSlide()[0];
2010 std::vector<ThreeFloats> vertices;
2011 for (int i = 2; i < primitive.getVerticesCount(); i += 18) {
2012 const glm::vec3& center = primitive.getVertex(i);
2013 for (int j = 0; j < 18; ++j)
2014 vertices.push_back({center.x, center.y, center.z});
2015 }
2016 glBufferData(GL_ARRAY_BUFFER, vertices.size() * 3 * sizeof(GLfloat), vertices.data(), GL_STATIC_DRAW);
2017
2018 GLint location = glGetAttribLocation(m_nProgramObject, "center");
2019 if (location != -1) {
2020 glEnableVertexAttribArray(location);
2021 glVertexAttribPointer( location, 3, GL_FLOAT, false, 0, nullptr );
2022 CHECK_GL_ERROR();
2023 }
2024
2025 glBindBuffer(GL_ARRAY_BUFFER, 0);
2026 }
2027
cleanup()2028 void GlitterTransition::cleanup()
2029 {
2030 CHECK_GL_ERROR();
2031 glDeleteBuffers(1, &maBuffer);
2032 CHECK_GL_ERROR();
2033 }
2034
2035 std::shared_ptr<OGLTransitionImpl>
makeGlitterTransition(const Primitives_t & rLeavingSlidePrimitives,const Primitives_t & rEnteringSlidePrimitives,const TransitionSettings & rSettings)2036 makeGlitterTransition(const Primitives_t& rLeavingSlidePrimitives,
2037 const Primitives_t& rEnteringSlidePrimitives,
2038 const TransitionSettings& rSettings)
2039 {
2040 return std::make_shared<GlitterTransition>(TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives),
2041 rSettings);
2042 }
2043
2044 }
2045
makeGlitter()2046 std::shared_ptr<OGLTransitionImpl> makeGlitter()
2047 {
2048 const int NX = 80;
2049 const int NY = NX * 4 / 3;
2050
2051 Primitives_t aSlide;
2052 Primitives_t aEmptySlide;
2053 Primitive aHexagon;
2054
2055 for (int y = 0; y < NY+2; y+=2)
2056 for (int x = 0; x < NX+2; x+=2)
2057 createHexagon(aHexagon, x, y, NX, NY);
2058
2059 aSlide.push_back(aHexagon);
2060
2061 return makeGlitterTransition(aSlide, aEmptySlide, TransitionSettings());
2062 }
2063
2064 namespace
2065 {
2066
2067 class HoneycombTransition : public PermTextureTransition
2068 {
2069 public:
HoneycombTransition(const TransitionScene & rScene,const TransitionSettings & rSettings)2070 HoneycombTransition(const TransitionScene& rScene, const TransitionSettings& rSettings)
2071 : PermTextureTransition(rScene, rSettings)
2072 {
2073 mnDepthTextures[0] = 0;
2074 mnDepthTextures[1] = 0;
2075 }
2076
2077 private:
2078 virtual void finishTransition() override;
2079 virtual GLuint makeShader() const override;
2080 virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext ) override;
2081 virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext *pContext ) override;
2082
2083 GLint maHexagonSizeLocation = -1;
2084 GLint maSelectedTextureLocation = -1;
2085 GLint mnShadowLocation = -1;
2086 GLuint mnFramebuffer = 0u;
2087 std::array<GLuint, 2> mnDepthTextures;
2088 };
2089
finishTransition()2090 void HoneycombTransition::finishTransition()
2091 {
2092 PermTextureTransition::finishTransition();
2093
2094 CHECK_GL_ERROR();
2095 glActiveTexture( GL_TEXTURE2 );
2096 glBindTexture( GL_TEXTURE_2D, 0 );
2097 glActiveTexture( GL_TEXTURE3 );
2098 glBindTexture( GL_TEXTURE_2D, 0 );
2099 glActiveTexture( GL_TEXTURE0 );
2100 CHECK_GL_ERROR();
2101 glDeleteTextures(2, mnDepthTextures.data());
2102 mnDepthTextures = {0u, 0u};
2103 CHECK_GL_ERROR();
2104 glDeleteFramebuffers(1, &mnFramebuffer);
2105 mnFramebuffer = 0u;
2106 CHECK_GL_ERROR();
2107 }
2108
makeShader() const2109 GLuint HoneycombTransition::makeShader() const
2110 {
2111 return OpenGLHelper::LoadShaders( "honeycombVertexShader", "honeycombFragmentShader", "honeycombGeometryShader" );
2112 }
2113
prepareTransition(sal_Int32 glLeavingSlideTex,sal_Int32 glEnteringSlideTex,OpenGLContext * pContext)2114 void HoneycombTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext )
2115 {
2116 CHECK_GL_ERROR();
2117 PermTextureTransition::prepareTransition( glLeavingSlideTex, glEnteringSlideTex, pContext );
2118
2119 CHECK_GL_ERROR();
2120 maHexagonSizeLocation = glGetUniformLocation(m_nProgramObject, "hexagonSize");
2121 maSelectedTextureLocation = glGetUniformLocation( m_nProgramObject, "selectedTexture" );
2122 mnShadowLocation = glGetUniformLocation(m_nProgramObject, "shadow");
2123 GLint nOrthoProjectionMatrix = glGetUniformLocation(m_nProgramObject, "orthoProjectionMatrix");
2124 GLint nOrthoViewMatrix = glGetUniformLocation(m_nProgramObject, "orthoViewMatrix");
2125 GLint location = glGetUniformLocation(m_nProgramObject, "colorShadowTexture");
2126 glUniform1i(location, 2);
2127 location = glGetUniformLocation(m_nProgramObject, "depthShadowTexture");
2128 glUniform1i(location, 3);
2129 CHECK_GL_ERROR();
2130
2131 // We want to see the entering slide behind the leaving one.
2132 glEnable(GL_BLEND);
2133 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2134 CHECK_GL_ERROR();
2135
2136 double EyePos(10.0);
2137 double const RealF(1.0);
2138 double const RealN(-1.0);
2139 double const RealL(-4.0);
2140 double RealR(4.0);
2141 double const RealB(-4.0);
2142 double RealT(4.0);
2143 double ClipN(EyePos+5.0*RealN);
2144 double ClipF(EyePos+15.0*RealF);
2145 double ClipL(RealL*8.0);
2146 double ClipR(RealR*8.0);
2147 double ClipB(RealB*8.0);
2148 double ClipT(RealT*8.0);
2149
2150 glm::mat4 projection = glm::ortho<float>(ClipL, ClipR, ClipB, ClipT, ClipN, ClipF);
2151 //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.
2152 glm::vec3 scale(1.0 / (((RealR * 2.0 * ClipN) / (EyePos * (ClipR - ClipL))) - ((ClipR + ClipL) / (ClipR - ClipL))),
2153 1.0 / (((RealT * 2.0 * ClipN) / (EyePos * (ClipT - ClipB))) - ((ClipT + ClipB) / (ClipT - ClipB))),
2154 1.0);
2155 projection = glm::scale(projection, scale);
2156 glUniformMatrix4fv(nOrthoProjectionMatrix, 1, false, glm::value_ptr(projection));
2157
2158 glm::mat4 view = lookAt(glm::vec3(0, 0, EyePos), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
2159 glUniformMatrix4fv(nOrthoViewMatrix, 1, false, glm::value_ptr(view));
2160
2161 // Generate the framebuffer and textures for the shadows.
2162 glGenTextures(2, mnDepthTextures.data());
2163 glActiveTexture(GL_TEXTURE2);
2164 glBindTexture(GL_TEXTURE_2D, mnDepthTextures[0]);
2165 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2048, 2048, 0, GL_RGBA, GL_FLOAT, nullptr);
2166 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2167 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2168 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2169 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2170
2171 glActiveTexture(GL_TEXTURE3);
2172 glBindTexture(GL_TEXTURE_2D, mnDepthTextures[1]);
2173 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 2048, 2048, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
2174 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2175 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2176 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2177 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2178
2179 glActiveTexture(GL_TEXTURE0);
2180 glGenFramebuffers(1, &mnFramebuffer);
2181 glBindFramebuffer(GL_FRAMEBUFFER, mnFramebuffer);
2182 glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mnDepthTextures[0], 0);
2183 glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, mnDepthTextures[1], 0);
2184
2185 // Always check that our framebuffer is ok
2186 if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
2187 SAL_WARN("slideshow.opengl", "Wrong framebuffer!");
2188 return;
2189 }
2190
2191 pContext->restoreDefaultFramebuffer();
2192 }
2193
displaySlides_(double nTime,sal_Int32 glLeavingSlideTex,sal_Int32 glEnteringSlideTex,double SlideWidthScale,double SlideHeightScale,OpenGLContext * pContext)2194 void HoneycombTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex,
2195 double SlideWidthScale, double SlideHeightScale, OpenGLContext *pContext )
2196 {
2197 CHECK_GL_ERROR();
2198 applyOverallOperations(nTime, SlideWidthScale, SlideHeightScale);
2199 glUniform1f(m_nTimeLocation, nTime);
2200 glUniform1f(mnShadowLocation, 1.0);
2201 CHECK_GL_ERROR();
2202
2203 const float borderSize = 0.15f;
2204
2205 std::array<GLint, 4> viewport;
2206 glGetIntegerv(GL_VIEWPORT, viewport.data());
2207 glViewport(0, 0, 2048, 2048);
2208 glBindFramebuffer(GL_FRAMEBUFFER, mnFramebuffer);
2209 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2210 glUniform1f(mnShadowLocation, 1.0);
2211 glUniform1f(maSelectedTextureLocation, 1.0);
2212 glUniform1f(maHexagonSizeLocation, 1.0f - borderSize);
2213 displaySlide(nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale);
2214 glUniform1f(maHexagonSizeLocation, 1.0f + borderSize);
2215 displaySlide(nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale);
2216
2217 // The back (entering) slide needs to be drawn before the front (leaving) one in order for blending to work.
2218 glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
2219 pContext->restoreDefaultFramebuffer();
2220 glUniform1f(mnShadowLocation, 0.0);
2221 glUniform1f(maSelectedTextureLocation, 0.0);
2222 glUniform1f(maHexagonSizeLocation, 1.0f - borderSize);
2223 displaySlide(nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale);
2224 glUniform1f(maHexagonSizeLocation, 1.0f + borderSize);
2225 displaySlide(nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale);
2226 glUniform1f(maSelectedTextureLocation, 1.0);
2227 glUniform1f(maHexagonSizeLocation, 1.0f - borderSize);
2228 displaySlide(nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale);
2229 glUniform1f(maHexagonSizeLocation, 1.0f + borderSize);
2230 displaySlide(nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale);
2231 CHECK_GL_ERROR();
2232 }
2233
2234 std::shared_ptr<OGLTransitionImpl>
makeHoneycombTransition(const Primitives_t & rLeavingSlidePrimitives,const Primitives_t & rEnteringSlidePrimitives,const TransitionSettings & rSettings)2235 makeHoneycombTransition(const Primitives_t& rLeavingSlidePrimitives,
2236 const Primitives_t& rEnteringSlidePrimitives,
2237 const TransitionSettings& rSettings)
2238 {
2239 // The center point should be adjustable by the user, but we have no way to do that in the UI
2240 return std::make_shared<HoneycombTransition>(TransitionScene(rLeavingSlidePrimitives, rEnteringSlidePrimitives),
2241 rSettings);
2242 }
2243
2244 }
2245
makeHoneycomb()2246 std::shared_ptr<OGLTransitionImpl> makeHoneycomb()
2247 {
2248 const int NX = 21;
2249 const int NY = 21;
2250
2251 TransitionSettings aSettings;
2252 aSettings.mnRequiredGLVersion = 3.2f;
2253
2254 Primitives_t aSlide;
2255 Primitive aHexagon;
2256 for (int y = 0; y < NY+2; y+=2)
2257 for (int x = 0; x < NX+2; x+=2)
2258 aHexagon.pushTriangle(glm::vec2((y % 4) ? fdiv(x, NX) : fdiv(x + 1, NX), fdiv(y, NY)), glm::vec2(1, 0), glm::vec2(0, 0));
2259 aSlide.push_back(aHexagon);
2260
2261 return makeHoneycombTransition(aSlide, aSlide, aSettings);
2262 }
2263
makeNewsflash()2264 std::shared_ptr<OGLTransitionImpl> makeNewsflash()
2265 {
2266 Primitive Slide;
2267
2268 Slide.pushTriangle(glm::vec2(0,0),glm::vec2(1,0),glm::vec2(0,1));
2269 Slide.pushTriangle(glm::vec2(1,0),glm::vec2(0,1),glm::vec2(1,1));
2270 Slide.Operations.push_back(makeSRotate(glm::vec3(0,0,1),glm::vec3(0,0,0),3000,true,0,0.5));
2271 Slide.Operations.push_back(makeSScale(glm::vec3(0.01,0.01,0.01),glm::vec3(0,0,0),true,0,0.5));
2272 Slide.Operations.push_back(makeSTranslate(glm::vec3(-10000, 0, 0),false, 0.5, 2));
2273 Primitives_t aLeavingSlide;
2274 aLeavingSlide.push_back(Slide);
2275
2276 Slide.Operations.clear();
2277 Slide.Operations.push_back(makeSRotate(glm::vec3(0,0,1),glm::vec3(0,0,0),-3000,true,0.5,1));
2278 Slide.Operations.push_back(makeSTranslate(glm::vec3(-100, 0, 0),false, -1, 1));
2279 Slide.Operations.push_back(makeSTranslate(glm::vec3(100, 0, 0),false, 0.5, 1));
2280 Slide.Operations.push_back(makeSScale(glm::vec3(0.01,0.01,0.01),glm::vec3(0,0,0),false,-1,1));
2281 Slide.Operations.push_back(makeSScale(glm::vec3(100,100,100),glm::vec3(0,0,0),true,0.5,1));
2282 Primitives_t aEnteringSlide;
2283 aEnteringSlide.push_back(Slide);
2284
2285 Operations_t aOverallOperations;
2286 aOverallOperations.push_back(makeSRotate(glm::vec3(0,0,1),glm::vec3(0.2,0.2,0),1080,true,0,1));
2287
2288 return makeSimpleTransition(aLeavingSlide, aEnteringSlide, aOverallOperations);
2289 }
2290
2291 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2292