Browse Source

Ensured that GUIArea and GUIWidget use Viewport for determining size, instead of window (which was only there for input purposes)
Also refactored Viewport to be in line with our coding style

Marko Pintera 12 years ago
parent
commit
3294c5f20f

+ 1 - 2
BansheeEngine/Include/BsCamera.h

@@ -513,8 +513,7 @@ namespace BansheeEngine {
 
 		void initialize(CM::RenderTargetPtr target = nullptr,
 			float left = 0.0f, float top = 0.0f,
-			float width = 1.0f, float height = 1.0f,
-			int ZOrder = 0);
+			float width = 1.0f, float height = 1.0f);
 
 		CM::ViewportPtr getViewport() const { return mViewport; }
 

+ 0 - 2
BansheeEngine/Include/BsGUIManager.h

@@ -155,7 +155,6 @@ namespace BansheeEngine
 
 		boost::signals::connection mWindowGainedFocusConn;
 		boost::signals::connection mWindowLostFocusConn;
-		boost::signals::connection mWindowMovedOrResizedConn;
 
 		boost::signals::connection mMouseLeftWindowConn;
 
@@ -179,7 +178,6 @@ namespace BansheeEngine
 
 		void onWindowFocusGained(CM::RenderWindow& win);
 		void onWindowFocusLost(CM::RenderWindow& win);
-		void onWindowMovedOrResized(CM::RenderWindow& win);
 
 		void onMouseLeftWindow(CM::RenderWindow* win);
 

+ 3 - 1
BansheeEngine/Include/BsGUIWidget.h

@@ -70,7 +70,7 @@ namespace BansheeEngine
 		void registerArea(GUIArea* area);
 		void unregisterArea(GUIArea* area);
 
-		virtual void ownerWindowResized();
+		virtual void ownerTargetResized();
 		virtual void ownerWindowFocusChanged();
 
 		virtual void update();
@@ -89,6 +89,8 @@ namespace BansheeEngine
 		CM::Quaternion mLastFrameRotation;
 		CM::Vector3 mLastFrameScale;
 
+		boost::signals::connection mOwnerTargetResizedConn;
+
 		mutable bool mWidgetIsDirty;
 		mutable CM::Rect mBounds;
 		mutable CM::Vector<CM::HMesh>::type mCachedMeshes;

+ 2 - 2
BansheeEngine/Include/BsProfilerOverlay.h

@@ -103,10 +103,10 @@ namespace BansheeEngine
 		CM::Vector<BasicRow>::type mBasicRows;
 		CM::Vector<PreciseRow>::type mPreciseRows;
 
-		boost::signals::connection mWindowMovedOrResized;
+		boost::signals::connection mTargetResizedConn;
 		bool mIsShown;
 
-		void windowMovedOrResized(CM::RenderWindow& window);
+		void targetResized();
 		void updateAreaSizes();
 		void updateContents(const CM::ProfilerReport& report);
 	};

+ 2 - 2
BansheeEngine/Source/BsCamera.cpp

@@ -91,11 +91,11 @@ namespace BansheeEngine
     Camera::~Camera()
     {
     }
-	void Camera::initialize(RenderTargetPtr target, float left, float top, float width, float height, int ZOrder)
+	void Camera::initialize(RenderTargetPtr target, float left, float top, float width, float height)
 	{
 		target->synchonize();
 
-		mViewport = cm_shared_ptr<Viewport, PoolAlloc>(target, left, top, width, height, ZOrder);
+		mViewport = cm_shared_ptr<Viewport, PoolAlloc>(target, left, top, width, height);
 	}
 	//-----------------------------------------------------------------------
 	void Camera::setHorzFOV(const Radian& fov)

+ 1 - 2
BansheeEngine/Source/BsGUIArea.cpp

@@ -119,9 +119,8 @@ namespace BansheeEngine
 
 		if(mWidget != nullptr)
 		{
-			// TODO - It might be more appropriate to use Viewport size instead of window size
 			// Ensure the size is valid, otherwise next GUI layout update will calculate wrong element coordinates
-			updateSizeBasedOnParent(mWidget->getOwnerWindow()->getWidth(), mWidget->getOwnerWindow()->getHeight());
+			updateSizeBasedOnParent(mWidget->getTarget()->getWidth(), mWidget->getTarget()->getHeight());
 		}
 
 		mIsDirty = true;

+ 1 - 1
BansheeEngine/Source/BsGUIDropDownBox.cpp

@@ -107,7 +107,7 @@ namespace BansheeEngine
 
 		mLocalizedEntryNames = dropDownData.localizedNames;
 
