csplugincommon/rendermanager/posteffects.h
Go to the documentation of this file.00001 /* 00002 Copyright (C) 2007-2008 by Marten Svanfeldt 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_POSTEFFECTS_H__ 00020 #define __CS_CSPLUGINCOMMON_RENDERMANAGER_POSTEFFECTS_H__ 00021 00026 #include "csgfx/shadervarcontext.h" 00027 #include "csplugincommon/rendermanager/rendertree.h" 00028 #include "csutil/array.h" 00029 #include "csutil/dirtyaccessarray.h" 00030 #include "csutil/genericresourcecache.h" 00031 #include "csutil/parray.h" 00032 #include "csutil/ref.h" 00033 #include "imap/services.h" 00034 #include "ivideo/shader/shader.h" 00035 00036 struct iGraphics3D; 00037 struct iObjectRegistry; 00038 struct iRenderView; 00039 struct iShader; 00040 struct iSyntaxService; 00041 struct iTextureHandle; 00042 struct iView; 00043 00044 namespace CS 00045 { 00046 namespace RenderManager 00047 { 00104 class CS_CRYSTALSPACE_EXPORT PostEffectManager : 00105 public CS::Memory::CustomAllocatedDerived<csRefCount> 00106 { 00107 struct DimensionData; 00108 public: 00109 class Layer; 00113 struct LayerOptions 00114 { 00116 bool mipmap; 00118 int maxMipmap; 00123 int downsample; 00125 bool noTextureReuse; 00130 csRef<iTextureHandle> manualTarget; 00132 csRect targetRect; 00137 Layer* renderOn; 00142 bool readback; 00143 00144 LayerOptions() : mipmap (false), maxMipmap (-1), downsample (0), 00145 noTextureReuse (false), renderOn (0), readback (false) {} 00146 00147 bool operator==(const LayerOptions& other) const 00148 { 00149 return (mipmap == other.mipmap) 00150 && (maxMipmap == other.maxMipmap) 00151 && (downsample == other.downsample) 00152 && (noTextureReuse == other.noTextureReuse) 00153 && (manualTarget == other.manualTarget) 00154 && (targetRect == other.targetRect) 00155 && (renderOn == other.renderOn) 00156 && (readback == other.readback); 00157 } 00158 }; 00159 00161 struct LayerInputMap 00162 { 00167 csRef<csShaderVariable> manualInput; 00169 Layer* inputLayer; 00171 csString textureName; 00176 csString texcoordName; 00181 csString inputPixelSizeName; 00186 csRect sourceRect; 00187 00188 LayerInputMap() : inputLayer (0), textureName ("tex diffuse"), 00189 texcoordName ("texture coordinate 0") {} 00190 }; 00191 00193 class Layer 00194 { 00195 private: 00196 friend class PostEffectManager; 00197 friend struct DimensionData; 00198 00199 csRef<iShader> effectShader; 00200 int outTextureNum; 00201 csArray<LayerInputMap> inputs; 00202 csRef<iShaderVariableContext> svContext; 00203 LayerOptions options; 00204 00205 Layer() 00206 { 00207 svContext.AttachNew (new csShaderVariableContext); 00208 } 00209 bool IsInput (const Layer* layer) const; 00210 public: 00212 iShaderVariableContext* GetSVContext() const { return svContext; } 00214 const csArray<LayerInputMap>& GetInputs() const { return inputs; } 00215 00217 const LayerOptions& GetOptions() const { return options; } 00219 void SetOptions (const LayerOptions& opt) { options = opt; } 00220 00222 void SetShader (iShader* shader) { effectShader = shader; } 00224 iShader* GetShader () const { return effectShader; } 00226 int GetOutTextureNum () const { return outTextureNum; } 00227 }; 00228 00229 PostEffectManager (); 00230 ~PostEffectManager (); 00231 00233 void Initialize (iObjectRegistry* objectReg); 00234 00236 void SetIntermediateTargetFormat (const char* textureFmt); 00238 const char* GetIntermediateTargetFormat (); 00239 00241 00250 bool SetupView (iView* view, CS::Math::Matrix4& perspectiveFixup); 00251 bool SetupView (uint width, uint height, 00252 CS::Math::Matrix4& perspectiveFixup); 00254 00258 void ClearIntermediates(); 00259 00261 iTextureHandle* GetScreenTarget (); 00262 00267 void DrawPostEffects (RenderTreeBase& renderTree); 00268 00270 00271 Layer* AddLayer (iShader* shader); 00272 Layer* AddLayer (iShader* shader, const LayerOptions& opt); 00274 00275 00276 Layer* AddLayer (iShader* shader, size_t numMaps, const LayerInputMap* maps); 00277 Layer* AddLayer (iShader* shader, const LayerOptions& opt, size_t numMaps, 00278 const LayerInputMap* maps); 00280 00281 bool RemoveLayer (Layer* layer); 00283 void ClearLayers(); 00284 00286 Layer* GetScreenLayer() { return postLayers[0]; } 00287 00289 Layer* GetLastLayer() { return lastLayer; } 00290 00292 iTextureHandle* GetLayerOutput (const Layer* layer); 00293 00297 void GetLayerRenderSVs (const Layer* layer, csShaderVariableStack& svStack) const; 00298 00304 void SetEffectsOutputTarget (iTextureHandle* tex) 00305 { 00306 if (chainedEffects) 00307 chainedEffects->SetEffectsOutputTarget (tex); 00308 else 00309 target = tex; 00310 } 00312 iTextureHandle* GetEffectsOutputTarget () const 00313 { 00314 if (chainedEffects) return chainedEffects->GetEffectsOutputTarget (); 00315 return target; 00316 } 00317 00319 00323 void SetChainedOutput (PostEffectManager* nextEffects); 00324 void SetChainedOutput (PostEffectManager& nextEffects) 00325 { SetChainedOutput (&nextEffects); } 00327 00332 bool ScreenSpaceYFlipped (); 00333 private: 00334 uint frameNum; 00335 csRef<iGraphics3D> graphics3D; 00336 csRef<iShaderVarStringSet> svStrings; 00337 bool keepAllIntermediates; 00338 csRef<iRenderBuffer> indices; 00339 csRef<iTextureHandle> target; 00340 PostEffectManager* chainedEffects; 00341 uint dbgIntermediateTextures; 00342 00343 void SetupScreenQuad (); 00344 const Layer& GetRealOutputLayer (const Layer& layer) const 00345 { 00346 return layer.options.renderOn 00347 ? GetRealOutputLayer (*(layer.options.renderOn)) 00348 : layer; 00349 } 00350 00351 struct Dimensions 00352 { 00353 uint x, y; 00354 }; 00356 struct DimensionData 00357 { 00358 Dimensions dim; 00363 struct TexturesBucket 00364 { 00366 csRefArray<iTextureHandle> textures; 00371 float texMaxX, texMaxY; 00372 00373 TexturesBucket() : texMaxX (1), texMaxY (1) { } 00374 }; 00375 csArray<TexturesBucket> buckets; 00376 00377 struct LayerRenderInfo 00378 { 00380 csRef<csShaderVariable> svPixelSize; 00382 csRef<iRenderBuffer> vertBuf; 00384 csRef<iShaderVariableContext> layerSVs; 00386 csRef<csRenderBufferHolder> buffers; 00388 csSimpleRenderMesh fullscreenQuad; 00389 }; 00391 csArray<LayerRenderInfo> layerRenderInfos; 00392 00393 void AllocatePingpongTextures (PostEffectManager& pfx); 00394 void UpdateSVContexts (PostEffectManager& pfx); 00395 00396 void SetupRenderInfo (PostEffectManager& pfx); 00397 protected: 00398 csPtr<iRenderBuffer> ComputeTexCoords (iTextureHandle* tex, 00399 const csRect& rect, const csRect& targetRect, 00400 float& pixSizeX, float& pixSizeY); 00401 }; 00402 00403 struct DimensionCacheSorting 00404 { 00405 typedef Dimensions KeyType; 00406 00407 static bool IsLargerEqual (const DimensionData& b1, 00408 const DimensionData& b2) 00409 { 00410 return (b1.dim.x >= b2.dim.x) && (b1.dim.y >= b2.dim.y); 00411 } 00412 00413 static bool IsEqual (const DimensionData& b1, 00414 const DimensionData& b2) 00415 { 00416 return (b1.dim.x == b2.dim.x) && (b1.dim.y == b2.dim.y); 00417 } 00418 00419 static bool IsLargerEqual (const DimensionData& b1, 00420 const Dimensions& b2) 00421 { 00422 return (b1.dim.x >= b2.x) && (b1.dim.y >= b2.y); 00423 } 00424 00425 static bool IsEqual (const DimensionData& b1, 00426 const Dimensions& b2) 00427 { 00428 return (b1.dim.x == b2.x) && (b1.dim.y == b2.y); 00429 } 00430 00431 static bool IsLargerEqual (const Dimensions& b1, 00432 const DimensionData& b2) 00433 { 00434 return (b1.x >= b2.dim.x) && (b1.y >= b2.dim.y); 00435 } 00436 }; 00437 CS::Utility::GenericResourceCache<DimensionData, 00438 uint, DimensionCacheSorting, 00439 CS::Utility::ResourceCache::ReuseConditionFlagged> dimCache; 00440 DimensionData* currentDimData; 00441 00442 uint currentWidth, currentHeight; 00443 00444 bool textureDistributionDirty; 00445 void UpdateTextureDistribution(); 00446 00447 csString textureFmt; 00448 Layer* lastLayer; 00449 csPDelArray<Layer> postLayers; 00450 bool layersDirty; 00451 void UpdateLayers(); 00452 00453 struct BucketsCommon 00454 { 00455 LayerOptions options; 00456 size_t textureNum; 00457 }; 00458 csArray<BucketsCommon> buckets; 00459 size_t GetBucketIndex (const LayerOptions& options); 00460 BucketsCommon& GetBucket (const LayerOptions& options) 00461 { return buckets[GetBucketIndex (options)]; } 00462 }; 00463 00464 // @@@ TODO: give a simple example 00466 class CS_CRYSTALSPACE_EXPORT PostEffectLayersParser : 00467 public CS::Memory::CustomAllocated 00468 { 00469 csStringHash xmltokens; 00470 iObjectRegistry* objReg; 00471 csRef<iSyntaxService> synldr; 00472 00473 typedef csHash<PostEffectManager::Layer*, csString> ParsedLayers; 00474 typedef csDirtyAccessArray<PostEffectManager::LayerInputMap> InputsArray; 00475 typedef csHash<csRef<iShader>, csString> ShadersLayers; 00476 00477 bool ParseInputs (iDocumentNode* node, PostEffectManager& effects, 00478 ParsedLayers& layers, ShadersLayers& shaders, 00479 InputsArray& inputs); 00480 bool ParseLayer (iDocumentNode* node, PostEffectManager& effects, 00481 ParsedLayers& layers, ShadersLayers& shaders); 00482 public: 00484 PostEffectLayersParser (iObjectRegistry* objReg); 00485 ~PostEffectLayersParser(); 00486 00488 bool AddLayersFromDocument (iDocumentNode* node, PostEffectManager& effects); 00490 bool AddLayersFromFile (const char* filename, PostEffectManager& effects); 00491 }; 00492 00493 } 00494 } 00495 00496 #endif
Generated for Crystal Space 2.0 by doxygen 1.6.1