Browse Source

Started work toward renderpath programmability.

Lasse Öörni 13 years ago
parent
commit
ec07e6c524

+ 14 - 13
Engine/Engine/GraphicsAPI.cpp

@@ -148,20 +148,20 @@ static void RegisterSkeleton(asIScriptEngine* engine)
 
 static Viewport* ConstructViewport()
 {
-    return new Viewport();
+    return new Viewport(GetScriptContext());
 }
 
-static Viewport* ConstructViewportSceneCamera(Scene* scene, Camera* camera)
+static Viewport* ConstructViewportSceneCamera(Scene* scene, Camera* camera, XMLFile* renderPath)
 {
-    return new Viewport(scene, camera);
+    return new Viewport(GetScriptContext(), scene, camera, renderPath);
 }
 
-static Viewport* ConstructViewportSceneCameraRect(Scene* scene, Camera* camera, const IntRect& rect)
+static Viewport* ConstructViewportSceneCameraRect(Scene* scene, Camera* camera, const IntRect& rect, XMLFile* renderPath)
 {
-    return new Viewport(scene, camera, rect);
+    return new Viewport(GetScriptContext(), scene, camera, rect, renderPath);
 }
 
-static Viewport* ConstructViewportSceneCameraPostProcesses(Scene* scene, Camera* camera, CScriptArray* arr)
+static Viewport* ConstructViewportSceneCameraPostProcesses(Scene* scene, Camera* camera, CScriptArray* arr, XMLFile* renderPath)
 {
     Vector<SharedPtr<PostProcess> > vec;
     if (arr)
@@ -171,10 +171,10 @@ static Viewport* ConstructViewportSceneCameraPostProcesses(Scene* scene, Camera*
             vec.Push(SharedPtr<PostProcess>(*(static_cast<PostProcess**>(arr->At(i)))));
     }
     
-    return new Viewport(scene, camera, vec);
+    return new Viewport(GetScriptContext(), scene, camera, vec, renderPath);
 }
 
-static Viewport* ConstructViewportSceneCameraRectPostProcesses(Scene* scene, Camera* camera, const IntRect& rect, CScriptArray* arr)
+static Viewport* ConstructViewportSceneCameraRectPostProcesses(Scene* scene, Camera* camera, const IntRect& rect, CScriptArray* arr, XMLFile* renderPath)
 {
     Vector<SharedPtr<PostProcess> > vec;
     if (arr)
@@ -184,7 +184,7 @@ static Viewport* ConstructViewportSceneCameraRectPostProcesses(Scene* scene, Cam
             vec.Push(SharedPtr<PostProcess>(*(static_cast<PostProcess**>(arr->At(i)))));
     }
     
-    return new Viewport(scene, camera, rect, vec);
+    return new Viewport(GetScriptContext(), scene, camera, rect, vec, renderPath);
 }
 
 static bool Texture2DLoad(Image* image, bool useAlpha, Texture2D* ptr)
@@ -239,10 +239,10 @@ static void RegisterTextures(asIScriptEngine* engine)
     RegisterObject<PostProcess>(engine, "PostProcess");
     RegisterRefCounted<Viewport>(engine, "Viewport");
     engine->RegisterObjectBehaviour("Viewport", asBEHAVE_FACTORY, "Viewport@+ f()", asFUNCTION(ConstructViewport), asCALL_CDECL);
