Browse Source

Changed Viewport to be a reference-counted object.
Changed the Viewport API to allow easier manipulation of the post-process chain.
Added PostProcess::Clone().

Lasse Öörni 14 years ago
parent
commit
9fc3d48c12

+ 8 - 7
Bin/Data/Scripts/TestScene.as

@@ -212,14 +212,15 @@ void InitScene()
     camera = cameraNode.CreateComponent("Camera");
     camera = cameraNode.CreateComponent("Camera");
     cameraNode.position = Vector3(0, 2, 0);
     cameraNode.position = Vector3(0, 2, 0);
 
 
-    Array<PostProcess@> effectChain;
-    edgeFilter = PostProcess();
-    edgeFilter.parameters = cache.GetResource("XMLFile", "PostProcess/EdgeFilter.xml");
-    edgeFilter.active = false; // Start out disabled
-    effectChain.Push(edgeFilter);
-
     if (!engine.headless)
     if (!engine.headless)
-        renderer.viewports[0] = Viewport(testScene, camera, effectChain);
+    {
+        edgeFilter = PostProcess();
+        edgeFilter.parameters = cache.GetResource("XMLFile", "PostProcess/EdgeFilter.xml");
+        edgeFilter.active = false; // Start out disabled
+
+        renderer.viewports[0] = Viewport(testScene, camera);
+        renderer.viewports[0].AddPostProcess(edgeFilter);
+    }
 }
 }
 
 
 bool CheckInLight(Drawable@ drawable)
 bool CheckInLight(Drawable@ drawable)

+ 8 - 6
Bin/Data/Scripts/TestSceneOld.as

@@ -312,13 +312,15 @@ void CreateCamera()
     cameraLight.rampTexture = cache.GetResource("Texture2D", "Textures/RampWide.png");
     cameraLight.rampTexture = cache.GetResource("Texture2D", "Textures/RampWide.png");
     cameraLight.shapeTexture = cache.GetResource("Texture2D", "Textures/SpotWide.png");
     cameraLight.shapeTexture = cache.GetResource("Texture2D", "Textures/SpotWide.png");
 
 
-    Array<PostProcess@> effectChain;
-    edgeFilter = PostProcess();
-    edgeFilter.parameters = cache.GetResource("XMLFile", "PostProcess/EdgeFilter.xml");
-    edgeFilter.active = false; // Start out disabled
-    effectChain.Push(edgeFilter);
+    if (!engine.headless)
+    {
+        edgeFilter = PostProcess();
+        edgeFilter.parameters = cache.GetResource("XMLFile", "PostProcess/EdgeFilter.xml");
+        edgeFilter.active = false; // Start out disabled
 
 
-    renderer.viewports[0] = Viewport(testScene, camera, effectChain);
+        renderer.viewports[0] = Viewport(testScene, camera);
+        renderer.viewports[0].AddPostProcess(edgeFilter);
+    }
 }
 }
 
 
 void HandleUpdate(StringHash eventType, VariantMap& eventData)
 void HandleUpdate(StringHash eventType, VariantMap& eventData)

+ 12 - 5
Docs/ScriptAPI.dox

@@ -1500,6 +1500,7 @@ PostProcess
 Methods:<br>
 Methods:<br>
 - bool CreateRenderTarget(const String&, uint, uint, uint, bool, bool)
 - bool CreateRenderTarget(const String&, uint, uint, uint, bool, bool)
 - void RemoveRenderTarget(const String&)
 - void RemoveRenderTarget(const String&)
+- PostProcess@ Clone() const
 - bool HasRenderTarget(const String&) const
 - bool HasRenderTarget(const String&) const
 
 
 Properties:<br>
 Properties:<br>
@@ -1513,12 +1514,18 @@ Properties:<br>
 
 
 Viewport
 Viewport
 
 
+Methods:<br>
+- void AddPostProcess(PostProcess@)
+- void InsertPostProcess(uint, PostProcess@)
+- void RemovePostProcess(PostProcess@)
+- void RemovePostProcess(uint)
+- void RemoveAllPostProcesses()
+
 Properties:<br>
 Properties:<br>
 - Scene@ scene
 - Scene@ scene
 - Camera@ camera
 - Camera@ camera
-- PostProcess@[] postProcesses
-- uint numPostProcesses
-- IntRect rect
+- IntRect& rect
+- uint numPostProcesses (readonly)
 
 
 
 
 RenderSurface
 RenderSurface
@@ -1528,7 +1535,7 @@ Properties:<br>
 - int width (readonly)
 - int width (readonly)
 - int height (readonly)
 - int height (readonly)
 - TextureUsage usage (readonly)
 - TextureUsage usage (readonly)
-- Viewport& viewport
+- Viewport@ viewport
 - RenderSurface@ linkedRenderTarget
 - RenderSurface@ linkedRenderTarget
 - RenderSurface@ linkedDepthStencil
 - RenderSurface@ linkedDepthStencil
 
 
@@ -2281,7 +2288,7 @@ Properties:<br>
 - ShortStringHash type (readonly)
 - ShortStringHash type (readonly)
 - String& typeName (readonly)
 - String& typeName (readonly)
 - uint numViewports
 - uint numViewports
-- Viewport&[] viewports
+- Viewport@[] viewports
 - bool lightPrepass
 - bool lightPrepass
 - bool specularLighting
 - bool specularLighting
 - int textureAnisotropy
 - int textureAnisotropy

+ 45 - 86
Engine/Engine/GraphicsAPI.cpp

@@ -124,27 +124,22 @@ static void RegisterSkeleton(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Skeleton", "Bone@+ get_bones(uint)", asMETHODPR(Skeleton, GetBone, (unsigned), Bone*), asCALL_THISCALL);
     engine->RegisterObjectMethod("Skeleton", "Bone@+ get_bones(uint)", asMETHODPR(Skeleton, GetBone, (unsigned), Bone*), asCALL_THISCALL);
 }
 }
 
 
-static void ConstructViewport(Viewport* ptr)
+static Viewport* ConstructViewport()
 {
 {
-    new(ptr) Viewport();
+    return new Viewport();
 }
 }
 
 
-static void ConstructViewportCopy(const Viewport& viewport, Viewport* ptr)
+static Viewport* ConstructViewportSceneCamera(Scene* scene, Camera* camera)
 {
 {
-    new(ptr) Viewport(viewport);
+    return new Viewport(scene, camera);
 }
 }
 
 
-static void ConstructViewportSceneCamera(Scene* scene, Camera* camera, Viewport* ptr)
+static Viewport* ConstructViewportSceneCameraRect(Scene* scene, Camera* camera, const IntRect& rect)
 {
 {
-    new(ptr) Viewport(scene, camera);
+    return new Viewport(scene, camera, rect);
 }
 }
 
 
