void TrapezoidalShadowMapEngine::handlePointLightEnter( PointLight *pointL, RenderAction *ract, TSMEngineData *data) { RenderPartition *parentPart = ract->getActivePartition(); Matrixr matEyeToWorld(parentPart->getCameraToWorld()); Matrixr matLightProj; Real shadowNear = (getShadowNear() != 0.f ? getShadowNear() : parentPart->getNear() ); Real shadowFar = (getShadowFar () != 0.f ? getShadowFar () : parentPart->getFar() ); Inherited::calcPointLightRange( pointL, 0.01f, shadowNear, shadowFar, shadowNear, shadowFar); MatrixPerspective(matLightProj, Pi / 4.f, 1.f, shadowNear, shadowFar ); Matrixr matWorldToLight; Matrixr matEyeToLight; MFMatrixr mfMatNT; mfMatNT.resize(6); Inherited::calcPointLightMatrices(matWorldToLight, matEyeToLight, pointL, matEyeToWorld ); Inherited::updatePointLightShadowTexImage (data); Inherited::updatePointLightShadowTexBuffers(data); Inherited::updatePointLightRenderTargets (data); Int32 shadowTexUnit = (this->getForceTextureUnit() >= 0) ? this->getForceTextureUnit() : 7; ShaderProgram *shadowFP = this->getShadowFragmentProgram(); if(shadowFP == NULL) { ShaderProgramUnrecPtr newShadowFP = ShaderProgram::createLocal(); newShadowFP->setShaderType(GL_FRAGMENT_SHADER); newShadowFP->setProgram (_pointFPCode ); newShadowFP->addUniformVariable("TSME_matEyeToLight", matEyeToLight); newShadowFP->addUniformVariable("TSME_matLightProj", matLightProj ); newShadowFP->addUniformVariable("TSME_matNT", mfMatNT ); newShadowFP->addUniformVariable("TSME_texShadow", shadowTexUnit); newShadowFP->addUniformVariable("TSME_texShadowSizeInv", Vec2f(1.f / getWidth (), 1.f / getHeight() ) ); this->setShadowFragmentProgram(newShadowFP); shadowFP = newShadowFP; } else { shadowFP->updateUniformVariable("TSME_matEyeToLight", matEyeToLight); shadowFP->updateUniformVariable("TSME_matLightProj", matLightProj ); } const FrustumVolume &eyeFrust = parentPart->getFrustum(); for(UInt16 faceIdx = 0; faceIdx < 6; ++faceIdx) { Matrixr matWorldToLightFace (matWorldToLight ); matWorldToLightFace.multLeft(_matCubeFaceInv[faceIdx]); Matrixr matLightFull(matWorldToLightFace); matLightFull.multLeft(matLightProj); FrustumVolume lightFrust; Matrixr matNT; lightFrust.setPlanes(matLightFull); bool matNTValid = calcTrapezoidalTransform(mfMatNT[faceIdx], matEyeToWorld, matLightFull, eyeFrust, lightFrust ); if(matNTValid == false) { // setup a minimal partition to clear the cube face commitChanges(); this->pushPartition(ract, RenderPartition::CopyNothing, RenderPartition::SimpleCallback); { RenderPartition *part = ract->getActivePartition( ); Window *win = ract->getWindow ( ); FrameBufferObject *target = data->getRenderTargets (faceIdx); Background *back = data->getBackground ( ); part->setSetupMode(RenderPartition::ViewportSetup | RenderPartition::BackgroundSetup ); part->setRenderTarget(target); part->setWindow (win ); part->calcViewportDimension(0.f, 0.f, 1.f, 1.f, target->getWidth (), target->getHeight() ); part->setBackground(back); RenderPartition::SimpleDrawCallback emptyCubeFaceDraw = boost::bind( &TrapezoidalShadowMapEngine::emptyCubeFaceDrawFunc, this, _1); part->dropFunctor(emptyCubeFaceDraw); } this->popPartition(ract); } else { updateLightPassMaterial(data, faceIdx, mfMatNT[faceIdx]); commitChanges(); this->pushPartition(ract); { RenderPartition *part = ract->getActivePartition( ); Window *win = ract->getWindow ( ); FrameBufferObject *target = data->getRenderTargets (faceIdx); Background *back = data->getBackground ( ); part->setRenderTarget(target); part->setWindow (win ); part->calcViewportDimension(0.f, 0.f, 1.f, 1.f, target->getWidth (), target->getHeight() ); part->setupProjection(matLightProj, Matrixr::identity()); part->setupViewing (matWorldToLightFace ); part->setNear (parentPart->getNear()); part->setFar (parentPart->getFar ()); part->setFrustum (lightFrust ); part->setBackground (back ); part->overrideMaterial(data->getLightPassMaterials(faceIdx), ract->getActNode ( ) ); this->recurseFrom(ract, pointL); ract->useNodeList(false ); part->overrideMaterial(NULL, ract->getActNode ( ) ); } this->popPartition(ract); } } shadowFP->updateUniformVariable("TSME_matNT", mfMatNT); }
static inline void setGenFunc( GLenum coord, GLenum gen, GLenum func, const Vec4f &plane, Node *beacon, Matrix &cameraMat, UInt32 eyeMode, Matrix &eyeMatrix) { #ifndef OSG_EMBEDDED if(beacon != NULL) { Matrixr beaconMat; beacon->getToWorld(beaconMat); beaconMat.multLeft(cameraMat); glPushMatrix(); glLoadMatrixf(beaconMat.getValues()); glTexGenfv(coord, GL_EYE_PLANE, const_cast<GLfloat *>(plane.getValues())); glTexGeni(coord, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glPopMatrix(); glEnable(gen); } else if(func == GL_EYE_LINEAR) { glPushMatrix(); switch(eyeMode) { case TexGenChunk::EyeModelViewIdentity: glLoadIdentity(); break; case TexGenChunk::EyeModelViewStored: glLoadMatrixf(eyeMatrix.getValues()); break; case TexGenChunk::EyeModelViewCamera: glLoadMatrixf(cameraMat.getValues()); break; default: break; } glTexGenfv(coord, GL_EYE_PLANE, const_cast<GLfloat *>(plane.getValues())); glTexGeni(coord, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glPopMatrix(); glEnable(gen); } else if(func != GL_NONE) { glTexGeni(coord, GL_TEXTURE_GEN_MODE, func); if(func == GL_OBJECT_LINEAR) { glTexGenfv(coord, GL_OBJECT_PLANE, const_cast<GLfloat *>(plane.getValues())); } glEnable(gen); } #endif }