NL3D::CShadowMapManager Class Reference

#include <shadow_map_manager.h>


Detailed Description

A class to manage the render of shadow map.
Author:
Lionel Berenguier

Nevrax France

Date:
2003

Definition at line 58 of file shadow_map_manager.h.

Public Member Functions

void addShadowCaster (CTransform *model)
 Add a ShadowCaster that influence the scene this pass.

void addShadowCasterGenerate (CTransform *model)
void addShadowReceiver (CTransform *model)
 Add a ShadowRecevier visible in this scene for this pass.

 CShadowMapManager ()
 Constructor.

void enableShadowPolySmooth (bool enable)
 Enable Polygon Smoothing.

CMaterialgetCasterShadowMaterial ()
 Get the typical Material for Caster.

bool getEnableShadowPolySmooth () const
 get Enable Polygon Smoothing flag

void renderGenerate (CScene *scene)
void renderProject (CScene *scene)
void selectShadowMapsToGenerate (CScene *scene)
void setQuadGridSize (uint size, float cellSize)
 change the QuadGrid size. it reset all the receivers!

 ~CShadowMapManager ()
Texture Allocation
ITextureallocateTexture (uint textSize)
 Allocate a texture for a shadowMap. NB: owned by a smartPtr. nlassert powerof2.

void releaseTexture (ITexture *text)

Private Types

typedef TTextureMap::iterator ItTextureMap
typedef CQuadGrid< CTransform * > TShadowReceiverGrid
typedef std::map< ITexture *,
CSmartPtr< ITexture > > 
TTextureMap

Private Member Functions

void applyFakeGaussianBlur (IDriver *drv, uint numPassText, uint numTextW, uint numTextH, uint baseTextureSize)
void clearGenerateShadowCasters ()
void computeShadowColors (CScene *scene, CTransform *sc, CRGBA &ambient, CRGBA &diffuse)
void computeShadowDirection (CScene *scene, CTransform *sc, CVector &lightDir)
void copyScreenToBlurTexture (IDriver *drv, uint numPassText, uint numTextW, uint numTextH, uint baseTextureSize)
void fillBlackBorder (IDriver *drv, uint numPassText, uint numTextW, uint numTextH, uint baseTextureSize)
void garbageShadowTextures (CScene *scene)
void setBlackQuad (uint index, sint x, sint y, sint w, sint h)
void setBlurQuadFakeGaussian (uint index, sint x, sint y, sint w, sint h)
void updateBlurTexture (uint w, uint h)

Private Attributes

CMaterial _BlurMaterial
CVertexBuffer _BlurQuads
CSmartPtr< ITexture_BlurTexture
float _BlurTextureD05H
float _BlurTextureD05W
uint32 _BlurTextureH
float _BlurTextureOOH
float _BlurTextureOOW
uint32 _BlurTextureW
CMaterial _CasterShadowMaterial
NLMISC::CSmartPtr< ITexture_ClampTexture
CMaterial _FillMaterial
CVertexBuffer _FillQuads
std::vector< ItTextureMap_FreeShadowTextures
std::vector< CTransform * > _GenerateShadowCasters
uint _NumShadowReceivers
bool _PolySmooth
CMaterial _ReceiveShadowMaterial
std::vector< CTransform * > _ShadowCasters
TShadowReceiverGrid _ShadowReceiverGrid
TTextureMap _ShadowTextureMap
CMatrix _XYZToUWVMatrix
CMatrix _XYZToWUVMatrix


Member Typedef Documentation

typedef TTextureMap::iterator NL3D::CShadowMapManager::ItTextureMap [private]
 

Definition at line 166 of file shadow_map_manager.h.

Referenced by releaseTexture().

typedef CQuadGrid<CTransform*> NL3D::CShadowMapManager::TShadowReceiverGrid [private]
 

Definition at line 120 of file shadow_map_manager.h.

typedef std::map<ITexture *, CSmartPtr<ITexture> > NL3D::CShadowMapManager::TTextureMap [private]
 

Definition at line 165 of file shadow_map_manager.h.


Constructor & Destructor Documentation

NL3D::CShadowMapManager::CShadowMapManager  ) 
 

Constructor.

Definition at line 59 of file shadow_map_manager.cpp.

References _BlurMaterial, _BlurQuads, _BlurTextureH, _BlurTextureW, _CasterShadowMaterial, _ClampTexture, _FillMaterial, _FillQuads, _GenerateShadowCasters, _NumShadowReceivers, _PolySmooth, _ReceiveShadowMaterial, _ShadowCasters, _XYZToUWVMatrix, _XYZToWUVMatrix, NL3D::easeInEaseOut(), NL3D::CMaterial::enableUserTexMat(), NL3D::CMaterial::initUnlit(), NL3D_SMM_QUADCELL_SIZE, NL3D_SMM_QUADGRID_SIZE, NL3D::CMaterial::setAlphaTest(), NL3D::CMaterial::setAlphaTestThreshold(), NL3D::CMaterial::setBlend(), NL3D::CMaterial::setBlendFunc(), NL3D::CMaterial::setColor(), NL3D::CMaterial::setDoubleSided(), NL3D::CVertexBuffer::setNumVertices(), setQuadGridSize(), NLMISC::CMatrix::setRot(), NL3D::CMaterial::setTexCoordGen(), NL3D::CMaterial::setTexCoordGenMode(), NL3D::CMaterial::setTexture(), NL3D::CVertexBuffer::setVertexFormat(), NL3D::CMaterial::setZFunc(), NL3D::CMaterial::setZWrite(), NL3D::CMaterial::texConstantColor(), NL3D::CMaterial::texEnvArg0Alpha(), NL3D::CMaterial::texEnvArg0RGB(), NL3D::CMaterial::texEnvArg1Alpha(), NL3D::CMaterial::texEnvArg1RGB(), NL3D::CMaterial::texEnvOpAlpha(), NL3D::CMaterial::texEnvOpRGB(), uint, and uint8.

