CrystalSpace

Public API Reference

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.7.6.1