-		Rect availableBounds(target->getLeft(), target->getTop(), target->getWidth(), target->getHeight());
+		Rect availableBounds(target->getX(), target->getY(), target->getWidth(), target->getHeight());
 		mRootMenu = cm_new<DropDownSubMenu>(this, placement, availableBounds, dropDownData, type, 0);
 	}
 

+ 0 - 12
BansheeEngine/Source/BsGUIManager.cpp

@@ -70,7 +70,6 @@ namespace BansheeEngine
 
 		mWindowGainedFocusConn = RenderWindowManager::instance().onFocusGained.connect(boost::bind(&GUIManager::onWindowFocusGained, this, _1));
 		mWindowLostFocusConn = RenderWindowManager::instance().onFocusLost.connect(boost::bind(&GUIManager::onWindowFocusLost, this, _1));
-		mWindowMovedOrResizedConn = RenderWindowManager::instance().onMovedOrResized.connect(boost::bind(&GUIManager::onWindowMovedOrResized, this, _1));
 
 		mMouseLeftWindowConn = Platform::onMouseLeftWindow.connect(boost::bind(&GUIManager::onMouseLeftWindow, this, _1));
 
@@ -109,7 +108,6 @@ namespace BansheeEngine
 
 		mWindowGainedFocusConn.disconnect();
 		mWindowLostFocusConn.disconnect();
-		mWindowMovedOrResizedConn.disconnect();
 
 		mMouseLeftWindowConn.disconnect();
 
@@ -1049,16 +1047,6 @@ namespace BansheeEngine
 		}
 	}
 
-	void GUIManager::onWindowMovedOrResized(RenderWindow& win)
-	{
-		for(auto& widgetInfo : mWidgets)
-		{
-			GUIWidget* widget = widgetInfo.widget;
-			if(widget->getOwnerWindow() == &win)
-				widget->ownerWindowResized();
-		}
-	}
-
 	// We stop getting mouse move events once it leaves the window, so make sure
 	// nothing stays in hover state
 	void GUIManager::onMouseLeftWindow(CM::RenderWindow* win)

+ 1 - 1
BansheeEngine/Source/BsGUIViewport.cpp

@@ -110,6 +110,6 @@ namespace BansheeEngine
 		float width = mWidth / (float)renderTarget->getWidth();
 		float height = mHeight / (float)renderTarget->getHeight();
 
-		viewport->setDimensions(x, y, width, height);
+		viewport->setArea(x, y, width, height);
 	}
 }

+ 9 - 4
BansheeEngine/Source/BsGUIWidget.cpp

@@ -38,14 +38,20 @@ namespace BansheeEngine
 		mTarget = target;
 		mOwnerWindow = ownerWindow;
 
+		mOwnerTargetResizedConn = mTarget->onResized.connect(boost::bind(&GUIWidget::ownerTargetResized, this));
+
 		GUIManager::instance().registerWidget(this);
 	}
 
 	GUIWidget::~GUIWidget()
 	{
 		if(mTarget != nullptr)
+		{
 			GUIManager::instance().unregisterWidget(this);
 
+			mOwnerTargetResizedConn.disconnect();
+		}
+
 		// Iterate over all elements in this way because each
 		// GUIElement::destroy call internally unregisters the element
 		// from the widget, and modifies the mElements array
@@ -302,7 +308,7 @@ namespace BansheeEngine
 	bool GUIWidget::inBounds(const Int2& position) const
 	{
 		// Technically GUI widget bounds can be larger than the viewport, so make sure we clip to viewport first
-		if(!getTarget()->getDimensions().contains(position))
+		if(!getTarget()->getArea().contains(position))
 			return false;
 
 		const Matrix4& worldTfrm = SO()->getWorldTfrm();
@@ -325,12 +331,11 @@ namespace BansheeEngine
 		}
 	}
 
-	void GUIWidget::ownerWindowResized()
+	void GUIWidget::ownerTargetResized()
 	{
 		for(auto& area : mAreas)
 		{
-			// TODO - It might be more appropriate to use Viewport size instead of window size
-			area->updateSizeBasedOnParent(getOwnerWindow()->getWidth(), getOwnerWindow()->getHeight());
+			area->updateSizeBasedOnParent(getTarget()->getWidth(), getTarget()->getHeight());
 		}
 	}
 

+ 11 - 14
BansheeEngine/Source/BsProfilerOverlay.cpp

@@ -1,6 +1,5 @@
 #include "BsProfilerOverlay.h"
 #include "CmSceneObject.h"
-#include "CmRenderWindowManager.h"
 #include "BsGUIWidget.h"
 #include "BsGUIArea.h"
 #include "BsGUILayout.h"