00060 {
00061         uint    i;
00062 
00063         setQuadGridSize(NL3D_SMM_QUADGRID_SIZE, NL3D_SMM_QUADCELL_SIZE);
00064         _ShadowCasters.reserve(256);
00065         _GenerateShadowCasters.reserve(256);
00066         _NumShadowReceivers= 0;
00067         _PolySmooth= true;
00068 
00069         // **** Setup Fill
00070         _FillQuads.setVertexFormat(CVertexBuffer::PositionFlag);
00071         _FillMaterial.initUnlit();
00072         _FillMaterial.setColor(CRGBA(0,0,0,0));
00073         _FillMaterial.setZWrite(false);
00074         _FillMaterial.setZFunc(CMaterial::always);
00075         _FillMaterial.setDoubleSided(true);
00076 
00077         // **** Setup Blur
00078         _BlurQuads.setVertexFormat(CVertexBuffer::PositionFlag |
00079                 CVertexBuffer::TexCoord0Flag |
00080                 CVertexBuffer::TexCoord1Flag |
00081                 CVertexBuffer::TexCoord2Flag |
00082                 CVertexBuffer::TexCoord3Flag);
00083         // Only 2 quads are used to blur
00084         _BlurQuads.setNumVertices(8);
00085         _BlurMaterial.initUnlit();
00086         _BlurMaterial.setColor(CRGBA::White);
00087         _BlurMaterial.setZWrite(false);
00088         _BlurMaterial.setZFunc(CMaterial::always);
00089         _BlurMaterial.setDoubleSided(true);
00090         // Setup The Blur. NB: it will take advantage of Max 4 texture driver support, but will still 
00091         // work with 2 or 3 (less beautifull).
00092         for(i=1;i<4;i++)
00093         {
00094                 _BlurMaterial.texEnvOpRGB(i, CMaterial::InterpolateConstant);
00095                 _BlurMaterial.texEnvArg0RGB(i, CMaterial::Texture, CMaterial::SrcColor);
00096                 _BlurMaterial.texEnvArg1RGB(i, CMaterial::Previous, CMaterial::SrcColor);
00097                 _BlurMaterial.texEnvOpAlpha(i, CMaterial::InterpolateConstant);
00098                 _BlurMaterial.texEnvArg0Alpha(i, CMaterial::Texture, CMaterial::SrcAlpha);
00099                 _BlurMaterial.texEnvArg1Alpha(i, CMaterial::Previous, CMaterial::SrcAlpha);
00100         }
00101         // Factor for Stage so the sum is 1.
00102         _BlurMaterial.texConstantColor(1, CRGBA(128,128,128,128));              // factor= 1/2
00103         _BlurMaterial.texConstantColor(2, CRGBA(85,85,85,85));                  // factor= 1/3
00104         _BlurMaterial.texConstantColor(3, CRGBA(64,64,64,64));                  // factor= 1/4
00105 
00106         _BlurTextureW= 0;
00107         _BlurTextureH= 0;
00108 
00109         // **** Setup Receiving
00110 
00111         // Setup the clamp texture.
00112         const   uint    clampTextSize= 512;
00113         const   uint    clampNearFadeSize= 32;
00114         const   uint    clampFarFadeSize= 128;
00115         uint                    textMemSize= 4*clampTextSize*1;
00116         // Fill mem
00117         uint8   *tmpMem= new uint8[textMemSize];
00118         memset(tmpMem, 255, textMemSize);
00119         for(i=0;i<clampNearFadeSize;i++)
00120         {
00121                 float   f= (float)i/clampNearFadeSize;
00122                 f= easeInEaseOut(f);
00123                 tmpMem[4*i+3]= (uint)(255*f);
00124         }
00125         for(i=0;i<clampFarFadeSize;i++)
00126         {
00127                 float   f= (float)i/clampFarFadeSize;
00128                 f= easeInEaseOut(f);
00129                 tmpMem[4*(clampTextSize-i-1)+3]= (uint)(255*f);
00130         }
00131         // build the texture
00132         _ClampTexture = new CTextureMem (tmpMem, 4*clampTextSize*1, true, false, clampTextSize, 1);
00133         _ClampTexture->setWrapS (ITexture::Clamp);
00134         _ClampTexture->setWrapT (ITexture::Clamp);
00135         _ClampTexture->setFilterMode (ITexture::Linear, ITexture::LinearMipMapOff);
00136         _ClampTexture->generate();
00137         _ClampTexture->setReleasable (false);
00138 
00139         // init material
00140         _ReceiveShadowMaterial.initUnlit();
00141         _ReceiveShadowMaterial.setBlend(true);
00142         _ReceiveShadowMaterial.setBlendFunc(CMaterial::zero, CMaterial::srccolor);
00143         // FillRate Optim
00144         _ReceiveShadowMaterial.setAlphaTest(true);
00145         _ReceiveShadowMaterial.setAlphaTestThreshold(0.01f);
00146 
00147         // ---- Stage 0. Project the ShadowMap. Blend the color between ShadowColor and White.
00148         // setup texture coord gen
00149         _ReceiveShadowMaterial.enableUserTexMat(0, true);
00150         _ReceiveShadowMaterial.setTexCoordGen(0, true);
00151         _ReceiveShadowMaterial.setTexCoordGenMode(0, CMaterial::TexCoordGenObjectSpace);
00152         // Setup the stage so we interpolate ShadowColor and White (according to shadowmap alpha)
00153         _ReceiveShadowMaterial.texEnvOpRGB(0, CMaterial::InterpolateTexture);
00154         _ReceiveShadowMaterial.texEnvArg0RGB(0, CMaterial::Diffuse, CMaterial::SrcColor);
00155         _ReceiveShadowMaterial.texEnvArg1RGB(0, CMaterial::Constant, CMaterial::SrcColor);
00156         _ReceiveShadowMaterial.texConstantColor(0, CRGBA::White);
00157         // Take Alpha for AlphaTest only.
00158         _ReceiveShadowMaterial.texEnvOpAlpha(0, CMaterial::Replace);
00159         _ReceiveShadowMaterial.texEnvArg0Alpha(0, CMaterial::Texture, CMaterial::SrcAlpha);
00160 
00161         // ---- Stage 1. "Modulate" by Clamp Texture. Blend the color between stage0 color and White.
00162         // setup texture coord gen
00163         _ReceiveShadowMaterial.enableUserTexMat(1, true);
00164         _ReceiveShadowMaterial.setTexCoordGen(1, true);
00165         _ReceiveShadowMaterial.setTexCoordGenMode(1, CMaterial::TexCoordGenObjectSpace);
00166         _ReceiveShadowMaterial.setTexture(1, _ClampTexture);
00167         // Setup the stage so we interpolate Shadow and White (according to clamp alpha)
00168         _ReceiveShadowMaterial.texEnvOpRGB(1, CMaterial::InterpolateTexture);
00169         //_ReceiveShadowMaterial.texEnvArg0RGB(1, CMaterial::Previous, CMaterial::SrcColor);
00170         _ReceiveShadowMaterial.texEnvArg0RGB(1, CMaterial::Previous, CMaterial::SrcColor);
00171         _ReceiveShadowMaterial.texEnvArg1RGB(1, CMaterial::Constant, CMaterial::SrcColor);
00172         _ReceiveShadowMaterial.texConstantColor(1, CRGBA::White);
00173         // Take Alpha for AlphaTest only. (take 1st texture alpha...)
00174         _ReceiveShadowMaterial.texEnvOpAlpha(0, CMaterial::Replace);
00175         _ReceiveShadowMaterial.texEnvArg0Alpha(0, CMaterial::Previous, CMaterial::SrcAlpha);
00176 
00177         // Trans matrix from Nel basis (Z up) to UVW basis (V up)
00178         _XYZToUWVMatrix.setRot(CVector::I, CVector::K, CVector::J, true);
00179         // Trans Matrix so Y is now the U (for clamp map).
00180         _XYZToWUVMatrix.setRot(CVector::K, CVector::I, CVector::J, true);
00181 
00182         // **** Setup Casting
00183         _CasterShadowMaterial.initUnlit();
00184         _CasterShadowMaterial.setColor(CRGBA::White);
00185         _CasterShadowMaterial.setZWrite(false);
00186         _CasterShadowMaterial.setZFunc(CMaterial::always);
00187         _CasterShadowMaterial.setDoubleSided(true);
00188         // Alpha Polygon coverage accumulate, for polygon smoothing
00189         _CasterShadowMaterial.setBlend(true);
00190         _CasterShadowMaterial.setBlendFunc(CMaterial::one, CMaterial::one);
00191 }

NL3D::CShadowMapManager::~CShadowMapManager  ) 
 

Definition at line 194 of file shadow_map_manager.cpp.

References _NumShadowReceivers, _ShadowCasters, _ShadowReceiverGrid, NL3D::CQuadGrid< CTransform * >::clear(), and clearGenerateShadowCasters().

00195 {
00196         _ShadowReceiverGrid.clear();
00197         _ShadowCasters.clear();
00198         clearGenerateShadowCasters();
00199         _NumShadowReceivers= 0;
00200 }


Member Function Documentation

void NL3D::CShadowMapManager::addShadowCaster CTransform model  ) 
 

Add a ShadowCaster that influence the scene this pass.

Definition at line 209 of file shadow_map_manager.cpp.

References _ShadowCasters.

Referenced by NL3D::CClipTrav::clipSkeletonShadowMaps(), and NL3D::CMeshInstance::traverseRender().

00210 {
00211         _ShadowCasters.push_back(model);
00212 }

void NL3D::CShadowMapManager::addShadowCasterGenerate CTransform model  ) 
 

Add Manually a ShadowCaster that will compute his ShadowMap this pass. NB: model->setGeneratingShadowMap(true); is called

Definition at line 215 of file shadow_map_manager.cpp.

References _GenerateShadowCasters, and NL3D::CTransform::setGeneratingShadowMap().

Referenced by NL3D::CMeshInstance::traverseRender().

00216 {
00217         _GenerateShadowCasters.push_back(model);
00218         // Indicate this model that it will render its ShadowMap
00219         model->setGeneratingShadowMap(true);
00220 }

void NL3D::CShadowMapManager::addShadowReceiver CTransform model  ) 
 

Add a ShadowRecevier visible in this scene for this pass.

Definition at line 223 of file shadow_map_manager.cpp.

References _NumShadowReceivers, _ShadowReceiverGrid, NLMISC::CAABBox::getMax(), NLMISC::CAABBox::getMin(), NL3D::CTransform::getReceiverBBox(), and NL3D::CQuadGrid< CTransform * >::insert().

Referenced by NL3D::CLandscapeModel::traverseRender().

00224 {
00225         CAABBox bb;
00226         model->getReceiverBBox(bb);
00227 
00228         _ShadowReceiverGrid.insert(bb.getMin(), bb.getMax(), model);
00229 
00230         _NumShadowReceivers++;
00231 }

ITexture * NL3D::CShadowMapManager::allocateTexture uint  textSize  ) 
 

Allocate a texture for a shadowMap. NB: owned by a smartPtr. nlassert powerof2.

Definition at line 957 of file shadow_map_manager.cpp.

References _FreeShadowTextures, _ShadowTextureMap, NL3D::ITexture::generate(), NLMISC::CBitmap::getWidth(), NLMISC::isPowerOf2(), nlassert, NL3D::ITexture::setFilterMode(), NL3D::ITexture::setReleasable(), NL3D::ITexture::setWrapS(), NL3D::ITexture::setWrapT(), uint, and uint8.

