00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __CS_CSPLUGINCOMMON_RENDERMANAGER_AUTOFX_REFLREFR_H__
00020 #define __CS_CSPLUGINCOMMON_RENDERMANAGER_AUTOFX_REFLREFR_H__
00021
00026 #include "iengine/mesh.h"
00027 #include "imesh/object.h"
00028 #include "imesh/objmodel.h"
00029 #include "csgeom/polyclip.h"
00030
00031 #include "csplugincommon/rendermanager/posteffects.h"
00032 #include "csplugincommon/rendermanager/rendertree.h"
00033 #include "csplugincommon/rendermanager/texturecache.h"
00034
00035 namespace CS
00036 {
00037 namespace RenderManager
00038 {
00039 namespace AutoFX
00040 {
00046 class ReflectRefract_Base
00047 {
00048 public:
00050 enum { svUserFlags = iShader::svuTextures };
00051
00057 struct CS_CRYSTALSPACE_EXPORT PersistentData
00058 {
00059 CS::ShaderVarStringID svTexPlaneRefl;
00060 CS::ShaderVarStringID svTexPlaneRefr;
00061 CS::ShaderVarStringID svTexPlaneReflDepth;
00062 CS::ShaderVarStringID svTexPlaneRefrDepth;
00063
00064 CS::ShaderVarStringID svPlaneRefl;
00065 CS::ShaderVarStringID svClipPlaneReflRefr;
00066
00067 CS::ShaderVarStringID svReflXform;
00068 csRef<csShaderVariable> reflXformSV;
00069 CS::ShaderVarStringID svRefrXform;
00070 csRef<csShaderVariable> refrXformSV;
00071 bool screenFlipped;
00072 float mappingStretch;
00073
00074 uint currentFrame;
00075 uint updatesThisFrame;
00076
00077 TextureCacheT<CS::Utility::ResourceCache::ReuseIfOnlyOneRef> texCache;
00078 TextureCacheT<CS::Utility::ResourceCache::ReuseIfOnlyOneRef> texCacheDepth;
00079 struct ReflectRefractSVs
00080 {
00081 csTicks lastUpdate;
00082 uint lastUpdateFrame;
00083 csTransform lastCamera;
00084
00085 csRef<csShaderVariable> reflectSV;
00086 csRef<csShaderVariable> refractSV;
00087 csRef<csShaderVariable> reflectDepthSV;
00088 csRef<csShaderVariable> refractDepthSV;
00089
00090 csRef<iShaderVariableContext> clipPlaneReflContext;
00091 csRef<csShaderVariable> clipPlaneReflSV;
00092 csRef<iShaderVariableContext> clipPlaneRefrContext;
00093 csRef<csShaderVariable> clipPlaneRefrSV;
00094
00095 ReflectRefractSVs() : lastUpdate (0), lastUpdateFrame (~0) {}
00096 };
00097 typedef csHash<ReflectRefractSVs, csPtrKey<iMeshWrapper> > ReflRefrCache;
00098 ReflRefrCache reflRefrCache;
00099
00100 int resolutionReduceRefl;
00101 int resolutionReduceRefr;
00102 uint texUpdateInterval;
00103 uint maxUpdatesPerFrame;
00104 float cameraChangeThresh;
00105
00106 uint dbgReflRefrTex;
00107
00109 PersistentData();
00110
00118 void Initialize (iObjectRegistry* objReg,
00119 RenderTreeBase::DebugPersistent& dbgPersist,
00120 PostEffectManager* postEffects);
00121
00126 void UpdateNewFrame ();
00127 };
00128
00129 ReflectRefract_Base (PersistentData& persist) : persist (persist)
00130 {}
00131 protected:
00132 PersistentData& persist;
00133 };
00134
00189 template<typename RenderTree,
00190 typename ContextSetupReflect,
00191 typename ContextSetupRefract = ContextSetupReflect>
00192 class ReflectRefract : public ReflectRefract_Base
00193 {
00194 public:
00195 ReflectRefract (PersistentData& persist,
00196 ContextSetupReflect& contextFunction) :
00197 ReflectRefract_Base (persist),
00198 contextFunctionRefl (contextFunction),
00199 contextFunctionRefr (contextFunction)
00200 {}
00201 ReflectRefract (PersistentData& persist,
00202 ContextSetupReflect& contextFunctionRefl,
00203 ContextSetupRefract& contextFunctionRefr) :
00204 ReflectRefract_Base (persist),
00205 contextFunctionRefl (contextFunctionRefl),
00206 contextFunctionRefr (contextFunctionRefr)
00207 {}
00208
00214 void operator() (typename RenderTree::MeshNode* node,
00215 size_t layer,
00216 typename RenderTree::MeshNode::SingleMesh& mesh,
00217 const csBitArray& names)
00218 {
00219
00220 if (!names.IsBitSetTolerant (persist.svTexPlaneRefl)
00221 && !names.IsBitSetTolerant (persist.svTexPlaneRefr))
00222 return;
00223
00224
00225
00226
00227 typename PersistentData::ReflectRefractSVs& meshReflectRefract =
00228 persist.reflRefrCache.GetOrCreate (mesh.meshWrapper);
00229
00230 typename RenderTree::ContextNode& context = node->GetOwner();
00231 RenderTree& renderTree = context.owner;
00232 RenderView* rview = context.renderView;
00233
00234 csShaderVariableStack localStack;
00235 context.svArrays.SetupSVStack (localStack, layer, mesh.contextLocalId);
00236
00237 csTicks currentTicks = csGetTicks ();
00238 bool forceUpdate = (persist.texUpdateInterval == 0)
00239 || ((currentTicks - meshReflectRefract.lastUpdate) >
00240 persist.texUpdateInterval);
00241
00242 forceUpdate &= (persist.maxUpdatesPerFrame == 0)
00243 || (persist.currentFrame - meshReflectRefract.lastUpdateFrame >=
00244 ((persist.reflRefrCache.GetSize()+persist.maxUpdatesPerFrame-1)
00245 / persist.maxUpdatesPerFrame));
00246
00247 forceUpdate &= (persist.maxUpdatesPerFrame == 0)
00248 || (persist.updatesThisFrame < persist.maxUpdatesPerFrame);
00249
00250
00251 iCamera* cam = rview->GetCamera();
00252
00253
00254
00255 if (!forceUpdate && (persist.cameraChangeThresh > 0))
00256 {
00257 const csTransform& camTrans = cam->GetTransform();
00258 float cameraDiff;
00259
00260 cameraDiff = fabsf (camTrans.GetO2T().m11
00261 - meshReflectRefract.lastCamera.GetO2T().m11);
00262 cameraDiff += fabsf (camTrans.GetO2T().m12
00263 - meshReflectRefract.lastCamera.GetO2T().m12);
00264 cameraDiff += fabsf (camTrans.GetO2T().m13
00265 - meshReflectRefract.lastCamera.GetO2T().m13);
00266
00267 cameraDiff += fabsf (camTrans.GetO2T().m21
00268 - meshReflectRefract.lastCamera.GetO2T().m21);
00269 cameraDiff += fabsf (camTrans.GetO2T().m22
00270 - meshReflectRefract.lastCamera.GetO2T().m22);
00271 cameraDiff += fabsf (camTrans.GetO2T().m23
00272 - meshReflectRefract.lastCamera.GetO2T().m23);
00273
00274 cameraDiff += fabsf (camTrans.GetO2T().m31
00275 - meshReflectRefract.lastCamera.GetO2T().m31);
00276 cameraDiff += fabsf (camTrans.GetO2T().m32
00277 - meshReflectRefract.lastCamera.GetO2T().m32);
00278 cameraDiff += fabsf (camTrans.GetO2T().m33
00279 - meshReflectRefract.lastCamera.GetO2T().m33);
00280
00281 cameraDiff += fabsf (camTrans.GetO2TTranslation().x
00282 - meshReflectRefract.lastCamera.GetO2TTranslation().x);
00283 cameraDiff += fabsf (camTrans.GetO2TTranslation().y
00284 - meshReflectRefract.lastCamera.GetO2TTranslation().y);
00285 cameraDiff += fabsf (camTrans.GetO2TTranslation().z
00286 - meshReflectRefract.lastCamera.GetO2TTranslation().z);
00287
00288 forceUpdate = cameraDiff >= persist.cameraChangeThresh;
00289 }
00290
00291
00292 forceUpdate &= (persist.currentFrame != meshReflectRefract.lastUpdateFrame);
00293
00294 bool usesReflTex = names.IsBitSetTolerant (persist.svTexPlaneRefl);
00295 bool usesReflDepthTex = names.IsBitSetTolerant (persist.svTexPlaneReflDepth);
00296 bool needReflTex = (usesReflTex
00297 && (!meshReflectRefract.reflectSV.IsValid() || forceUpdate))
00298 || (usesReflDepthTex
00299 && (!meshReflectRefract.reflectDepthSV.IsValid() || forceUpdate));
00300
00301 bool usesRefrTex = names.IsBitSetTolerant (persist.svTexPlaneRefr);
00302 bool usesRefrDepthTex = names.IsBitSetTolerant (persist.svTexPlaneRefrDepth);
00303 bool needRefrTex = (usesRefrTex
00304 && (!meshReflectRefract.refractSV.IsValid() || forceUpdate))
00305 || (usesRefrDepthTex
00306 && (!meshReflectRefract.refractDepthSV.IsValid() || forceUpdate));
00307
00308 int renderW = 512, renderH = 512;
00309 context.GetTargetDimensions (renderW, renderH);
00310 int txt_w_refl = renderW >> persist.resolutionReduceRefl;
00311 int txt_h_refl = renderH >> persist.resolutionReduceRefl;
00312 int txt_w_refr = renderW >> persist.resolutionReduceRefr;
00313 int txt_h_refr = renderH >> persist.resolutionReduceRefr;
00314
00315
00316 bool doRender = localStack[persist.svClipPlaneReflRefr] == 0;
00317
00318 csPlane3 reflRefrPlane, reflRefrPlane_cam;
00319 csBox2 clipBoxRefl, clipBoxRefr;
00320 if ((needReflTex || needRefrTex) && doRender)
00321 {
00322
00323 if ((localStack.GetSize() > persist.svPlaneRefl)
00324 && (localStack[persist.svPlaneRefl] != 0))
00325 {
00326
00327 csShaderVariable* planeSV = localStack[persist.svPlaneRefl];
00328 csVector4 v;
00329 planeSV->GetValue (v);
00330 reflRefrPlane.Set (v.x, v.y, v.z, v.w);
00331 }
00332 else
00333 {
00334
00335
00336
00337 const csBox3& objBB =
00338 mesh.meshWrapper->GetMeshObject()->GetObjectModel()->GetObjectBoundingBox();
00339 const csVector3& bbSize = objBB.GetSize();
00340
00341 int axis;
00342 if ((bbSize[0] < bbSize[1]) && (bbSize[0] < bbSize[2]))
00343 {
00344 axis = 0;
00345 }
00346 else if (bbSize[1] < bbSize[2])
00347 {
00348 axis = 1;
00349 }
00350 else
00351 {
00352 axis = 2;
00353 }
00354
00355 csVector3 planeNorm (0);
00356 planeNorm[axis] = -1;
00357 reflRefrPlane.Set (planeNorm, 0);
00358 reflRefrPlane.SetOrigin (objBB.GetCenter());
00359 }
00360
00361 reflRefrPlane =
00362 mesh.meshWrapper->GetMovable()->GetFullTransform().This2Other (reflRefrPlane);
00363
00364 reflRefrPlane_cam =
00365 cam->GetTransform().Other2This (reflRefrPlane);
00366 doRender = reflRefrPlane.Classify (cam->GetTransform().GetOrigin()) <= 0;
00367
00368 meshReflectRefract.clipPlaneReflSV.AttachNew (new csShaderVariable (
00369 persist.svClipPlaneReflRefr));
00370 meshReflectRefract.clipPlaneReflSV->SetValue (csVector4 (
00371 -reflRefrPlane.A(),
00372 -reflRefrPlane.B(),
00373 -reflRefrPlane.C(),
00374 -reflRefrPlane.D()));
00375 meshReflectRefract.clipPlaneReflContext.AttachNew (
00376 new csShaderVariableContext);
00377 meshReflectRefract.clipPlaneReflContext->AddVariable (
00378 meshReflectRefract.clipPlaneReflSV);
00379
00380 meshReflectRefract.clipPlaneRefrSV.AttachNew (new csShaderVariable (
00381 persist.svClipPlaneReflRefr));
00382 meshReflectRefract.clipPlaneRefrSV->SetValue (csVector4 (
00383 reflRefrPlane.A(),
00384 reflRefrPlane.B(),
00385 reflRefrPlane.C(),
00386 reflRefrPlane.D()));
00387 meshReflectRefract.clipPlaneRefrContext.AttachNew (
00388 new csShaderVariableContext);
00389 meshReflectRefract.clipPlaneRefrContext->AddVariable (
00390 meshReflectRefract.clipPlaneRefrSV);
00391
00392
00393 {
00394 const csBox3& objBB_world = mesh.meshWrapper->GetWorldBoundingBox();
00395 float min_z, max_z;
00396 objBB_world.ProjectBox (cam->GetTransform(),
00397 cam->GetProjectionMatrix(), clipBoxRefl, min_z, max_z,
00398 txt_w_refl, txt_h_refl);
00399 objBB_world.ProjectBox (cam->GetTransform(),
00400 cam->GetProjectionMatrix(), clipBoxRefr, min_z, max_z,
00401 txt_w_refr, txt_h_refr);
00402 }
00403
00404
00405
00406 if ((persist.mappingStretch > 0)
00407 && ((persist.resolutionReduceRefr > 0)
00408 || (persist.resolutionReduceRefl > 0)))
00409 {
00410
00411
00412
00413
00414 csBox2 dstBox;
00415 int txt_w, txt_h;
00416 if (persist.resolutionReduceRefr > persist.resolutionReduceRefl)
00417 {
00418 dstBox = clipBoxRefr;
00419 txt_w = txt_w_refr;
00420 txt_h = txt_h_refr;
00421 }
00422 else
00423 {
00424 dstBox = clipBoxRefl;
00425 txt_w = txt_w_refl;
00426 txt_h = txt_h_refl;
00427 }
00428
00429 float oldMinY = dstBox.MinY();
00430 dstBox.SetMin (1, txt_h-dstBox.MaxY());
00431 dstBox.SetMax (1, txt_h-oldMinY);
00432 dstBox *= csBox2 (0, 0, txt_w, txt_h);
00433 csBox2 useBox (dstBox.MinX() + persist.mappingStretch,
00434 dstBox.MinY() + persist.mappingStretch,
00435 dstBox.MaxX() - persist.mappingStretch,
00436 dstBox.MaxY() - persist.mappingStretch);
00437 float dw = dstBox.MaxX() - dstBox.MinX();
00438 float dh = dstBox.MaxY() - dstBox.MinY();
00439 float sw = useBox.MaxX() - useBox.MinX();
00440 float sh = useBox.MaxY() - useBox.MinY();
00441 float scaleX = sw/dw;
00442 float scaleY = sh/dh;
00443 float cX1 = useBox.GetCenter().x/(float)txt_w;
00444 float cY1 = useBox.GetCenter().y/(float)txt_h;
00445 float cX2 = dstBox.GetCenter().x/(float)txt_w;
00446 float cY2 = dstBox.GetCenter().y/(float)txt_h;
00447 float dX = (0.5f-cX1)*scaleX + cX2;
00448 float dY = (0.5f-cY1)*scaleY + cY2;
00449
00450 persist.reflXformSV->SetValue (csVector4 (0.5f * scaleX,
00451 (persist.screenFlipped ? 0.5f : -0.5f) * scaleY,
00452 dX, dY));
00453 }
00454 else
00455 {
00456 persist.reflXformSV->SetValue (csVector4 (0.5f,
00457 (persist.screenFlipped ? 0.5f : -0.5f),
00458 0.5f, 0.5f));
00459 }
00460 persist.refrXformSV->SetValue (csVector4 (0.5f,
00461 (persist.screenFlipped ? 0.5f : -0.5f),
00462 0.5f, 0.5f));
00463 }
00464
00465 typename RenderTree::ContextNode* reflCtx = 0;
00466 typename RenderTree::ContextNode* refrCtx = 0;
00467
00468 if (usesReflTex || usesReflDepthTex)
00469 {
00470 csRef<csShaderVariable> svReflection;
00471 csRef<csShaderVariable> svReflectionDepth;
00472
00473 if (needReflTex && doRender)
00474 {
00475
00476 iCamera* cam = rview->GetCamera();
00477
00478 csRef<CS::RenderManager::RenderView> reflView;
00479 csRef<iCamera> newCam (cam->Clone());
00480 iCamera* inewcam = newCam;
00481 reflView = renderTree.GetPersistentData().renderViews.CreateRenderView (rview);
00482 reflView->SetCamera (inewcam);
00483 CS::Utility::MeshFilter meshFilter;
00484 meshFilter.AddFilterMesh (mesh.meshWrapper);
00485 reflView->SetMeshFilter(meshFilter);
00486
00487
00488 csReversibleTransform reflection (csTransform::GetReflect (reflRefrPlane));
00489 csTransform reflection_cam (csTransform::GetReflect (reflRefrPlane_cam));
00490 const csTransform& world2cam (inewcam->GetTransform());
00491 csTransform reflected;
00492 reflected.SetO2T (reflection_cam.GetO2T() * world2cam.GetO2T());
00493 reflected.SetOrigin (reflection.Other2This (world2cam.GetOrigin()));
00494 inewcam->SetTransform (reflected);
00495 inewcam->SetMirrored (true);
00496
00497 csPlane3 reflRefrPlane_newcam;
00498 reflRefrPlane_newcam = reflected.Other2This (reflRefrPlane);
00499 reflView->SetClipPlane (reflRefrPlane_newcam);
00500
00501 csRef<iTextureHandle> tex;
00502 csRef<iTextureHandle> texDepth;
00503 if (usesReflTex)
00504 {
00505 tex =
00506 persist.texCache.QueryUnusedTexture (txt_w_refl, txt_h_refl);
00507 }
00508 if (usesReflDepthTex)
00509 {
00510 texDepth =
00511 persist.texCacheDepth.QueryUnusedTexture (txt_w_refl, txt_h_refl);
00512 }
00513
00514
00515 reflView->SetViewDimensions (txt_w_refl, txt_h_refl);
00516 csRef<iClipper2D> newView;
00517 newView.AttachNew (new csBoxClipper (clipBoxRefl));
00518 reflView->SetClipper (newView);
00519
00520 reflCtx = renderTree.CreateContext (reflView);
00521 reflCtx->renderTargets[rtaColor0].texHandle = tex;
00522 reflCtx->renderTargets[rtaDepth].texHandle = texDepth;
00523 reflCtx->drawFlags = CSDRAW_CLEARSCREEN | CSDRAW_CLEARZBUFFER
00524 | CSDRAW_NOCLIPCLEAR;
00525 reflCtx->shadervars = meshReflectRefract.clipPlaneReflContext;
00526
00527 if (meshReflectRefract.reflectSV)
00528 {
00529 svReflection = meshReflectRefract.reflectSV;
00530 }
00531 else
00532 {
00533 svReflection.AttachNew (new csShaderVariable (
00534 persist.svTexPlaneRefl));
00535 meshReflectRefract.reflectSV = svReflection;
00536 }
00537 svReflection->SetValue (tex);
00538
00539 if (meshReflectRefract.reflectDepthSV)
00540 {
00541 svReflectionDepth = meshReflectRefract.reflectDepthSV;
00542 }
00543 else
00544 {
00545 svReflectionDepth.AttachNew (new csShaderVariable (
00546 persist.svTexPlaneReflDepth));
00547 meshReflectRefract.reflectDepthSV = svReflectionDepth;
00548 }
00549 svReflectionDepth->SetValue (texDepth);
00550
00551 if (renderTree.IsDebugFlagEnabled (persist.dbgReflRefrTex))
00552 {
00553 float dbgAspect = (float)txt_w_refl/(float)txt_h_refl;
00554 renderTree.AddDebugTexture (tex, dbgAspect);
00555 renderTree.AddDebugTexture (texDepth, dbgAspect);
00556 }
00557 }
00558 else
00559 {
00560 svReflection = meshReflectRefract.reflectSV;
00561 svReflectionDepth = meshReflectRefract.reflectDepthSV;
00562
00563 if (renderTree.IsDebugFlagEnabled (persist.dbgReflRefrTex)
00564 && doRender)
00565 {
00566 float dbgAspect = (float)txt_w_refl/(float)txt_h_refl;
00567 iTextureHandle* texh = 0;
00568 if (svReflection.IsValid()) svReflection->GetValue (texh);
00569 renderTree.AddDebugTexture (texh, dbgAspect);
00570 texh = 0;
00571 if (svReflectionDepth.IsValid()) svReflectionDepth->GetValue (texh);
00572 renderTree.AddDebugTexture (texh, dbgAspect);
00573 }
00574 }
00575
00576
00577 localStack[persist.svTexPlaneRefl] = svReflection;
00578 localStack[persist.svTexPlaneReflDepth] = svReflectionDepth;
00579 localStack[persist.svReflXform] = persist.reflXformSV;
00580 }
00581
00582 if (usesRefrTex || usesRefrDepthTex)
00583 {
00584 csRef<csShaderVariable> svRefraction;
00585 csRef<csShaderVariable> svRefractionDepth;
00586
00587 if (needRefrTex && doRender)
00588 {
00589
00590
00591
00592 csRef<CS::RenderManager::RenderView> refrView;
00593
00594 refrView = renderTree.GetPersistentData().renderViews.CreateRenderView (rview, true);
00595
00596 csRef<iTextureHandle> tex;
00597 csRef<iTextureHandle> texDepth;
00598 if (usesRefrTex)
00599 {
00600 tex =
00601 persist.texCache.QueryUnusedTexture (txt_w_refr, txt_h_refr);
00602 }
00603 if (usesRefrDepthTex)
00604 {
00605 texDepth =
00606 persist.texCacheDepth.QueryUnusedTexture (txt_w_refr, txt_h_refr);
00607 }
00608
00609
00610 refrView->SetViewDimensions (txt_w_refr, txt_h_refr);
00611 csRef<iClipper2D> newView;
00612 newView.AttachNew (new csBoxClipper (clipBoxRefr));
00613 refrView->SetClipper (newView);
00614 CS::Utility::MeshFilter meshFilter;
00615 meshFilter.AddFilterMesh (mesh.meshWrapper);
00616 refrView->SetMeshFilter(meshFilter);
00617 refrView->SetClipPlane (reflRefrPlane_cam.Inverse ());
00618
00619 refrCtx = renderTree.CreateContext (refrView);
00620 refrCtx->renderTargets[rtaColor0].texHandle = tex;
00621 refrCtx->renderTargets[rtaDepth].texHandle = texDepth;
00622 refrCtx->drawFlags = CSDRAW_CLEARSCREEN | CSDRAW_CLEARZBUFFER
00623 | CSDRAW_NOCLIPCLEAR;
00624 refrCtx->shadervars = meshReflectRefract.clipPlaneRefrContext;
00625
00626
00627 if (meshReflectRefract.refractSV)
00628 {
00629 svRefraction = meshReflectRefract.refractSV;
00630 }
00631 else
00632 {
00633 svRefraction.AttachNew (new csShaderVariable (
00634 persist.svTexPlaneRefr));
00635 meshReflectRefract.refractSV = svRefraction;
00636 }
00637 svRefraction->SetValue (tex);
00638
00639 if (meshReflectRefract.refractDepthSV)
00640 {
00641 svRefractionDepth = meshReflectRefract.refractDepthSV;
00642 }
00643 else
00644 {
00645 svRefractionDepth.AttachNew (new csShaderVariable (
00646 persist.svTexPlaneRefrDepth));
00647 meshReflectRefract.refractDepthSV = svRefractionDepth;
00648 }
00649 svRefractionDepth->SetValue (texDepth);
00650
00651 if (renderTree.IsDebugFlagEnabled (persist.dbgReflRefrTex))
00652 {
00653 float dbgAspect = (float)txt_w_refr/(float)txt_h_refr;
00654 renderTree.AddDebugTexture (tex, dbgAspect);
00655 renderTree.AddDebugTexture (texDepth, dbgAspect);
00656 }
00657 }
00658 else
00659 {
00660 svRefraction = meshReflectRefract.refractSV;
00661 svRefractionDepth = meshReflectRefract.refractDepthSV;
00662
00663 if (renderTree.IsDebugFlagEnabled (persist.dbgReflRefrTex)
00664 && doRender)
00665 {
00666 float dbgAspect = (float)txt_w_refl/(float)txt_h_refl;
00667 iTextureHandle* texh = 0;
00668 if (svRefraction.IsValid()) svRefraction->GetValue (texh);
00669 renderTree.AddDebugTexture (texh, dbgAspect);
00670 texh = 0;
00671 if (svRefractionDepth.IsValid()) svRefractionDepth->GetValue (texh);
00672 renderTree.AddDebugTexture (texh, dbgAspect);
00673 }
00674 }
00675
00676
00677 localStack[persist.svTexPlaneRefr] = svRefraction;
00678 localStack[persist.svTexPlaneRefrDepth] = svRefractionDepth;
00679 localStack[persist.svRefrXform] = persist.refrXformSV;
00680 }
00681 if ((needReflTex || needRefrTex) && doRender)
00682 {
00683 meshReflectRefract.lastUpdate = currentTicks;
00684 meshReflectRefract.lastUpdateFrame = persist.currentFrame;
00685 meshReflectRefract.lastCamera = cam->GetTransform();
00686 persist.updatesThisFrame++;
00687 }
00688
00689
00690 if (reflCtx) contextFunctionRefl (*reflCtx);
00691 if (refrCtx) contextFunctionRefr (*refrCtx);
00692 }
00693 protected:
00694 ContextSetupReflect& contextFunctionRefl;
00695 ContextSetupRefract& contextFunctionRefr;
00696 };
00697
00698 }
00699 }
00700 }
00701
00702 #endif // __CS_CSPLUGINCOMMON_RENDERMANAGER_AUTOFX_REFLREFR_H__