@@ -9,6 +8,7 @@
 #include "BsGUISpace.h"
 #include "BsEngineGUI.h"
 #include "CmProfiler.h"
+#include "CmViewport.h"
 
 using namespace CamelotFramework;
 
@@ -244,8 +244,6 @@ namespace BansheeEngine
 		mTitlePreciseAvgCyclesSelf(nullptr), mTitlePreciseTotalCyclesSelf(nullptr), mTitlePreciseEstOverhead(nullptr), mTitlePreciseEstOverheadSelf(nullptr)
 	{
 		setTarget(target, ownerWindow);
-
-		mWindowMovedOrResized = RenderWindowManager::instance().onMovedOrResized.connect(boost::bind(&ProfilerOverlay::windowMovedOrResized, this, _1));
 	}
 
 	ProfilerOverlay::~ProfilerOverlay()
@@ -253,8 +251,8 @@ namespace BansheeEngine
 		if(mIsShown)
 			hide();
 
-		if(mOwnerWindow != nullptr)
-			mWindowMovedOrResized.disconnect();
+		if(mTarget != nullptr)
+			mTargetResizedConn.disconnect();
 
 		if(mWidgetSO)
 			mWidgetSO->destroy();
@@ -262,12 +260,14 @@ namespace BansheeEngine
 
 	void ProfilerOverlay::setTarget(const CM::ViewportPtr& target, const CM::RenderWindowPtr& ownerWindow)
 	{
-		if(mOwnerWindow != nullptr)
-			mWindowMovedOrResized.disconnect();
+		if(mTarget != nullptr)
+			mTargetResizedConn.disconnect();
 
 		mTarget = target;
 		mOwnerWindow = ownerWindow;
 
+		mTargetResizedConn = target->onResized.connect(boost::bind(&ProfilerOverlay::targetResized, this));
+
 		if(mWidgetSO)
 			mWidgetSO->destroy();
 
@@ -375,12 +375,9 @@ namespace BansheeEngine
 		updateContents(latestReport);
 	}
 
-	void ProfilerOverlay::windowMovedOrResized(RenderWindow& window)
+	void ProfilerOverlay::targetResized()
 	{
-		if(&window != mOwnerWindow.get())
-		{
-			updateAreaSizes();
-		}
+		updateAreaSizes();
 	}
 
 	void ProfilerOverlay::updateAreaSizes()
@@ -388,8 +385,8 @@ namespace BansheeEngine
 		static const INT32 PADDING = 10;
 		static const float LABELS_CONTENT_RATIO = 0.3f;
 
-		UINT32 width = (UINT32)std::max(0, (INT32)mOwnerWindow->getWidth() - PADDING * 2);
-		UINT32 height = (UINT32)std::max(0, (INT32)(mOwnerWindow->getHeight() - PADDING * 3)/2);
+		UINT32 width = (UINT32)std::max(0, (INT32)mTarget->getWidth() - PADDING * 2);
+		UINT32 height = (UINT32)std::max(0, (INT32)(mTarget->getHeight() - PADDING * 3)/2);
 
 		UINT32 labelsWidth = Math::CeilToInt(width * LABELS_CONTENT_RATIO);
 		UINT32 contentWidth = width - labelsWidth;

+ 1 - 1
CamelotClient/Include/BsEditorWindow.h

@@ -18,7 +18,7 @@ namespace BansheeEditor
 		friend class EditorWindowManager;
 		EditorWindow();
 
-		virtual void movedOrResized();
+		virtual void resized();
 	private:
 		EditorWidgetContainer* mWidgets;
 

+ 2 - 4
CamelotClient/Include/BsEditorWindowBase.h

@@ -39,10 +39,8 @@ namespace BansheeEditor
 
 		void construct(const CM::RenderWindowPtr& renderWindow);
 		virtual void initialize();
-		virtual void movedOrResized() { }
+		virtual void resized() { }
 	private:
-		boost::signals::connection mMoveOrResizeConn;
-		
-		void movedOrResized(CM::RenderWindow& renderWindow);
+		boost::signals::connection mResizedConn;
 	};
 }

+ 1 - 1
CamelotClient/Include/BsGUIWindowFrameWidget.h

@@ -22,7 +22,7 @@ namespace BansheeEditor
 
 		virtual bool _mouseEvent(BS::GUIElement* element, const BS::GUIMouseEvent& ev);
 		virtual void ownerWindowFocusChanged();
-		virtual void ownerWindowResized();
+		virtual void ownerTargetResized();
 
 		void refreshNonClientAreas() const;
 	};

+ 1 - 1
CamelotClient/Include/BsMainEditorWindow.h