Referenced by NL3D::CShadowMap::initTexture().

00958 {
00959         nlassert( isPowerOf2(textSize) );
00960 
00961         // **** First, find a free texture already allocated.
00962         if(!_FreeShadowTextures.empty())
00963         {
00964                 ITexture        *freeText= _FreeShadowTextures.back()->second;
00965                 // If Ok for the size.
00966                 if(freeText->getWidth() == textSize)
00967                 {
00968                         // take this texture => no more free.
00969                         _FreeShadowTextures.pop_back();
00970                         return freeText;
00971                 }
00972                 // else, suppose that we still take this slot.
00973                 else
00974                 {
00975                         // but since bad size, delete this slot from the map and create a new one (below)
00976                         _ShadowTextureMap.erase(_FreeShadowTextures.back());
00977                         // no more valid it
00978                         _FreeShadowTextures.pop_back();
00979                 }
00980         }
00981 
00982         // **** Else Allocate new one.
00983         // NB: the format must be RGBA; else slow copyFrameBufferToTexture()
00984         uint8   *tmpMem= new uint8[4*textSize*textSize];
00985         ITexture        *text;
00986         text = new CTextureMem (tmpMem, 4*textSize*textSize, true, false, textSize, textSize);
00987         text->setWrapS (ITexture::Clamp);
00988         text->setWrapT (ITexture::Clamp);
00989         text->setFilterMode (ITexture::Linear, ITexture::LinearMipMapOff);
00990         text->generate();
00991         text->setReleasable (false);
00992 
00993         // Setup in the map.
00994         _ShadowTextureMap[text]= text;
00995 
00996         return text;
00997 }

void NL3D::CShadowMapManager::applyFakeGaussianBlur IDriver drv,
uint  numPassText,
uint  numTextW,
uint  numTextH,
uint  baseTextureSize
[private]
 

Definition at line 802 of file shadow_map_manager.cpp.

References _BlurMaterial, _BlurQuads, NL3D::IDriver::activeVertexBuffer(), index, NL3D::IDriver::renderQuads(), setBlurQuadFakeGaussian(), and uint.

Referenced by renderGenerate().

00803 {
00804         if(numPassText==0)
00805                 return;
00806 
00807         // the number of lines that have all their column disp.
00808         uint    numFullLine= numPassText/numTextW;
00809         // for the last line not full, the number of column setuped
00810         uint    lastLineNumCol=  numPassText - (numFullLine*numTextW);
00811 
00812         // Split into 2 quads. one for the first full lines, and one for the last not full line.
00813         uint    index= 0;
00814         if(numFullLine)
00815                 setBlurQuadFakeGaussian(index++, 0, 0, numTextW*baseTextureSize, numFullLine*baseTextureSize);
00816         if(lastLineNumCol)
00817                 setBlurQuadFakeGaussian(index++, 0, numFullLine*baseTextureSize, lastLineNumCol*baseTextureSize, baseTextureSize);
00818 
00819         // render
00820         drv->activeVertexBuffer(_BlurQuads);
00821         drv->renderQuads(_BlurMaterial, 0, index);
00822 }

void NL3D::CShadowMapManager::clearGenerateShadowCasters  )  [private]
 

Definition at line 945 of file shadow_map_manager.cpp.

References _GenerateShadowCasters, and uint.

Referenced by renderGenerate(), selectShadowMapsToGenerate(), and ~CShadowMapManager().

00946 {
00947         // Reset first each flag of all models
00948         for(uint i=0;i<_GenerateShadowCasters.size();i++)
00949         {
00950                 _GenerateShadowCasters[i]->setGeneratingShadowMap(false);
00951         }
00952 
00953         _GenerateShadowCasters.clear();
00954 }

void NL3D::CShadowMapManager::computeShadowColors CScene scene,
CTransform sc,
CRGBA ambient,
CRGBA diffuse
[private]
 

Definition at line 626 of file shadow_map_manager.cpp.

References NL3D::CLightContribution::AttFactor, NLMISC::CRGBA::B, NL3D::CLightContribution::computeCurrentAmbient(), NLMISC::CRGBA::G, NL3D::CPointLight::getDiffuse(), NL3D::CTransform::getLightContribution(), NL3D::CScene::getSunAmbient(), NL3D::CScene::getSunDiffuse(), min, NL3D_MAX_LIGHT_CONTRIBUTION, NL3D::CLightContribution::PointLight, NLMISC::CRGBA::R, r, NL3D::CLightContribution::SunContribution, and uint.

Referenced by renderProject().

00627 {
00628         const   CLightContribution      &lc= sc->getLightContribution();
00629 
00630         // Get the current ambiant
00631         ambient= lc.computeCurrentAmbient(scene->getSunAmbient());
00632 
00633         // Compute the current diffuse as a sum (not a mean)
00634         uint    r, g, b;
00635         CRGBA   color= scene->getSunDiffuse();
00636         r= color.R * lc.SunContribution;
00637         g= color.G * lc.SunContribution;
00638         b= color.B * lc.SunContribution;
00639 
00640         // Add PointLights contribution
00641         for(uint i=0;i<NL3D_MAX_LIGHT_CONTRIBUTION;i++)
00642         {
00643                 CPointLight             *pl= lc.PointLight[i];
00644                 // End of List?
00645                 if(!pl)
00646                         break;
00647 
00648                 // Sum with this light, weighted by AttFactor
00649                 color= pl->getDiffuse();
00650                 r+= color.R * lc.AttFactor[i];
00651                 g+= color.G * lc.AttFactor[i];
00652                 b+= color.B * lc.AttFactor[i];
00653         }
00654 
00655         // normalize
00656         r>>=8;
00657         g>>=8;
00658         b>>=8;
00659 
00660         // Don't take the MergedPointLight into consideration (should add to the diffuse part here, but rare case)
00661 
00662         diffuse.R= min(r, 255U);
00663         diffuse.G= min(g, 255U);
00664         diffuse.B= min(b, 255U);
00665 }

void NL3D::CShadowMapManager::computeShadowDirection CScene scene,
CTransform sc,
CVector lightDir
[private]
 

Definition at line 595 of file shadow_map_manager.cpp.

References NL3D::CLightContribution::AttFactor, NLMISC::CRGBA::B, NLMISC::CRGBA::G, NL3D::CPointLight::getDiffuse(), NL3D::CTransform::getLightContribution(), NLMISC::CMatrix::getPos(), NL3D::CPointLight::getPosition(), NL3D::CScene::getSunDiffuse(), NL3D::CScene::getSunDirection(), NL3D::CTransform::getWorldMatrix(), NL3D_MAX_LIGHT_CONTRIBUTION, NLMISC::CVector::normalize(), NL3D::CLightContribution::PointLight, NLMISC::CRGBA::R, NL3D::CLightContribution::SunContribution, and uint.

Referenced by renderGenerate().

00596 {
00597         // merge the sunLight and pointLights into a single directional
00598         lightDir= scene->getSunDirection();
00599         const   CLightContribution      &lc= sc->getLightContribution();
00600         // For Better result, weight with the light color too.
00601         CRGBA   color= scene->getSunDiffuse();
00602         lightDir*= (float)lc.SunContribution * (color.R + color.G + color.B);
00603 
00604         // merge pointLights
00605         const CVector           &modelPos= sc->getWorldMatrix().getPos();
00606         for(uint i=0;i<NL3D_MAX_LIGHT_CONTRIBUTION;i++)
00607         {
00608                 CPointLight             *pl= lc.PointLight[i];
00609                 // End of List?
00610                 if(!pl)
00611                         break;
00612 
00613                 CVector plDir= modelPos - pl->getPosition();
00614                 plDir.normalize();
00615                 // Sum with this light, weighted by AttFactor, and light color
00616                 color= pl->getDiffuse();
00617                 lightDir+= plDir * (float)lc.AttFactor[i] * (float)(color.R + color.G + color.B);
00618         }
00619 
00620         // normalize merged dir
00621         lightDir.normalize();
00622 }

void NL3D::CShadowMapManager::copyScreenToBlurTexture IDriver drv,
uint  numPassText,
uint  numTextW,
uint  numTextH,
uint  baseTextureSize
[private]
 

Definition at line 786 of file shadow_map_manager.cpp.

References _BlurTexture, NL3D::IDriver::copyFrameBufferToTexture(), and uint.

Referenced by renderGenerate().

00787 {
00788         if(numPassText==0)
00789                 return;
00790 
00791         // TODO_SHADOW: optim: split into 2 copy for less pixel draw on the last line? No because of OverHead?
00792 
00793         // number of line including the last line if not empty
00794         uint    numTotalLine= (numPassText+numTextW-1)/numTextW;
00795         // number of column.
00796         uint    numTotalCol= (numPassText<numTextW)?numPassText:numTextW;
00797 
00798         drv->copyFrameBufferToTexture(_BlurTexture, 0, 0, 0, 0, 0, numTotalCol*baseTextureSize, numTotalLine*baseTextureSize);
00799 }

