csplugincommon/rendermanager/autofx_reflrefr.h
Go to the documentation of this file.00001 /* 00002 Copyright (C) 2008 by Frank Richter 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public 00015 License along with this library; if not, write to the Free 00016 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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/cameracache.h" 00032 #include "csplugincommon/rendermanager/posteffects.h" 00033 #include "csplugincommon/rendermanager/rendertree.h" 00034 #include "csplugincommon/rendermanager/texturecache.h" 00035 00036 namespace CS 00037 { 00038 namespace RenderManager 00039 { 00040 namespace AutoFX 00041 { 00047 class ReflectRefract_Base 00048 { 00049 public: 00051 enum { svUserFlags = iShader::svuTextures }; 00052 00058 struct CS_CRYSTALSPACE_EXPORT PersistentData 00059 { 00060 CS::ShaderVarStringID svTexPlaneRefl; 00061 CS::ShaderVarStringID svTexPlaneRefr; 00062 CS::ShaderVarStringID svTexPlaneReflDepth; 00063 CS::ShaderVarStringID svTexPlaneRefrDepth; 00064 00065 CS::ShaderVarStringID svPlaneRefl; 00066 CS::ShaderVarStringID svClipPlaneReflRefr; 00067 00068 CS::ShaderVarStringID svReflXform; 00069 csRef<csShaderVariable> reflXformSV; 00070 CS::ShaderVarStringID svRefrXform; 00071 csRef<csShaderVariable> refrXformSV; 00072 bool screenFlipped; 00073 float mappingStretch; 00074 00075 uint currentFrame; 00076 uint updatesThisFrame; 00077 00078 TextureCacheT<CS::Utility::ResourceCache::ReuseIfOnlyOneRef> texCache; 00079 TextureCacheT<CS::Utility::ResourceCache::ReuseIfOnlyOneRef> texCacheDepth; 00080 struct ReflectRefractSVs 00081 { 00082 csTicks lastUpdate; 00083 uint lastUpdateFrame; 00084 csTransform lastCamera; 00085 00086 csRef<csShaderVariable> reflectSV; 00087 csRef<csShaderVariable> refractSV; 00088 csRef<csShaderVariable> reflectDepthSV; 00089 csRef<csShaderVariable> refractDepthSV; 00090 00091 csRef<iShaderVariableContext> clipPlaneReflContext; 00092 csRef<csShaderVariable> clipPlaneReflSV; 00093 csRef<iShaderVariableContext> clipPlaneRefrContext; 00094 csRef<csShaderVariable> clipPlaneRefrSV; 00095 00096 ReflectRefractSVs() : lastUpdate (0), lastUpdateFrame (~0) {} 00097 }; 00098 typedef csHash<ReflectRefractSVs, csPtrKey<iMeshWrapper> > ReflRefrCache; 00099 ReflRefrCache reflRefrCache; 00101 CameraCache reflectionCams; 00102 00103 int resolutionReduceRefl; 00104 int resolutionReduceRefr; 00105 uint texUpdateInterval; 00106 uint maxUpdatesPerFrame; 00107 float cameraChangeThresh; 00108 00109 uint dbgReflRefrTex; 00110 00112 PersistentData(); 00113 00121 void Initialize (iObjectRegistry* objReg, 00122 RenderTreeBase::DebugPersistent& dbgPersist, 00123 PostEffectManager* postEffects); 00124 00129 void UpdateNewFrame (); 00130 }; 00131 00132 ReflectRefract_Base (PersistentData& persist) : persist (persist) 00133 {} 00134 protected: 00135 PersistentData& persist; 00136 }; 00137 00192 template<typename RenderTree, 00193 typename ContextSetupReflect, 00194 typename ContextSetupRefract = ContextSetupReflect> 00195 class ReflectRefract : public ReflectRefract_Base 00196 { 00197 public: 00198 ReflectRefract (PersistentData& persist, 00199 ContextSetupReflect& contextFunction) : 00200 ReflectRefract_Base (persist), 00201 contextFunctionRefl (contextFunction), 00202 contextFunctionRefr (contextFunction) 00203 {} 00204 ReflectRefract (PersistentData& persist, 00205 ContextSetupReflect& contextFunctionRefl, 00206 ContextSetupRefract& contextFunctionRefr) : 00207 ReflectRefract_Base (persist), 00208 contextFunctionRefl (contextFunctionRefl), 00209 contextFunctionRefr (contextFunctionRefr) 00210 {} 00211 00217 void operator() (typename RenderTree::MeshNode* node, 00218 size_t layer, 00219 typename RenderTree::MeshNode::SingleMesh& mesh, 00220 const csBitArray& names) 00221 { 00222 // Check if reflection or refraction is needed 00223 if (!names.IsBitSetTolerant (persist.svTexPlaneRefl) 00224 && !names.IsBitSetTolerant (persist.svTexPlaneRefr)) 00225 return; 00226 00227 /* @@@ NOTE:The same mesh, if rendered in multiple views, will get 00228 the same reflection/refraction texture. This is wrong. 00229 However, ignore for now, until someone complains */ 00230 typename PersistentData::ReflectRefractSVs& meshReflectRefract = 00231 persist.reflRefrCache.GetOrCreate (mesh.meshWrapper); 00232 00233 typename RenderTree::ContextNode& context = node->GetOwner(); 00234 RenderTree& renderTree = context.owner; 00235 RenderView* rview = context.renderView; 00236 00237 csShaderVariableStack localStack; 00238 context.svArrays.SetupSVStack (localStack, layer, mesh.contextLocalId); 00239 00240 csTicks currentTicks = csGetTicks (); 00241 bool forceUpdate = (persist.texUpdateInterval == 0) 00242 || ((currentTicks - meshReflectRefract.lastUpdate) > 00243 persist.texUpdateInterval); 00244 00245 forceUpdate &= (persist.maxUpdatesPerFrame == 0) 00246 || (persist.currentFrame - meshReflectRefract.lastUpdateFrame >= 00247 ((persist.reflRefrCache.GetSize()+persist.maxUpdatesPerFrame-1) 00248 / persist.maxUpdatesPerFrame)); 00249 00250 forceUpdate &= (persist.maxUpdatesPerFrame == 0) 00251 || (persist.updatesThisFrame < persist.maxUpdatesPerFrame); 00252 00253 00254 iCamera* cam = rview->GetCamera(); 00255 /* Compute a difference for the camera between the last render; 00256 if bigger than a certain threshold, rerender (whether it's the 00257 reflections's turn or not) */ 00258 if (!forceUpdate && (persist.cameraChangeThresh > 0)) 00259 { 00260 const csTransform& camTrans = cam->GetTransform(); 00261 float cameraDiff; 00262 00263 cameraDiff = fabsf (camTrans.GetO2T().m11 00264 - meshReflectRefract.lastCamera.GetO2T().m11); 00265 cameraDiff += fabsf (camTrans.GetO2T().m12 00266 - meshReflectRefract.lastCamera.GetO2T().m12); 00267 cameraDiff += fabsf (camTrans.GetO2T().m13 00268 - meshReflectRefract.lastCamera.GetO2T().m13); 00269 00270 cameraDiff += fabsf (camTrans.GetO2T().m21 00271 - meshReflectRefract.lastCamera.GetO2T().m21); 00272 cameraDiff += fabsf (camTrans.GetO2T().m22 00273 - meshReflectRefract.lastCamera.GetO2T().m22); 00274 cameraDiff += fabsf (camTrans.GetO2T().m23 00275 - meshReflectRefract.lastCamera.GetO2T().m23); 00276 00277 cameraDiff += fabsf (camTrans.GetO2T().m31 00278 - meshReflectRefract.lastCamera.GetO2T().m31); 00279 cameraDiff += fabsf (camTrans.GetO2T().m32 00280 - meshReflectRefract.lastCamera.GetO2T().m32); 00281 cameraDiff += fabsf (camTrans.GetO2T().m33 00282 - meshReflectRefract.lastCamera.GetO2T().m33); 00283 00284 cameraDiff += fabsf (camTrans.GetO2TTranslation().x 00285 - meshReflectRefract.lastCamera.GetO2TTranslation().x); 00286 cameraDiff += fabsf (camTrans.GetO2TTranslation().y 00287 - meshReflectRefract.lastCamera.GetO2TTranslation().y); 00288 cameraDiff += fabsf (camTrans.GetO2TTranslation().z 00289 - meshReflectRefract.lastCamera.GetO2TTranslation().z); 00290 00291 forceUpdate = cameraDiff >= persist.cameraChangeThresh; 00292 } 00293 00294 // But never force an update if we already rendered in this frame 00295 forceUpdate &= (persist.currentFrame != meshReflectRefract.lastUpdateFrame); 00296 00297 bool usesReflTex = names.IsBitSetTolerant (persist.svTexPlaneRefl); 00298 bool usesReflDepthTex = names.IsBitSetTolerant (persist.svTexPlaneReflDepth); 00299 bool needReflTex = (usesReflTex 00300 && (!meshReflectRefract.reflectSV.IsValid() || forceUpdate)) 00301 || (usesReflDepthTex 00302 && (!meshReflectRefract.reflectDepthSV.IsValid() || forceUpdate)); 00303 00304 bool usesRefrTex = names.IsBitSetTolerant (persist.svTexPlaneRefr); 00305 bool usesRefrDepthTex = names.IsBitSetTolerant (persist.svTexPlaneRefrDepth); 00306 bool needRefrTex = (usesRefrTex 00307 && (!meshReflectRefract.refractSV.IsValid() || forceUpdate)) 00308 || (usesRefrDepthTex 00309 && (!meshReflectRefract.refractDepthSV.IsValid() || forceUpdate)); 00310 00311 int renderW = 512, renderH = 512; 00312 context.GetTargetDimensions (renderW, renderH); 00313 int txt_w_refl = renderW >> persist.resolutionReduceRefl; 00314 int txt_h_refl = renderH >> persist.resolutionReduceRefl; 00315 int txt_w_refr = renderW >> persist.resolutionReduceRefr; 00316 int txt_h_refr = renderH >> persist.resolutionReduceRefr; 00317 00318 // @@@ Kludge: don't render nested reflections 00319 bool doRender = localStack[persist.svClipPlaneReflRefr] == 0; 00320 00321 csPlane3 reflRefrPlane, reflRefrPlane_cam; 00322 csBox2 clipBoxRefl, clipBoxRefr; 00323 if ((needReflTex || needRefrTex) && doRender) 00324 { 00325 // Compute reflect/refract plane 00326 if ((localStack.GetSize() > persist.svPlaneRefl) 00327 && (localStack[persist.svPlaneRefl] != 0)) 00328 { 00329 // Grab reflection plane from a SV 00330 csShaderVariable* planeSV = localStack[persist.svPlaneRefl]; 00331 csVector4 v; 00332 planeSV->GetValue (v); 00333 reflRefrPlane.Set (v.x, v.y, v.z, v.w); 00334 } 00335 else 00336 { 00337 /* Guess reflection plane from mesh bbox: 00338 Take smallest dimension of object space bounding box, make that 00339 the direction of reflect plane */ 00340 const csBox3& objBB = 00341 mesh.meshWrapper->GetMeshObject()->GetObjectModel()->GetObjectBoundingBox(); 00342 const csVector3& bbSize = objBB.GetSize(); 00343 00344 int axis; 00345 if ((bbSize[0] < bbSize[1]) && (bbSize[0] < bbSize[2])) 00346 { 00347 axis = 0; 00348 } 00349 else if (bbSize[1] < bbSize[2]) 00350 { 00351 axis = 1; 00352 } 00353 else 00354 { 00355 axis = 2; 00356 } 00357 00358 csVector3 planeNorm (0); 00359 planeNorm[axis] = -1; 00360 reflRefrPlane.Set (planeNorm, 0); 00361 reflRefrPlane.SetOrigin (objBB.GetCenter()); 00362 } 00363 00364 reflRefrPlane = 00365 mesh.meshWrapper->GetMovable()->GetFullTransform().This2Other (reflRefrPlane); 00366 00367 reflRefrPlane_cam = 00368 cam->GetTransform().Other2This (reflRefrPlane); 00369 doRender = reflRefrPlane.Classify (cam->GetTransform().GetOrigin()) <= 0; 00370 00371 meshReflectRefract.clipPlaneReflSV.AttachNew (new csShaderVariable ( 00372 persist.svClipPlaneReflRefr)); 00373 meshReflectRefract.clipPlaneReflSV->SetValue (csVector4 ( 00374 -reflRefrPlane.A(), 00375 -reflRefrPlane.B(), 00376 -reflRefrPlane.C(), 00377 -reflRefrPlane.D())); 00378 meshReflectRefract.clipPlaneReflContext.AttachNew ( 00379 new csShaderVariableContext); 00380 meshReflectRefract.clipPlaneReflContext->AddVariable ( 00381 meshReflectRefract.clipPlaneReflSV); 00382 00383 meshReflectRefract.clipPlaneRefrSV.AttachNew (new csShaderVariable ( 00384 persist.svClipPlaneReflRefr)); 00385 meshReflectRefract.clipPlaneRefrSV->SetValue (csVector4 ( 00386 reflRefrPlane.A(), 00387 reflRefrPlane.B(), 00388 reflRefrPlane.C(), 00389 reflRefrPlane.D())); 00390 meshReflectRefract.clipPlaneRefrContext.AttachNew ( 00391 new csShaderVariableContext); 00392 meshReflectRefract.clipPlaneRefrContext->AddVariable ( 00393 meshReflectRefract.clipPlaneRefrSV); 00394 00395 // Compute screen space bounding box 00396 { 00397 const csBox3& objBB_world = mesh.meshWrapper->GetWorldBoundingBox(); 00398 float min_z, max_z; 00399 objBB_world.ProjectBox (cam->GetTransform(), 00400 cam->GetProjectionMatrix(), clipBoxRefl, min_z, max_z, 00401 txt_w_refl, txt_h_refl); 00402 objBB_world.ProjectBox (cam->GetTransform(), 00403 cam->GetProjectionMatrix(), clipBoxRefr, min_z, max_z, 00404 txt_w_refr, txt_h_refr); 00405 } 00406 00407 /* To reduce bleeding from filtering, fuzz the reflection mapping to 00408 be actually stretched out a pixel at the corners */ 00409 if ((persist.mappingStretch > 0) 00410 && ((persist.resolutionReduceRefr > 0) 00411 || (persist.resolutionReduceRefl > 0))) 00412 { 00413 /* Since reflection + refraction share the same TC transform, 00414 compute the 'fuzz' from the smaller one. This can lead to 00415 distortions when the resolutions differ a lot ... but hopefully 00416 doesn't happen often */ 00417 csBox2 dstBox; 00418 int txt_w, txt_h; 00419 if (persist.resolutionReduceRefr > persist.resolutionReduceRefl) 00420 { 00421 dstBox = clipBoxRefr; 00422 txt_w = txt_w_refr; 00423 txt_h = txt_h_refr; 00424 } 00425 else 00426 { 00427 dstBox = clipBoxRefl; 00428 txt_w = txt_w_refl; 00429 txt_h = txt_h_refl; 00430 } 00431 00432 float oldMinY = dstBox.MinY(); 00433 dstBox.SetMin (1, txt_h-dstBox.MaxY()); 00434 dstBox.SetMax (1, txt_h-oldMinY); 00435 dstBox *= csBox2 (0, 0, txt_w, txt_h); 00436 csBox2 useBox (dstBox.MinX() + persist.mappingStretch, 00437 dstBox.MinY() + persist.mappingStretch, 00438 dstBox.MaxX() - persist.mappingStretch, 00439 dstBox.MaxY() - persist.mappingStretch); 00440 float dw = dstBox.MaxX() - dstBox.MinX(); 00441 float dh = dstBox.MaxY() - dstBox.MinY(); 00442 float sw = useBox.MaxX() - useBox.MinX(); 00443 float sh = useBox.MaxY() - useBox.MinY(); 00444 float scaleX = sw/dw; 00445 float scaleY = sh/dh; 00446 float cX1 = useBox.GetCenter().x/(float)txt_w; 00447 float cY1 = useBox.GetCenter().y/(float)txt_h; 00448 float cX2 = dstBox.GetCenter().x/(float)txt_w; 00449 float cY2 = dstBox.GetCenter().y/(float)txt_h; 00450 float dX = (0.5f-cX1)*scaleX + cX2; 00451 float dY = (0.5f-cY1)*scaleY + cY2; 00452 00453 persist.reflXformSV->SetValue (csVector4 (0.5f * scaleX, 00454 (persist.screenFlipped ? 0.5f : -0.5f) * scaleY, 00455 dX, dY)); 00456 } 00457 else 00458 { 00459 persist.reflXformSV->SetValue (csVector4 (0.5f, 00460 (persist.screenFlipped ? 0.5f : -0.5f), 00461 0.5f, 0.5f)); 00462 } 00463 persist.refrXformSV->SetValue (csVector4 (0.5f, 00464 (persist.screenFlipped ? 0.5f : -0.5f), 00465 0.5f, 0.5f)); 00466 } 00467 00468 typename RenderTree::ContextNode* reflCtx = 0; 00469 typename RenderTree::ContextNode* refrCtx = 0; 00470 00471 if (usesReflTex || usesReflDepthTex) 00472 { 00473 csRef<csShaderVariable> svReflection; 00474 csRef<csShaderVariable> svReflectionDepth; 00475 00476 if (needReflTex && doRender) 00477 { 00478 // Compute reflection view 00479 iCamera* cam = rview->GetCamera(); 00480 // Create a new view 00481 csRef<CS::RenderManager::RenderView> reflView; 00482 csRef<iCamera> newCam (persist.reflectionCams.GetClone (cam, 00483 CameraCache::syncSector | CameraCache::syncFarPlane 00484 | CameraCache::syncProjection)); 00485 iCamera* inewcam = newCam; 00486 /* 'Keeping' the camera prevents a clone to be made, which we'd immediately replace 00487 * anyway */ 00488 reflView = renderTree.GetPersistentData().renderViews.CreateRenderView (rview, true); 00489 reflView->SetCamera (inewcam); 00490 reflView->SetOriginalCamera (rview->GetOriginalCamera ()); 00491 CS::Utility::MeshFilter meshFilter; 00492 meshFilter.AddFilterMesh (mesh.meshWrapper); 00493 reflView->SetMeshFilter(meshFilter); 00494 00495 // Change the camera transform to be a reflection across reflRefrPlane 00496 csReversibleTransform reflection (csTransform::GetReflect (reflRefrPlane)); 00497 csTransform reflection_cam (csTransform::GetReflect (reflRefrPlane_cam)); 00498 const csTransform& world2cam (cam->GetTransform()); 00499 csTransform reflected; 00500 reflected.SetO2T (reflection_cam.GetO2T() * world2cam.GetO2T()); 00501 reflected.SetOrigin (reflection.Other2This (world2cam.GetOrigin())); 00502 inewcam->SetTransform (reflected); 00503 inewcam->SetMirrored (true); 00504 00505 csPlane3 reflRefrPlane_newcam; 00506 reflRefrPlane_newcam = reflected.Other2This (reflRefrPlane); 00507 reflView->SetClipPlane (reflRefrPlane_newcam); 00508 00509 csRef<iTextureHandle> tex; 00510 csRef<iTextureHandle> texDepth; 00511 if (usesReflTex) 00512 { 00513 tex = 00514 persist.texCache.QueryUnusedTexture (txt_w_refl, txt_h_refl); 00515 } 00516 if (usesReflDepthTex) 00517 { 00518 texDepth = 00519 persist.texCacheDepth.QueryUnusedTexture (txt_w_refl, txt_h_refl); 00520 } 00521 00522 // Set up context for reflection, clipped to plane 00523 reflView->SetViewDimensions (txt_w_refl, txt_h_refl); 00524 csRef<iClipper2D> newView; 00525 newView.AttachNew (new csBoxClipper (clipBoxRefl)); 00526 reflView->SetClipper (newView); 00527 00528 reflCtx = renderTree.CreateContext (reflView); 00529 reflCtx->renderTargets[rtaColor0].texHandle = tex; 00530 reflCtx->renderTargets[rtaDepth].texHandle = texDepth; 00531 reflCtx->drawFlags = CSDRAW_CLEARSCREEN | CSDRAW_CLEARZBUFFER 00532 | CSDRAW_NOCLIPCLEAR; 00533 reflCtx->shadervars = meshReflectRefract.clipPlaneReflContext; 00534 00535 if (meshReflectRefract.reflectSV) 00536 { 00537 svReflection = meshReflectRefract.reflectSV; 00538 } 00539 else 00540 { 00541 svReflection.AttachNew (new csShaderVariable ( 00542 persist.svTexPlaneRefl)); 00543 meshReflectRefract.reflectSV = svReflection; 00544 } 00545 svReflection->SetValue (tex); 00546 00547 if (meshReflectRefract.reflectDepthSV) 00548 { 00549 svReflectionDepth = meshReflectRefract.reflectDepthSV; 00550 } 00551 else 00552 { 00553 svReflectionDepth.AttachNew (new csShaderVariable ( 00554 persist.svTexPlaneReflDepth)); 00555 meshReflectRefract.reflectDepthSV = svReflectionDepth; 00556 } 00557 svReflectionDepth->SetValue (texDepth); 00558 00559 if (renderTree.IsDebugFlagEnabled (persist.dbgReflRefrTex)) 00560 { 00561 float dbgAspect = (float)txt_w_refl/(float)txt_h_refl; 00562 renderTree.AddDebugTexture (tex, dbgAspect); 00563 renderTree.AddDebugTexture (texDepth, dbgAspect); 00564 } 00565 } 00566 else 00567 { 00568 svReflection = meshReflectRefract.reflectSV; 00569 svReflectionDepth = meshReflectRefract.reflectDepthSV; 00570 00571 if (renderTree.IsDebugFlagEnabled (persist.dbgReflRefrTex) 00572 && doRender) 00573 { 00574 float dbgAspect = (float)txt_w_refl/(float)txt_h_refl; 00575 iTextureHandle* texh = 0; 00576 if (svReflection.IsValid()) svReflection->GetValue (texh); 00577 renderTree.AddDebugTexture (texh, dbgAspect); 00578 texh = 0; 00579 if (svReflectionDepth.IsValid()) svReflectionDepth->GetValue (texh); 00580 renderTree.AddDebugTexture (texh, dbgAspect); 00581 } 00582 } 00583 00584 // Attach reflection texture to mesh 00585 localStack[persist.svTexPlaneRefl] = svReflection; 00586 localStack[persist.svTexPlaneReflDepth] = svReflectionDepth; 00587 localStack[persist.svReflXform] = persist.reflXformSV; 00588 } 00589 00590 if (usesRefrTex || usesRefrDepthTex) 00591 { 00592 csRef<csShaderVariable> svRefraction; 00593 csRef<csShaderVariable> svRefractionDepth; 00594 00595 if (needRefrTex && doRender) 00596 { 00597 // Set up context for refraction, clipped to plane 00598 00599 // Create a new view 00600 csRef<CS::RenderManager::RenderView> refrView; 00601 /* Keep old camera to allow shadow map caching */ 00602 refrView = renderTree.GetPersistentData().renderViews.CreateRenderView (rview, true); 00603 00604 csRef<iTextureHandle> tex; 00605 csRef<iTextureHandle> texDepth; 00606 if (usesRefrTex) 00607 { 00608 tex = 00609 persist.texCache.QueryUnusedTexture (txt_w_refr, txt_h_refr); 00610 } 00611 if (usesRefrDepthTex) 00612 { 00613 texDepth = 00614 persist.texCacheDepth.QueryUnusedTexture (txt_w_refr, txt_h_refr); 00615 } 00616 00617 // Set up context for reflection, clipped to plane 00618 refrView->SetViewDimensions (txt_w_refr, txt_h_refr); 00619 csRef<iClipper2D> newView; 00620 newView.AttachNew (new csBoxClipper (clipBoxRefr)); 00621 refrView->SetClipper (newView); 00622 CS::Utility::MeshFilter meshFilter; 00623 meshFilter.AddFilterMesh (mesh.meshWrapper); 00624 refrView->SetMeshFilter(meshFilter); 00625 refrView->SetClipPlane (reflRefrPlane_cam.Inverse ()); 00626 00627 refrCtx = renderTree.CreateContext (refrView); 00628 refrCtx->renderTargets[rtaColor0].texHandle = tex; 00629 refrCtx->renderTargets[rtaDepth].texHandle = texDepth; 00630 refrCtx->drawFlags = CSDRAW_CLEARSCREEN | CSDRAW_CLEARZBUFFER 00631 | CSDRAW_NOCLIPCLEAR; 00632 refrCtx->shadervars = meshReflectRefract.clipPlaneRefrContext; 00633 00634 // Attach refraction texture to mesh 00635 if (meshReflectRefract.refractSV) 00636 { 00637 svRefraction = meshReflectRefract.refractSV; 00638 } 00639 else 00640 { 00641 svRefraction.AttachNew (new csShaderVariable ( 00642 persist.svTexPlaneRefr)); 00643 meshReflectRefract.refractSV = svRefraction; 00644 } 00645 svRefraction->SetValue (tex); 00646 00647 if (meshReflectRefract.refractDepthSV) 00648 { 00649 svRefractionDepth = meshReflectRefract.refractDepthSV; 00650 } 00651 else 00652 { 00653 svRefractionDepth.AttachNew (new csShaderVariable ( 00654 persist.svTexPlaneRefrDepth)); 00655 meshReflectRefract.refractDepthSV = svRefractionDepth; 00656 } 00657 svRefractionDepth->SetValue (texDepth); 00658 00659 if (renderTree.IsDebugFlagEnabled (persist.dbgReflRefrTex)) 00660 { 00661 float dbgAspect = (float)txt_w_refr/(float)txt_h_refr; 00662 renderTree.AddDebugTexture (tex, dbgAspect); 00663 renderTree.AddDebugTexture (texDepth, dbgAspect); 00664 } 00665 } 00666 else 00667 { 00668 svRefraction = meshReflectRefract.refractSV; 00669 svRefractionDepth = meshReflectRefract.refractDepthSV; 00670 00671 if (renderTree.IsDebugFlagEnabled (persist.dbgReflRefrTex) 00672 && doRender) 00673 { 00674 float dbgAspect = (float)txt_w_refl/(float)txt_h_refl; 00675 iTextureHandle* texh = 0; 00676 if (svRefraction.IsValid()) svRefraction->GetValue (texh); 00677 renderTree.AddDebugTexture (texh, dbgAspect); 00678 texh = 0; 00679 if (svRefractionDepth.IsValid()) svRefractionDepth->GetValue (texh); 00680 renderTree.AddDebugTexture (texh, dbgAspect); 00681 } 00682 } 00683 00684 // Attach refraction texture to mesh 00685 localStack[persist.svTexPlaneRefr] = svRefraction; 00686 localStack[persist.svTexPlaneRefrDepth] = svRefractionDepth; 00687 localStack[persist.svRefrXform] = persist.refrXformSV; 00688 } 00689 if ((needReflTex || needRefrTex) && doRender) 00690 { 00691 meshReflectRefract.lastUpdate = currentTicks; 00692 meshReflectRefract.lastUpdateFrame = persist.currentFrame; 00693 meshReflectRefract.lastCamera = cam->GetTransform(); 00694 persist.updatesThisFrame++; 00695 } 00696 00697 // Setup the new contexts 00698 if (reflCtx) contextFunctionRefl (*reflCtx); 00699 if (refrCtx) contextFunctionRefr (*refrCtx); 00700 } 00701 protected: 00702 ContextSetupReflect& contextFunctionRefl; 00703 ContextSetupRefract& contextFunctionRefr; 00704 }; 00705 00706 } // namespace AutoFX 00707 } // namespace RenderManager 00708 } // namespace CS 00709 00710 #endif // __CS_CSPLUGINCOMMON_RENDERMANAGER_AUTOFX_REFLREFR_H__
Generated for Crystal Space 2.1 by doxygen 1.6.1