@@ -21,7 +21,7 @@ namespace BansheeEditor
 		GUIMenuBar* mMenuBar;
 		DockManager* mDockManager;
 
-		virtual void movedOrResized();
+		virtual void resized();
 
 		void updateAreas();
 	};

+ 2 - 2
CamelotClient/Source/BsEditorWindow.cpp

@@ -21,9 +21,9 @@ namespace BansheeEditor
 		cm_delete(mWidgets);
 	}
 
-	void EditorWindow::movedOrResized()
+	void EditorWindow::resized()
 	{
-		EditorWindowBase::movedOrResized();
+		EditorWindowBase::resized();
 
 		updateSize();
 	}

+ 3 - 10
CamelotClient/Source/BsEditorWindowBase.cpp

@@ -2,7 +2,6 @@
 #include "CmApplication.h"
 #include "CmSceneObject.h"
 #include "CmRenderWindow.h"
-#include "CmRenderWindowManager.h"
 
 #include "BsEditorWindowManager.h"
 #include "BsCamera.h"
@@ -38,7 +37,7 @@ namespace BansheeEditor
 
 	EditorWindowBase::~EditorWindowBase()
 	{
-		mMoveOrResizeConn.disconnect();
+		mResizedConn.disconnect();
 
 		if(mOwnsRenderWindow)
 			mRenderWindow->destroy();
@@ -68,7 +67,7 @@ namespace BansheeEditor
 		mSceneObject = SceneObject::create("EditorWindow");
 
 		mCamera = mSceneObject->addComponent<Camera>();
-		mCamera->initialize(renderWindow, 0.0f, 0.0f, 1.0f, 1.0f, 0);
+		mCamera->initialize(renderWindow, 0.0f, 0.0f, 1.0f, 1.0f);
 		mCamera->setNearClipDistance(5);
 		mCamera->setAspectRatio(1.0f);
 		mCamera->setIgnoreSceneRenderables(true);
@@ -81,13 +80,7 @@ namespace BansheeEditor
 		mWindowFrame = mSceneObject->addComponent<WindowFrameWidget>(mCamera->getViewport().get(), renderWindow.get(), EngineGUI::instance().getSkin());
 		mWindowFrame->setDepth(129);
 
-		mMoveOrResizeConn = RenderWindowManager::instance().onMovedOrResized.connect(boost::bind(&EditorWindowBase::movedOrResized, this, _1));
-	}
-
-	void EditorWindowBase::movedOrResized(RenderWindow& renderWindow)
-	{
-		if(&renderWindow == mRenderWindow.get())
-			movedOrResized();
+		mResizedConn = mCamera->getViewport()->onResized.connect(boost::bind(&EditorWindowBase::resized, this));
 	}
 
 	void EditorWindowBase::setPosition(CM::INT32 x, CM::INT32 y)

+ 2 - 2
CamelotClient/Source/BsGUIWindowFrameWidget.cpp

@@ -55,9 +55,9 @@ namespace BansheeEditor
 		GUIWidget::ownerWindowFocusChanged();
 	}
 
-	void WindowFrameWidget::ownerWindowResized()
+	void WindowFrameWidget::ownerTargetResized()
 	{
-		GUIWidget::ownerWindowResized();
+		GUIWidget::ownerTargetResized();
 
 		refreshNonClientAreas();
 	}

+ 3 - 3
CamelotClient/Source/BsMainEditorWindow.cpp

@@ -48,7 +48,7 @@ namespace BansheeEditor
 
 		RenderTexturePtr sceneRenderTarget = RenderTexture::create(TEX_TYPE_2D, 800, 600);
 
-		sceneCamera->initialize(sceneRenderTarget, 0.0f, 0.0f, 1.0f, 1.0f, 0);
+		sceneCamera->initialize(sceneRenderTarget, 0.0f, 0.0f, 1.0f, 1.0f);
 		sceneCamera->setPriority(-1);
 		sceneCameraGO->setPosition(Vector3(0,50,1240));
 		sceneCameraGO->lookAt(Vector3(0,50,-300));
@@ -83,9 +83,9 @@ namespace BansheeEditor
 		cm_delete(mMenuBar);
 	}
 
-	void MainEditorWindow::movedOrResized()
+	void MainEditorWindow::resized()
 	{
-		EditorWindowBase::movedOrResized();
+		EditorWindowBase::resized();
 
 		updateAreas();
 	}

+ 1 - 1
CamelotCore/Include/CmRenderTarget.h