void NL3D::CShadowMapManager::enableShadowPolySmooth bool  enable  )  [inline]
 

Enable Polygon Smoothing.

Definition at line 94 of file shadow_map_manager.h.

References _PolySmooth.

Referenced by NL3D::CScene::enableShadowPolySmooth().

00094 {_PolySmooth= enable;}

void NL3D::CShadowMapManager::fillBlackBorder IDriver drv,
uint  numPassText,
uint  numTextW,
uint  numTextH,
uint  baseTextureSize
[private]
 

Definition at line 669 of file shadow_map_manager.cpp.

References _FillMaterial, _FillQuads, NL3D::IDriver::activeVertexBuffer(), NL3D::IDriver::renderQuads(), setBlackQuad(), NL3D::CMaterial::setColor(), NL3D::CVertexBuffer::setNumVertices(), uint, and w.

Referenced by renderGenerate().

00670 {
00671         if(numPassText==0)
00672                 return;
00673 
00674         // the number of lines that have all their column disp.
00675         uint    numFullLine= numPassText/numTextW;
00676         // for the last line not full, the number of column setuped
00677         uint    lastLineNumCol=  numPassText - (numFullLine*numTextW);
00678         // number of line including the last line if not empty
00679         uint    numTotalLine= numFullLine + (lastLineNumCol?1:0);
00680 
00681         // Compute how many quads to render
00682         uint    numHQuads= numTotalLine * 2;
00683         uint    numTotalCol;
00684         uint    numVQuads;
00685         if(numFullLine)
00686                 numTotalCol= numTextW;
00687         else
00688                 numTotalCol= lastLineNumCol;
00689         numVQuads= numTotalCol * 2;
00690 
00691         _FillQuads.setNumVertices((numVQuads + numHQuads)*4);
00692 
00693         // Fill HQuads.
00694         uint    i;
00695         for(i=0;i<numTotalLine;i++)
00696         {
00697                 uint    w;
00698                 if(i<numFullLine)
00699                         w= numTextW*baseTextureSize;
00700                 else
00701                         w= lastLineNumCol*baseTextureSize;
00702                 // bottom of text
00703                 setBlackQuad(i*2+0, 0, i*baseTextureSize, w, 1);
00704                 // top of text
00705                 setBlackQuad(i*2+1, 0, (i+1)*baseTextureSize-1, w, 1);
00706         }
00707 
00708         // Fill VQuads;
00709         uint    baseId= numTotalLine*2;
00710         for(i=0;i<numTotalCol;i++)
00711         {
00712                 uint    h;
00713                 if(i<lastLineNumCol)
00714                         h= numTotalLine*baseTextureSize;
00715                 else
00716                         h= numFullLine*baseTextureSize;
00717                 // left of text
00718                 setBlackQuad(baseId + i*2+0, i*baseTextureSize, 0, 1, h);
00719                 // right of text
00720                 setBlackQuad(baseId + i*2+1, (i+1)*baseTextureSize-1, 0, 1, h);
00721         }
00722 
00723         // Render Quads
00724         _FillMaterial.setColor(CRGBA(0,0,0,0));
00725         drv->activeVertexBuffer(_FillQuads);
00726         drv->renderQuads(_FillMaterial, 0, numHQuads+numVQuads);
00727 }

void NL3D::CShadowMapManager::garbageShadowTextures CScene scene  )  [private]
 

Definition at line 1013 of file shadow_map_manager.cpp.

References _FreeShadowTextures, _ShadowTextureMap, NL3D::CScene::getShadowMapTextureSize(), NL3D_SMM_MAX_FREETEXT, and uint.

Referenced by renderGenerate().

01014 {
01015         uint    defSize= scene->getShadowMapTextureSize();
01016 
01017         // For all Free Textures only, release the one that are no more of the wanted default ShadowMap Size.
01018         std::vector<ItTextureMap>::iterator             itVec= _FreeShadowTextures.begin();
01019         for(;itVec!=_FreeShadowTextures.end();)
01020         {
01021                 if((*itVec)->second->getWidth() != defSize)
01022                 {
01023                         // release the map texture iterator
01024                         _ShadowTextureMap.erase(*itVec);
01025                         // release the Vector Free iterator.
01026                         itVec= _FreeShadowTextures.erase(itVec);
01027                 }
01028                 else
01029                 {
01030                         itVec++;
01031                 }
01032         }
01033 
01034         // For memory optimisation, allow only a small extra of Texture allocated.
01035         if(_FreeShadowTextures.size()>NL3D_SMM_MAX_FREETEXT)
01036         {
01037                 // Release the extra texture (Hysteresis: divide by 2 the max wanted free to leave)
01038                 uint    startToFree= NL3D_SMM_MAX_FREETEXT/2;
01039                 for(uint i=startToFree;i<_FreeShadowTextures.size();i++)
01040                 {
01041                         // Free the texture entry.
01042                         _ShadowTextureMap.erase(_FreeShadowTextures[i]);
01043                 }
01044                 // resize vector
01045                 _FreeShadowTextures.resize(startToFree);
01046         }
01047 }

CMaterial& NL3D::CShadowMapManager::getCasterShadowMaterial  )  [inline]
 

Get the typical Material for Caster.

Definition at line 99 of file shadow_map_manager.h.

References _CasterShadowMaterial.

Referenced by NL3D::CSkeletonModel::generateShadowMap(), and NL3D::CMeshInstance::generateShadowMap().

00099 {return _CasterShadowMaterial;}

bool NL3D::CShadowMapManager::getEnableShadowPolySmooth  )  const [inline]
 

get Enable Polygon Smoothing flag

Definition at line 96 of file shadow_map_manager.h.

References _PolySmooth.

Referenced by NL3D::CScene::getEnableShadowPolySmooth().

00096 {return _PolySmooth;}

void NL3D::CShadowMapManager::releaseTexture ITexture text  ) 
 

Release this one. NB: the texture is not deleted, but still will be used for later use

Definition at line 1000 of file shadow_map_manager.cpp.

References _FreeShadowTextures, _ShadowTextureMap, ItTextureMap, and nlassert.

Referenced by NL3D::CShadowMap::resetTexture().

01001 {
01002         if(!text)
01003                 return;
01004 
01005         ItTextureMap    it= _ShadowTextureMap.find(text);
01006         nlassert(it!=_ShadowTextureMap.end());
01007 
01008         // Don't release it, but insert in Free Space
01009         _FreeShadowTextures.push_back(it);
01010 }

void NL3D::CShadowMapManager::renderGenerate CScene scene  ) 
 

render ShadowMap with ShadowCasters. Generate ShadowMap only (with the AuxDriver). NB: current driver Frustum, ViewMatrix kept their initial state but ModelMatrix not.

Definition at line 234 of file shadow_map_manager.cpp.

References _GenerateShadowCasters, _NumShadowReceivers, _PolySmooth, _ShadowCasters, _ShadowReceiverGrid, applyFakeGaussianBlur(), NLMISC::clamp(), NL3D::CQuadGrid< CTransform * >::clear(), NL3D::IDriver::clear2D(), clearGenerateShadowCasters(), computeShadowDirection(), NL3D::IDriver::copyFrameBufferToTexture(), copyScreenToBlurTexture(), NL3D::IDriver::enableFog(), NL3D::IDriver::enablePolygonSmoothing(), fillBlackBorder(), NL3D::IDriver::fogEnabled(), garbageShadowTextures(), NL3D::CTransform::generateShadowMap(), NL3D::CRenderTrav::getAuxDriver(), NL3D::CScene::getNumRender(), NL3D::CScene::getRenderTrav(), NL3D::CTransform::getShadowMap(), NL3D::CScene::getShadowMapBlurSize(), NL3D::CScene::getShadowMapTextureSize(), NL3D::CShadowMap::getTexture(), NL3D::IDriver::getViewport(), NL3D::IDriver::getWindowSize(), H_AUTO, NL3D::CScissor::init(), NL3D::CViewport::init(), NL3D::CViewport::initFullScreen(), NL3D::CScissor::initFullScreen(), NLMISC::isPowerOf2(), NL3D::CShadowMap::LastGenerationFrame, min, NL3D_SMM_MAX_TEXTDEST_SIZE, NLMISC::raiseToNextPowerOf2(), NL3D::IDriver::setColorMask(), NL3D::IDriver::setFrustum(), NL3D::CRenderTrav::setupDriverCamera(), NL3D::IDriver::setupModelMatrix(), NL3D::IDriver::setupScissor(), NL3D::IDriver::setupViewMatrix(), NL3D::IDriver::setupViewport(), uint, uint32, and updateBlurTexture().