-static void ConstructViewportSceneCameraRect(Scene* scene, Camera* camera, const IntRect& rect, Viewport* ptr)
-{
-    new(ptr) Viewport(scene, camera, rect);
-}
-
-static void ConstructViewportSceneCameraPostProcesses(Scene* scene, Camera* camera, CScriptArray* arr, Viewport* ptr)
+static Viewport* ConstructViewportSceneCameraPostProcesses(Scene* scene, Camera* camera, CScriptArray* arr)
 {
 {
     Vector<SharedPtr<PostProcess> > vec;
     Vector<SharedPtr<PostProcess> > vec;
     if (arr)
     if (arr)
@@ -153,10 +148,10 @@ static void ConstructViewportSceneCameraPostProcesses(Scene* scene, Camera* came
             vec.Push(SharedPtr<PostProcess>(*(static_cast<PostProcess**>(arr->At(i)))));
             vec.Push(SharedPtr<PostProcess>(*(static_cast<PostProcess**>(arr->At(i)))));
     }
     }
     
     
-    new(ptr) Viewport(scene, camera, vec);
+    return new Viewport(scene, camera, vec);
 }
 }
 
 
-static void ConstructViewportSceneCameraRectPostProcesses(Scene* scene, Camera* camera, const IntRect& rect, CScriptArray* arr, Viewport* ptr)
+static Viewport* ConstructViewportSceneCameraRectPostProcesses(Scene* scene, Camera* camera, const IntRect& rect, CScriptArray* arr)
 {
 {
     Vector<SharedPtr<PostProcess> > vec;
     Vector<SharedPtr<PostProcess> > vec;
     if (arr)
     if (arr)
@@ -165,53 +160,7 @@ static void ConstructViewportSceneCameraRectPostProcesses(Scene* scene, Camera*
             vec.Push(SharedPtr<PostProcess>(*(static_cast<PostProcess**>(arr->At(i)))));
             vec.Push(SharedPtr<PostProcess>(*(static_cast<PostProcess**>(arr->At(i)))));
     }
     }
     
     
-    new(ptr) Viewport(scene, camera, rect, vec);
-}
-
-static void DestructViewport(Viewport* ptr)
-{
-    ptr->~Viewport();
-}
-
-static void ViewportSetScene(Scene* scene, Viewport* ptr)
-{
-    ptr->scene_ = scene;
-}
-
-static void ViewportSetCamera(Camera* camera, Viewport* ptr)
-{
-    ptr->camera_ = camera;
-}
-
-static Scene* ViewportGetScene(Viewport* ptr)
-{
-    return ptr->scene_;
-}
-
-static Camera* ViewportGetCamera(Viewport* ptr)
-{
-    return ptr->camera_;
-}
-
-static void ViewportSetPostProcess(unsigned index, PostProcess* effect, Viewport* ptr)
-{
-    if (index < ptr->postProcesses_.Size())
-        ptr->postProcesses_[index] = effect;
-}
-
-static PostProcess* ViewportGetPostProcess(unsigned index, Viewport* ptr)
-{
-    return index < ptr->postProcesses_.Size() ? ptr->postProcesses_[index] : (PostProcess*)0;
-}
-
-static void ViewportSetNumPostProcesses(unsigned num, Viewport* ptr)
-{
-    ptr->postProcesses_.Resize(num);
-}
-
-static unsigned ViewportGetNumPostProcesses(Viewport* ptr)
-{
-    return ptr->postProcesses_.Size();
+    return new Viewport(scene, camera, rect, vec);
 }
 }
 
 
 static bool Texture2DLoad(Image* image, bool useAlpha, Texture2D* ptr)
 static bool Texture2DLoad(Image* image, bool useAlpha, Texture2D* ptr)
@@ -264,24 +213,24 @@ static void RegisterTextures(asIScriptEngine* engine)
     
     
     // Must register PostProcess early as Viewport needs it
     // Must register PostProcess early as Viewport needs it
     RegisterObject<PostProcess>(engine, "PostProcess");
     RegisterObject<PostProcess>(engine, "PostProcess");
