csplugincommon/rendermanager/posteffects.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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