Referenced by NL3D::CRenderTrav::traverse().

00235 {
00236         H_AUTO( NL3D_ShadowManager_Generate );
00237 
00238         // Each frame, do a small garbage collector for unused free textures.
00239         garbageShadowTextures(scene);
00240 
00241         IDriver *driverForShadowGeneration= scene->getRenderTrav().getAuxDriver();
00242 
00243         // Init
00244         // ********
00245         uint32  wndW= 0, wndH= 0;
00246         // get some text/screen size.
00247         if(driverForShadowGeneration)
00248                 driverForShadowGeneration->getWindowSize(wndW, wndH);
00249         uint    baseTextureSize= scene->getShadowMapTextureSize();
00250         // Minimize the Dest Texture size, so the blurTexture don't get to heavy in VRAM.
00251         uint32  textDestW= min(wndW, (uint32)NL3D_SMM_MAX_TEXTDEST_SIZE);
00252         uint32  textDestH= min(wndH, (uint32)NL3D_SMM_MAX_TEXTDEST_SIZE);
00253 
00254         // if not needed or if not possible, exit. test for wndSize is also important when window is minimized
00255         if( _ShadowCasters.empty() || 
00256                 _NumShadowReceivers==0 ||
00257                 textDestW<baseTextureSize || textDestH<baseTextureSize)
00258         {
00259                 _ShadowReceiverGrid.clear();
00260                 _NumShadowReceivers= 0;
00261                 _ShadowCasters.clear();
00262                 clearGenerateShadowCasters();
00263                 return;
00264         }
00265 
00266         // If Needed to project some ShadowCaster, but none to compute this frame, quit.
00267         if( _GenerateShadowCasters.empty() )
00268         {
00269                 // But here don't reset since the renderProject() will do job
00270                 return;
00271         }
00272 
00273         // get the number of shadowMap compute we can do in one screen.
00274         uint    numTextW= textDestW/baseTextureSize;
00275         uint    numTextH= textDestH/baseTextureSize;
00276         if(!isPowerOf2(numTextW))
00277                 numTextW= raiseToNextPowerOf2(numTextW)/2;
00278         if(!isPowerOf2(numTextH))
00279                 numTextH= raiseToNextPowerOf2(numTextH)/2;
00280         // the max shadow casters we can do in 1 screen pass.
00281         uint    maxSCPerPass= numTextW * numTextH;
00282 
00283         // compute vp float size.
00284         float   vpWidth= (float)baseTextureSize / (float)wndW;
00285         float   vpHeight= (float)baseTextureSize / (float)wndH;
00286 
00287 
00288         // Create / Update the Blur Texture 
00289         updateBlurTexture(numTextW * baseTextureSize, numTextH * baseTextureSize);
00290 
00291 
00292         // Do NPass if a screen is not sufficient to render all shadow maps...
00293         // ********
00294 
00295         // bkup driver state
00296         CViewport       bkupViewport;
00297         driverForShadowGeneration->getViewport(bkupViewport);
00298         bool            bkupFog= driverForShadowGeneration->fogEnabled();
00299 
00300         // setup some state
00301         driverForShadowGeneration->enableFog(false);
00302         // Allow Writing on alpha only. => don't write on RGB objects!
00303         driverForShadowGeneration->setColorMask(false, false, false, true);
00304 
00305         uint    numSC= _GenerateShadowCasters.size();
00306         uint    baseSC= 0;
00307         while(numSC>0)
00308         {
00309                 uint    numPassSC= min(maxSCPerPass, numSC);
00310                 uint    textX, textY;
00311                 uint    i;
00312 
00313                 // Render All Shadow Map
00314                 // ********
00315 
00316                 // Render the polygons with Smooth Anti-Alias. Less jittering for little performance overcost
00317                 if(_PolySmooth)
00318                         driverForShadowGeneration->enablePolygonSmoothing(true);
00319 
00320                 textX=0;
00321                 textY=0;
00322                 for(i=0;i<numPassSC;i++)
00323                 {
00324                         // get the transform to compute shadow map.
00325                         CTransform      *sc= _GenerateShadowCasters[baseSC+i];
00326 
00327                         // select the shadow direction
00328                         CVector         lightDir;
00329                         computeShadowDirection(scene, sc, lightDir);
00330 
00331                         // setup viewport to render to
00332                         CViewport       vp;
00333                         vp.init(textX*baseTextureSize/(float)wndW, textY*baseTextureSize/(float)wndH, vpWidth, vpHeight);
00334                         driverForShadowGeneration->setupViewport(vp);
00335 
00336                         // TODO_SHADOW: optim: one big erase per pass, but just bbox needed (according to number of SC to render)
00337                         // do a siccor or prefer do a polygon clear?
00338                         CScissor        sic;
00339                         sic.init(textX*baseTextureSize/(float)wndW, textY*baseTextureSize/(float)wndH, vpWidth, vpHeight);
00340                         driverForShadowGeneration->setupScissor(sic);
00341                         driverForShadowGeneration->clear2D(CRGBA(0,0,0,0));
00342 
00343                         // render to screen
00344                         sc->generateShadowMap(lightDir);
00345 
00346                         // next text
00347                         textX++;
00348                         if(textX==numTextW)
00349                         {
00350                                 textX= 0;
00351                                 textY++;
00352                         }
00353                 }
00354 
00355                 // Restore
00356                 if(_PolySmooth)
00357                         driverForShadowGeneration->enablePolygonSmoothing(false);
00358 
00359                 // For Subsequent operations, setup a full viewport and a "Screen Frustum"
00360                 CScissor        sic;
00361                 sic.initFullScreen();
00362                 // TODO_SHADOW: optim: need scissor?
00363                 driverForShadowGeneration->setupScissor(sic);
00364                 CViewport       vp;
00365                 vp.initFullScreen();
00366                 driverForShadowGeneration->setupViewport(vp);
00367                 driverForShadowGeneration->setFrustum(0, (float)wndW, 0, (float)wndH, -1,1,false);
00368                 driverForShadowGeneration->setupViewMatrix(CMatrix::Identity);
00369                 driverForShadowGeneration->setupModelMatrix(CMatrix::Identity);
00370 
00371                 // Ensure the One pixel black security on texture border
00372                 fillBlackBorder(driverForShadowGeneration, numPassSC, numTextW, numTextH, baseTextureSize);
00373 
00374                 // Blur.
00375                 // ********
00376                 uint    numBlur= scene->getShadowMapBlurSize();
00377                 clamp(numBlur, 0U, 3U);
00378                 for(i=0;i<numBlur;i++)
00379                 {
00380                         // copy from FB to BlurTexture
00381                         copyScreenToBlurTexture(driverForShadowGeneration, numPassSC, numTextW, numTextH, baseTextureSize);
00382 
00383                         // blur
00384                         applyFakeGaussianBlur(driverForShadowGeneration, numPassSC, numTextW, numTextH, baseTextureSize);
00385 
00386                         // Ensure the One pixel black security on texture border
00387                         fillBlackBorder(driverForShadowGeneration, numPassSC, numTextW, numTextH, baseTextureSize);
00388                 }
00389 
00390                 // Store Screen in ShadowMaps
00391                 // ********
00392                 textX=0;
00393                 textY=0;
00394                 for(i=0;i<numPassSC;i++)
00395                 {
00396                         // get the transform to compute shadow map.
00397                         CTransform      *sc= _GenerateShadowCasters[baseSC+i];
00398                         CShadowMap      *sm= sc->getShadowMap();
00399                         if(sm)
00400                         {
00401                                 ITexture        *text= sm->getTexture();
00402                                 if(text)
00403                                 {
00404                                         uint    bts= baseTextureSize;
00405                                         driverForShadowGeneration->copyFrameBufferToTexture(text, 0, 0, 0, textX*bts, textY*bts, bts, bts);
00406                                         // Indicate to the ShadowMap that we have updated his Texture
00407                                         sm->LastGenerationFrame= scene->getNumRender();
00408                                 }
00409                         }
00410 
00411                         // next text
00412                         textX++;
00413                         if(textX==numTextW)
00414                         {
00415                                 textX= 0;
00416                                 textY++;
00417                         }
00418                 }
00419 
00420 
00421                 // next screen pass.
00422                 baseSC+= numPassSC;
00423                 numSC-= numPassSC;
00424         }
00425 
00426         // Allow Writing on all.
00427         driverForShadowGeneration->setColorMask(true, true, true, true);
00428         // Restore driver state. (do it here because driverForShadowGeneration may be the main screen).
00429         driverForShadowGeneration->setupViewport(bkupViewport);
00430         driverForShadowGeneration->enableFog(bkupFog);
00431         // TODO_SHADOW: optim need scissor?
00432         CScissor        sic;
00433         sic.initFullScreen();
00434         driverForShadowGeneration->setupScissor(sic);
00435 
00436         // ensure the Scene Driver has correct matrix setup (in common case where AuxDriver == Std Driver)
00437         scene->getRenderTrav().setupDriverCamera();
00438 
00439 
00440         // Clear ShadowCaster Generation
00441         clearGenerateShadowCasters();
00442 }

