CrystalSpace

Public API Reference

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/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           // Check if reflection or refraction is needed
00220           if (!names.IsBitSetTolerant (persist.svTexPlaneRefl)
00221               && !names.IsBitSetTolerant (persist.svTexPlaneRefr))
00222             return;
00223           
00224           /* @@@ NOTE:The same mesh, if rendered in multiple views, will get
00225             the same reflection/refraction texture. This is wrong.
00226             However, ignore for now, until someone complains */
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           /* Compute a difference for the camera between the last render;
00253             if bigger than a certain threshold, rerender (whether it's the
00254             reflections's turn or not) */
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           // But never force an update if we already rendered in this frame
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           // @@@ Kludge: don't render nested reflections
00316           bool doRender = localStack[persist.svClipPlaneReflRefr] == 0;
00317           
00318           csPlane3 reflRefrPlane, reflRefrPlane_cam;
00319           csBox2 clipBoxRefl, clipBoxRefr;
00320           if ((needReflTex || needRefrTex) && doRender)
00321           {
00322             // Compute reflect/refract plane
00323             if ((localStack.GetSize() > persist.svPlaneRefl)
00324                 && (localStack[persist.svPlaneRefl] != 0))
00325             {
00326               // Grab reflection plane from a SV
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               /* Guess reflection plane from mesh bbox:
00335                 Take smallest dimension of object space bounding box, make that
00336                 the direction of reflect plane */
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             // Compute screen space bounding box
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             /* To reduce bleeding from filtering, fuzz the reflection mapping to 
00405                 be actually stretched out a pixel at the corners */
00406             if ((persist.mappingStretch > 0)
00407                 && ((persist.resolutionReduceRefr > 0)
00408                   || (persist.resolutionReduceRefl > 0)))
00409             {
00410               /* Since reflection + refraction share the same TC transform, 
00411                 compute the 'fuzz' from the smaller one. This can lead to 
00412                 distortions when the resolutions differ a lot ... but hopefully
00413                 doesn't happen often */
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               // Compute reflection view
00476               iCamera* cam = rview->GetCamera();
00477               // Create a new view
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               // Change the camera transform to be a reflection across reflRefrPlane
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               // Set up context for reflection, clipped to plane
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             // Attach reflection texture to mesh
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               // Set up context for refraction, clipped to plane
00590               
00591               // Create a new view
00592               csRef<CS::RenderManager::RenderView> refrView;
00593               /* Keep old camera to allow shadow map caching  */
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               // Set up context for reflection, clipped to plane
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               // Attach refraction texture to mesh
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             // Attach refraction texture to mesh
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           // Setup the new contexts
00690           if (reflCtx) contextFunctionRefl (*reflCtx);
00691           if (refrCtx) contextFunctionRefr (*refrCtx);
00692         }
00693       protected:
00694         ContextSetupReflect& contextFunctionRefl;
00695         ContextSetupRefract& contextFunctionRefr;
00696       };
00697 
00698     } // namespace AutoFX
00699   } // namespace RenderManager
00700 } // namespace CS
00701 
00702 #endif // __CS_CSPLUGINCOMMON_RENDERMANAGER_AUTOFX_REFLREFR_H__

Generated for Crystal Space 2.0 by doxygen 1.7.6.1