fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / NodeCores / Groups / Light / Shadow / Engines / OSGSimpleShadowMapEngine.cpp
blob71f66493243d0b52d8155235bead82143e3512c9
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
18 * *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 #include <cstdlib>
40 #include <cstdio>
42 #include "OSGConfig.h"
44 #include "OSGSimpleShadowMapEngine.h"
46 #include "OSGMatrixCamera.h"
48 #include "OSGMatrixUtility.h"
49 #include "OSGRenderAction.h"
51 #include "OSGRenderPartition.h"
52 #include "OSGFrameBufferObject.h"
53 #include "OSGGroup.h"
54 #include "OSGChunkMaterial.h"
56 #include "OSGTextureBuffer.h"
57 #include "OSGTextureObjChunk.h"
58 #include "OSGPolygonChunk.h"
59 #include "OSGTexGenChunk.h"
60 #include "OSGBlendChunk.h"
61 #include "OSGImage.h"
63 OSG_USING_NAMESPACE
65 // Documentation for this class is emited in the
66 // OSGSimpleShadowMapEngineBase.cpp file.
67 // To modify it, please change the .fcd file (OSGSimpleShadowMapEngine.fcd) and
68 // regenerate the base file.
71 /*! \class OSG::SimpleShadowMapEngine
74 /*-------------------------------------------------------------------------*/
75 /* Sync */
77 void SimpleShadowMapEngine::changed(ConstFieldMaskArg whichField,
78 UInt32 origin,
79 BitVector details)
81 Inherited::changed(whichField, origin, details);
84 /*-------------------------------------------------------------------------*/
85 /* Dump */
87 void SimpleShadowMapEngine::dump( UInt32 uiIndent,
88 const BitVector bvFlags) const
90 Inherited::dump(uiIndent, bvFlags);
93 /*-------------------------------------------------------------------------*/
94 /* Constructors */
96 SimpleShadowMapEngine::SimpleShadowMapEngine(void) :
97 Inherited( )
101 SimpleShadowMapEngine::SimpleShadowMapEngine(
102 const SimpleShadowMapEngine &source) :
104 Inherited(source)
108 /*-------------------------------------------------------------------------*/
109 /* Destructor */
111 SimpleShadowMapEngine::~SimpleShadowMapEngine(void)
116 /*-------------------------------------------------------------------------*/
117 /* Init */
119 void SimpleShadowMapEngine::initMethod(InitPhase ePhase)
121 Inherited::initMethod(ePhase);
123 if(ePhase == TypeObject::SystemPost)
128 void SimpleShadowMapEngine::lightRenderEnter(Light *pLight,
129 RenderAction *pAction)
131 if(pLight->getOn() == false)
132 return;
134 StateChunk *pChunk = pLight->getChunk();
136 UInt32 uiSlot = pChunk->getClassId();
138 Int32 iLightIndex = pAction->allocateLightIndex();
140 // LightChunk *pLightChunk = dynamic_cast<LightChunk *>(pChunk);
142 // Color4f tmpVal(0.0, 0.0, 0.0, 1.0);
144 // pLightChunk->setAmbient(tmpVal);
147 if(iLightIndex >= 0)
149 pAction->addOverride(uiSlot + iLightIndex, pChunk);
151 else
153 SWARNING << "maximum light source limit ("
154 << -iLightIndex
155 << ") is reached"
156 << " skipping light sources!"
157 << std::endl;
161 void SimpleShadowMapEngine::setupCamera(Light *pLight,
162 LightTypeE eType,
163 RenderAction *pAction,
164 EngineDataPtr pEngineData)
166 if(eType == Directional)
168 DirectionalLight *pDLight =
169 dynamic_cast<DirectionalLight *>(pLight);
171 MatrixCameraUnrecPtr pCam =
172 dynamic_cast<MatrixCamera *>(pEngineData->getCamera());
174 if(pCam == NULL)
176 pCam = MatrixCamera::createLocal();
178 pEngineData->setCamera(pCam);
182 Vec3f diff;
183 Pnt3f center;
184 Matrix transMatrix;
185 Node *pNode = pAction->getActNode();
187 // tmpDir = DirectionalLightPtr::dcast(_lights[i]);
189 diff = (pNode->getVolume().getMax() -
190 pNode->getVolume().getMin());
192 Real32 sceneWidth = diff.length() * 0.5f;
193 // Not final values. May get tweaked in the future
195 Real32 sceneHeight = diff.length() * 0.5f;
197 pNode->getVolume().getCenter(center);
199 Vec3f lightdir = pDLight->getDirection();
201 if(pLight->getBeacon() != NULL)
203 Matrix m = pLight->getBeacon()->getToWorld();
205 m.mult(lightdir, lightdir);
208 MatrixLookAt(transMatrix,
209 center + lightdir,
210 center,
211 Vec3f(0,1,0));
213 transMatrix.invert();
215 Matrix proMatrix;
217 proMatrix.setIdentity();
219 MatrixOrthogonal( proMatrix,
220 -sceneWidth, sceneWidth, -sceneHeight,
221 sceneHeight, -sceneWidth, sceneWidth);
224 pCam->setProjectionMatrix(proMatrix );
225 pCam->setModelviewMatrix (transMatrix);
227 else if(eType == Point)
229 PointLight *pPLight = dynamic_cast<PointLight *>(pLight);
231 MatrixCameraUnrecPtr pCam =
232 dynamic_cast<MatrixCamera *>(pEngineData->getCamera());
234 if(pCam == NULL)
236 pCam = MatrixCamera::createLocal();
238 pEngineData->setCamera(pCam);
241 Real32 angle;
242 Vec3f dist;
243 Pnt3f center;
244 Vec3f diff;
246 Matrix transMatrix;
248 Node *pNode = pAction->getActNode();
251 pNode->getVolume().getCenter(center);
253 Pnt3f lightpos = pPLight->getPosition();
255 if(pLight->getBeacon() != NULL)
257 Matrix m = pLight->getBeacon()->getToWorld();
259 m.mult(lightpos, lightpos);
263 MatrixLookAt(transMatrix,
264 lightpos,
265 center,
266 Vec3f(0,1,0));
268 transMatrix.invert();
271 diff = (pNode->getVolume().getMax() -
272 pNode->getVolume().getMin());
274 dist = lightpos - center;
276 angle = atan((diff.length() * 0.5) / dist.length());
278 Matrix proMatrix;
280 proMatrix.setIdentity();
282 MatrixPerspective( proMatrix,
283 2.f * angle,
285 pAction->getActivePartition()->getNear(),
286 pAction->getActivePartition()->getFar ());
289 pCam->setProjectionMatrix(proMatrix );
290 pCam->setModelviewMatrix (transMatrix);
294 void SimpleShadowMapEngine::setupLightChunk(Light *pLight,
295 LightTypeE eType,
296 RenderAction *pAction,
297 EngineDataPtr pEngineData)
299 if(eType == Directional)
301 DirectionalLight *pDLight =
302 dynamic_cast<DirectionalLight *>(pLight);
304 LightChunkUnrecPtr pChunk = pEngineData->getLightChunk();
306 if(pChunk == NULL)
308 pChunk = LightChunk::createLocal();
310 pEngineData->setLightChunk(pChunk);
313 Color4f tmpVal(0.0, 0.0, 0.0, 1.0);
315 pChunk->setSpecular(tmpVal);
317 tmpVal.setValuesRGBA(0.2f, 0.2f, 0.2f, 1.0f);
319 pChunk->setDiffuse (tmpVal);
321 tmpVal.setValuesRGBA(0.0, 0.0, 0.0, 1.0);
323 pChunk->setAmbient (tmpVal);
325 Vec4f dir(pDLight->getDirection());
327 dir[3] = 0;
329 pChunk->setPosition(dir);
331 pChunk->setBeacon(pLight->getBeacon());
333 else if(eType == Point)
335 PointLight *pPLight = dynamic_cast<PointLight *>(pLight);
337 LightChunkUnrecPtr pChunk = pEngineData->getLightChunk();
339 if(pChunk == NULL)
341 pChunk = LightChunk::createLocal();
343 pEngineData->setLightChunk(pChunk);
346 Color4f tmpVal(0.0, 0.0, 0.0, 1.0);
348 pChunk->setSpecular(tmpVal);
350 tmpVal.setValuesRGBA(this->getShadowColor()[0],
351 this->getShadowColor()[1],
352 this->getShadowColor()[2],
353 this->getShadowColor()[3]);
355 pChunk->setDiffuse (tmpVal);
357 tmpVal.setValuesRGBA(0.0, 0.0, 0.0, 1.0);
359 pChunk->setAmbient (tmpVal);
361 Vec4f pos(pPLight->getPosition());
363 pos[3] = 1;
365 pChunk->setPosition(pos);
367 pChunk->setBeacon(pLight->getBeacon());
372 void SimpleShadowMapEngine::doLightPass(Light *pLight,
373 RenderAction *pAction,
374 EngineDataPtr pEngineData)
376 this->pushPartition(pAction);
378 RenderPartition *pPart = pAction ->getActivePartition();
379 Viewarea *pArea = pAction ->getViewarea ();
380 Background *pBack = pAction ->getBackground ();
382 FrameBufferObject *pTarget = pEngineData->getRenderTarget();
384 if(pTarget == NULL)
386 FrameBufferObjectUnrecPtr pFBO = FrameBufferObject::createLocal();
388 pFBO->setWidth (this->getWidth ());
389 pFBO->setHeight(this->getHeight());
391 pEngineData->setRenderTarget(pFBO);
393 pTarget = pFBO;
396 TextureObjChunk *pTexChunk = pEngineData->getTexChunk();
399 TextureBufferUnrecPtr pTexBuffer = pEngineData->getTexBuffer();
401 if(pTexBuffer == NULL)
403 pTexBuffer = TextureBuffer::createLocal();
405 pEngineData->setTexBuffer (pTexBuffer);
407 pTexBuffer->setTexture (pTexChunk );
408 pTarget ->setDepthAttachment(pTexBuffer);
411 PolygonChunkUnrecPtr pPoly = pEngineData->getPolyChunk();
413 if(pPoly == NULL)
415 pPoly = PolygonChunk::createLocal();
417 pPoly->setOffsetBias (this->getOffsetBias ());
418 pPoly->setOffsetFactor(this->getOffsetFactor());
419 pPoly->setOffsetFill (true );
421 pEngineData->setPolyChunk(pPoly);
424 pPart->setRenderTarget(pTarget);
426 if(pArea != NULL)
428 Camera *pCam = pEngineData->getCamera();
430 pPart->setWindow (pAction->getWindow());
432 pPart->calcViewportDimension(0.f, 0.f, 1.f, 1.f,
433 pTarget->getWidth (),
434 pTarget->getHeight ());
436 Matrix m, t;
438 // set the projection
439 pCam->getProjection (m,
440 pPart->getViewportWidth (),
441 pPart->getViewportHeight());
443 pCam->getProjectionTranslation(t,
444 pPart->getViewportWidth (),
445 pPart->getViewportHeight());
448 pPart->setupProjection(m, t);
450 pCam->getViewing(m,
451 pPart->getViewportWidth (),
452 pPart->getViewportHeight());
455 pPart->setupViewing(m);
457 pPart->setNear (pCam->getNear());
458 pPart->setFar (pCam->getFar ());
460 pPart->calcFrustum ();
462 pPart->setBackground(pBack);
465 Node *pActNode = pAction->getActNode();
467 pAction->overrideMaterial(_pLightPassMat, pActNode);
469 pAction->pushState();
471 UInt32 uiPolySlot = pPoly->getClassId();
473 pAction->addOverride (uiPolySlot, pPoly);
475 // lightRenderEnter(pLight, pAction);
477 pAction->useNodeList(false);
479 this->recurseFrom(pAction, pLight);
481 pAction->popState();
483 pAction->overrideMaterial(NULL, pActNode);
485 this->popPartition(pAction);
488 void SimpleShadowMapEngine::doAmbientPass(Light *pLight,
489 RenderAction *pAction,
490 EngineDataPtr pEngineData)
492 this->pushPartition(pAction,
493 (RenderPartition::CopyViewing |
494 RenderPartition::CopyProjection |
495 RenderPartition::CopyWindow |
496 RenderPartition::CopyViewportSize |
497 RenderPartition::CopyFrustum |
498 RenderPartition::CopyNearFar ));
500 LightChunk *pChunk = pEngineData->getLightChunk();
502 UInt32 uiSlot = pChunk->getClassId();
504 Int32 iLightIndex = pAction->allocateLightIndex();
506 pAction->pushState();
508 if(iLightIndex >= 0)
510 pAction->addOverride(uiSlot + iLightIndex, pChunk);
512 else
514 SWARNING << "maximum light source limit ("
515 << -iLightIndex
516 << ") is reached"
517 << " skipping light sources!"
518 << std::endl;
521 pAction->useNodeList(false);
523 this->recurseFrom(pAction, pLight);
525 pAction->popState();
527 this->popPartition(pAction);
530 void SimpleShadowMapEngine::doFinalPass(Light *pLight,
531 RenderAction *pAction,
532 EngineDataPtr pEngineData)
534 this->pushPartition(pAction,
535 (RenderPartition::CopyViewing |
536 RenderPartition::CopyProjection |
537 RenderPartition::CopyWindow |
538 RenderPartition::CopyViewportSize |
539 RenderPartition::CopyFrustum |
540 RenderPartition::CopyNearFar ));
542 FrameBufferObject *pTarget = pEngineData->getRenderTarget();
544 if(pTarget == NULL)
546 FrameBufferObjectUnrecPtr pFBO = FrameBufferObject::createLocal();
548 pFBO->setWidth (this->getWidth ());
549 pFBO->setHeight(this->getHeight());
551 pEngineData->setRenderTarget(pFBO);
553 pTarget = pFBO;
556 BlendChunkUnrecPtr pBlender = pEngineData->getBlendChunk();
558 if(pBlender == NULL)
560 pBlender = BlendChunk::createLocal();
562 pBlender->setSrcFactor(GL_ONE);
563 pBlender->setDestFactor(GL_ONE);
564 pBlender->setAlphaFunc(GL_GEQUAL);
565 pBlender->setAlphaValue(0.99f);
567 pEngineData->setBlendChunk(pBlender);
571 Matrix4f projectionMatrix, viewMatrix, biasMatrix;
573 biasMatrix.setIdentity();
574 biasMatrix.setScale(0.5);
575 biasMatrix.setTranslate(0.5,0.5,0.5);
577 MatrixCamera *pCam = dynamic_cast<MatrixCamera *>(
578 pEngineData->getCamera());
580 pCam->getProjection(projectionMatrix,
581 this->getWidth (),
582 this->getHeight());
584 pCam->getViewing (viewMatrix,
585 this->getWidth (),
586 this->getHeight());
588 Matrix textureMatrix = biasMatrix;
589 textureMatrix.mult(projectionMatrix);
590 textureMatrix.mult(viewMatrix);
592 textureMatrix.transpose();
593 Vec4f ps = textureMatrix[0];
594 Vec4f pt = textureMatrix[1];
595 Vec4f pr = textureMatrix[2];
596 Vec4f pq = textureMatrix[3];
598 TexGenChunkUnrecPtr pTexGen = pEngineData->getTexGenChunk();
600 if(pTexGen == NULL)
602 pTexGen = TexGenChunk::createLocal();
604 pEngineData->setTexGenChunk(pTexGen);
606 pTexGen->setEyeModelViewMode(TexGenChunk::EyeModelViewCamera);
608 pTexGen->setGenFuncS(GL_EYE_LINEAR);
609 pTexGen->setGenFuncT(GL_EYE_LINEAR);
610 pTexGen->setGenFuncR(GL_EYE_LINEAR);
611 pTexGen->setGenFuncQ(GL_EYE_LINEAR);
614 pTexGen->setGenFuncSPlane(ps);
615 pTexGen->setGenFuncTPlane(pt);
616 pTexGen->setGenFuncRPlane(pr);
617 pTexGen->setGenFuncQPlane(pq);
619 TextureObjChunkUnrecPtr pTexChunk = pEngineData->getTexChunk();
621 if(pTexChunk == NULL)
623 pTexChunk = TextureObjChunk::createLocal();
625 pEngineData->setTexChunk(pTexChunk);
627 ImageUnrecPtr pImage = Image::createLocal();
629 // creates a image without allocating main memory.
631 pImage->set(Image::OSG_L_PF,
632 pTarget->getWidth (),
633 pTarget->getHeight(),
638 NULL,
639 Image::OSG_UINT8_IMAGEDATA,
640 false);
643 pTexChunk->setImage (pImage);
644 pTexChunk->setInternalFormat(GL_DEPTH_COMPONENT32);
645 pTexChunk->setExternalFormat(GL_DEPTH_COMPONENT);
646 pTexChunk->setMinFilter (GL_LINEAR);
647 pTexChunk->setMagFilter (GL_LINEAR);
648 pTexChunk->setWrapS (GL_CLAMP_TO_BORDER);
649 pTexChunk->setWrapT (GL_CLAMP_TO_BORDER);
650 // pTexChunk->setEnvMode (GL_MODULATE);
651 pTexChunk->setTarget (GL_TEXTURE_2D);
653 pTexChunk->setCompareMode(GL_COMPARE_R_TO_TEXTURE);
654 pTexChunk->setCompareFunc(GL_LEQUAL);
655 pTexChunk->setDepthMode (GL_INTENSITY);
658 pAction->pushState();
660 UInt32 uiBlendSlot = pBlender ->getClassId();
661 UInt32 uiTexSlot = pTexChunk->getClassId();
662 UInt32 uiTexGenSlot = pTexGen ->getClassId();
664 if(this->getForceTextureUnit() != -1)
666 uiTexSlot += this->getForceTextureUnit();
667 uiTexGenSlot += this->getForceTextureUnit();
669 else
671 uiTexSlot += 3;
672 uiTexGenSlot += 3;
675 pAction->addOverride(uiBlendSlot, pBlender );
676 pAction->addOverride(uiTexSlot, pTexChunk);
677 pAction->addOverride(uiTexGenSlot, pTexGen );
679 lightRenderEnter(pLight, pAction);
681 pAction->useNodeList(false);
683 this->recurseFrom(pAction, pLight);
685 pAction->popState();
687 this->popPartition(pAction);
691 Action::ResultE SimpleShadowMapEngine::runOnEnter(
692 Light *pLight,
693 LightTypeE eType,
694 RenderAction *pAction)
696 EngineDataUnrecPtr pEngineData =
697 pAction->getData<SimpleShadowMapEngineData *>(_iDataSlotId);
699 if(pEngineData == NULL)
701 pEngineData = EngineData::createLocal();
703 this->setData(pEngineData, _iDataSlotId, pAction);
706 BitVector bvMask = pAction->getPassMask() & (bvLightPassMask |
707 bvAmbientPassMask |
708 bvDiffusePassMask );
711 fprintf(stderr, "%p %llu %llu | %llu %llu %llu\n",
712 this,
713 bvMask,
714 (bvLightPassMask |
715 bvAmbientPassMask |
716 bvDiffusePassMask ),
717 bvLightPassMask,
718 bvAmbientPassMask,
719 bvDiffusePassMask);
722 if(0x0000 != bvMask)
724 if(0x0000 != (bvMask & bvDiffusePassMask))
726 this->recurseFrom(pAction, pLight);
728 setupCamera (pLight, eType, pAction, pEngineData);
729 doFinalPass (pLight, pAction, pEngineData);
732 if(0x0000 != (bvMask & bvAmbientPassMask))
734 this->recurseFrom(pAction, pLight);
736 setupLightChunk(pLight, eType, pAction, pEngineData);
739 if(0x0000 != (bvMask & bvLightPassMask))
741 this->recurseFrom(pAction, pLight);
743 doLightPass (pLight, pAction, pEngineData);
746 else
748 setupCamera (pLight, eType, pAction, pEngineData);
750 setupLightChunk(pLight, eType, pAction, pEngineData);
752 pAction->addPassMask(bvDiffusePassMask);
753 doFinalPass (pLight, pAction, pEngineData);
754 pAction->subPassMask(bvDiffusePassMask);
756 pAction->addPassMask(bvAmbientPassMask);
757 doAmbientPass (pLight, pAction, pEngineData);
758 pAction->subPassMask(bvAmbientPassMask);
760 pAction->addPassMask(bvLightPassMask);
761 doLightPass (pLight, pAction, pEngineData);
762 pAction->subPassMask(bvLightPassMask);
765 return Action::Skip;
768 Action::ResultE SimpleShadowMapEngine::runOnLeave(
769 Light *pLight,
770 LightTypeE eType,
771 RenderAction *pAction)
773 return Action::Continue;