void NL3D::CShadowMapManager::renderProject CScene scene  ) 
 

project ShadowMaps onto receivers. NB: renderGenerate() must have been called before. NB: current driver Frustum, ViewMatrix kept their initial state but ModelMatrix not.

Definition at line 445 of file shadow_map_manager.cpp.

References _NumShadowReceivers, _ReceiveShadowMaterial, _ShadowCasters, _ShadowReceiverGrid, _XYZToUWVMatrix, _XYZToWUVMatrix, NLMISC::CRGBA::B, NL3D::CQuadGrid< CTransform * >::begin(), NLMISC::clamp(), NL3D::CQuadGrid< CTransform * >::clear(), computeShadowColors(), NL3D::CQuadGrid< CTransform * >::end(), NLMISC::CRGBA::G, NLMISC::CAABBox::getCenter(), NL3D::CRenderTrav::getDriver(), NL3D::CShadowMap::getFinalFade(), NL3D::IDriver::getFogColor(), NL3D::IDriver::getFogEnd(), NL3D::IDriver::getFogStart(), NLMISC::CAABBox::getMax(), NLMISC::CAABBox::getMin(), NLMISC::CMatrix::getPos(), NL3D::CTransform::getReceiverRenderWorldMatrix(), NL3D::CScene::getRenderTrav(), NL3D::CTransform::getShadowMap(), NL3D::CShadowMap::getTexture(), NL3D::CTransform::getWorldMatrix(), H_AUTO, NLMISC::CMatrix::invert(), NL3D::CShadowMap::LocalBoundingBox, NL3D::CShadowMap::LocalProjectionMatrix, nlassert, NLMISC::OptFastFloor(), NLMISC::CRGBA::R, NL3D::CTransform::receiveShadowMap(), NL3D::CQuadGrid< CTransform * >::select(), NLMISC::CAABBox::setCenter(), NL3D::CMaterial::setColor(), NLMISC::CMatrix::setMulMatrix(), NLMISC::CMatrix::setPos(), NL3D::CMaterial::setTexture(), NL3D::IDriver::setupFog(), NL3D::CMaterial::setUserTexMat(), sint, and uint.

Referenced by NL3D::CRenderTrav::traverse().

00446 {
00447         // if not needed exit. NB renderGenerate() must have been called before.
00448         if( _NumShadowReceivers==0 )
00449         {
00450                 nlassert(_ShadowCasters.empty());
00451                 return;
00452         }
00453 
00454 
00455         // Project ShadowMap on receivers.
00456         // ********
00457 
00458         H_AUTO( NL3D_ShadowManager_Project );
00459 
00460 
00461         /* Fog Case: Since we do a modulate, we don't want to modulate the fog color with himself.
00462                 Instead, if the shadowed pixel is in full fog, we have to modulate him with White
00463                 => replace fog color with white temporarly.
00464         */
00465         IDriver *driver= scene->getRenderTrav().getDriver();
00466         CRGBA   bkupFogColor= driver->getFogColor();
00467         driver->setupFog(driver->getFogStart(), driver->getFogEnd(), CRGBA::White);
00468 
00469         // For each ShadowMap
00470         for(uint i=0;i<_ShadowCasters.size();i++)
00471         {
00472                 CTransform      *caster= _ShadowCasters[i];
00473                 CShadowMap      *sm= caster->getShadowMap();
00474                 nlassert(sm);
00475                 // NB: the ShadowCaster may not have a texture yet, for example because of Generate selection...
00476                 // If the final fade is 1, don't render!
00477                 if( sm->getTexture() && sm->getFinalFade()<1 )
00478                 {
00479                         CVector         casterPos= caster->getWorldMatrix().getPos();
00480 
00481                         // Compute the World bbox (for quadGrid intersection)
00482                         CAABBox         worldBB= sm->LocalBoundingBox;
00483                         worldBB.setCenter(worldBB.getCenter() + casterPos);
00484 
00485                         // compute the world matrix of the projection.
00486                         CMatrix         worldProjMat= sm->LocalProjectionMatrix;
00487                         worldProjMat.setPos(worldProjMat.getPos()+casterPos);
00488 
00489                         // Now compute the textureMatrix, from WorldSpace to UV.
00490                         CMatrix         wsTextMat;
00491                         CMatrix         osTextMat;
00492                         wsTextMat= worldProjMat;
00493                         wsTextMat.invert();
00494 
00495                         // setup the Material.
00496                         _ReceiveShadowMaterial.setTexture(0, sm->getTexture());
00498                         CRGBA   ambient, diffuse;
00499                         computeShadowColors(scene, caster, ambient, diffuse);
00500                         // copute the shadowColor so that modulating a Medium diffuse terrain will  get the correct result.
00501                         uint    R= ambient.R + (diffuse.R>>1);
00502                         uint    G= ambient.G + (diffuse.G>>1);
00503                         uint    B= ambient.B + (diffuse.B>>1);
00504                         clamp(R, 1U, 256U);
00505                         clamp(G, 1U, 256U);
00506                         clamp(B, 1U, 256U);
00507                         /* screen= text*(a+d*0.5) (mean value). if we do shadowColor= a/(a+d*0.5f), 
00508                                 then we'll have "in theory"  screen= text*a
00509                         */
00510                         R= (uint)(256 * ambient.R / (float)R);
00511                         G= (uint)(256 * ambient.G / (float)G);
00512                         B= (uint)(256 * ambient.B / (float)B);
00513                         clamp(R,0U,255U);
00514                         clamp(G,0U,255U);
00515                         clamp(B,0U,255U);
00517                         if(sm->getFinalFade()>0)
00518                         {
00519                                 sint    factor= OptFastFloor( 256 * sm->getFinalFade() );
00520                                 clamp(factor, 0, 256);
00521                                 R= 255*factor + R*(256-factor); R>>=8;
00522                                 G= 255*factor + G*(256-factor); G>>=8;
00523                                 B= 255*factor + B*(256-factor); B>>=8;
00524                         }
00525                         _ReceiveShadowMaterial.setColor(CRGBA(R,G,B,255));
00526 
00527 
00528                         // select receivers.
00529                         _ShadowReceiverGrid.select(worldBB.getMin(), worldBB.getMax());
00530                         // For all receivers
00531                         TShadowReceiverGrid::CIterator  it;
00532                         for(it= _ShadowReceiverGrid.begin();it!=_ShadowReceiverGrid.end();it++)
00533                         {
00534                                 CTransform      *receiver= *it;
00535                                 // Avoid Auto-Casting.
00536                                 if(receiver==caster)
00537                                         continue;
00538 
00539                                 /* The problem is material don't support WorldSpace Coordinate Generation, but ObjectSpace ones.
00540                                         Hence must take back the coordinate in ObjectSpace before set textMat. 
00541                                         see getReceiverRenderWorldMatrix() Doc for why using this instead of getWorldMatrix()
00542                                 */
00543                                 osTextMat.setMulMatrix(wsTextMat, receiver->getReceiverRenderWorldMatrix());
00544 
00545                                 /* Set the TextureMatrix for ShadowMap projection so that UVW= mat * XYZ. 
00546                                         its osTextMat but must rotate so Z map to V
00547                                 */
00548                                 _ReceiveShadowMaterial.setUserTexMat(0, _XYZToUWVMatrix * osTextMat);
00549                                 /* Set the TextureMatrix for ClampMap projection so that UVW= mat * XYZ. 
00550                                         its osTextMat but must rotate so Y map to U
00551                                 */
00552                                 _ReceiveShadowMaterial.setUserTexMat(1, _XYZToWUVMatrix * osTextMat);
00553 
00554                                 // cast the shadow on them
00555                                 receiver->receiveShadowMap(sm, casterPos, _ReceiveShadowMaterial);
00556                         }
00557                 }
00558         }
00559 
00560         // Restore fog color
00561         driver->setupFog(driver->getFogStart(), driver->getFogEnd(), bkupFogColor);
00562 
00563 
00564         // TestYoyo. Display Projection BBox.
00565         /*{
00566                 for(uint i=0;i<_ShadowCasters.size();i++)
00567                 {
00568                         // get the transform to compute shadow map.
00569                         CTransform      *sc= _ShadowCasters[i];
00570 
00571                         CShadowMap      *sm= sc->getShadowMap();
00572                         if(sm)
00573                         {
00574                                 CVector         p0= sm->LocalProjectionMatrix.getPos() + sc->getWorldMatrix().getPos();
00575                                 IDriver         &drv= *driver;
00576 
00577                                 drv.setupModelMatrix(CMatrix::Identity);
00578 
00579                                 CDRU::drawWiredBox(p0, sm->LocalProjectionMatrix.getI(), sm->LocalProjectionMatrix.getJ(), 
00580                                         sm->LocalProjectionMatrix.getK(), CRGBA::White, drv);
00581                         }
00582                 }
00583         }*/
00584 
00585 
00586         // Release pass.
00587         // ********
00588         _ShadowReceiverGrid.clear();
00589         _ShadowCasters.clear();
00590         _NumShadowReceivers= 0;
00591 }

