Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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