@@ -92,7 +92,7 @@ namespace CamelotFramework
 		virtual void copyToMemory(const PixelData &dst, FrameBuffer buffer = FB_AUTO) = 0;
 		virtual bool requiresTextureFlipping() const = 0;
 
-		mutable boost::signal<void(RenderTarget*)> onMovedOrResized;
+		mutable boost::signal<void()> onResized;
     protected:
 		RenderTarget();
 

+ 0 - 1
CamelotCore/Include/CmRenderWindowManager.h

@@ -26,7 +26,6 @@ namespace CamelotFramework
 
 		boost::signal<void(RenderWindow&)> onFocusGained;
 		boost::signal<void(RenderWindow&)> onFocusLost;
-		boost::signal<void(RenderWindow&)> onMovedOrResized;
 	protected:
 		friend class RenderWindow;
 

+ 85 - 162
CamelotCore/Include/CmViewport.h

@@ -1,156 +1,88 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-    (Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org/
-
-Copyright (c) 2000-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
-#ifndef __Viewport_H__
-#define __Viewport_H__
+#pragma once
 
 #include "CmPrerequisites.h"
 #include "CmCommonEnums.h"
 #include "CmColor.h"
 #include "CmRect.h"
+#include "CmFRect.h"
 #include <boost/signals/connection.hpp>
 
-namespace CamelotFramework {
-	/** \addtogroup Core
-	*  @{
-	*/
-	/** \addtogroup RenderSystem
-	*  @{
-	*/
-	/** An abstraction of a viewport, i.e. a rendering region on a render
-        target.
-        @remarks
-            A viewport is the meeting of a camera and a rendering surface -
-            the camera renders the scene from a viewpoint, and places its
-            results into some subset of a rendering target, which may be the
-            whole surface or just a part of the surface. Each viewport has a
-            single camera as source and a single target as destination. A
-            camera only has 1 viewport, but a render target may have several.
-            A viewport also has a Z-order, i.e. if there is more than one
-            viewport on a single render target and they overlap, one must
-            obscure the other in some predetermined way.
-    */
+namespace CamelotFramework 
+{
+	/**
+	 * @brief	Viewport provides you with a way to render to only a part of a 
+	 * 			RenderTarget. It also allows you to set up color/depth/stencil
+	 * 			clear values for that specific region.
+	 */
 	class CM_EXPORT Viewport
     {
     public:       
 		Viewport();
-        /** The usual constructor.
-            @param
-                cam Pointer to a camera to be the source for the image.
-            @param
-                target Pointer to the render target to be the destination
-                for the rendering.
-            @param
-                left
-            @param
-                top
-            @param
-                width
-            @param
-                height
-                Dimensions of the viewport, expressed as a value between
-                0 and 1. This allows the dimensions to apply irrespective of
-                changes in the target's size: e.g. to fill the whole area,
-                values of 0,0,1,1 are appropriate.
-            @param
-                ZOrder Relative Z-order on the target. Lower = further to
-                the front.
-        */
-        Viewport(
-            RenderTargetPtr target,
-            float left = 0.0f, float top = 0.0f,
-            float width = 1.0f, float height = 1.0f,
-            int ZOrder = 0);
-
-        /** Default destructor.
-        */
+        
+        /**
+         * @brief	Constructs a new viewport.
+         *
+         * @note	Viewport coordinates are normalized in [0, 1] range.
+         */
+        Viewport(const RenderTargetPtr& target, float x = 0.0f, float y = 0.0f, float width = 1.0f, float height = 1.0f);
         virtual ~Viewport();
 
-        /** Retrieves a pointer to the render target for this viewport.
-        */
-        RenderTargetPtr getTarget(void) const;
-
-		/** Gets one of the relative dimensions of the viewport,
-            a value between 0.0 and 1.0.
-        */
-        float getNormalizedLeft(void) const;
-
-        /** Gets one of the relative dimensions of the viewport, a value
-            between 0.0 and 1.0.
-        */
-        float getNormalizedTop(void) const;
-
-        /** Gets one of the relative dimensions of the viewport, a value
-            between 0.0 and 1.0.
-        */
-
-        float getNormalizedWidth(void) const;
-        /** Gets one of the relative dimensions of the viewport, a value
-            between 0.0 and 1.0.
-        */
-
-        float getNormalizedHeight(void) const;
-        /** Gets one of the actual dimensions of the viewport, a value in
-            pixels.
-        */
-
-        int getLeft(void) const;
-        /** Gets one of the actual dimensions of the viewport, a value in
-            pixels.
-        */
-
-        int getTop(void) const;
-        /** Gets one of the actual dimensions of the viewport, a value in
-            pixels.
-        */
-        int getWidth(void) const;
-        /** Gets one of the actual dimensions of the viewport, a value in
-            pixels.
-        */
-
-        int getHeight(void) const;
+        /**
+         * @brief	Returns the render target the viewport is associated with.
+         */
+        RenderTargetPtr getTarget() const { return mTarget; }
+
+        /**
+         * @brief	Gets the normalized x coordinate of the viewport, in [0, 1] range.
+         */
+        float getNormalizedX() const { return mNormArea.x; }
+
+        /**
+         * @brief	Gets the normalized y coordinate of the viewport, in [0, 1] range.
+         */
+        float getNormalizedY() const { return mNormArea.y; }
+
+        /**
+         * @brief	Gets the normalized width of the viewport, in [0, 1] range.
+         */
+        float getNormalizedWidth() const { return mNormArea.width; }
+
+		/**
+         * @brief	Gets the normalized height of the viewport, in [0, 1] range.
+         */
+        float getNormalizedHeight() const { return mNormArea.height; }
+
+        /**
+         * @brief	Gets the actual x coordinate of the viewport in pixels, in [0, RenderTargetWidth] range.
+         */
+        INT32 getX() const { return mArea.x; }
+
+        /**
+         * @brief	Gets the actual y coordinate of the viewport in pixels, in [0, RenderTargetHeight] range.
+         */
+        INT32 getY() const { return mArea.y; }
+
+		/**
+         * @brief	Gets the actual width coordinate of the viewport in pixels, in [0, RenderTargetWidth] range.
+         */
+        INT32 getWidth() const { return mArea.width; }
+
+		/**
+         * @brief	Gets the actual height coordinate of the viewport in pixels, in [0, RenderTargetHeight] range.
+         */
+        INT32 getHeight() const { return mArea.height; }
                
-        /** Sets the dimensions (after creation).
-            @param
-                left
-            @param
-                top
-            @param
-                width
-            @param
-                height Dimensions relative to the size of the target,
-                represented as real values between 0 and 1. i.e. the full
-                target area is 0, 0, 1, 1.
-        */
-        void setDimensions(float left, float top, float width, float height);
-
-		/** Access to actual dimensions (based on target size).
-        */
-		const Rect& getDimensions() const { return mDimensions; }
+        /**
+         * @brief	Changes the area that the viewport covers.
+         *
+         * @note	Viewport coordinates are normalized in [0, 1] range.
+         */
+        void setArea(float x, float y, float width, float height);
+
+		/**
+		 * @brief	Returns actual area of the viewport, in pixels.
+		 */
+		const Rect& getArea() const { return mArea; }
 
 		const Color& getClearColor() const { return mClearColor; }
 		void setClearColor(const Color& clearColor) { mClearColor = clearColor; }
@@ -170,35 +102,26 @@ namespace CamelotFramework {
 		bool getRequiresStencilClear() const { return mRequiresStencilClear; }
 		void setRequiresStencilClear(bool requiresClear) { mRequiresStencilClear = requiresClear; }
 
+		boost::signal<void()> onResized;
     protected:
         RenderTargetPtr mTarget;
-        // Relative dimensions, irrespective of target dimensions (0..1)
-        float mRelLeft, mRelTop, mRelWidth, mRelHeight;
-        // Actual dimensions, based on target dimensions
-		Rect mDimensions;
-		bool mRequiresColorClear, mRequiresDepthClear, mRequiresStencilClear;
+
+		FRect mNormArea;
+		Rect mArea;
+
+		bool mRequiresColorClear;
+		bool mRequiresDepthClear;
+		bool mRequiresStencilClear;
+
 		Color mClearColor;
 		float mDepthClearValue;
 		UINT16 mStencilClearValue;
 
-		boost::signals::connection mTargetConn;
+		boost::signals::connection mTargetResizedConn;
 
-		static const Color DefaultClearColor;
+		static const Color DEFAULT_CLEAR_COLOR;
 
-		/** Notifies the viewport of a possible change in dimensions.
-            @remarks
-                Used by the target to update the viewport's dimensions
-                (usually the result of a change in target size).
-            @note
-                Internal use by engine only.
-        */
-        void updateDimensions(void);
-
-		void targetResized(RenderTarget* target);
+        void updateArea();
+		void targetResized();
     };
-	/** @} */
-	/** @} */
-
-}
-
-#endif
+}

+ 0 - 3
CamelotCore/Source/CmRenderWindow.cpp

@@ -57,9 +57,6 @@ namespace CamelotFramework
 	void RenderWindow::_windowMovedOrResized()
 	{
 		THROW_IF_NOT_CORE_THREAD;
-
-		if(!onMovedOrResized.empty())
-			onMovedOrResized(this);
 	}
 
 	void RenderWindow::_windowFocusReceived()

+ 3 - 5
CamelotCore/Source/CmRenderWindowManager.cpp

@@ -95,12 +95,10 @@ namespace CamelotFramework
 			mWindowInFocus = newWinInFocus;
 		}
 
-		if(!onMovedOrResized.empty())
+		for(auto& window : movedOrResizedWindows)
 		{
-			for(auto& window : movedOrResizedWindows)
-			{
-				onMovedOrResized(*window);
-			}
+			if(!window->onResized.empty())
+				window->onResized();
 		}
 	}
 