-    engine->RegisterObjectType("Viewport", sizeof(Viewport), asOBJ_VALUE | asOBJ_APP_CLASS_CDAK);
-    engine->RegisterObjectBehaviour("Viewport", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructViewport), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectBehaviour("Viewport", asBEHAVE_CONSTRUCT, "void f(const Viewport&in)", asFUNCTION(ConstructViewportCopy), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectBehaviour("Viewport", asBEHAVE_CONSTRUCT, "void f(Scene@+, Camera@+)", asFUNCTION(ConstructViewportSceneCamera), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectBehaviour("Viewport", asBEHAVE_CONSTRUCT, "void f(Scene@+, Camera@+, const IntRect&in)", asFUNCTION(ConstructViewportSceneCameraRect), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectBehaviour("Viewport", asBEHAVE_CONSTRUCT, "void f(Scene@+, Camera@+, Array<PostProcess@>@+)", asFUNCTION(ConstructViewportSceneCameraPostProcesses), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectBehaviour("Viewport", asBEHAVE_CONSTRUCT, "void f(Scene@+, Camera@+, const IntRect&in, Array<PostProcess@>@+)", asFUNCTION(ConstructViewportSceneCameraRectPostProcesses), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectBehaviour("Viewport", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructViewport), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("Viewport", "Viewport& opAssign(const Viewport&in)", asMETHOD(Viewport, operator =), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Viewport", "void set_scene(Scene@+)", asFUNCTION(ViewportSetScene), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("Viewport", "void set_camera(Camera@+)", asFUNCTION(ViewportSetCamera), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("Viewport", "Scene@+ get_scene() const", asFUNCTION(ViewportGetScene), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("Viewport", "Camera@+ get_camera() const", asFUNCTION(ViewportGetCamera), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectProperty("Viewport", "IntRect rect", offsetof(Viewport, rect_));
-    engine->RegisterObjectMethod("Viewport", "void set_postProcesses(uint, PostProcess@+)", asFUNCTION(ViewportSetPostProcess), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("Viewport", "PostProcess@+ get_postProcesses(uint) const", asFUNCTION(ViewportGetPostProcess), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("Viewport", "void set_numPostProcesses(uint)", asFUNCTION(ViewportSetNumPostProcesses), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("Viewport", "uint get_numPostProcesses() const", asFUNCTION(ViewportGetNumPostProcesses), asCALL_CDECL_OBJLAST);
+    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->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);
+    engine->RegisterObjectMethod("Viewport", "void RemovePostProcess(uint)", asMETHODPR(Viewport, RemovePostProcess, (unsigned), void), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Viewport", "void RemoveAllPostProcesses()", asMETHOD(Viewport, RemoveAllPostProcesses), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Viewport", "void set_scene(Scene@+)", asMETHOD(Viewport, SetScene), asCALL_THISCALL);
+    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_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);
     
     
     engine->RegisterObjectType("RenderSurface", 0, asOBJ_REF);
     engine->RegisterObjectType("RenderSurface", 0, asOBJ_REF);
     engine->RegisterObjectBehaviour("RenderSurface", asBEHAVE_ADDREF, "void f()", asMETHOD(RenderSurface, AddRef), asCALL_THISCALL);
     engine->RegisterObjectBehaviour("RenderSurface", asBEHAVE_ADDREF, "void f()", asMETHOD(RenderSurface, AddRef), asCALL_THISCALL);
@@ -290,8 +239,8 @@ static void RegisterTextures(asIScriptEngine* engine)
     engine->RegisterObjectMethod("RenderSurface", "int get_width() const", asMETHOD(RenderSurface, GetWidth), asCALL_THISCALL);
     engine->RegisterObjectMethod("RenderSurface", "int get_width() const", asMETHOD(RenderSurface, GetWidth), asCALL_THISCALL);
     engine->RegisterObjectMethod("RenderSurface", "int get_height() const", asMETHOD(RenderSurface, GetHeight), asCALL_THISCALL);
     engine->RegisterObjectMethod("RenderSurface", "int get_height() const", asMETHOD(RenderSurface, GetHeight), asCALL_THISCALL);
     engine->RegisterObjectMethod("RenderSurface", "TextureUsage get_usage() const", asMETHOD(RenderSurface, GetUsage), asCALL_THISCALL);
     engine->RegisterObjectMethod("RenderSurface", "TextureUsage get_usage() const", asMETHOD(RenderSurface, GetUsage), asCALL_THISCALL);
-    engine->RegisterObjectMethod("RenderSurface", "void set_viewport(const Viewport&in)", asMETHOD(RenderSurface, SetViewport), asCALL_THISCALL);
-    engine->RegisterObjectMethod("RenderSurface", "const Viewport& get_viewport() const", asMETHOD(RenderSurface, GetViewport), asCALL_THISCALL);
+    engine->RegisterObjectMethod("RenderSurface", "void set_viewport(Viewport@+)", asMETHOD(RenderSurface, SetViewport), asCALL_THISCALL);
+    engine->RegisterObjectMethod("RenderSurface", "Viewport@+ get_viewport() const", asMETHOD(RenderSurface, GetViewport), asCALL_THISCALL);
     engine->RegisterObjectMethod("RenderSurface", "void set_linkedRenderTarget(RenderSurface@+)", asMETHOD(RenderSurface, SetLinkedRenderTarget), asCALL_THISCALL);
     engine->RegisterObjectMethod("RenderSurface", "void set_linkedRenderTarget(RenderSurface@+)", asMETHOD(RenderSurface, SetLinkedRenderTarget), asCALL_THISCALL);
     engine->RegisterObjectMethod("RenderSurface", "RenderSurface@+ get_linkedRenderTarget() const", asMETHOD(RenderSurface, GetLinkedRenderTarget), asCALL_THISCALL);
     engine->RegisterObjectMethod("RenderSurface", "RenderSurface@+ get_linkedRenderTarget() const", asMETHOD(RenderSurface, GetLinkedRenderTarget), asCALL_THISCALL);
     engine->RegisterObjectMethod("RenderSurface", "void set_linkedDepthStencil(RenderSurface@+)", asMETHOD(RenderSurface, SetLinkedDepthStencil), asCALL_THISCALL);
     engine->RegisterObjectMethod("RenderSurface", "void set_linkedDepthStencil(RenderSurface@+)", asMETHOD(RenderSurface, SetLinkedDepthStencil), asCALL_THISCALL);
@@ -318,11 +267,11 @@ static void RegisterTextures(asIScriptEngine* engine)
 
 
 static Material* MaterialClone(const String& cloneName, Material* ptr)
 static Material* MaterialClone(const String& cloneName, Material* ptr)
 {
 {
-    SharedPtr<Material> clonedMaterial = ptr->Clone(cloneName);
+    SharedPtr<Material> clone = ptr->Clone(cloneName);
     // The shared pointer will go out of scope, so have to increment the reference count
     // The shared pointer will go out of scope, so have to increment the reference count
     // (here an auto handle can not be used)
     // (here an auto handle can not be used)
-    clonedMaterial->AddRef();
-    return clonedMaterial.Get();
+    clone->AddRef();
+    return clone.Get();
 }
 }
 
 
 static void RegisterMaterial(asIScriptEngine* engine)
 static void RegisterMaterial(asIScriptEngine* engine)
@@ -409,6 +358,15 @@ static void RegisterMaterial(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Material", "CullMode get_shadowCullMode() const", asMETHOD(Material, GetShadowCullMode), asCALL_THISCALL);
     engine->RegisterObjectMethod("Material", "CullMode get_shadowCullMode() const", asMETHOD(Material, GetShadowCullMode), asCALL_THISCALL);
 }
 }
 
 
+static PostProcess* PostProcessClone(PostProcess* ptr)
+{
+    SharedPtr<PostProcess> clone = ptr->Clone();
+    // The shared pointer will go out of scope, so have to increment the reference count
+    // (here an auto handle can not be used)
+    clone->AddRef();
+    return clone.Get();
+}
+
 static void RegisterPostProcess(asIScriptEngine* engine)
 static void RegisterPostProcess(asIScriptEngine* engine)
 {
 {
     RegisterRefCounted<PostProcessPass>(engine, "PostProcessPass");
     RegisterRefCounted<PostProcessPass>(engine, "PostProcessPass");
@@ -427,6 +385,7 @@ static void RegisterPostProcess(asIScriptEngine* engine)
     RegisterObjectConstructor<PostProcess>(engine, "PostProcess");
     RegisterObjectConstructor<PostProcess>(engine, "PostProcess");
     engine->RegisterObjectMethod("PostProcess", "bool CreateRenderTarget(const String&in, uint, uint, uint, bool, bool)", asMETHOD(PostProcess, CreateRenderTarget), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "bool CreateRenderTarget(const String&in, uint, uint, uint, bool, bool)", asMETHOD(PostProcess, CreateRenderTarget), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "void RemoveRenderTarget(const String&in)", asMETHOD(PostProcess, RemoveRenderTarget), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "void RemoveRenderTarget(const String&in)", asMETHOD(PostProcess, RemoveRenderTarget), asCALL_THISCALL);
+    engine->RegisterObjectMethod("PostProcess", "PostProcess@ Clone() const", asFUNCTION(PostProcessClone), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("PostProcess", "bool HasRenderTarget(const String&in) const", asMETHOD(PostProcess, HasRenderTarget), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "bool HasRenderTarget(const String&in) const", asMETHOD(PostProcess, HasRenderTarget), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "bool set_parameters(XMLFile@+)", asMETHOD(PostProcess, LoadParameters), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "bool set_parameters(XMLFile@+)", asMETHOD(PostProcess, LoadParameters), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "XMLFile@+ get_parameters() const", asMETHOD(PostProcess, GetParameters), asCALL_THISCALL);
     engine->RegisterObjectMethod("PostProcess", "XMLFile@+ get_parameters() const", asMETHOD(PostProcess, GetParameters), asCALL_THISCALL);
@@ -847,8 +806,8 @@ static void RegisterRenderer(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Renderer", "void DrawDebugGeometry(bool) const", asMETHOD(Renderer, DrawDebugGeometry), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void DrawDebugGeometry(bool) const", asMETHOD(Renderer, DrawDebugGeometry), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void set_numViewports(uint)", asMETHOD(Renderer, SetNumViewports), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void set_numViewports(uint)", asMETHOD(Renderer, SetNumViewports), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "uint get_numViewports() const", asMETHOD(Renderer, GetNumViewports), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "uint get_numViewports() const", asMETHOD(Renderer, GetNumViewports), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Renderer", "void set_viewports(uint, const Viewport&in)", asMETHOD(Renderer, SetViewport), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Renderer", "const Viewport& get_viewports(uint) const", asMETHOD(Renderer, GetViewport), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Renderer", "bool set_viewports(uint, Viewport@+)", asMETHOD(Renderer, SetViewport), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Renderer", "Viewport@+ get_viewports(uint) const", asMETHOD(Renderer, GetViewport), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void set_lightPrepass(bool)", asMETHOD(Renderer, SetLightPrepass), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void set_lightPrepass(bool)", asMETHOD(Renderer, SetLightPrepass), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "bool get_lightPrepass() const", asMETHOD(Renderer, GetLightPrepass), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "bool get_lightPrepass() const", asMETHOD(Renderer, GetLightPrepass), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void set_specularLighting(bool)", asMETHOD(Renderer, SetSpecularLighting), asCALL_THISCALL);
     engine->RegisterObjectMethod("Renderer", "void set_specularLighting(bool)", asMETHOD(Renderer, SetSpecularLighting), asCALL_THISCALL);

+ 5 - 38
Engine/Graphics/Direct3D9/D3D9RenderSurface.cpp

@@ -32,44 +32,10 @@
 
 
 #include "DebugNew.h"
 #include "DebugNew.h"
 
 
-Viewport::Viewport() :
-    rect_(IntRect::ZERO)
-{
-}
-
-Viewport::Viewport(Scene* scene, Camera* camera) :
-    scene_(scene),
-    camera_(camera),
-    rect_(IntRect::ZERO)
-{
-}
-
-Viewport::Viewport(Scene* scene, Camera* camera, const IntRect& rect) :
-    scene_(scene),
-    camera_(camera),
-    rect_(rect)
-{
-}
-
-Viewport::Viewport(Scene* scene, Camera* camera, const Vector<SharedPtr<PostProcess> >& postProcesses) :
-    scene_(scene),
-    camera_(camera),
-    rect_(IntRect::ZERO),
-    postProcesses_(postProcesses)
-{
-}
-
-Viewport::Viewport(Scene* scene, Camera* camera, const IntRect& rect, const Vector<SharedPtr<PostProcess> >& postProcesses) :
-    scene_(scene),
-    camera_(camera),
-    rect_(rect),
-    postProcesses_(postProcesses)
-{
-}
-
 RenderSurface::RenderSurface(Texture* parentTexture) :
 RenderSurface::RenderSurface(Texture* parentTexture) :
     parentTexture_(parentTexture),
     parentTexture_(parentTexture),
-    surface_(0)
+    surface_(0),
+    viewport_(new Viewport())
 {
 {
 }
 }
 
 
@@ -78,9 +44,10 @@ RenderSurface::~RenderSurface()
     Release();
     Release();
 }
 }
 
 
-void RenderSurface::SetViewport(const Viewport& viewport)
+void RenderSurface::SetViewport(Viewport* viewport)
 {
 {
-    viewport_ = viewport;
+    if (viewport)
+        viewport_ = viewport;
 }
 }
 
 
 void RenderSurface::SetLinkedRenderTarget(RenderSurface* renderTarget)
 void RenderSurface::SetLinkedRenderTarget(RenderSurface* renderTarget)

+ 5 - 33
Engine/Graphics/Direct3D9/D3D9RenderSurface.h

@@ -23,39 +23,11 @@
 
 
 #pragma once
 #pragma once
 
 
-#include "Rect.h"
 #include "GraphicsDefs.h"
 #include "GraphicsDefs.h"
-#include "PostProcess.h"
-#include "Ptr.h"
+#include "Viewport.h"
 
 
-class Camera;
-class Scene;
 class Texture;
 class Texture;
 
 
-/// %Viewport definition either for a render surface or the backbuffer.
-struct Viewport
-{
-    /// Construct with defaults.
-    Viewport();
-    /// Construct with a full rectangle.
-    Viewport(Scene* scene, Camera* camera);
-    /// Construct with a specified rectangle.
-    Viewport(Scene* scene, Camera* camera, const IntRect& rect);
-    /// Construct with a full rectangle and post-processing effects.
-    Viewport(Scene* scene, Camera* camera, const Vector<SharedPtr<PostProcess> >& postProcesses);
-    /// Construct with a specified rectangle and post-processing effects.
-    Viewport(Scene* scene, Camera* camera, const IntRect& rect, const Vector<SharedPtr<PostProcess> >& postProcesses);
-    
-    /// Scene pointer.
-    WeakPtr<Scene> scene_;
-    /// Camera pointer.
-    WeakPtr<Camera> camera_;
-    /// Viewport rectangle.
-    IntRect rect_;
-    /// Post-processing effects.
-    Vector<SharedPtr<PostProcess> > postProcesses_;
-};
-
 /// %Color or depth-stencil surface that can be rendered into.
 /// %Color or depth-stencil surface that can be rendered into.
 class RenderSurface : public RefCounted
 class RenderSurface : public RefCounted
 {
 {
@@ -68,8 +40,8 @@ public:
     /// Destruct.
     /// Destruct.
     ~RenderSurface();
     ~RenderSurface();
     
     
-    /// %Set viewport for auxiliary view rendering.
-    void SetViewport(const Viewport& viewport);
+    /// Set viewport for auxiliary view rendering.
+    void SetViewport(Viewport* viewport);
     /// %Set linked color rendertarget.
     /// %Set linked color rendertarget.
     void SetLinkedRenderTarget(RenderSurface* renderTarget);
     void SetLinkedRenderTarget(RenderSurface* renderTarget);
     /// %Set linked depth-stencil surface.
     /// %Set linked depth-stencil surface.
@@ -88,7 +60,7 @@ public:
     /// Return usage.
     /// Return usage.
     TextureUsage GetUsage() const;
     TextureUsage GetUsage() const;
     /// Return auxiliary view rendering viewport.
     /// Return auxiliary view rendering viewport.
-    const Viewport& GetViewport() const { return viewport_; }
+    Viewport* GetViewport() const { return viewport_; }
     /// Return linked color rendertarget.
     /// Return linked color rendertarget.
     RenderSurface* GetLinkedRenderTarget() const { return linkedRenderTarget_; }
     RenderSurface* GetLinkedRenderTarget() const { return linkedRenderTarget_; }
     /// Return linked depth-stencil surface.
     /// Return linked depth-stencil surface.
@@ -100,7 +72,7 @@ private:
     /// Direct3D surface.
     /// Direct3D surface.
     void* surface_;
     void* surface_;
     /// Viewport.
     /// Viewport.
-    Viewport viewport_;
+    SharedPtr<Viewport> viewport_;
     /// Linked color buffer.
     /// Linked color buffer.
     WeakPtr<RenderSurface> linkedRenderTarget_;
     WeakPtr<RenderSurface> linkedRenderTarget_;
     /// Linked depth buffer.
     /// Linked depth buffer.

+ 5 - 38
Engine/Graphics/OpenGL/OGLRenderSurface.cpp

@@ -32,45 +32,11 @@
 
 
 #include "DebugNew.h"
 #include "DebugNew.h"
 
 
-Viewport::Viewport() :
-    rect_(IntRect::ZERO)
-{
-}
-
-Viewport::Viewport(Scene* scene, Camera* camera) :
-    scene_(scene),
-    camera_(camera),
-    rect_(IntRect::ZERO)
-{
-}
-
-Viewport::Viewport(Scene* scene, Camera* camera, const IntRect& rect) :
-    scene_(scene),
-    camera_(camera),
-    rect_(rect)
-{
-}
-
-Viewport::Viewport(Scene* scene, Camera* camera, const Vector<SharedPtr<PostProcess> >& postProcesses) :
-    scene_(scene),
-    camera_(camera),
-    rect_(IntRect::ZERO),
-    postProcesses_(postProcesses)
-{
-}
-
-Viewport::Viewport(Scene* scene, Camera* camera, const IntRect& rect, const Vector<SharedPtr<PostProcess> >& postProcesses) :
-    scene_(scene),
-    camera_(camera),
-    rect_(rect),
-    postProcesses_(postProcesses)
-{
-}
-
 RenderSurface::RenderSurface(Texture* parentTexture, unsigned target) :
 RenderSurface::RenderSurface(Texture* parentTexture, unsigned target) :
     parentTexture_(parentTexture),
     parentTexture_(parentTexture),
     target_(target),
     target_(target),
-    renderBuffer_(0)
+    renderBuffer_(0),
+    viewport_(new Viewport())
 {
 {
 }
 }
 
 
@@ -79,9 +45,10 @@ RenderSurface::~RenderSurface()
     Release();
     Release();
 }
 }
 
 
-void RenderSurface::SetViewport(const Viewport& viewport)
+void RenderSurface::SetViewport(Viewport* viewport)
 {
 {
-    viewport_ = viewport;
+    if (viewport)
+        viewport_ = viewport;
 }
 }
 
 
 void RenderSurface::SetLinkedRenderTarget(RenderSurface* renderTarget)
 void RenderSurface::SetLinkedRenderTarget(RenderSurface* renderTarget)

+ 3 - 29
Engine/Graphics/OpenGL/OGLRenderSurface.h

@@ -24,38 +24,12 @@
 #pragma once
 #pragma once
 
 
 #include "GraphicsDefs.h"
 #include "GraphicsDefs.h"
-#include "PostProcess.h"
-#include "Rect.h"
-#include "Ptr.h"
+#include "Viewport.h"
 
 
 class Camera;
 class Camera;
 class Scene;
 class Scene;
 class Texture;
 class Texture;
 
 
-/// %Viewport definition either for a render surface or the backbuffer.
-struct Viewport
-{
-    /// Construct with defaults.
-    Viewport();
-    /// Construct with a full rectangle.
-    Viewport(Scene* scene, Camera* camera);
-    /// Construct with a specified rectangle.
-    Viewport(Scene* scene, Camera* camera, const IntRect& rect);
-    /// Construct with a full rectangle and post-processing effects.
-    Viewport(Scene* scene, Camera* camera, const Vector<SharedPtr<PostProcess> >& postProcesses);
-    /// Construct with a specified rectangle and post-processing effects.
-    Viewport(Scene* scene, Camera* camera, const IntRect& rect, const Vector<SharedPtr<PostProcess> >& postProcesses);
-    
-    /// Scene pointer.
-    WeakPtr<Scene> scene_;
-    /// Camera pointer.
-    WeakPtr<Camera> camera_;
-    /// Viewport rectangle.
-    IntRect rect_;
-    /// Post-processing effects.
-    Vector<SharedPtr<PostProcess> > postProcesses_;
-};
-
 /// %Color or depth-stencil surface that can be rendered into.
 /// %Color or depth-stencil surface that can be rendered into.
 class RenderSurface : public RefCounted
 class RenderSurface : public RefCounted
 {
 {
@@ -69,7 +43,7 @@ public:
     ~RenderSurface();
     ~RenderSurface();
     
     
     /// Set viewport for auxiliary view rendering.
     /// Set viewport for auxiliary view rendering.
-    void SetViewport(const Viewport& viewport);
+    void SetViewport(Viewport* viewport);
     /// Set linked color rendertarget.
     /// Set linked color rendertarget.
     void SetLinkedRenderTarget(RenderSurface* renderTarget);
     void SetLinkedRenderTarget(RenderSurface* renderTarget);
     /// Set linked depth-stencil surface.
     /// Set linked depth-stencil surface.
@@ -92,7 +66,7 @@ public:
     /// Return usage.
     /// Return usage.
     TextureUsage GetUsage() const;
     TextureUsage GetUsage() const;
     /// Return auxiliary view rendering viewport.
     /// Return auxiliary view rendering viewport.
-    const Viewport& GetViewport() const { return viewport_; }
+    Viewport* GetViewport() const { return viewport_; }
     /// Return linked color buffer.
     /// Return linked color buffer.
     RenderSurface* GetLinkedRenderTarget() const { return linkedRenderTarget_; }
     RenderSurface* GetLinkedRenderTarget() const { return linkedRenderTarget_; }
     /// Return linked depth buffer.
     /// Return linked depth buffer.

+ 25 - 0
Engine/Graphics/PostProcess.cpp

@@ -72,6 +72,19 @@ void PostProcessPass::SetOutput(const String& name)
     outputName_ = name;
     outputName_ = name;
 }
 }
 
 
+SharedPtr<PostProcessPass> PostProcessPass::Clone()
+{
+    SharedPtr<PostProcessPass> clone(new PostProcessPass());
+    clone->vertexShaderName_ = vertexShaderName_;
+    clone->pixelShaderName_ = pixelShaderName_;
+    clone->shaderParameters_ = shaderParameters_;
+    for (unsigned i = 0; i < MAX_MATERIAL_TEXTURE_UNITS; ++i)
+        clone->textureNames_[i] = textureNames_[i];
+    clone->outputName_ = outputName_;
+    
+    return clone;
+}
+
 const String& PostProcessPass::GetTexture(TextureUnit unit) const
 const String& PostProcessPass::GetTexture(TextureUnit unit) const
 {
 {
     return unit < MAX_MATERIAL_TEXTURE_UNITS ? textureNames_[unit] : emptyName;
     return unit < MAX_MATERIAL_TEXTURE_UNITS ? textureNames_[unit] : emptyName;
@@ -230,6 +243,18 @@ void PostProcess::SetActive(bool active)
     active_ = active;
     active_ = active;
 }
 }
 
 
+SharedPtr<PostProcess> PostProcess::Clone()
+{
+    SharedPtr<PostProcess> clone(new PostProcess(context_));
+    clone->passes_.Resize(passes_.Size());
+    for (unsigned i = 0; i < passes_.Size(); ++i)
+        clone->passes_[i] = passes_[i]->Clone();
+    clone->renderTargets_ = renderTargets_;
+    clone->active_ = active_;
+    
+    return clone;
+}
+
 PostProcessPass* PostProcess::GetPass(unsigned index) const
 PostProcessPass* PostProcess::GetPass(unsigned index) const
 {
 {
     if (index < passes_.Size())
     if (index < passes_.Size())

+ 4 - 0
Engine/Graphics/PostProcess.h

@@ -51,6 +51,8 @@ public:
     void RemoveShaderParameter(const String& name);
     void RemoveShaderParameter(const String& name);
     /// %Set output rendertarget name.
     /// %Set output rendertarget name.
     void SetOutput(const String& name);
     void SetOutput(const String& name);
+    /// Clone the post-process pass.
+    SharedPtr<PostProcessPass> Clone();
     
     
     /// Return vertex shader name.
     /// Return vertex shader name.
     const String& GetVertexShader() const { return vertexShaderName_; }
     const String& GetVertexShader() const { return vertexShaderName_; }
@@ -114,6 +116,8 @@ public:
     void RemoveRenderTarget(const String& name);
     void RemoveRenderTarget(const String& name);
     /// Set active flag.
     /// Set active flag.
     void SetActive(bool active);
     void SetActive(bool active);
+    /// Clone the post-process.
+    SharedPtr<PostProcess> Clone();
     
     
     /// Return parameter XML file.
     /// Return parameter XML file.
     XMLFile* GetParameters() const { return parameterSource_; }
     XMLFile* GetParameters() const { return parameterSource_; }

+ 28 - 13
Engine/Graphics/Renderer.cpp

@@ -256,7 +256,6 @@ static const String lightPSVariations[] =
 
 
 static const unsigned INSTANCING_BUFFER_MASK = MASK_INSTANCEMATRIX1 | MASK_INSTANCEMATRIX2 | MASK_INSTANCEMATRIX3;
 static const unsigned INSTANCING_BUFFER_MASK = MASK_INSTANCEMATRIX1 | MASK_INSTANCEMATRIX2 | MASK_INSTANCEMATRIX3;
 static const unsigned MAX_BUFFER_AGE = 2000;
 static const unsigned MAX_BUFFER_AGE = 2000;
-static const Viewport noViewport;
 
 
 OBJECTTYPESTATIC(Renderer);
 OBJECTTYPESTATIC(Renderer);
 
 
@@ -293,6 +292,7 @@ Renderer::Renderer(Context* context) :
     
     
     // Try to initialize right now, but skip if screen mode is not yet set
     // Try to initialize right now, but skip if screen mode is not yet set
     Initialize();
     Initialize();
+    SetNumViewports(1);
 }
 }
 
 
 Renderer::~Renderer()
 Renderer::~Renderer()
@@ -302,17 +302,30 @@ Renderer::~Renderer()
 void Renderer::SetNumViewports(unsigned num)
 void Renderer::SetNumViewports(unsigned num)
 {
 {
     viewports_.Resize(num);
     viewports_.Resize(num);
+    
+    for (unsigned i = 0; i < viewports_.Size(); ++i)
+    {
+        if (!viewports_[i])
+            viewports_[i] = new Viewport();
+    }
 }
 }
 
 
-void Renderer::SetViewport(unsigned index, const Viewport& viewport)
+bool Renderer::SetViewport(unsigned index, Viewport* viewport)
 {
 {
     if (index >= viewports_.Size())
     if (index >= viewports_.Size())
     {
     {
         LOGERROR("Viewport index out of bounds");
         LOGERROR("Viewport index out of bounds");
-        return;
+        return false;
+    }
+    
+    if (!viewport)
+    {
+        LOGERROR("Null viewport");
+        return false;
     }
     }
     
     
     viewports_[index] = viewport;
     viewports_[index] = viewport;
+    return true;
 }
 }
 
 
 void Renderer::SetLightPrepass(bool enable)
 void Renderer::SetLightPrepass(bool enable)
@@ -478,9 +491,9 @@ void Renderer::SetOccluderSizeThreshold(float screenSize)
     occluderSizeThreshold_ = Max(screenSize, 0.0f);
     occluderSizeThreshold_ = Max(screenSize, 0.0f);
 }
 }
 
 
-const Viewport& Renderer::GetViewport(unsigned index) const
+Viewport* Renderer::GetViewport(unsigned index) const
 {
 {
-    return index < viewports_.Size() ? viewports_[index] : noViewport;
+    return index < viewports_.Size() ? viewports_[index] : (Viewport*)0;
 }
 }
 
 
 ShaderVariation* Renderer::GetVertexShader(const String& name, bool checkExists) const
 ShaderVariation* Renderer::GetVertexShader(const String& name, bool checkExists) const
@@ -573,17 +586,19 @@ void Renderer::Update(float timeStep)
     for (unsigned i = viewports_.Size() - 1; i < viewports_.Size(); --i)
     for (unsigned i = viewports_.Size() - 1; i < viewports_.Size(); --i)
     {
     {
         unsigned mainView = numViews_;
         unsigned mainView = numViews_;
-        Viewport& viewport = viewports_[i];
-        if (!AddView(0, viewport))
+        Viewport* viewport = viewports_[i];
+        if (!viewport || !AddView(0, viewport))
             continue;
             continue;
         
         
+        const IntRect& viewRect = viewport->GetRect();
+        
         // Update octree (perform early update for drawables which need that, and reinsert moved drawables.)
         // Update octree (perform early update for drawables which need that, and reinsert moved drawables.)
         // However, if the same scene is viewed from multiple cameras, update the octree only once
         // However, if the same scene is viewed from multiple cameras, update the octree only once
-        Octree* octree = viewport.scene_->GetComponent<Octree>();
+        Octree* octree = viewport->GetScene()->GetComponent<Octree>();
         if (!updatedOctrees_.Contains(octree))
         if (!updatedOctrees_.Contains(octree))
         {
         {
-            frame_.camera_ = viewport.camera_;
-            frame_.viewSize_ = IntVector2(viewport.rect_.right_ - viewport.rect_.left_, viewport.rect_.bottom_ - viewport.rect_.top_);
+            frame_.camera_ = viewport->GetCamera();
+            frame_.viewSize_ = IntVector2(viewRect.right_ - viewRect.left_, viewRect.bottom_ - viewRect.top_);
             if (frame_.viewSize_ == IntVector2::ZERO)
             if (frame_.viewSize_ == IntVector2::ZERO)
                 frame_.viewSize_ = IntVector2(graphics_->GetWidth(), graphics_->GetHeight());
                 frame_.viewSize_ = IntVector2(graphics_->GetWidth(), graphics_->GetHeight());
             octree->Update(frame_);
             octree->Update(frame_);
@@ -591,9 +606,9 @@ void Renderer::Update(float timeStep)
             
             
             // Set also the view for the debug graphics already here, so that it can use culling
             // Set also the view for the debug graphics already here, so that it can use culling
             /// \todo May result in incorrect debug geometry culling if the same scene is drawn from multiple viewports
             /// \todo May result in incorrect debug geometry culling if the same scene is drawn from multiple viewports
-            DebugRenderer* debug = viewport.scene_->GetComponent<DebugRenderer>();
+            DebugRenderer* debug = viewport->GetScene()->GetComponent<DebugRenderer>();
             if (debug)
             if (debug)
-                debug->SetView(viewport.camera_);
+                debug->SetView(viewport->GetCamera());
         }
         }
         
         
         // Update the viewport's main view and any auxiliary views it has created
         // Update the viewport's main view and any auxiliary views it has created
@@ -698,7 +713,7 @@ void Renderer::DrawDebugGeometry(bool depthTest)
     }
     }
 }
 }
 
 
-bool Renderer::AddView(RenderSurface* renderTarget, const Viewport& viewport)
+bool Renderer::AddView(RenderSurface* renderTarget, Viewport* viewport)
 {
 {
     // If using a rendertarget texture, make sure it will not be rendered to multiple times
     // If using a rendertarget texture, make sure it will not be rendered to multiple times
     if (renderTarget)
     if (renderTarget)

+ 7 - 6
Engine/Graphics/Renderer.h

@@ -29,7 +29,7 @@
 #include "HashMap.h"
 #include "HashMap.h"
 #include "HashSet.h"
 #include "HashSet.h"
 #include "Mutex.h"
 #include "Mutex.h"
-#include "RenderSurface.h"
+#include "Viewport.h"
 
 
 class DebugRenderer;
 class DebugRenderer;
 class Geometry;
 class Geometry;
@@ -40,6 +40,7 @@ class Pass;
 class Technique;
 class Technique;
 class Octree;
 class Octree;
 class Graphics;
 class Graphics;
+class RenderSurface;
 class ResourceCache;
 class ResourceCache;
 class Skeleton;
 class Skeleton;
 class OcclusionBuffer;
 class OcclusionBuffer;
@@ -167,8 +168,8 @@ public:
     
     
     /// %Set number of viewports to render.
     /// %Set number of viewports to render.
     void SetNumViewports(unsigned num);
     void SetNumViewports(unsigned num);
-    /// %Set a viewport.
-    void SetViewport(unsigned index, const Viewport& viewport);
+    /// %Set a viewport. Return true if successful.
+    bool SetViewport(unsigned index, Viewport* viewport);
     /// %Set light prepass rendering on/off.
     /// %Set light prepass rendering on/off.
     void SetLightPrepass(bool enable);
     void SetLightPrepass(bool enable);
     /// %Set specular lighting on/off.
     /// %Set specular lighting on/off.
@@ -206,7 +207,7 @@ public:
     /// Return number of viewports.
     /// Return number of viewports.
     unsigned GetNumViewports() const { return viewports_.Size(); }
     unsigned GetNumViewports() const { return viewports_.Size(); }
     /// Return viewport.
     /// Return viewport.
-    const Viewport& GetViewport(unsigned index) const;
+    Viewport* GetViewport(unsigned index) const;
     /// Return whether light prepass rendering is enabled.
     /// Return whether light prepass rendering is enabled.
     bool GetLightPrepass() const { return lightPrepass_; }
     bool GetLightPrepass() const { return lightPrepass_; }
     /// Return whether specular lighting is enabled.
     /// Return whether specular lighting is enabled.
@@ -287,7 +288,7 @@ public:
     /// Add debug geometry to the debug renderer.
     /// Add debug geometry to the debug renderer.
     void DrawDebugGeometry(bool depthTest);
     void DrawDebugGeometry(bool depthTest);
     /// Add a view. Return true if successful.
     /// Add a view. Return true if successful.
-    bool AddView(RenderSurface* renderTarget, const Viewport& viewport);
+    bool AddView(RenderSurface* renderTarget, Viewport* viewport);
     /// Return volume geometry for a light.
     /// Return volume geometry for a light.
     Geometry* GetLightGeometry(Light* light);
     Geometry* GetLightGeometry(Light* light);
     /// Allocate a shadow map. If shadow map reuse is disabled, a different map is returned each time.
     /// Allocate a shadow map. If shadow map reuse is disabled, a different map is returned each time.
@@ -400,7 +401,7 @@ private:
     /// Saved status of screen buffer allocations for restoring.
     /// Saved status of screen buffer allocations for restoring.
     HashMap<long long, unsigned> savedScreenBufferAllocations_;
     HashMap<long long, unsigned> savedScreenBufferAllocations_;
     /// Viewports.
     /// Viewports.
-    Vector<Viewport> viewports_;
+    Vector<SharedPtr<Viewport> > viewports_;
     /// Views.
     /// Views.
     Vector<SharedPtr<View> > views_;
     Vector<SharedPtr<View> > views_;
     /// Octrees that have been updated during the frame.
     /// Octrees that have been updated during the frame.

+ 23 - 17
Engine/Graphics/View.cpp

@@ -33,6 +33,7 @@
 #include "Octree.h"
 #include "Octree.h"
 #include "Renderer.h"
 #include "Renderer.h"
 #include "ResourceCache.h"
 #include "ResourceCache.h"
+#include "PostProcess.h"
 #include "Profiler.h"
 #include "Profiler.h"
 #include "Scene.h"
 #include "Scene.h"
 #include "ShaderVariation.h"
 #include "ShaderVariation.h"
@@ -164,42 +165,47 @@ View::~View()
 {
 {
 }
 }
 
 
-bool View::Define(RenderSurface* renderTarget, const Viewport& viewport)
+bool View::Define(RenderSurface* renderTarget, Viewport* viewport)
 {
 {
-    if (!viewport.scene_ || !viewport.camera_)
+    Scene* scene = viewport->GetScene();
+    Camera* camera = viewport->GetCamera();
+    if (!scene || !camera)
         return false;
         return false;
     
     
     // If scene is loading asynchronously, it is incomplete and should not be rendered
     // If scene is loading asynchronously, it is incomplete and should not be rendered
-    if (viewport.scene_->IsAsyncLoading())
+    if (scene->IsAsyncLoading())
         return false;
         return false;
     
     
-    Octree* octree = viewport.scene_->GetComponent<Octree>();
+    Octree* octree = scene->GetComponent<Octree>();
     if (!octree)
     if (!octree)
         return false;
         return false;
     
     
     lightPrepass_ = renderer_->GetLightPrepass();
     lightPrepass_ = renderer_->GetLightPrepass();
     octree_ = octree;
     octree_ = octree;
-    camera_ = viewport.camera_;
+    camera_ = camera;
     renderTarget_ = renderTarget;
     renderTarget_ = renderTarget;
     
     
     // Get active post-processing effects on the viewport
     // Get active post-processing effects on the viewport
+    const Vector<SharedPtr<PostProcess> >& postProcesses = viewport->GetPostProcesses();
     postProcesses_.Clear();
     postProcesses_.Clear();
-    for (unsigned i = 0; i < viewport.postProcesses_.Size(); ++i)
+    for (Vector<SharedPtr<PostProcess> >::ConstIterator i = postProcesses.Begin(); i != postProcesses.End(); ++i)
     {
     {
-        PostProcess* effect = viewport.postProcesses_[i];
+        PostProcess* effect = i->Get();
         if (effect && effect->IsActive())
         if (effect && effect->IsActive())
-            postProcesses_.Push(SharedPtr<PostProcess>(effect));
+            postProcesses_.Push(*i);
     }
     }
     
     
     // Validate the rect and calculate size. If zero rect, use whole rendertarget size
     // Validate the rect and calculate size. If zero rect, use whole rendertarget size
     int rtWidth = renderTarget ? renderTarget->GetWidth() : graphics_->GetWidth();
     int rtWidth = renderTarget ? renderTarget->GetWidth() : graphics_->GetWidth();
     int rtHeight = renderTarget ? renderTarget->GetHeight() : graphics_->GetHeight();
     int rtHeight = renderTarget ? renderTarget->GetHeight() : graphics_->GetHeight();
-    if (viewport.rect_ != IntRect::ZERO)
+    const IntRect& rect = viewport->GetRect();
+    
+    if (rect != IntRect::ZERO)
     {
     {
-        viewRect_.left_ = Clamp(viewport.rect_.left_, 0, rtWidth - 1);
-        viewRect_.top_ = Clamp(viewport.rect_.top_, 0, rtHeight - 1);
-        viewRect_.right_ = Clamp(viewport.rect_.right_, viewRect_.left_ + 1, rtWidth);
-        viewRect_.bottom_ = Clamp(viewport.rect_.bottom_, viewRect_.top_ + 1, rtHeight);
+        viewRect_.left_ = Clamp(rect.left_, 0, rtWidth - 1);
+        viewRect_.top_ = Clamp(rect.top_, 0, rtHeight - 1);
+        viewRect_.right_ = Clamp(rect.right_, viewRect_.left_ + 1, rtWidth);
+        viewRect_.bottom_ = Clamp(rect.bottom_, viewRect_.top_ + 1, rtHeight);
     }
     }
     else
     else
         viewRect_ = IntRect(0, 0, rtWidth, rtHeight);
         viewRect_ = IntRect(0, 0, rtWidth, rtHeight);
@@ -2196,8 +2202,8 @@ void View::CheckMaterialForAuxView(Material* material)
                 RenderSurface* target = tex2D->GetRenderSurface();
                 RenderSurface* target = tex2D->GetRenderSurface();
                 if (target)
                 if (target)
                 {
                 {
-                    const Viewport& viewport = target->GetViewport();
-                    if (viewport.scene_ && viewport.camera_)
+                    Viewport* viewport = target->GetViewport();
+                    if (viewport->GetScene() && viewport->GetCamera())
                         renderer_->AddView(target, viewport);
                         renderer_->AddView(target, viewport);
                 }
                 }
             }
             }
@@ -2209,8 +2215,8 @@ void View::CheckMaterialForAuxView(Material* material)
                     RenderSurface* target = texCube->GetRenderSurface((CubeMapFace)j);
                     RenderSurface* target = texCube->GetRenderSurface((CubeMapFace)j);
                     if (target)
                     if (target)
                     {
                     {
-                        const Viewport& viewport = target->GetViewport();
-                        if (viewport.scene_ && viewport.camera_)
+                        Viewport* viewport = target->GetViewport();
+                        if (viewport->GetScene() && viewport->GetCamera())
                             renderer_->AddView(target, viewport);
                             renderer_->AddView(target, viewport);
                     }
                     }
                 }
                 }

+ 2 - 2
Engine/Graphics/View.h

@@ -38,8 +38,8 @@ class Octree;
 class RenderSurface;
 class RenderSurface;
 class Technique;
 class Technique;
 class Texture2D;
 class Texture2D;
+class Viewport;
 class Zone;
 class Zone;
-struct Viewport;
 struct WorkItem;
 struct WorkItem;
 
 
 /// %Geometry view space depth minimum and maximum values.
 /// %Geometry view space depth minimum and maximum values.
@@ -91,7 +91,7 @@ public:
     virtual ~View();
     virtual ~View();
     
     
     /// Define with rendertarget and viewport. Return true if successful.
     /// Define with rendertarget and viewport. Return true if successful.
-    bool Define(RenderSurface* renderTarget, const Viewport& viewport);
+    bool Define(RenderSurface* renderTarget, Viewport* viewport);
     /// Update and cull objects and construct rendering batches.
     /// Update and cull objects and construct rendering batches.
     void Update(const FrameInfo& frame);
     void Update(const FrameInfo& frame);
     /// Render batches.
     /// Render batches.