-    engine->RegisterObjectBehaviour("Viewport", asBEHAVE_FACTORY, "Viewport@+ f(Scene@+, Camera@+)", asFUNCTION(ConstructViewportSceneCamera), asCALL_CDECL);
-    engine->RegisterObjectBehaviour("Viewport", asBEHAVE_FACTORY, "Viewport@+ f(Scene@+, Camera@+, const IntRect&in)", asFUNCTION(ConstructViewportSceneCameraRect), asCALL_CDECL);
-    engine->RegisterObjectBehaviour("Viewport", asBEHAVE_FACTORY, "Viewport@+ f(Scene@+, Camera@+, Array<PostProcess@>@+)", asFUNCTION(ConstructViewportSceneCameraPostProcesses), asCALL_CDECL);
-    engine->RegisterObjectBehaviour("Viewport", asBEHAVE_FACTORY, "Viewport@+ f(Scene@+, Camera@+, const IntRect&in, Array<PostProcess@>@+)", asFUNCTION(ConstructViewportSceneCameraRectPostProcesses), asCALL_CDECL);
+    engine->RegisterObjectBehaviour("Viewport", asBEHAVE_FACTORY, "Viewport@+ f(Scene@+, Camera@+, XMLFile@+ renderPath = null)", asFUNCTION(ConstructViewportSceneCamera), asCALL_CDECL);
+    engine->RegisterObjectBehaviour("Viewport", asBEHAVE_FACTORY, "Viewport@+ f(Scene@+, Camera@+, const IntRect&in, XMLFile@+ renderPath = null)", asFUNCTION(ConstructViewportSceneCameraRect), asCALL_CDECL);
+    engine->RegisterObjectBehaviour("Viewport", asBEHAVE_FACTORY, "Viewport@+ f(Scene@+, Camera@+, Array<PostProcess@>@+, XMLFile@+ renderPath = null)", asFUNCTION(ConstructViewportSceneCameraPostProcesses), asCALL_CDECL);
+    engine->RegisterObjectBehaviour("Viewport", asBEHAVE_FACTORY, "Viewport@+ f(Scene@+, Camera@+, const IntRect&in, Array<PostProcess@>@+, XMLFile@+ renderPath = null)", asFUNCTION(ConstructViewportSceneCameraRectPostProcesses), asCALL_CDECL);
     engine->RegisterObjectMethod("Viewport", "void AddPostProcess(PostProcess@+)", asMETHOD(Viewport, AddPostProcess), asCALL_THISCALL);
     engine->RegisterObjectMethod("Viewport", "void InsertPostProcess(uint, PostProcess@+)", asMETHOD(Viewport, InsertPostProcess), asCALL_THISCALL);
     engine->RegisterObjectMethod("Viewport", "void RemovePostProcess(PostProcess@+)", asMETHODPR(Viewport, RemovePostProcess, (PostProcess*), void), asCALL_THISCALL);