void NL3D::CShadowMapManager::selectShadowMapsToGenerate CScene scene  ) 
 

From List of ShadowCaster, select a sub - part (so called Loding ShadowMap Casters) NB: Beware that this clear the currentlist of shadowMap to generate NB: model->setGeneratingShadowMap(true); are called for each model selected

Definition at line 880 of file shadow_map_manager.cpp.

References _GenerateShadowCasters, _ShadowCasters, NL3D::CTravCameraScene::CamPos, NL3D::CShadowMapSort::Caster, clearGenerateShadowCasters(), NL3D::CScene::getFilterRenderFlags(), NL3D::CShadowMap::getFinalFade(), NL3D::CScene::getNumRender(), NLMISC::CMatrix::getPos(), NL3D::CScene::getRenderTrav(), NL3D::CTransform::getShadowMap(), NL3D::CTransform::getWorldMatrix(), NL3D::CShadowMap::LastGenerationFrame, min, uint, and NL3D::CShadowMapSort::Weight.

Referenced by NL3D::CClipTrav::clipSkeletonShadowMaps().

00881 {
00882         // TODO: Scene option.
00883         const uint              maxPerFrame= 8;
00884         const float             minCamDist= 10;
00885         const CVector   &camPos= scene->getRenderTrav().CamPos;
00886         uint                    i;
00887 
00888         // **** Clear first
00889         clearGenerateShadowCasters();
00890 
00891         // If the scene filter skeleton render, suppose no generation at all. Ugly.
00892         if(! (scene->getFilterRenderFlags() & UScene::FilterSkeleton) )
00893                 return;
00894 
00895         // **** Select
00896         // For all ShadowCaster inserted
00897         static vector<CShadowMapSort>           sortList;
00898         sortList.clear();
00899         sortList.reserve(_ShadowCasters.size());
00900         for(i=0;i<_ShadowCasters.size();i++)
00901         {
00902                 CTransform      *caster= _ShadowCasters[i];
00903                 /* If the shadowMap exist, and if not totaly faded
00904                         NB: take FinalFade here because if 1, it won't be rendered in renderProject()
00905                         so don't really need to update (usefull for update reason, but LastGenerationFrame do the job)
00906                 */
00907                 if(caster->getShadowMap() && caster->getShadowMap()->getFinalFade()<1 )
00908                 {
00909                         CShadowMapSort          sms;
00910                         sms.Caster= caster;
00911                         // The Weight is the positive delta of frame
00912                         sms.Weight= (float)(scene->getNumRender() - caster->getShadowMap()->LastGenerationFrame);
00913                         // Modulated by Caster Distance from Camera.
00914                         float   distToCam= (caster->getWorldMatrix().getPos() - camPos).norm();
00915                         distToCam= max(distToCam, minCamDist);
00916                         // The farthest, the less important
00917                         sms.Weight/= distToCam;
00918 
00919                         // Append
00920                         sortList.push_back(sms);
00921                 }
00922         }
00923 
00924         // Sort increasing
00925         sort(sortList.begin(), sortList.end());
00926 
00927         // Select the best
00928         uint    numSel= min((uint)sortList.size(), maxPerFrame);
00929         _GenerateShadowCasters.resize(numSel);
00930         for(i= 0;i<numSel;i++)
00931         {
00932                 _GenerateShadowCasters[i]= sortList[sortList.size()-1-i].Caster;
00933         }
00934 
00935         // **** Flag selecteds
00936         // For All selected models, indicate that they will generate shadowMap for this Frame.
00937         for(i=0;i<_GenerateShadowCasters.size();i++)
00938         {
00939                 _GenerateShadowCasters[i]->setGeneratingShadowMap(true);
00940         }
00941 }

void NL3D::CShadowMapManager::setBlackQuad uint  index,
sint  x,
sint  y,
sint  w,
sint  h
[private]
 

Definition at line 731 of file shadow_map_manager.cpp.

References _FillQuads, index, NL3D::CVertexBuffer::setVertexCoord(), sint, uint, w, x, and y.

Referenced by fillBlackBorder().

00732 {
00733         float   x0= (float)x;
00734         float   y0= (float)y;
00735         float   x1= (float)x+(float)w;
00736         float   y1= (float)y+(float)h;
00737         index*= 4;
00738         _FillQuads.setVertexCoord (index+0, CVector (x0, 0, y0));
00739         _FillQuads.setVertexCoord (index+1, CVector (x1, 0, y0));
00740         _FillQuads.setVertexCoord (index+2, CVector (x1, 0, y1));
00741         _FillQuads.setVertexCoord (index+3, CVector (x0, 0, y1));
00742 }

void NL3D::CShadowMapManager::setBlurQuadFakeGaussian uint  index,
sint  x,
sint  y,
sint  w,
sint  h
[private]
 

Definition at line 826 of file shadow_map_manager.cpp.

References _BlurQuads, _BlurTextureD05H, _BlurTextureD05W, _BlurTextureOOH, _BlurTextureOOW, index, NL3D::CVertexBuffer::setTexCoord(), NL3D::CVertexBuffer::setVertexCoord(), sint, uint, w, x, and y.

Referenced by applyFakeGaussianBlur().

00827 {
00828         float   x0= (float)x;
00829         float   y0= (float)y;
00830         float   x1= (float)x+(float)w;
00831         float   y1= (float)y+(float)h;
00832         float   u0= x0*_BlurTextureOOW;
00833         float   v0= y0*_BlurTextureOOH;
00834         float   u1= x1*_BlurTextureOOW;
00835         float   v1= y1*_BlurTextureOOH;
00836         index*= 4;
00837 
00838         // NB: the order of the Delta (--,++,-+,+-) is made so it works well with 2,3 or 4 texture support.
00839 
00840         // vertex 0
00841         _BlurQuads.setVertexCoord (index+0, CVector (x0, 0, y0));
00842         _BlurQuads.setTexCoord(index+0, 0, u0-_BlurTextureD05W, v0-_BlurTextureD05H);
00843         _BlurQuads.setTexCoord(index+0, 1, u0+_BlurTextureD05W, v0+_BlurTextureD05H);
00844         _BlurQuads.setTexCoord(index+0, 2, u0-_BlurTextureD05W, v0+_BlurTextureD05H);
00845         _BlurQuads.setTexCoord(index+0, 3, u0+_BlurTextureD05W, v0-_BlurTextureD05H);
00846         // vertex 1
00847         _BlurQuads.setVertexCoord (index+1, CVector (x1, 0, y0));
00848         _BlurQuads.setTexCoord(index+1, 0, u1-_BlurTextureD05W, v0-_BlurTextureD05H);
00849         _BlurQuads.setTexCoord(index+1, 1, u1+_BlurTextureD05W, v0+_BlurTextureD05H);
00850         _BlurQuads.setTexCoord(index+1, 2, u1-_BlurTextureD05W, v0+_BlurTextureD05H);
00851         _BlurQuads.setTexCoord(index+1, 3, u1+_BlurTextureD05W, v0-_BlurTextureD05H);
00852         // vertex 2
00853         _BlurQuads.setVertexCoord (index+2, CVector (x1, 0, y1));
00854         _BlurQuads.setTexCoord(index+2, 0, u1-_BlurTextureD05W, v1-_BlurTextureD05H);
00855         _BlurQuads.setTexCoord(index+2, 1, u1+_BlurTextureD05W, v1+_BlurTextureD05H);
00856         _BlurQuads.setTexCoord(index+2, 2, u1-_BlurTextureD05W, v1+_BlurTextureD05H);
00857         _BlurQuads.setTexCoord(index+2, 3, u1+_BlurTextureD05W, v1-_BlurTextureD05H);
00858         // vertex 3
00859         _BlurQuads.setVertexCoord (index+3, CVector (x0, 0, y1));
00860         _BlurQuads.setTexCoord(index+3, 0, u0-_BlurTextureD05W, v1-_BlurTextureD05H);
00861         _BlurQuads.setTexCoord(index+3, 1, u0+_BlurTextureD05W, v1+_BlurTextureD05H);
00862         _BlurQuads.setTexCoord(index+3, 2, u0-_BlurTextureD05W, v1+_BlurTextureD05H);
00863         _BlurQuads.setTexCoord(index+3, 3, u0+_BlurTextureD05W, v1-_BlurTextureD05H);
00864 }

