1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include "OGLTrans_TransitionImpl.hxx" 25 #include "OGLTrans_Shaders.hxx" 26 #include <GL/gl.h> 27 #include <math.h> 28 29 30 void OGLTransitionImpl::clear() 31 { 32 for(unsigned int i( 0 ); i < OverallOperations.size(); ++i) 33 delete OverallOperations[i]; 34 OverallOperations.clear(); 35 maLeavingSlidePrimitives.clear(); 36 maEnteringSlidePrimitives.clear(); 37 for(unsigned int i(0); i < maSceneObjects.size(); ++i) 38 delete maSceneObjects[i]; 39 maSceneObjects.clear(); 40 41 mbReflectSlides = false; 42 43 #ifdef GL_VERSION_2_0 44 if( mProgramObject ) { 45 OGLShaders::glDeleteProgram( mProgramObject ); 46 mProgramObject = 0; 47 } 48 49 if( mVertexObject ) { 50 OGLShaders::glDeleteShader( mVertexObject ); 51 mVertexObject = 0; 52 } 53 54 if( mFragmentObject ) { 55 OGLShaders::glDeleteShader( mFragmentObject ); 56 mFragmentObject = 0; 57 } 58 #endif 59 60 if( maHelperTexture ) { 61 glDeleteTextures( 1, &maHelperTexture ); 62 maHelperTexture = 0; 63 } 64 65 if( mmClearTransition ) 66 (this->*mmClearTransition)(); 67 } 68 69 OGLTransitionImpl::~OGLTransitionImpl() 70 { 71 clear(); 72 } 73 74 void OGLTransitionImpl::prepare( ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex ) 75 { 76 for(unsigned int i(0); i < maSceneObjects.size(); ++i) { 77 maSceneObjects[i]->prepare(); 78 } 79 80 if( mmPrepareTransition ) 81 (this->*mmPrepareTransition)( glLeavingSlideTex, glEnteringSlideTex ); 82 } 83 84 void OGLTransitionImpl::finish() 85 { 86 for(unsigned int i(0); i < maSceneObjects.size(); ++i) { 87 maSceneObjects[i]->finish(); 88 } 89 } 90 91 static void blendSlide( double depth ) 92 { 93 double showHeight = -1 + depth*2; 94 GLfloat reflectionColor[] = {0, 0, 0, 0.25}; 95 96 glDisable( GL_DEPTH_TEST ); 97 glBegin( GL_QUADS ); 98 glColor4fv( reflectionColor ); 99 glVertex3f( -1, -1, 0 ); 100 glColor4f( 0, 0, 0, 1 ); 101 glVertex3f(-1, showHeight, 0 ); 102 glVertex3f( 1, showHeight, 0 ); 103 glColor4fv( reflectionColor ); 104 glVertex3f( 1, -1, 0 ); 105 glEnd(); 106 107 glBegin( GL_QUADS ); 108 glColor4f( 0, 0, 0, 1 ); 109 glVertex3f( -1, showHeight, 0 ); 110 glVertex3f( -1, 1, 0 ); 111 glVertex3f( 1, 1, 0 ); 112 glVertex3f( 1, showHeight, 0 ); 113 glEnd(); 114 glEnable( GL_DEPTH_TEST ); 115 } 116 117 static void slideShadow( double nTime, Primitive& primitive, double sw, double sh ) 118 { 119 double reflectionDepth = 0.3; 120 121 glEnable(GL_BLEND); 122 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 123 glDisable(GL_LIGHTING); 124 125 glPushMatrix(); 126 primitive.applyOperations( nTime, sw, sh ); 127 blendSlide( reflectionDepth ); 128 glPopMatrix(); 129 130 glDisable(GL_BLEND); 131 glEnable(GL_LIGHTING); 132 } 133 134 void OGLTransitionImpl::display( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, 135 double SlideWidth, double SlideHeight, double DispWidth, double DispHeight ) 136 { 137 double SlideWidthScale, SlideHeightScale; 138 139 SlideWidthScale = SlideWidth/DispWidth; 140 SlideHeightScale = SlideHeight/DispHeight; 141 142 if( mmPrepare ) { 143 clear(); 144 (this->*mmPrepare)( nTime, SlideWidth, SlideHeight, DispWidth, DispHeight ); 145 } 146 147 glPushMatrix(); 148 displaySlides( nTime, glLeavingSlideTex, glEnteringSlideTex, SlideWidthScale, SlideHeightScale ); 149 displayScene( nTime, SlideWidth, SlideHeight, DispWidth, DispHeight ); 150 glPopMatrix(); 151 } 152 153 void OGLTransitionImpl::applyOverallOperations( double nTime, double SlideWidthScale, double SlideHeightScale ) 154 { 155 for(unsigned int i(0); i < OverallOperations.size(); ++i) 156 OverallOperations[i]->interpolate(nTime,SlideWidthScale,SlideHeightScale); 157 } 158 159 void OGLTransitionImpl::displaySlide( double nTime, ::sal_Int32 glSlideTex, std::vector<Primitive>& primitives, 160 double SlideWidthScale, double SlideHeightScale ) 161 { 162 //TODO change to foreach 163 glBindTexture(GL_TEXTURE_2D, glSlideTex); 164 165 // display slide reflection 166 // note that depth test is turned off while blending the shadow 167 // so the slides has to be rendered in right order, see rochade as example 168 if( mbReflectSlides ) { 169 double surfaceLevel = -0.04; 170 171 /* reflected slides */ 172 glPushMatrix(); 173 174 glScaled( 1, -1, 1 ); 175 glTranslated( 0, 2 - surfaceLevel, 0 ); 176 177 glCullFace(GL_FRONT); 178 for(unsigned int i(0); i < primitives.size(); ++i) 179 primitives[i].display(nTime, SlideWidthScale, SlideHeightScale); 180 glCullFace(GL_BACK); 181 182 slideShadow( nTime, primitives[0], SlideWidthScale, SlideHeightScale ); 183 184 glPopMatrix(); 185 } 186 187 for(unsigned int i(0); i < primitives.size(); ++i) 188 primitives[i].display(nTime, SlideWidthScale, SlideHeightScale); 189 } 190 191 void OGLTransitionImpl::displaySlides( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, 192 double SlideWidthScale, double SlideHeightScale ) 193 { 194 if( mmDisplaySlides ) 195 (this->*mmDisplaySlides)( nTime, glLeavingSlideTex, glEnteringSlideTex, SlideWidthScale, SlideHeightScale ); 196 else { 197 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale ); 198 199 glEnable(GL_TEXTURE_2D); 200 displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale ); 201 displaySlide( nTime, glEnteringSlideTex, maEnteringSlidePrimitives, SlideWidthScale, SlideHeightScale ); 202 } 203 } 204 205 void OGLTransitionImpl::displayScene( double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight ) 206 { 207 glEnable(GL_TEXTURE_2D); 208 for(unsigned int i(0); i < maSceneObjects.size(); ++i) 209 maSceneObjects[i]->display(nTime, SlideWidth, SlideHeight, DispWidth, DispHeight); 210 } 211 212 void Primitive::display(double nTime, double WidthScale, double HeightScale) 213 { 214 glPushMatrix(); 215 216 applyOperations( nTime, WidthScale, HeightScale ); 217 218 glEnableClientState( GL_VERTEX_ARRAY ); 219 if(!Normals.empty()) 220 { 221 glNormalPointer( GL_DOUBLE , 0 , &Normals[0] ); 222 glEnableClientState( GL_NORMAL_ARRAY ); 223 } 224 glEnableClientState( GL_TEXTURE_COORD_ARRAY ); 225 glTexCoordPointer( 2, GL_DOUBLE, 0, &TexCoords[0] ); 226 glVertexPointer( 3, GL_DOUBLE, 0, &Vertices[0] ); 227 glDrawArrays( GL_TRIANGLES, 0, Vertices.size() ); 228 glPopMatrix(); 229 } 230 231 void Primitive::applyOperations(double nTime, double WidthScale, double HeightScale) 232 { 233 for(unsigned int i(0); i < Operations.size(); ++i) 234 Operations[i]->interpolate( nTime ,WidthScale,HeightScale); 235 glScaled(WidthScale,HeightScale,1); 236 } 237 238 Primitive::~Primitive() 239 { 240 for(unsigned int i( 0 ); i < Operations.size(); ++i) 241 delete Operations[i]; 242 } 243 244 245 void SceneObject::display(double nTime, double /* SlideWidth */, double /* SlideHeight */, double DispWidth, double DispHeight ) 246 { 247 for(unsigned int i(0); i < maPrimitives.size(); ++i) { 248 // fixme: allow various model spaces, now we make it so that 249 // it is regular -1,-1 to 1,1, where the whole display fits in 250 glPushMatrix(); 251 if (DispHeight > DispWidth) 252 glScaled(DispHeight/DispWidth, 1, 1); 253 else 254 glScaled(1, DispWidth/DispHeight, 1); 255 maPrimitives[i].display(nTime, 1, 1); 256 glPopMatrix(); 257 } 258 } 259 260 void SceneObject::pushPrimitive(const Primitive &p) 261 { 262 maPrimitives.push_back(p); 263 } 264 265 SceneObject::SceneObject() 266 : maPrimitives() 267 { 268 } 269 270 Iris::Iris() 271 : SceneObject () 272 { 273 } 274 275 void Iris::display(double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight ) 276 { 277 glBindTexture(GL_TEXTURE_2D, maTexture); 278 SceneObject::display(nTime, SlideWidth, SlideHeight, DispWidth, DispHeight); 279 } 280 281 void Iris::prepare() 282 { 283 static GLubyte img[3] = { 80, 80, 80 }; 284 285 glGenTextures(1, &maTexture); 286 glBindTexture(GL_TEXTURE_2D, maTexture); 287 glTexImage2D(GL_TEXTURE_2D, 0, 3, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, img); 288 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); 289 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); 290 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 291 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 292 } 293 294 void Iris::finish() 295 { 296 glDeleteTextures(1, &maTexture); 297 } 298 299 void OGLTransitionImpl::makeOutsideCubeFaceToLeft() 300 { 301 clear(); 302 Primitive Slide; 303 304 Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1)); 305 Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1)); 306 307 maLeavingSlidePrimitives.push_back(Slide); 308 309 Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,-1),90,false,0.0,1.0)); 310 311 maEnteringSlidePrimitives.push_back(Slide); 312 313 OverallOperations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,-1),-90,true,0.0,1.0)); 314 } 315 316 void OGLTransitionImpl::makeInsideCubeFaceToLeft() 317 { 318 clear(); 319 Primitive Slide; 320 321 Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1)); 322 Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1)); 323 324 maLeavingSlidePrimitives.push_back(Slide); 325 326 Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,1),-90,false,0.0,1.0)); 327 328 maEnteringSlidePrimitives.push_back(Slide); 329 330 OverallOperations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,1),90,true,0.0,1.0)); 331 } 332 333 void OGLTransitionImpl::makeFallLeaving() 334 { 335 clear(); 336 Primitive Slide; 337 338 Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1)); 339 Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1)); 340 maEnteringSlidePrimitives.push_back(Slide); 341 342 Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(1,0,0),basegfx::B3DVector(0,-1,0), 90,true,0.0,1.0)); 343 maLeavingSlidePrimitives.push_back(Slide); 344 345 mbUseMipMapEntering = false; 346 } 347 348 void OGLTransitionImpl::makeTurnAround() 349 { 350 clear(); 351 Primitive Slide; 352 353 mbReflectSlides = true; 354 355 Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1)); 356 Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1)); 357 maLeavingSlidePrimitives.push_back(Slide); 358 359 Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,0),-180,false,0.0,1.0)); 360 maEnteringSlidePrimitives.push_back(Slide); 361 362 OverallOperations.push_back(new STranslate(basegfx::B3DVector(0, 0, -1.5),true, 0, 0.5)); 363 OverallOperations.push_back(new STranslate(basegfx::B3DVector(0, 0, 1.5), true, 0.5, 1)); 364 OverallOperations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0, 1, 0),basegfx::B3DVector(0, 0, 0), -180, true, 0.0, 1.0)); 365 } 366 367 void OGLTransitionImpl::makeTurnDown() 368 { 369 clear(); 370 Primitive Slide; 371 372 Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1)); 373 Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1)); 374 maLeavingSlidePrimitives.push_back(Slide); 375 376 Slide.Operations.push_back(new STranslate(basegfx::B3DVector(0, 0, 0.0001), false, -1.0, 0.0)); 377 Slide.Operations.push_back(new SRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(-1, 1, 0), -90, true, 0.0, 1.0)); 378 Slide.Operations.push_back(new SRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(-1, 1, 0), 90, false, -1.0, 0.0)); 379 maEnteringSlidePrimitives.push_back(Slide); 380 381 mbUseMipMapLeaving = false; 382 } 383 384 void OGLTransitionImpl::makeIris() 385 { 386 clear(); 387 Primitive Slide; 388 389 Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1)); 390 Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1)); 391 maEnteringSlidePrimitives.push_back (Slide); 392 393 Slide.Operations.push_back (new STranslate (basegfx::B3DVector (0, 0, 0.000001), false, -1, 0)); 394 Slide.Operations.push_back (new STranslate (basegfx::B3DVector (0, 0, -0.000002), false, 0.5, 1)); 395 maLeavingSlidePrimitives.push_back (Slide); 396 397 398 Primitive irisPart, part; 399 int i, nSteps = 24, nParts = 7; 400 double lt = 0, t = 1.0/nSteps, cx, cy, lcx, lcy, lx = 1, ly = 0, x, y, cxo, cyo, lcxo, lcyo, of=2.2, f=1.42; 401 402 for (i=1; i<=nSteps; i++) { 403 x = cos ((3*2*M_PI*t)/nParts); 404 y = -sin ((3*2*M_PI*t)/nParts); 405 cx = (f*x + 1)/2; 406 cy = (f*y + 1)/2; 407 lcx = (f*lx + 1)/2; 408 lcy = (f*ly + 1)/2; 409 cxo = (of*x + 1)/2; 410 cyo = (of*y + 1)/2; 411 lcxo = (of*lx + 1)/2; 412 lcyo = (of*ly + 1)/2; 413 irisPart.pushTriangle (basegfx::B2DVector (lcx, lcy), 414 basegfx::B2DVector (lcxo, lcyo), 415 basegfx::B2DVector (cx, cy)); 416 irisPart.pushTriangle (basegfx::B2DVector (cx, cy), 417 basegfx::B2DVector (lcxo, lcyo), 418 basegfx::B2DVector (cxo, cyo)); 419 lx = x; 420 ly = y; 421 lt = t; 422 t += 1.0/nSteps; 423 } 424 425 Iris* pIris = new Iris(); 426 double angle = 87; 427 428 for (i = 0; i < nParts; i++) { 429 irisPart.Operations.clear (); 430 double rx, ry; 431 432 rx = cos ((2*M_PI*i)/nParts); 433 ry = sin ((2*M_PI*i)/nParts); 434 irisPart.Operations.push_back (new SRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(rx, ry, 0), angle, true, 0.0, 0.5)); 435 irisPart.Operations.push_back (new SRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(rx, ry, 0), -angle, true, 0.5, 1)); 436 if (i > 0) { 437 irisPart.Operations.push_back (new STranslate (basegfx::B3DVector(rx, ry, 0), false, -1, 0)); 438 irisPart.Operations.push_back (new SRotate (basegfx::B3DVector(0, 0, 1), basegfx::B3DVector(0, 0, 0), i*360.0/nParts, false, -1, 0)); 439 irisPart.Operations.push_back (new STranslate (basegfx::B3DVector(-1, 0, 0), false, -1, 0)); 440 } 441 irisPart.Operations.push_back(new STranslate(basegfx::B3DVector(0, 0, 1), false, -2, 0.0)); 442 irisPart.Operations.push_back (new SRotate (basegfx::B3DVector(1, .5, 0), basegfx::B3DVector(1, 0, 0), -30, false, -1, 0)); 443 pIris->pushPrimitive (irisPart); 444 } 445 446 maSceneObjects.push_back (pIris); 447 448 mbUseMipMapLeaving = mbUseMipMapEntering = false; 449 } 450 451 void OGLTransitionImpl::displaySlidesRochade( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, 452 double SlideWidthScale, double SlideHeightScale ) 453 { 454 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale ); 455 456 glEnable(GL_TEXTURE_2D); 457 458 if( nTime > .5) { 459 displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale ); 460 displaySlide( nTime, glEnteringSlideTex, maEnteringSlidePrimitives, SlideWidthScale, SlideHeightScale ); 461 } else { 462 displaySlide( nTime, glEnteringSlideTex, maEnteringSlidePrimitives, SlideWidthScale, SlideHeightScale ); 463 displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale ); 464 } 465 } 466 467 void OGLTransitionImpl::makeRochade() 468 { 469 clear(); 470 Primitive Slide; 471 472 mbReflectSlides = true; 473 mmDisplaySlides = &OGLTransitionImpl::displaySlidesRochade; 474 475 double w, h; 476 477 w = 2.2; 478 h = 10; 479 480 Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1)); 481 Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1)); 482 483 Slide.Operations.push_back(new SEllipseTranslate(w, h, 0.25, -0.25, true, 0, 1)); 484 Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,0), -45, true, 0, 1)); 485 maLeavingSlidePrimitives.push_back(Slide); 486 487 Slide.Operations.clear(); 488 Slide.Operations.push_back(new SEllipseTranslate(w, h, 0.75, 0.25, true, 0, 1)); 489 Slide.Operations.push_back(new STranslate(basegfx::B3DVector(0, 0, -h), false, -1, 0)); 490 Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,0), -45, true, 0, 1)); 491 Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0,1,0),basegfx::B3DVector(0,0,0), 45, false, -1, 0)); 492 maEnteringSlidePrimitives.push_back(Slide); 493 494 // OverallOperations.push_back(new SEllipseTranslate(0.5, 2, 0, 1, true, 0, 1)); 495 // push_back(new STranslate(basegfx::B3DVector(0, 0, -2), true, 0, 0.5)); 496 // OverallOperations.push_back(new STranslate(basegfx::B3DVector(0, 0, 2), true, 0.5, 1)); 497 } 498 499 // TODO(Q3): extract to basegfx 500 inline basegfx::B2DVector clamp(const basegfx::B2DVector& v) 501 { 502 return basegfx::B2DVector(min(max(v.getX(),-1.0),1.0), 503 min(max(v.getY(),-1.0),1.0)); 504 } 505 506 // TODO(Q3): extract to basegfx 507 inline basegfx::B3DVector clamp(const basegfx::B3DVector& v) 508 { 509 return basegfx::B3DVector(min(max(v.getX(),-1.0),1.0), 510 min(max(v.getY(),-1.0),1.0), 511 min(max(v.getZ(),-1.0),1.0)); 512 } 513 514 inline double randFromNeg1to1() 515 { 516 return ( ( static_cast<double>( rand() ) / static_cast<double>( RAND_MAX ) ) * 2.0 ) - 1.0; 517 } 518 519 // TODO(Q3): extract to basegfx 520 inline basegfx::B3DVector randNormVectorInXYPlane() 521 { 522 basegfx::B3DVector toReturn(randFromNeg1to1(),randFromNeg1to1(),0.0); 523 return toReturn/toReturn.getLength(); 524 } 525 526 void OGLTransitionImpl::makeRevolvingCircles( ::sal_uInt16 nCircles , ::sal_uInt16 nPointsOnCircles ) 527 { 528 clear(); 529 double dAngle(2*3.1415926/static_cast<double>( nPointsOnCircles )); 530 if(nCircles < 2 || nPointsOnCircles < 4) 531 { 532 makeNByMTileFlip(1,1); 533 return; 534 } 535 double Radius(1.0/static_cast<double>( nCircles )); 536 double dRadius(Radius); 537 double LastRadius(0.0); 538 double NextRadius(2*Radius); 539 540 /// now we know there is at least two circles 541 /// the first will always be a full circle 542 /// the last will always be the outer shell of the slide with a circle hole 543 544 //add the full circle 545 vector<basegfx::B2DVector> unScaledTexCoords; 546 double TempAngle(0.0); 547 for(unsigned int Point(0); Point < nPointsOnCircles; ++Point) 548 { 549 unScaledTexCoords.push_back( basegfx::B2DVector( cos(TempAngle - 3.1415926/2.0) , sin(TempAngle- 3.1415926/2.0) ) ); 550 551 TempAngle += dAngle; 552 } 553 554 { 555 //double angle(0.0); 556 Primitive EnteringSlide; 557 Primitive LeavingSlide; 558 for(int Point(0); Point + 1 < nPointsOnCircles; ++Point) 559 { 560 EnteringSlide.pushTriangle( basegfx::B2DVector( 0.5 , 0.5 ) , Radius * unScaledTexCoords[ Point + 1 ] / 2.0 + basegfx::B2DVector( 0.5 , 0.5 ) , Radius * unScaledTexCoords[ Point ] / 2.0 + basegfx::B2DVector( 0.5 , 0.5 ) ); 561 LeavingSlide.pushTriangle( basegfx::B2DVector( 0.5 , 0.5 ) , Radius * unScaledTexCoords[ Point + 1 ] / 2.0 + basegfx::B2DVector( 0.5 , 0.5 ) , Radius * unScaledTexCoords[ Point ] / 2.0 + basegfx::B2DVector( 0.5, 0.5) ); 562 } 563 EnteringSlide.pushTriangle( basegfx::B2DVector(0.5,0.5) , Radius * unScaledTexCoords[ 0 ] / 2.0 + basegfx::B2DVector( 0.5 , 0.5 ) , Radius * unScaledTexCoords[ nPointsOnCircles - 1 ] / 2.0 + basegfx::B2DVector( 0.5 , 0.5 ) ); 564 LeavingSlide.pushTriangle( basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); 565 566 basegfx::B3DVector axis(randNormVectorInXYPlane()); 567 EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) ); 568 LeavingSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) ); 569 EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , -180, false,0.0,1.0) ); 570 571 maEnteringSlidePrimitives.push_back(EnteringSlide); 572 maLeavingSlidePrimitives.push_back(LeavingSlide); 573 LastRadius = Radius; 574 Radius = NextRadius; 575 NextRadius += dRadius; 576 } 577 578 for(int i(1); i < nCircles - 1; ++i) 579 { 580 Primitive LeavingSlide; 581 Primitive EnteringSlide; 582 for(int Side(0); Side < nPointsOnCircles - 1; ++Side) 583 { 584 EnteringSlide.pushTriangle(Radius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); 585 EnteringSlide.pushTriangle(Radius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); 586 587 LeavingSlide.pushTriangle(Radius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); 588 LeavingSlide.pushTriangle(Radius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); 589 } 590 591 EnteringSlide.pushTriangle(Radius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); 592 EnteringSlide.pushTriangle(Radius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); 593 594 LeavingSlide.pushTriangle(Radius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); 595 LeavingSlide.pushTriangle(Radius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) , Radius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); 596 597 basegfx::B3DVector axis(randNormVectorInXYPlane()); 598 EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) ); 599 LeavingSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, Radius/2.0 , (NextRadius + 1)/2.0 ) ); 600 EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , -180, false,0.0,1.0) ); 601 602 maEnteringSlidePrimitives.push_back(EnteringSlide); 603 maLeavingSlidePrimitives.push_back(LeavingSlide); 604 605 LastRadius = Radius; 606 Radius = NextRadius; 607 NextRadius += dRadius; 608 } 609 { 610 Radius = sqrt(2.0); 611 Primitive LeavingSlide; 612 Primitive EnteringSlide; 613 for(int Side(0); Side < nPointsOnCircles - 1; ++Side) 614 { 615 616 EnteringSlide.pushTriangle(clamp(Radius*unScaledTexCoords[Side])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); 617 EnteringSlide.pushTriangle(clamp(Radius*unScaledTexCoords[Side])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) , clamp(Radius*unScaledTexCoords[Side + 1])/2.0 + basegfx::B2DVector(0.5,0.5) ); 618 619 LeavingSlide.pushTriangle(clamp(Radius*unScaledTexCoords[Side])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) ); 620 LeavingSlide.pushTriangle(clamp(Radius*unScaledTexCoords[Side])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[Side + 1]/2.0 + basegfx::B2DVector(0.5,0.5) , clamp(Radius*unScaledTexCoords[Side + 1])/2.0 + basegfx::B2DVector(0.5,0.5) ); 621 } 622 623 EnteringSlide.pushTriangle(clamp(Radius*unScaledTexCoords[nPointsOnCircles - 1])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); 624 EnteringSlide.pushTriangle(clamp(Radius*unScaledTexCoords[nPointsOnCircles - 1])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) , clamp(Radius*unScaledTexCoords[0])/2.0 + basegfx::B2DVector(0.5,0.5) ); 625 626 LeavingSlide.pushTriangle(clamp(Radius*unScaledTexCoords[nPointsOnCircles - 1])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[nPointsOnCircles - 1]/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) ); 627 LeavingSlide.pushTriangle(clamp(Radius*unScaledTexCoords[nPointsOnCircles - 1])/2.0 + basegfx::B2DVector(0.5,0.5) , LastRadius*unScaledTexCoords[0]/2.0 + basegfx::B2DVector(0.5,0.5) , clamp(Radius*unScaledTexCoords[0])/2.0 + basegfx::B2DVector(0.5,0.5) ); 628 629 basegfx::B3DVector axis(randNormVectorInXYPlane()); 630 EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, (LastRadius + dRadius)/2.0 , 1.0 ) ); 631 LeavingSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , 180, true, (LastRadius + dRadius)/2.0 , 1.0 ) ); 632 EnteringSlide.Operations.push_back( new SRotate( axis , basegfx::B3DVector(0,0,0) , -180, false,0.0,1.0) ); 633 634 maEnteringSlidePrimitives.push_back(EnteringSlide); 635 maLeavingSlidePrimitives.push_back(LeavingSlide); 636 } 637 } 638 639 void OGLTransitionImpl::makeHelix( ::sal_uInt16 nRows ) 640 { 641 clear(); 642 double invN(1.0/static_cast<double>(nRows)); 643 double iDn = 0.0; 644 double iPDn = invN; 645 for(unsigned int i(0); i < nRows; ++i) 646 { 647 Primitive Tile; 648 649 Tile.pushTriangle(basegfx::B2DVector( 1.0 , iDn ) , basegfx::B2DVector( 0.0 , iDn ) , basegfx::B2DVector( 0.0 , iPDn )); 650 651 Tile.pushTriangle(basegfx::B2DVector( 1.0 , iPDn ) , basegfx::B2DVector( 1.0 , iDn ) , basegfx::B2DVector( 0.0 , iPDn )); 652 653 Tile.Operations.push_back( new SRotate( basegfx::B3DVector( 0 , 1 , 0 ) , ( Tile.getVertices()[1] + Tile.getVertices()[3] )/2.0 , 180 , 654 true,min(max(static_cast<double>(i - nRows/2.0)*invN/2.0,0.0),1.0), 655 min(max(static_cast<double>(i + nRows/2.0)*invN/2.0,0.0),1.0) ) ); 656 657 maLeavingSlidePrimitives.push_back(Tile); 658 659 Tile.Operations.push_back( new SRotate( basegfx::B3DVector( 0 , 1 , 0 ) , ( Tile.getVertices()[1] + Tile.getVertices()[3] )/2.0 , -180 , false,0.0,1.0) ); 660 661 maEnteringSlidePrimitives.push_back(Tile); 662 663 iDn += invN; 664 iPDn += invN; 665 } 666 } 667 668 void OGLTransitionImpl::makeNByMTileFlip( ::sal_uInt16 n, ::sal_uInt16 m ) 669 { 670 clear(); 671 double invN(1.0/static_cast<double>(n)); 672 double invM(1.0/static_cast<double>(m)); 673 double iDn = 0.0; 674 double iPDn = invN; 675 for(unsigned int i(0); i < n; ++i) 676 { 677 double jDm = 0.0; 678 double jPDm = invM; 679 for(unsigned int j(0); j < m; ++j) 680 { 681 Primitive Tile; 682 683 Tile.pushTriangle(basegfx::B2DVector( iPDn , jDm ) , basegfx::B2DVector( iDn , jDm ) , basegfx::B2DVector( iDn , jPDm )); 684 685 Tile.pushTriangle(basegfx::B2DVector( iPDn , jPDm ) , basegfx::B2DVector( iPDn , jDm ) , basegfx::B2DVector( iDn , jPDm ));//bottom left corner of tile 686 687 Tile.Operations.push_back( new SRotate( basegfx::B3DVector( 1 , 1 , 0 ) , ( Tile.getVertices()[1] + Tile.getVertices()[3] )/2.0 , 180 , true, iDn*jDm/2.0 , ((iPDn*jPDm)+1.0)/2.0 ) ); 688 maLeavingSlidePrimitives.push_back(Tile); 689 Tile.Operations.push_back( new SRotate( basegfx::B3DVector( 1 , 1 , 0 ) , ( Tile.getVertices()[1] + Tile.getVertices()[3] )/2.0 , -180, false, iDn*jDm/2.0 , ((iPDn*jPDm)+1.0)/2.0 ) ); 690 691 maEnteringSlidePrimitives.push_back(Tile); 692 693 jDm += invM; 694 jPDm += invM; 695 } 696 iDn += invN; 697 iPDn += invN; 698 } 699 } 700 701 SRotate::SRotate(const basegfx::B3DVector& Axis,const basegfx::B3DVector& Origin,double Angle, bool bInter, double T0, double T1):axis(Axis),origin(Origin),angle(Angle) 702 { 703 nT0 = T0; 704 nT1 = T1; 705 bInterpolate = bInter; 706 } 707 708 SScale::SScale(const basegfx::B3DVector& Scale,const basegfx::B3DVector& Origin, bool bInter, double T0, double T1):scale(Scale),origin(Origin) 709 { 710 nT0 = T0; 711 nT1 = T1; 712 bInterpolate = bInter; 713 } 714 715 RotateAndScaleDepthByWidth::RotateAndScaleDepthByWidth(const basegfx::B3DVector& Axis,const basegfx::B3DVector& Origin,double Angle, bool bInter, double T0, double T1):axis(Axis),origin(Origin),angle(Angle) 716 { 717 nT0 = T0; 718 nT1 = T1; 719 bInterpolate = bInter; 720 } 721 722 RotateAndScaleDepthByHeight::RotateAndScaleDepthByHeight(const basegfx::B3DVector& Axis,const basegfx::B3DVector& Origin,double Angle, bool bInter, double T0, double T1):axis(Axis),origin(Origin),angle(Angle) 723 { 724 nT0 = T0; 725 nT1 = T1; 726 bInterpolate = bInter; 727 } 728 729 730 STranslate::STranslate(const basegfx::B3DVector& Vector, bool bInter, double T0, double T1):vector(Vector) 731 { 732 nT0 = T0; 733 nT1 = T1; 734 bInterpolate = bInter; 735 } 736 737 inline double intervalInter(double t, double T0, double T1) 738 { 739 return ( t - T0 ) / ( T1 - T0 ); 740 } 741 742 void STranslate::interpolate(double t,double SlideWidthScale,double SlideHeightScale) 743 { 744 if(t <= nT0) 745 return; 746 if(!bInterpolate || t > nT1) 747 t = nT1; 748 t = intervalInter(t,nT0,nT1); 749 glTranslated(SlideWidthScale*t*vector.getX(),SlideHeightScale*t*vector.getY(),t*vector.getZ()); 750 } 751 752 void SRotate::interpolate(double t,double SlideWidthScale,double SlideHeightScale) 753 { 754 if(t <= nT0) 755 return; 756 if(!bInterpolate || t > nT1) 757 t = nT1; 758 t = intervalInter(t,nT0,nT1); 759 glTranslated(SlideWidthScale*origin.getX(),SlideHeightScale*origin.getY(),origin.getZ()); 760 glScaled(SlideWidthScale,SlideHeightScale,1); 761 glRotated(t*angle,axis.getX(),axis.getY(),axis.getZ()); 762 glScaled(1/SlideWidthScale,1/SlideHeightScale,1); 763 glTranslated(-SlideWidthScale*origin.getX(),-SlideHeightScale*origin.getY(),-origin.getZ()); 764 } 765 766 void SScale::interpolate(double t,double SlideWidthScale,double SlideHeightScale) 767 { 768 if(t <= nT0) 769 return; 770 if(!bInterpolate || t > nT1) 771 t = nT1; 772 t = intervalInter(t,nT0,nT1); 773 glTranslated(SlideWidthScale*origin.getX(),SlideHeightScale*origin.getY(),origin.getZ()); 774 glScaled((1-t) + t*scale.getX(),(1-t) + t*scale.getY(),(1-t) + t*scale.getZ()); 775 glTranslated(-SlideWidthScale*origin.getX(),-SlideHeightScale*origin.getY(),-origin.getZ()); 776 } 777 778 void RotateAndScaleDepthByWidth::interpolate(double t,double SlideWidthScale,double SlideHeightScale) 779 { 780 if(t <= nT0) 781 return; 782 if(!bInterpolate || t > nT1) 783 t = nT1; 784 t = intervalInter(t,nT0,nT1); 785 glTranslated(SlideWidthScale*origin.getX(),SlideHeightScale*origin.getY(),SlideWidthScale*origin.getZ()); 786 glRotated(t*angle,axis.getX(),axis.getY(),axis.getZ()); 787 glTranslated(-SlideWidthScale*origin.getX(),-SlideHeightScale*origin.getY(),-SlideWidthScale*origin.getZ()); 788 } 789 790 void RotateAndScaleDepthByHeight::interpolate(double t,double SlideWidthScale,double SlideHeightScale) 791 { 792 if(t <= nT0) 793 return; 794 if(!bInterpolate || t > nT1) 795 t = nT1; 796 t = intervalInter(t,nT0,nT1); 797 glTranslated(SlideWidthScale*origin.getX(),SlideHeightScale*origin.getY(),SlideHeightScale*origin.getZ()); 798 glRotated(t*angle,axis.getX(),axis.getY(),axis.getZ()); 799 glTranslated(-SlideWidthScale*origin.getX(),-SlideHeightScale*origin.getY(),-SlideHeightScale*origin.getZ()); 800 } 801 802 SEllipseTranslate::SEllipseTranslate(double dWidth, double dHeight, double dStartPosition, double dEndPosition, bool bInter, double T0, double T1) 803 { 804 nT0 = T0; 805 nT1 = T1; 806 bInterpolate = bInter; 807 width = dWidth; 808 height = dHeight; 809 startPosition = dStartPosition; 810 endPosition = dEndPosition; 811 } 812 813 void SEllipseTranslate::interpolate(double t,double /* SlideWidthScale */,double /* SlideHeightScale */) 814 { 815 if(t <= nT0) 816 return; 817 if(!bInterpolate || t > nT1) 818 t = nT1; 819 t = intervalInter(t,nT0,nT1); 820 821 double a1, a2, x, y; 822 a1 = startPosition*2*M_PI; 823 a2 = (startPosition + t*(endPosition - startPosition))*2*M_PI; 824 x = width*(cos (a2) - cos (a1))/2; 825 y = height*(sin (a2) - sin (a1))/2; 826 827 glTranslated(x, 0, y); 828 } 829 830 STranslate* STranslate::clone() 831 { 832 return new STranslate(*this); 833 } 834 SRotate* SRotate::clone() 835 { 836 return new SRotate(*this); 837 } 838 839 SScale* SScale::clone() 840 { 841 return new SScale(*this); 842 } 843 844 SEllipseTranslate* SEllipseTranslate::clone() 845 { 846 return new SEllipseTranslate(*this); 847 } 848 849 RotateAndScaleDepthByWidth* RotateAndScaleDepthByWidth::clone() 850 { 851 return new RotateAndScaleDepthByWidth(*this); 852 } 853 854 RotateAndScaleDepthByHeight* RotateAndScaleDepthByHeight::clone() 855 { 856 return new RotateAndScaleDepthByHeight(*this); 857 } 858 859 const Primitive& Primitive::operator=(const Primitive& rvalue) 860 { 861 for(unsigned int i( 0 ); i < rvalue.Operations.size(); ++i) 862 Operations.push_back(rvalue.Operations[i]->clone()); 863 for(unsigned int i( 0 ); i < rvalue.Vertices.size(); ++i)//SPEED! use copy or something. this is slow. 864 Vertices.push_back(rvalue.Vertices[i]); 865 for(unsigned int i( 0 ); i < rvalue.TexCoords.size(); ++i)//SPEED! use copy or something. this is slow. 866 TexCoords.push_back(rvalue.TexCoords[i]); 867 for(unsigned int i( 0 ); i < rvalue.Normals.size(); ++i)//SPEED! use copy or something. this is slow. 868 Normals.push_back(rvalue.Normals[i]); 869 return *this; 870 } 871 872 Primitive::Primitive(const Primitive& rvalue) 873 { 874 for(unsigned int i( 0 ); i < rvalue.Operations.size(); ++i) 875 Operations.push_back(rvalue.Operations[i]->clone()); 876 for(unsigned int i( 0 ); i < rvalue.Vertices.size(); ++i)//SPEED! use copy or something. this is slow. 877 Vertices.push_back(rvalue.Vertices[i]); 878 for(unsigned int i( 0 ); i < rvalue.TexCoords.size(); ++i)//SPEED! use copy or something. this is slow. 879 TexCoords.push_back(rvalue.TexCoords[i]); 880 for(unsigned int i( 0 ); i < rvalue.Normals.size(); ++i)//SPEED! use copy or something. this is slow. 881 Normals.push_back(rvalue.Normals[i]); 882 } 883 884 void Primitive::pushTriangle(const basegfx::B2DVector& SlideLocation0,const basegfx::B2DVector& SlideLocation1,const basegfx::B2DVector& SlideLocation2) 885 { 886 vector<basegfx::B3DVector> Verts; 887 vector<basegfx::B2DVector> Texs; 888 Verts.reserve(3); 889 Texs.reserve(3); 890 891 Verts.push_back(basegfx::B3DVector( 2*SlideLocation0.getX() - 1, -2*SlideLocation0.getY() + 1 , 0.0 )); 892 Verts.push_back(basegfx::B3DVector( 2*SlideLocation1.getX() - 1, -2*SlideLocation1.getY() + 1 , 0.0 )); 893 Verts.push_back(basegfx::B3DVector( 2*SlideLocation2.getX() - 1, -2*SlideLocation2.getY() + 1 , 0.0 )); 894 895 //figure out if they're facing the correct way, and make them face the correct way. 896 basegfx::B3DVector Normal( basegfx::cross( Verts[0] - Verts[1] , Verts[1] - Verts[2] ) ); 897 if(Normal.getZ() >= 0.0)//if the normal is facing us 898 { 899 Texs.push_back(SlideLocation0); 900 Texs.push_back(SlideLocation1); 901 Texs.push_back(SlideLocation2); 902 } 903 else // if the normal is facing away from us, make it face us 904 { 905 Texs.push_back(SlideLocation0); 906 Texs.push_back(SlideLocation2); 907 Texs.push_back(SlideLocation1); 908 Verts.clear(); 909 Verts.push_back(basegfx::B3DVector( 2*SlideLocation0.getX() - 1, -2*SlideLocation0.getY() + 1 , 0.0 )); 910 Verts.push_back(basegfx::B3DVector( 2*SlideLocation2.getX() - 1, -2*SlideLocation2.getY() + 1 , 0.0 )); 911 Verts.push_back(basegfx::B3DVector( 2*SlideLocation1.getX() - 1, -2*SlideLocation1.getY() + 1 , 0.0 )); 912 } 913 914 Vertices.push_back(Verts[0]); 915 Vertices.push_back(Verts[1]); 916 Vertices.push_back(Verts[2]); 917 918 TexCoords.push_back(Texs[0]); 919 TexCoords.push_back(Texs[1]); 920 TexCoords.push_back(Texs[2]); 921 922 Normals.push_back(basegfx::B3DVector(0,0,1));//all normals always face the screen when untransformed. 923 Normals.push_back(basegfx::B3DVector(0,0,1));//all normals always face the screen when untransformed. 924 Normals.push_back(basegfx::B3DVector(0,0,1));//all normals always face the screen when untransformed. 925 } 926 927 void OGLTransitionImpl::makeDiamond() 928 { 929 mmPrepare = &OGLTransitionImpl::prepareDiamond; 930 mbUseMipMapLeaving = mbUseMipMapEntering = false; 931 } 932 933 void OGLTransitionImpl::prepareDiamond( double nTime, double /* SlideWidth */, double /* SlideHeight */, double /* DispWidth */, double /* DispHeight */ ) 934 { 935 Primitive Slide1, Slide2; 936 937 Slide1.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1)); 938 Slide1.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1)); 939 maEnteringSlidePrimitives.push_back (Slide1); 940 941 942 if( nTime >= 0.5 ) { 943 double m = 1 - nTime; 944 945 Slide2.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (m,0), basegfx::B2DVector (0,m)); 946 Slide2.pushTriangle (basegfx::B2DVector (nTime,0), basegfx::B2DVector (1,0), basegfx::B2DVector (1,m)); 947 Slide2.pushTriangle (basegfx::B2DVector (1,nTime), basegfx::B2DVector (1,1), basegfx::B2DVector (nTime,1)); 948 Slide2.pushTriangle (basegfx::B2DVector (0,nTime), basegfx::B2DVector (m,1), basegfx::B2DVector (0,1)); 949 } else { 950 double l = 0.5 - nTime; 951 double h = 0.5 + nTime; 952 953 Slide2.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0.5,l)); 954 Slide2.pushTriangle (basegfx::B2DVector (0.5,l), basegfx::B2DVector (1,0), basegfx::B2DVector (h,0.5)); 955 Slide2.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (1,1), basegfx::B2DVector (h,0.5)); 956 Slide2.pushTriangle (basegfx::B2DVector (h,0.5), basegfx::B2DVector (1,1), basegfx::B2DVector (0.5,h)); 957 Slide2.pushTriangle (basegfx::B2DVector (0.5,h), basegfx::B2DVector (1,1), basegfx::B2DVector (0,1)); 958 Slide2.pushTriangle (basegfx::B2DVector (l,0.5), basegfx::B2DVector (0.5,h), basegfx::B2DVector (0,1)); 959 Slide2.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (l,0.5), basegfx::B2DVector (0,1)); 960 Slide2.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (0.5,l), basegfx::B2DVector (l,0.5)); 961 } 962 Slide2.Operations.push_back (new STranslate (basegfx::B3DVector (0, 0, 0.00000001), false, -1, 0)); 963 maLeavingSlidePrimitives.push_back (Slide2); 964 } 965 966 void OGLTransitionImpl::makeVenetianBlinds( bool vertical, int parts ) 967 { 968 static double t30 = tan( M_PI/6.0 ); 969 double n, ln = 0; 970 double p = 1.0/parts; 971 972 for( int i=0; i<parts; i++ ) { 973 Primitive Slide; 974 n = (i + 1)/(double)parts; 975 if( vertical ) { 976 Slide.pushTriangle (basegfx::B2DVector (ln,0), basegfx::B2DVector (n,0), basegfx::B2DVector (ln,1)); 977 Slide.pushTriangle (basegfx::B2DVector (n,0), basegfx::B2DVector (ln,1), basegfx::B2DVector (n,1)); 978 Slide.Operations.push_back(new RotateAndScaleDepthByWidth(basegfx::B3DVector(0, 1, 0), basegfx::B3DVector(n + ln - 1, 0, -t30*p), -120, true, 0.0, 1.0)); 979 } else { 980 Slide.pushTriangle (basegfx::B2DVector (0,ln), basegfx::B2DVector (1,ln), basegfx::B2DVector (0,n)); 981 Slide.pushTriangle (basegfx::B2DVector (1,ln), basegfx::B2DVector (0,n), basegfx::B2DVector (1,n)); 982 Slide.Operations.push_back(new RotateAndScaleDepthByHeight(basegfx::B3DVector(1, 0, 0), basegfx::B3DVector(0, 1 - n - ln, -t30*p), -120, true, 0.0, 1.0)); 983 } 984 maLeavingSlidePrimitives.push_back (Slide); 985 986 if( vertical ) { 987 Slide.Operations.push_back(new SRotate(basegfx::B3DVector(0, 1, 0), basegfx::B3DVector(2*n - 1, 0, 0), -60, false, -1, 0)); 988 Slide.Operations.push_back(new SRotate(basegfx::B3DVector(0, 1, 0), basegfx::B3DVector(n + ln - 1, 0, 0), 180, false, -1, 0)); 989 } else { 990 Slide.Operations.push_back(new SRotate(basegfx::B3DVector(1, 0, 0), basegfx::B3DVector(0, 1 - 2*n, 0), -60, false, -1, 0)); 991 Slide.Operations.push_back(new SRotate(basegfx::B3DVector(1, 0, 0), basegfx::B3DVector(0, 1 - n - ln, 0), 180, false, -1, 0)); 992 } 993 maEnteringSlidePrimitives.push_back (Slide); 994 ln = n; 995 } 996 } 997 998 void OGLTransitionImpl::displaySlidesFadeSmoothly( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale ) 999 { 1000 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale ); 1001 1002 glDisable(GL_DEPTH_TEST); 1003 1004 displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale ); 1005 1006 glDisable(GL_LIGHTING); 1007 glEnable(GL_BLEND); 1008 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1009 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 1010 glColor4f( 1, 1, 1, nTime ); 1011 displaySlide( nTime, glEnteringSlideTex, maEnteringSlidePrimitives, SlideWidthScale, SlideHeightScale ); 1012 glDisable(GL_BLEND); 1013 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1014 glEnable(GL_LIGHTING); 1015 1016 glEnable(GL_DEPTH_TEST); 1017 } 1018 1019 void OGLTransitionImpl::makeFadeSmoothly() 1020 { 1021 Primitive Slide; 1022 1023 Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1)); 1024 Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1)); 1025 maLeavingSlidePrimitives.push_back (Slide); 1026 maEnteringSlidePrimitives.push_back (Slide); 1027 1028 mmDisplaySlides = &OGLTransitionImpl::displaySlidesFadeSmoothly; 1029 mbUseMipMapLeaving = mbUseMipMapEntering = false; 1030 } 1031 1032 void OGLTransitionImpl::displaySlidesFadeThroughBlack( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale ) 1033 { 1034 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale ); 1035 1036 glDisable(GL_DEPTH_TEST); 1037 1038 glDisable(GL_LIGHTING); 1039 glEnable(GL_BLEND); 1040 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1041 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 1042 if( nTime < 0.5 ) { 1043 glColor4f( 1, 1, 1, 1 - nTime*2 ); 1044 displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale ); 1045 } else { 1046 glColor4f( 1, 1, 1, (nTime - 0.5)*2 ); 1047 displaySlide( nTime, glEnteringSlideTex, maEnteringSlidePrimitives, SlideWidthScale, SlideHeightScale ); 1048 } 1049 glDisable(GL_BLEND); 1050 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1051 glEnable(GL_LIGHTING); 1052 1053 glEnable(GL_DEPTH_TEST); 1054 } 1055 1056 void OGLTransitionImpl::makeFadeThroughBlack() 1057 { 1058 Primitive Slide; 1059 1060 Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1)); 1061 Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1)); 1062 maLeavingSlidePrimitives.push_back (Slide); 1063 maEnteringSlidePrimitives.push_back (Slide); 1064 1065 mmDisplaySlides = &OGLTransitionImpl::displaySlidesFadeThroughBlack; 1066 mbUseMipMapLeaving = mbUseMipMapEntering = false; 1067 } 1068 1069 static const char* basicVertexShader = "\n\ 1070 varying vec2 v_texturePosition;\n\ 1071 \n\ 1072 void main( void )\n\ 1073 {\n\ 1074 gl_Position = ftransform();\n\ 1075 v_texturePosition = gl_MultiTexCoord0.xy;\n\ 1076 }\n\ 1077 "; 1078 1079 static const char* staticFragmentShader = "\n\ 1080 uniform sampler2D leavingSlideTexture;\n\ 1081 uniform sampler2D enteringSlideTexture;\n\ 1082 uniform sampler2D permTexture;\n\ 1083 uniform float time;\n\ 1084 varying vec2 v_texturePosition;\n\ 1085 \n\ 1086 float snoise(vec2 P) {\n\ 1087 \n\ 1088 return texture2D(permTexture, P).r;\n\ 1089 }\n\ 1090 \n\ 1091 \n\ 1092 #define PART 0.5\n\ 1093 #define START 0.4\n\ 1094 #define END 0.9\n\ 1095 \n\ 1096 void main() {\n\ 1097 float sn = snoise(10.0*v_texturePosition+time*0.07);\n\ 1098 if( time < PART ) {\n\ 1099 float sn1 = snoise(vec2(time*15.0, 20.0*v_texturePosition.y));\n\ 1100 float sn2 = snoise(v_texturePosition);\n\ 1101 if (sn1 > 1.0 - time*time && sn2 < 2.0*time+0.1)\n\ 1102 gl_FragColor = vec4(sn, sn, sn, 1.0);\n\ 1103 else if (time > START )\n\ 1104 gl_FragColor = ((time-START)/(PART - START))*vec4(sn, sn, sn, 1.0) + (1.0 - (time - START)/(PART - START))*texture2D(leavingSlideTexture, v_texturePosition);\n\ 1105 else\n\ 1106 gl_FragColor = texture2D(leavingSlideTexture, v_texturePosition);\n\ 1107 } else if ( time < PART ) {\n\ 1108 gl_FragColor = texture2D(leavingSlideTexture, v_texturePosition);\n\ 1109 } else if ( time > END ) {\n\ 1110 gl_FragColor = ((1.0 - time)/(1.0 - END))*vec4(sn, sn, sn, 1.0) + ((time - END)/(1.0 - END))*texture2D(enteringSlideTexture, v_texturePosition);\n\ 1111 } else \n\ 1112 gl_FragColor = vec4(sn, sn, sn, 1.0);\n\ 1113 }\n\ 1114 "; 1115 1116 static const char* dissolveFragmentShader = "\n\ 1117 uniform sampler2D leavingSlideTexture;\n\ 1118 uniform sampler2D enteringSlideTexture;\n\ 1119 uniform sampler2D permTexture;\n\ 1120 uniform float time;\n\ 1121 varying vec2 v_texturePosition;\n\ 1122 \n\ 1123 float snoise(vec2 P) {\n\ 1124 \n\ 1125 return texture2D(permTexture, P).r;\n\ 1126 }\n\ 1127 \n\ 1128 void main() {\n\ 1129 float sn = snoise(10.0*v_texturePosition);\n\ 1130 if( sn < time)\n\ 1131 gl_FragColor = texture2D(enteringSlideTexture, v_texturePosition);\n\ 1132 else\n\ 1133 gl_FragColor = texture2D(leavingSlideTexture, v_texturePosition);\n\ 1134 }\n\ 1135 "; 1136 1137 int permutation256 [256]= { 1138 215, 100, 200, 204, 233, 50, 85, 196, 1139 71, 141, 122, 160, 93, 131, 243, 234, 1140 162, 183, 36, 155, 4, 62, 35, 205, 1141 40, 102, 33, 27, 255, 55, 214, 156, 1142 75, 163, 134, 126, 249, 74, 197, 228, 1143 72, 90, 206, 235, 17, 22, 49, 169, 1144 227, 89, 16, 5, 117, 60, 248, 230, 1145 217, 68, 138, 96, 194, 170, 136, 10, 1146 112, 238, 184, 189, 176, 42, 225, 212, 1147 84, 58, 175, 244, 150, 168, 219, 236, 1148 101, 208, 123, 37, 164, 110, 158, 201, 1149 78, 114, 57, 48, 70, 142, 106, 43, 1150 232, 26, 32, 252, 239, 98, 191, 94, 1151 59, 149, 39, 187, 203, 190, 19, 13, 1152 133, 45, 61, 247, 23, 34, 20, 52, 1153 118, 209, 146, 193, 222, 18, 1, 152, 1154 46, 41, 91, 148, 115, 25, 135, 77, 1155 254, 147, 224, 161, 9, 213, 223, 250, 1156 231, 251, 127, 166, 63, 179, 81, 130, 1157 139, 28, 120, 151, 241, 86, 111, 0, 1158 88, 153, 172, 182, 159, 105, 178, 47, 1159 51, 167, 65, 66, 92, 73, 198, 211, 1160 245, 195, 31, 220, 140, 76, 221, 186, 1161 154, 185, 56, 83, 38, 165, 109, 67, 1162 124, 226, 132, 53, 229, 29, 12, 181, 1163 121, 24, 207, 199, 177, 113, 30, 80, 1164 3, 97, 188, 79, 216, 173, 8, 145, 1165 87, 128, 180, 237, 240, 137, 125, 104, 1166 15, 242, 119, 246, 103, 143, 95, 144, 1167 2, 44, 69, 157, 192, 174, 14, 54, 1168 218, 82, 64, 210, 11, 6, 129, 21, 1169 116, 171, 99, 202, 7, 107, 253, 108 1170 }; 1171 1172 void initPermTexture(GLuint *texID) 1173 { 1174 glGenTextures(1, texID); 1175 glBindTexture(GL_TEXTURE_2D, *texID); 1176 1177 static bool initialized = false; 1178 static unsigned char permutation2D[256*256*4]; 1179 if( !initialized ) { 1180 int x, y; 1181 1182 for( y=0; y < 256; y++ ) 1183 for( x=0; x < 256; x++ ) 1184 permutation2D[x*4 + y*1024] = permutation256[(y + permutation256[x]) & 0xff]; 1185 1186 initialized = true; 1187 } 1188 1189 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, permutation2D ); 1190 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); 1191 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); 1192 } 1193 1194 void OGLTransitionImpl::preparePermShader() 1195 { 1196 #ifdef GL_VERSION_2_0 1197 if( mProgramObject ) { 1198 OGLShaders::glUseProgram( mProgramObject ); 1199 1200 GLint location = OGLShaders::glGetUniformLocation( mProgramObject, "leavingSlideTexture" ); 1201 if( location != -1 ) { 1202 OGLShaders::glUniform1i( location, 0 ); // texture unit 0 1203 } 1204 1205 glActiveTexture(GL_TEXTURE1); 1206 if( !maHelperTexture ) 1207 initPermTexture( &maHelperTexture ); 1208 glActiveTexture(GL_TEXTURE0); 1209 1210 location = OGLShaders::glGetUniformLocation( mProgramObject, "permTexture" ); 1211 if( location != -1 ) { 1212 OGLShaders::glUniform1i( location, 1 ); // texture unit 1 1213 } 1214 1215 location = OGLShaders::glGetUniformLocation( mProgramObject, "enteringSlideTexture" ); 1216 if( location != -1 ) { 1217 OGLShaders::glUniform1i( location, 2 ); // texture unit 2 1218 } 1219 } 1220 #endif 1221 } 1222 1223 void OGLTransitionImpl::prepareStatic( ::sal_Int32 /* glLeavingSlideTex */, ::sal_Int32 /* glEnteringSlideTex */ ) 1224 { 1225 mProgramObject = OGLShaders::LinkProgram( basicVertexShader, staticFragmentShader ); 1226 1227 preparePermShader(); 1228 } 1229 1230 void OGLTransitionImpl::displaySlidesShaders( double nTime, ::sal_Int32 glLeavingSlideTex, ::sal_Int32 glEnteringSlideTex, 1231 double SlideWidthScale, double SlideHeightScale ) 1232 { 1233 applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale ); 1234 1235 #ifdef GL_VERSION_2_0 1236 if( mProgramObject ) { 1237 GLint location = OGLShaders::glGetUniformLocation( mProgramObject, "time" ); 1238 if( location != -1 ) { 1239 OGLShaders::glUniform1f( location, nTime ); 1240 } 1241 } 1242 1243 glActiveTexture( GL_TEXTURE2 ); 1244 glBindTexture( GL_TEXTURE_2D, glEnteringSlideTex ); 1245 glActiveTexture( GL_TEXTURE0 ); 1246 #endif 1247 1248 displaySlide( nTime, glLeavingSlideTex, maLeavingSlidePrimitives, SlideWidthScale, SlideHeightScale ); 1249 } 1250 1251 void OGLTransitionImpl::makeStatic() 1252 { 1253 Primitive Slide; 1254 1255 Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1)); 1256 Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1)); 1257 maLeavingSlidePrimitives.push_back (Slide); 1258 maEnteringSlidePrimitives.push_back (Slide); 1259 1260 mmDisplaySlides = &OGLTransitionImpl::displaySlidesShaders; 1261 mmPrepareTransition = &OGLTransitionImpl::prepareStatic; 1262 mbUseMipMapLeaving = mbUseMipMapEntering = false; 1263 1264 mnRequiredGLVersion = 2.0; 1265 } 1266 1267 void OGLTransitionImpl::prepareDissolve( ::sal_Int32 /* glLeavingSlideTex */, ::sal_Int32 /* glEnteringSlideTex */ ) 1268 { 1269 mProgramObject = OGLShaders::LinkProgram( basicVertexShader, dissolveFragmentShader ); 1270 1271 preparePermShader(); 1272 } 1273 1274 void OGLTransitionImpl::makeDissolve() 1275 { 1276 Primitive Slide; 1277 1278 Slide.pushTriangle (basegfx::B2DVector (0,0), basegfx::B2DVector (1,0), basegfx::B2DVector (0,1)); 1279 Slide.pushTriangle (basegfx::B2DVector (1,0), basegfx::B2DVector (0,1), basegfx::B2DVector (1,1)); 1280 maLeavingSlidePrimitives.push_back (Slide); 1281 maEnteringSlidePrimitives.push_back (Slide); 1282 1283 mmDisplaySlides = &OGLTransitionImpl::displaySlidesShaders; 1284 mmPrepareTransition = &OGLTransitionImpl::prepareDissolve; 1285 mbUseMipMapLeaving = mbUseMipMapEntering = false; 1286 1287 mnRequiredGLVersion = 2.0; 1288 } 1289 1290 void OGLTransitionImpl::makeNewsflash() 1291 { 1292 Primitive Slide; 1293 1294 Slide.pushTriangle(basegfx::B2DVector(0,0),basegfx::B2DVector(1,0),basegfx::B2DVector(0,1)); 1295 Slide.pushTriangle(basegfx::B2DVector(1,0),basegfx::B2DVector(0,1),basegfx::B2DVector(1,1)); 1296 Slide.Operations.push_back(new SRotate(basegfx::B3DVector(0,0,1),basegfx::B3DVector(0,0,0),3000,true,0,0.5)); 1297 Slide.Operations.push_back(new SScale(basegfx::B3DVector(0.01,0.01,0.01),basegfx::B3DVector(0,0,0),true,0,0.5)); 1298 Slide.Operations.push_back(new STranslate(basegfx::B3DVector(-10000, 0, 0),false, 0.5, 2)); 1299 maLeavingSlidePrimitives.push_back(Slide); 1300 1301 Slide.Operations.clear(); 1302 Slide.Operations.push_back(new SRotate(basegfx::B3DVector(0,0,1),basegfx::B3DVector(0,0,0),-3000,true,0.5,1)); 1303 Slide.Operations.push_back(new STranslate(basegfx::B3DVector(-100, 0, 0),false, -1, 1)); 1304 Slide.Operations.push_back(new STranslate(basegfx::B3DVector(100, 0, 0),false, 0.5, 1)); 1305 Slide.Operations.push_back(new SScale(basegfx::B3DVector(0.01,0.01,0.01),basegfx::B3DVector(0,0,0),false,-1,1)); 1306 Slide.Operations.push_back(new SScale(basegfx::B3DVector(100,100,100),basegfx::B3DVector(0,0,0),true,0.5,1)); 1307 maEnteringSlidePrimitives.push_back(Slide); 1308 1309 OverallOperations.push_back(new SRotate(basegfx::B3DVector(0,0,1),basegfx::B3DVector(0.2,0.2,0),1080,true,0,1)); 1310 } 1311 1312