@@ -252,6 +252,7 @@ static void RegisterTextures(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Viewport", "Scene@+ get_scene() const", asMETHOD(Viewport, GetScene), asCALL_THISCALL);
     engine->RegisterObjectMethod("Viewport", "void set_camera(Camera@+)", asMETHOD(Viewport, SetCamera), asCALL_THISCALL);
     engine->RegisterObjectMethod("Viewport", "Camera@+ get_camera() const", asMETHOD(Viewport, GetCamera), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Viewport", "void set_renderPath(XMLFile@+)", asMETHOD(Viewport, SetRenderPath), asCALL_THISCALL);
     engine->RegisterObjectMethod("Viewport", "void set_rect(const IntRect&in)", asMETHOD(Viewport, SetCamera), asCALL_THISCALL);
     engine->RegisterObjectMethod("Viewport", "const IntRect& get_rect() const", asMETHOD(Viewport, GetCamera), asCALL_THISCALL);
     engine->RegisterObjectMethod("Viewport", "uint get_numPostProcesses() const", asMETHOD(Viewport, GetNumPostProcesses), asCALL_THISCALL);

+ 1 - 2
Engine/Graphics/Direct3D9/D3D9RenderSurface.cpp

@@ -37,8 +37,7 @@ namespace Urho3D
 
 RenderSurface::RenderSurface(Texture* parentTexture) :
     parentTexture_(parentTexture),
-    surface_(0),
-    viewport_(new Viewport())
+    surface_(0)
 {
 }
 

+ 1 - 2
Engine/Graphics/OpenGL/OGLRenderSurface.cpp

@@ -46,8 +46,7 @@ namespace Urho3D
 RenderSurface::RenderSurface(Texture* parentTexture, unsigned target) :
     parentTexture_(parentTexture),
     target_(target),
-    renderBuffer_(0),
-    viewport_(new Viewport())
+    renderBuffer_(0)
 {
 }
 

+ 1 - 1
Engine/Graphics/PostProcess.cpp

@@ -238,7 +238,7 @@ bool PostProcess::CreateRenderTarget(const String& name, unsigned width, unsigne
     if (name.Trimmed().Empty())
         return false;
     
-    PostProcessRenderTarget target;
+    RenderTargetInfo target;
     target.name_ = name;
     target.format_ = format;
     target.size_ = IntVector2(width, height),

+ 3 - 18
Engine/Graphics/PostProcess.h

@@ -24,7 +24,7 @@
 #pragma once
 
 #include "GraphicsDefs.h"
-#include "Object.h"
+#include "Viewport.h"
 
 namespace Urho3D
 {
@@ -84,21 +84,6 @@ private:
     String outputName_;
 };
 
-/// Post-processing rendertarget info.
-struct PostProcessRenderTarget
-{
-    /// Name.
-    String name_;
-    /// Texture format.
-    unsigned format_;
-    /// Size.
-    IntVector2 size_;
-    /// Divisor mode flag.
-    bool sizeDivisor_;
-    /// Filtering flag.
-    bool filtered_;
-};
-
 /// Post-processing effect.
 class PostProcess : public Object
 {
@@ -136,7 +121,7 @@ public:
     /// Return if has a specific rendertarget.
     bool HasRenderTarget(const String& name) const;
     /// Return all rendertargets.
-    const HashMap<StringHash, PostProcessRenderTarget>& GetRenderTargets() const { return renderTargets_; }
+    const HashMap<StringHash, RenderTargetInfo>& GetRenderTargets() const { return renderTargets_; }
     /// Return shader parameter.
     const Vector4& GetShaderParameter(const String& name) const;
     /// Return all global shader parameters.
@@ -149,7 +134,7 @@ private:
     /// Parameter XML file.
     SharedPtr<XMLFile> parameterSource_;
     /// Rendertargets.
-    HashMap<StringHash, PostProcessRenderTarget> renderTargets_;
+    HashMap<StringHash, RenderTargetInfo> renderTargets_;
     /// Global shader parameters.
     HashMap<StringHash, Vector4> shaderParameters_;
     /// Effect passes.

+ 1 - 1
Engine/Graphics/Renderer.cpp

@@ -307,7 +307,7 @@ void Renderer::SetNumViewports(unsigned num)
     for (unsigned i = 0; i < viewports_.Size(); ++i)
     {
         if (!viewports_[i])
-            viewports_[i] = new Viewport();
+            viewports_[i] = new Viewport(context_);
     }
 }
 

+ 5 - 5
Engine/Graphics/View.cpp

@@ -1491,9 +1491,9 @@ void View::RunPostProcesses()
         
         // For each effect, rendertargets can be re-used. Allocate them now
         renderer_->SaveScreenBufferAllocations();
-        const HashMap<StringHash, PostProcessRenderTarget>& renderTargetInfos = effect->GetRenderTargets();
+        const HashMap<StringHash, RenderTargetInfo>& renderTargetInfos = effect->GetRenderTargets();
         HashMap<StringHash, Texture2D*> renderTargets;
-        for (HashMap<StringHash, PostProcessRenderTarget>::ConstIterator j = renderTargetInfos.Begin(); j !=
+        for (HashMap<StringHash, RenderTargetInfo>::ConstIterator j = renderTargetInfos.Begin(); j !=
             renderTargetInfos.End(); ++j)
         {
             unsigned width = j->second_.size_.x_;
@@ -1576,7 +1576,7 @@ void View::RunPostProcesses()
             graphics_->SetShaderParameter(PSP_GBUFFERINVSIZE, Vector4(1.0f / rtWidth, 1.0f / rtHeight, 0.0f, 0.0f));
             
             // Set per-rendertarget inverse size / offset shader parameters as necessary
-            for (HashMap<StringHash, PostProcessRenderTarget>::ConstIterator k = renderTargetInfos.Begin(); k !=
+            for (HashMap<StringHash, RenderTargetInfo>::ConstIterator k = renderTargetInfos.Begin(); k !=
                 renderTargetInfos.End(); ++k)
             {
                 String invSizeName = k->second_.name_ + "InvSize";
@@ -2313,7 +2313,7 @@ void View::CheckMaterialForAuxView(Material* material)
                 if (target)
                 {
                     Viewport* viewport = target->GetViewport();
-                    if (viewport->GetScene() && viewport->GetCamera())
+                    if (viewport && viewport->GetScene() && viewport->GetCamera())
                         renderer_->AddView(target, viewport);
                 }
             }
@@ -2326,7 +2326,7 @@ void View::CheckMaterialForAuxView(Material* material)
                     if (target)
                     {
                         Viewport* viewport = target->GetViewport();
-                        if (viewport->GetScene() && viewport->GetCamera())
+                        if (viewport && viewport->GetScene() && viewport->GetCamera())
                             renderer_->AddView(target, viewport);
                     }
                 }

+ 189 - 6
Engine/Graphics/Viewport.cpp

@@ -23,48 +23,76 @@
 
 #include "Precompiled.h"
 #include "Camera.h"
+#include "Graphics.h"
+#include "Log.h"
 #include "PostProcess.h"
+#include "ResourceCache.h"
 #include "Scene.h"
-#include "Viewport.h"
+#include "StringUtils.h"
+#include "XMLFile.h"
 
 #include "DebugNew.h"
 
 namespace Urho3D
 {
 
-Viewport::Viewport() :
+TextureUnit ParseTextureUnitName(const String& name);
+
+static const String cmdNames[] =
+{
+    "clear",
+    "scenepass",
+    "quad",
+    "forwardlights",
+    "lightvolumes",
+    ""
+};
+
+OBJECTTYPESTATIC(Viewport);
+
+Viewport::Viewport(Context* context) :
+    Object(context),
     rect_(IntRect::ZERO)
 {
+    SetRenderPath(0);
 }
 
-Viewport::Viewport(Scene* scene, Camera* camera) :
+Viewport::Viewport(Context* context, Scene* scene, Camera* camera, XMLFile* renderPath) :
+    Object(context),
     scene_(scene),
     camera_(camera),
     rect_(IntRect::ZERO)
 {
+    SetRenderPath(renderPath);
 }
 
-Viewport::Viewport(Scene* scene, Camera* camera, const IntRect& rect) :
+Viewport::Viewport(Context* context, Scene* scene, Camera* camera, const IntRect& rect, XMLFile* renderPath) :
+    Object(context),
     scene_(scene),
     camera_(camera),
     rect_(rect)
 {
+    SetRenderPath(renderPath);
 }
 
-Viewport::Viewport(Scene* scene, Camera* camera, const Vector<SharedPtr<PostProcess> >& postProcesses) :
+Viewport::Viewport(Context* context, Scene* scene, Camera* camera, const Vector<SharedPtr<PostProcess> >& postProcesses, XMLFile* renderPath) :
+    Object(context),
     scene_(scene),
     camera_(camera),
     rect_(IntRect::ZERO),
     postProcesses_(postProcesses)
 {
+    SetRenderPath(renderPath);
 }
 
-Viewport::Viewport(Scene* scene, Camera* camera, const IntRect& rect, const Vector<SharedPtr<PostProcess> >& postProcesses) :
+Viewport::Viewport(Context* context, Scene* scene, Camera* camera, const IntRect& rect, const Vector<SharedPtr<PostProcess> >& postProcesses, XMLFile* renderPath) :
+    Object(context),
     scene_(scene),
     camera_(camera),
     rect_(rect),
     postProcesses_(postProcesses)
 {
+    SetRenderPath(renderPath);
 }
 
 Viewport::~Viewport()
@@ -86,6 +114,161 @@ void Viewport::SetRect(const IntRect& rect)
     rect_ = rect;
 }
 
+bool Viewport::SetRenderPath(XMLFile* file)
+{
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+    if (!file && cache)
+        file = cache->GetResource<XMLFile>("Data/RenderPaths/Forward.xml");
+    if (!file)
+        return false;
+    
+    XMLElement rootElem = file->GetRoot();
+    if (!rootElem)
+        return false;
+    
+    XMLElement rtElem = rootElem.GetChild("rendertarget");
+    while (rtElem)
+    {
+        String name = rtElem.GetAttribute("name");
+        
+        String formatName = rtElem.GetAttribute("format");
+        unsigned format = Graphics::GetFormat(formatName);
+        
+        bool sizeDivisor = false;
+        bool filtered = false;
+        unsigned width = 0;
+        unsigned height = 0;
+        
+        if (rtElem.HasAttribute("filter"))
+            filtered = rtElem.GetBool("filter");
+        if (rtElem.HasAttribute("size"))
+        {
+            IntVector2 size = rtElem.GetIntVector2("size");
+            width = size.x_;
+            height = size.y_;
+        }
+        if (rtElem.HasAttribute("width"))
+            width = rtElem.GetInt("width");
+        if (rtElem.HasAttribute("height"))
+            height = rtElem.GetInt("height");
+        if (rtElem.HasAttribute("sizedivisor"))
+        {
+            IntVector2 size = rtElem.GetIntVector2("sizedivisor");
+            width = size.x_;
+            height = size.y_;
+            sizeDivisor = true;
+        }
+        
+        if (!name.Trimmed().Empty())
+        {
+            RenderTargetInfo target;
+            target.name_ = name;
+            target.format_ = format;
+            target.size_ = IntVector2(width, height),
+            target.sizeDivisor_ = sizeDivisor;
+            target.filtered_ = filtered;
+            renderPath_.renderTargets_[StringHash(name)] = target;
+        }
+        
+        rtElem = rtElem.GetNext("rendertarget");
+    }
+    
+    XMLElement cmdElem = rootElem.GetChild("command");
+    while (cmdElem)
+    {
+        RenderCommandType type = (RenderCommandType)GetStringListIndex(cmdElem.GetAttributeLower("type"), cmdNames, CMD_UNKNOWN);
+        if (type != CMD_UNKNOWN)
+        {
+            RenderPathCommand cmd;
+            cmd.type_ = type;
+            cmd.passName_ = cmdElem.GetAttribute("pass");
+            cmd.vertexShaderName_ = cmdElem.GetAttribute("vs");
+            cmd.pixelShaderName_ = cmdElem.GetAttribute("ps");
+            
+            if (type == CMD_CLEAR)
+            {
+                cmd.clearFlags_ = 0;
+                if (cmdElem.HasAttribute("color"))
+                {
+                    cmd.clearFlags_ |= CLEAR_COLOR;
+                    // Mark fog color with negative values
+                    if (cmdElem.GetAttributeLower("color") == "fog")
+                        cmd.clearColor_ = Color(-1.0f, -1.0f, -1.0f, -1.0f);
+                    else
+                        cmd.clearColor_ = cmdElem.GetColor("color");
+                }
+                if (cmdElem.HasAttribute("depth"))
+                {
+                    cmd.clearFlags_ |= CLEAR_DEPTH;
+                    cmd.clearDepth_ = cmdElem.GetFloat("depth");
+                }
+                if (cmdElem.HasAttribute("stencil"))
+                {
+                    cmd.clearFlags_ |= CLEAR_STENCIL;
+                    cmd.clearStencil_ = cmdElem.GetInt("stencil");
+                }
+            }
+            
+            // By default use 1 output, which is the viewport
+            cmd.outputs_.Push("viewport");
+            if (cmdElem.HasAttribute("output"))
+                cmd.outputs_[0] = cmdElem.GetAttribute("output");
+            // Check for defining multiple outputs
+            XMLElement outputElem = cmdElem.GetChild("output");
+            while (outputElem)
+            {
+                unsigned index = outputElem.GetInt("index");
+                if (index < MAX_RENDERTARGETS)
+                {
+                    if (index >= cmd.outputs_.Size())
+                        cmd.outputs_.Resize(index + 1);
+                    cmd.outputs_[index] = outputElem.GetAttribute("name");
+                }
+                outputElem = outputElem.GetNext("output");
+            }
+            
+            XMLElement parameterElem = cmdElem.GetChild("parameter");
+            while (parameterElem)
+            {
+                String name = parameterElem.GetAttribute("name");
+                Vector4 value = parameterElem.GetVector("value");
+                cmd.shaderParameters_[StringHash(name)] = value;
+                
+                parameterElem = parameterElem.GetNext("parameter");
+            }
+            
+            XMLElement textureElem = cmdElem.GetChild("texture");
+            while (textureElem)
+            {
+                TextureUnit unit = TU_DIFFUSE;
+                if (textureElem.HasAttribute("unit"))
+                {
+                    String unitName = textureElem.GetAttributeLower("unit");
+                    if (unitName.Length() > 1)
+                    {
+                        unit = ParseTextureUnitName(unitName);
+                        if (unit == MAX_MATERIAL_TEXTURE_UNITS)
+                            LOGERROR("Unknown texture unit " + unitName);
+                    }
+                    else
+                        unit = (TextureUnit)Clamp(ToInt(unitName), 0, MAX_MATERIAL_TEXTURE_UNITS - 1);
+                }
+                if (unit != MAX_TEXTURE_UNITS)
+                {
+                    String name = textureElem.GetAttribute("name");
+                    cmd.textureNames_[unit] = name;
+                }
+                
+                textureElem = textureElem.GetNext("texture");
+            }
+        }
+        
+        cmdElem = cmdElem.GetNext("command");
+    }
+    
+    return true;
+}
+
 void Viewport::AddPostProcess(PostProcess* effect)
 {
     if (!effect)

+ 87 - 7
Engine/Graphics/Viewport.h

@@ -32,21 +32,96 @@ namespace Urho3D
 class Camera;
 class PostProcess;
 class Scene;
+class XMLFile;
+
+/// Rendering path command types.
+enum RenderCommandType
+{
+    CMD_CLEAR = 0,
+    CMD_SCENEPASS,
+    CMD_QUAD,
+    CMD_FORWARDLIGHTS,
+    CMD_LIGHTVOLUMES,
+    CMD_UNKNOWN
+};
+
+/// Rendering path sorting modes.
+enum RenderCommandSortMode
+{
+    SORT_STATE = 0,
+    SORT_FRONTTOBACK,
+    SORT_BACKTOFRONT
+};
+
+/// Rendertarget definition.
+struct RenderTargetInfo
+{
+    /// Name.
+    String name_;
+    /// Texture format.
+    unsigned format_;
+    /// Size.
+    IntVector2 size_;
+    /// Divisor mode flag.
+    bool sizeDivisor_;
+    /// Filtering flag.
+    bool filtered_;
+};
+
+/// Rendering path command.
+struct RenderPathCommand
+{
+    /// Command type.
+    RenderCommandType type_;
+    /// Sorting mode.
+    RenderCommandSortMode sortMode_;
+    /// Scene pass name.
+    String passName_;
+    /// Clear flags.
+    unsigned clearFlags_;
+    /// Clear color.
+    Color clearColor_;
+    /// Clear depth.
+    float clearDepth_;
+    /// Clear stencil value.
+    unsigned clearStencil_;
+    /// Vertex shader name.
+    String vertexShaderName_;
+    /// Pixel shader name.
+    String pixelShaderName_;
+    /// Textures.
+    String textureNames_[MAX_MATERIAL_TEXTURE_UNITS];
+    /// %Shader parameters.
+    HashMap<StringHash, Vector4> shaderParameters_;
+    /// Output rendertarget names.
+    Vector<String> outputs_;
+};
+
+/// Rendering path definition.
+struct RenderPath
+{
+    /// Rendertargets.
+    Vector<RenderTargetInfo> renderTargets_;
+    /// Rendering commands.
+    Vector<RenderPathCommand> commands_;
+};
 
 /// %Viewport definition either for a render surface or the backbuffer.
-class Viewport : public RefCounted
+class Viewport : public Object
 {
+    OBJECT(Viewport);
+    
 public:
     /// Construct with defaults.
-    Viewport();
+    Viewport(Context* context);
     /// Construct with a full rectangle.
-    Viewport(Scene* scene, Camera* camera);
+    Viewport(Context* context, Scene* scene, Camera* camera, XMLFile* renderPath = 0);
     /// Construct with a specified rectangle.
-    Viewport(Scene* scene, Camera* camera, const IntRect& rect);
+    Viewport(Context* context, Scene* scene, Camera* camera, const IntRect& rect, XMLFile* renderPath = 0);
     /// Construct with a full rectangle and post-processing effects.
-    Viewport(Scene* scene, Camera* camera, const Vector<SharedPtr<PostProcess> >& postProcesses);
+    Viewport(Context* context, Scene* scene, Camera* camera, const Vector<SharedPtr<PostProcess> >& postProcesses, XMLFile* renderPath = 0);
     /// Construct with a specified rectangle and post-processing effects.
-    Viewport(Scene* scene, Camera* camera, const IntRect& rect, const Vector<SharedPtr<PostProcess> >& postProcesses);
+    Viewport(Context* context, Scene* scene, Camera* camera, const IntRect& rect, const Vector<SharedPtr<PostProcess> >& postProcesses, XMLFile* renderPath = 0);
     /// Destruct.
     ~Viewport();
     
@@ -56,6 +131,8 @@ public:
     void SetCamera(Camera* camera);
     /// Set rectangle.
     void SetRect(const IntRect& rect);
+    /// Set rendering path. Return true if successful.
+    bool SetRenderPath(XMLFile* file);
     /// Add a post-processing effect at the end of the chain.
     void AddPostProcess(PostProcess* effect);
     /// Insert a post-processing effect at position in the chain.
@@ -71,6 +148,8 @@ public:
     Scene* GetScene() const;
     /// Return camera.
     Camera* GetCamera() const;
+    /// Return rendering path.
+    const RenderPath& GetRenderPath() const { return renderPath_; }
     /// Return rectangle.
     const IntRect& GetRect() const { return rect_; }
     /// Return number of post-processing effects.
@@ -87,9 +166,10 @@ private:
     WeakPtr<Camera> camera_;
     /// Viewport rectangle.
     IntRect rect_;
+    /// Rendering path.
+    RenderPath renderPath_;
     /// Post-processing effects.
     Vector<SharedPtr<PostProcess> > postProcesses_;
 };
 
-
 }