void NL3D::CShadowMapManager::setQuadGridSize uint  size,
float  cellSize
 

change the QuadGrid size. it reset all the receivers!

Definition at line 203 of file shadow_map_manager.cpp.

References _ShadowReceiverGrid, NL3D::CQuadGrid< CTransform * >::create(), size, and uint.

Referenced by CShadowMapManager().

00204 {
00205         _ShadowReceiverGrid.create(size, cellSize);
00206 }

void NL3D::CShadowMapManager::updateBlurTexture uint  w,
uint  h
[private]
 

Definition at line 745 of file shadow_map_manager.cpp.

References _BlurMaterial, _BlurTexture, _BlurTextureD05H, _BlurTextureD05W, _BlurTextureH, _BlurTextureOOH, _BlurTextureOOW, _BlurTextureW, NL3D::CMaterial::setTexture(), uint, uint8, and w.

Referenced by renderGenerate().

00746 {
00747         w= max(w, 2U);
00748         h= max(h, 2U);
00749         // if same size than setup, quit
00750         if(_BlurTextureW==w && _BlurTextureH==h)
00751                 return;
00752 
00753         // release old SmartPtr
00754         _BlurMaterial.setTexture(0, NULL);
00755         _BlurMaterial.setTexture(1, NULL);
00756         _BlurMaterial.setTexture(2, NULL);
00757         _BlurMaterial.setTexture(3, NULL);
00758         _BlurTexture= NULL;
00759         _BlurTextureW= w;
00760         _BlurTextureH= h;
00761         // NB: the format must be RGBA; else slow copyFrameBufferToTexture()
00762         uint8   *tmpMem= new uint8[4*_BlurTextureW*_BlurTextureH];
00763         _BlurTexture = new CTextureMem (tmpMem, 4*_BlurTextureW*_BlurTextureH, true, false, _BlurTextureW, _BlurTextureH);
00764         _BlurTexture->setWrapS (ITexture::Clamp);
00765         _BlurTexture->setWrapT (ITexture::Clamp);
00766         _BlurTexture->setFilterMode (ITexture::Linear, ITexture::LinearMipMapOff);
00767         _BlurTexture->generate();
00768         _BlurTexture->setReleasable (false);
00769 
00770         // set to the material
00771         _BlurMaterial.setTexture(0, _BlurTexture);
00772         _BlurMaterial.setTexture(1, _BlurTexture);
00773         _BlurMaterial.setTexture(2, _BlurTexture);
00774         _BlurMaterial.setTexture(3, _BlurTexture);
00775 
00776         // compute values for texturing
00777         _BlurTextureOOW= 1.f / _BlurTextureW;
00778         _BlurTextureOOH= 1.f / _BlurTextureH;
00779         // The Delta HalfPixel
00780         _BlurTextureD05W= 0.5f*_BlurTextureOOW;
00781         _BlurTextureD05H= 0.5f*_BlurTextureOOH;
00782 }


Field Documentation

CMaterial NL3D::CShadowMapManager::_BlurMaterial [private]
 

Definition at line 150 of file shadow_map_manager.h.

Referenced by applyFakeGaussianBlur(), CShadowMapManager(), and updateBlurTexture().

CVertexBuffer NL3D::CShadowMapManager::_BlurQuads [private]
 

Definition at line 151 of file shadow_map_manager.h.

Referenced by applyFakeGaussianBlur(), CShadowMapManager(), and setBlurQuadFakeGaussian().

CSmartPtr<ITexture> NL3D::CShadowMapManager::_BlurTexture [private]
 

Definition at line 143 of file shadow_map_manager.h.

Referenced by copyScreenToBlurTexture(), and updateBlurTexture().

float NL3D::CShadowMapManager::_BlurTextureD05H [private]
 

Definition at line 149 of file shadow_map_manager.h.

Referenced by setBlurQuadFakeGaussian(), and updateBlurTexture().

float NL3D::CShadowMapManager::_BlurTextureD05W [private]
 

Definition at line 148 of file shadow_map_manager.h.

Referenced by setBlurQuadFakeGaussian(), and updateBlurTexture().

uint32 NL3D::CShadowMapManager::_BlurTextureH [private]
 

Definition at line 145 of file shadow_map_manager.h.

Referenced by CShadowMapManager(), and updateBlurTexture().

float NL3D::CShadowMapManager::_BlurTextureOOH [private]
 

Definition at line 147 of file shadow_map_manager.h.

Referenced by setBlurQuadFakeGaussian(), and updateBlurTexture().

float NL3D::CShadowMapManager::_BlurTextureOOW [private]
 

Definition at line 146 of file shadow_map_manager.h.

Referenced by setBlurQuadFakeGaussian(), and updateBlurTexture().

uint32 NL3D::CShadowMapManager::_BlurTextureW [private]
 

Definition at line 144 of file shadow_map_manager.h.

Referenced by CShadowMapManager(), and updateBlurTexture().

CMaterial NL3D::CShadowMapManager::_CasterShadowMaterial [private]
 

Definition at line 160 of file shadow_map_manager.h.

Referenced by CShadowMapManager(), and getCasterShadowMaterial().

NLMISC::CSmartPtr<ITexture> NL3D::CShadowMapManager::_ClampTexture [private]
 

Definition at line 157 of file shadow_map_manager.h.

Referenced by CShadowMapManager().

CMaterial NL3D::CShadowMapManager::_FillMaterial [private]
 

Definition at line 140 of file shadow_map_manager.h.

Referenced by CShadowMapManager(), and fillBlackBorder().

CVertexBuffer NL3D::CShadowMapManager::_FillQuads [private]
 

Definition at line 139 of file shadow_map_manager.h.

Referenced by CShadowMapManager(), fillBlackBorder(), and setBlackQuad().

std::vector<ItTextureMap> NL3D::CShadowMapManager::_FreeShadowTextures [private]
 

Definition at line 169 of file shadow_map_manager.h.

Referenced by allocateTexture(), garbageShadowTextures(), and releaseTexture().

std::vector<CTransform*> NL3D::CShadowMapManager::_GenerateShadowCasters [private]
 

Definition at line 118 of file shadow_map_manager.h.

Referenced by addShadowCasterGenerate(), clearGenerateShadowCasters(), CShadowMapManager(), renderGenerate(), and selectShadowMapsToGenerate().

uint NL3D::CShadowMapManager::_NumShadowReceivers [private]
 

Definition at line 122 of file shadow_map_manager.h.

Referenced by addShadowReceiver(), CShadowMapManager(), renderGenerate(), renderProject(), and ~CShadowMapManager().

bool NL3D::CShadowMapManager::_PolySmooth [private]
 

Definition at line 136 of file shadow_map_manager.h.

Referenced by CShadowMapManager(), enableShadowPolySmooth(), getEnableShadowPolySmooth(), and renderGenerate().

CMaterial NL3D::CShadowMapManager::_ReceiveShadowMaterial [private]
 

Definition at line 154 of file shadow_map_manager.h.

Referenced by CShadowMapManager(), and renderProject().

std::vector<CTransform*> NL3D::CShadowMapManager::_ShadowCasters [private]
 

Definition at line 116 of file shadow_map_manager.h.

Referenced by addShadowCaster(), CShadowMapManager(), renderGenerate(), renderProject(), selectShadowMapsToGenerate(), and ~CShadowMapManager().

TShadowReceiverGrid NL3D::CShadowMapManager::_ShadowReceiverGrid [private]
 

Definition at line 121 of file shadow_map_manager.h.

Referenced by addShadowReceiver(), renderGenerate(), renderProject(), setQuadGridSize(), and ~CShadowMapManager().

TTextureMap NL3D::CShadowMapManager::_ShadowTextureMap [private]
 

Definition at line 167 of file shadow_map_manager.h.

Referenced by allocateTexture(), garbageShadowTextures(), and releaseTexture().

CMatrix NL3D::CShadowMapManager::_XYZToUWVMatrix [private]
 

Definition at line 155 of file shadow_map_manager.h.

Referenced by CShadowMapManager(), and renderProject().

CMatrix NL3D::CShadowMapManager::_XYZToWUVMatrix [private]
 

Definition at line 156 of file shadow_map_manager.h.

Referenced by CShadowMapManager(), and renderProject().


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 07:43:19 2004 for NeL by doxygen 1.3.6