+ 27 - 114
CamelotCore/Source/CmViewport.cpp

@@ -1,30 +1,3 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-    (Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org/
-
-Copyright (c) 2000-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
 #include "CmViewport.h"
 
 #include "CmException.h"
@@ -34,122 +7,62 @@ THE SOFTWARE.
 
 namespace CamelotFramework 
 {
-	const Color Viewport::DefaultClearColor = Color(143.0f / 255.0f, 111.0f / 255.0f, 0);
+	const Color Viewport::DEFAULT_CLEAR_COLOR = Color(143.0f / 255.0f, 111.0f / 255.0f, 0);
 
 	Viewport::Viewport()
-		:mTarget(nullptr)
-		, mRelLeft(0)
-		, mRelTop(0)
-		, mRelWidth(0)
-		, mRelHeight(0)
-		, mClearColor(DefaultClearColor)
-		, mRequiresColorClear(true)
-		, mRequiresDepthClear(true)
-		, mRequiresStencilClear(false)
-		, mStencilClearValue(0)
-		, mDepthClearValue(1.0f)
+		:mTarget(nullptr), mClearColor(DEFAULT_CLEAR_COLOR), mRequiresColorClear(true), mRequiresDepthClear(true), 
+		mRequiresStencilClear(false), mStencilClearValue(0), mDepthClearValue(1.0f)
 	{
-		// Calculate actual dimensions
-		updateDimensions();
+		updateArea();
 	}
 
-    Viewport::Viewport(RenderTargetPtr target, float left, float top, float width, float height, int ZOrder)
-         :mTarget(target)
-        , mRelLeft(left)
-        , mRelTop(top)
-        , mRelWidth(width)
-        , mRelHeight(height)
-		, mClearColor(DefaultClearColor)
-		, mRequiresColorClear(true)
-		, mRequiresDepthClear(true)
-		, mRequiresStencilClear(false)
-		, mStencilClearValue(0)
-		, mDepthClearValue(1.0f)
+    Viewport::Viewport(const RenderTargetPtr& target, float x, float y, float width, float height)
+         :mTarget(target), mNormArea(x, y, width, height), mClearColor(DEFAULT_CLEAR_COLOR), mRequiresColorClear(true), 
+		 mRequiresDepthClear(true), mRequiresStencilClear(false), mStencilClearValue(0), mDepthClearValue(1.0f)
     {
 		if(target != nullptr)
 		{
-			mTargetConn = target->onMovedOrResized.connect(boost::bind(&Viewport::targetResized, this, _1));
+			// Note: RenderTarget resize will only get triggered for RenderWindows, RenderTextures are immutable
+			mTargetResizedConn = target->onResized.connect(boost::bind(&Viewport::targetResized, this));
 		}
 
-        // Calculate actual dimensions
-        updateDimensions();
+        updateArea();
     }
 
     Viewport::~Viewport()
     {
-		mTargetConn.disconnect();
+		mTargetResizedConn.disconnect();
     }
 
-	void Viewport::targetResized(RenderTarget* target)
+	void Viewport::targetResized()
 	{
-		updateDimensions();
+		updateArea();
+
+		if(!onResized.empty())
+			onResized();
 	}
 
-    void Viewport::updateDimensions(void)
+    void Viewport::updateArea()
     {
 		if(mTarget != nullptr)
 		{
 			float height = (float) mTarget->getHeight();
 			float width = (float) mTarget->getWidth();
 
-			mDimensions.x = (int) (mRelLeft * width);
-			mDimensions.y = (int) (mRelTop * height);
-			mDimensions.width = (int) (mRelWidth * width);
-			mDimensions.height = (int) (mRelHeight * height);
+			mArea.x = (int) (mNormArea.x * width);
+			mArea.y = (int) (mNormArea.y * height);
+			mArea.width = (int) (mNormArea.width * width);
+			mArea.height = (int) (mNormArea.height * height);
 		}
     }
 
-    RenderTargetPtr Viewport::getTarget(void) const
-    {
-        return mTarget;
-    }
-
-    float Viewport::getNormalizedLeft(void) const
+    void Viewport::setArea(float x, float y, float width, float height)
     {
-        return mRelLeft;
-    }
-
-    float Viewport::getNormalizedTop(void) const
-    {
-        return mRelTop;
-    }
+        mNormArea.x = x;
+        mNormArea.y = y;
+        mNormArea.width = width;
+        mNormArea.height = height;
 
-    float Viewport::getNormalizedWidth(void) const
-    {
-        return mRelWidth;
-    }
-
-    float Viewport::getNormalizedHeight(void) const
-    {
-        return mRelHeight;
-    }
-
-    int Viewport::getLeft(void) const
-    {
-        return mDimensions.x;
-    }
-
-    int Viewport::getTop(void) const
-    {
-        return mDimensions.y;
-    }
-
-    int Viewport::getWidth(void) const
-    {
-        return mDimensions.width;
-    }
-
-    int Viewport::getHeight(void) const
-    {
-        return mDimensions.height;
-    }
-
-    void Viewport::setDimensions(float left, float top, float width, float height)
-    {
-        mRelLeft = left;
-        mRelTop = top;
-        mRelWidth = width;
-        mRelHeight = height;
-        updateDimensions();
+        updateArea();
     }
 }

+ 2 - 2
CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp

@@ -313,8 +313,8 @@ namespace CamelotFramework
 		setRenderTarget(target);
 
 		// set viewport dimensions
-		mViewport.TopLeftX = (FLOAT)vp->getLeft();
-		mViewport.TopLeftY = (FLOAT)vp->getTop();
+		mViewport.TopLeftX = (FLOAT)vp->getX();
+		mViewport.TopLeftY = (FLOAT)vp->getY();
 		mViewport.Width = (FLOAT)vp->getWidth();
 		mViewport.Height = (FLOAT)vp->getHeight();
 

+ 4 - 4
CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp

@@ -1152,11 +1152,11 @@ namespace CamelotFramework
 		// set viewport dimensions
 		mViewportWidth = vp->getWidth();
 		mViewportHeight = vp->getHeight();
-		mViewportLeft = vp->getLeft();
-		mViewportTop = vp->getTop();
+		mViewportLeft = vp->getX();
+		mViewportTop = vp->getY();
 
-		d3dvp.X = vp->getLeft();
-		d3dvp.Y = vp->getTop();
+		d3dvp.X = vp->getX();
+		d3dvp.Y = vp->getY();
 		d3dvp.Width = vp->getWidth();
 		d3dvp.Height = vp->getHeight();
 		if (target->requiresTextureFlipping())

+ 2 - 2
CamelotGLRenderer/Source/CmGLRenderSystem.cpp

@@ -578,8 +578,8 @@ namespace CamelotFramework
 		// Calculate the "lower-left" corner of the viewport
 		mViewportWidth = vp->getWidth();
 		mViewportHeight = vp->getHeight();
-		mViewportLeft = vp->getLeft();
-		mViewportTop = vp->getTop();
+		mViewportLeft = vp->getX();
+		mViewportTop = vp->getY();
 
 		if (!target->requiresTextureFlipping())
 		{

+ 15 - 1
TODO.txt

@@ -11,9 +11,23 @@ LONGTERM TODO:
 PROFILER:
  TODO: Profiler is right now including windows.h. I need to work around that but don't feel like bothering with it atm
   - Easy way would be to move CPUProfiler outside of Utility and into Core
-Fix GUIWidget so it can render to a regular render target, not just render window
+
+When rendering GUI in front of scene view it seems to be rendering before the actual scene!?
+
+Update GUIWidget input handling:
+ - Remove RenderWindow from GUIWidget constructor
+ - Remove getOwnerWindow from GUIWidget
+ - GUIWidget ownerWindowFocusChanged will also likely need to be replaced
+
+ - If GUIWidget target is a window, GUIManager can detect it and automatically use that as the input source
+   - GUIRenderTexture are special GUI elements that are registered with GUIManager (add a new type derived from GUITexture)
+   - If a GUIWidget target is a render texture GUIManager can detect that as well and figure out the real parent and offset the input
+
 Generating a report only generates it on the active thread. I need a way to generate profiler reports on the render thread as well. Maybe extend CoreThreadAccessor?
 
+
+
+
 I still re-create GUIWidget mesh every frame instead of just updating it.
 
 MAJOR ISSUE: writeSubresource/readSubresoure doesn't require a shared ptr to GpuResourceData which means it could get destroyed while still in command queue. Right now it only works because I block right after I call those methods, which ensures nothing is destroyed.