Przeglądaj źródła

GUIViewport works

Marko Pintera 12 lat temu
rodzic
commit
7e61e8215e

+ 5 - 0
BansheeEngine/Include/BsGUIViewport.h

@@ -53,6 +53,11 @@ namespace BansheeEngine
 		 */
 		virtual void updateBounds();
 
+		/**
+		 * @copydoc GUIElement::updateRenderElementsInternal()
+		 */
+		virtual void updateRenderElementsInternal();
+
 		virtual CM::UINT32 _getOptimalWidth() const;
 		virtual CM::UINT32 _getOptimalHeight() const;
 

+ 6 - 0
BansheeEngine/Source/BsGUIViewport.cpp

@@ -96,6 +96,12 @@ namespace BansheeEngine
 	void GUIViewport::fillBuffer(UINT8* vertices, UINT8* uv, UINT32* indices, UINT32 startingQuad, UINT32 maxNumQuads, 
 		UINT32 vertexStride, UINT32 indexStride, UINT32 renderElementIdx) const
 	{
+
+	}
+
+	void GUIViewport::updateRenderElementsInternal()
+	{
+		// TODO - This doesn't get called if element mesh is dirty!!! and I need to update the viewport when offset changes (in which case mesh is marked as dirty)
 		float currentAspect = mWidth / (float)mHeight;
 		Radian currentFOV = 2.0f * Math::ATan(Math::Tan(mVerticalFOV * 0.5f) * currentAspect);
 

+ 22 - 11
BansheeForwardRenderer/Source/BsForwardRenderer.cpp

@@ -71,28 +71,39 @@ namespace BansheeEngine
 			std::sort(begin(cameras), end(cameras), cameraComparer);
 		}
 
-		// Clear all targets
+		// Render everything, target by target
 		for(auto& camerasPerTarget : camerasPerRenderTarget)
 		{
 			RenderTargetPtr target = camerasPerTarget.target;
 			const Vector<HCamera>::type& cameras = camerasPerTarget.cameras;
 
-			coreAccessor.clear(target, FBT_COLOR | FBT_DEPTH, Color::Blue);
 			coreAccessor.beginFrame();
 
 			for(auto& camera : cameras)
 			{
-				// Render all cameras
-				for(auto& camera : cameras)
-					render(camera);
+				ViewportPtr viewport = camera->getViewport();
 
-				// Render overlays for all targets
-				for(auto& camera : cameras)
-					OverlayManager::instance().render(camera->getViewport(), coreAccessor);
+				UINT32 clearBuffers = 0;
+				if(viewport->getRequiresColorClear())
+					clearBuffers |= FBT_COLOR;
 
-				// Render all GUI elements
-				for(auto& camera : cameras)
-					GUIManager::instance().render(camera->getViewport(), coreAccessor);
+				if(viewport->getRequiresDepthClear())
+					clearBuffers |= FBT_DEPTH;
+
+				if(viewport->getRequiresStencilClear())
+					clearBuffers |= FBT_STENCIL;
+
+				if(clearBuffers != 0)
+					coreAccessor.clear(target, clearBuffers, viewport->getClearColor(), viewport->getClearDepthValue(), viewport->getClearStencilValue(), viewport->getDimensions());
+
+				// Render scene
+				render(camera);
+
+				// Render overlays
+				OverlayManager::instance().render(camera->getViewport(), coreAccessor);
+
+				// Render GUI elements
+				GUIManager::instance().render(camera->getViewport(), coreAccessor);
 			}
 
 			coreAccessor.endFrame();

+ 2 - 2
CamelotClient/CamelotClient.cpp

@@ -37,8 +37,8 @@
 #include "CmCursor.h"
 
 //#define DX11
-#define DX9
-//#define GL
+//#define DX9
+#define GL
 
 using namespace CamelotFramework;
 using namespace BansheeEditor;

+ 4 - 3
CamelotClient/Source/BsMainEditorWindow.cpp

@@ -21,9 +21,10 @@ namespace BansheeEditor
 		HSceneObject sceneCameraGO = SceneObject::create("SceneCamera");
 		HCamera sceneCamera = sceneCameraGO->addComponent<Camera>();
 
-		RenderTexturePtr sceneRenderTarget = RenderTexture::create(TEX_TYPE_2D, 800, 600);
+		//RenderTexturePtr sceneRenderTarget = RenderTexture::create(TEX_TYPE_2D, 800, 600);
 
-		sceneCamera->initialize(sceneRenderTarget, 0.0f, 0.0f, 1.0f, 1.0f, 0);
+		sceneCamera->initialize(mCamera->getViewport()->getTarget(), 0.0f, 0.0f, 1.0f, 1.0f, 0);
+		sceneCamera->setPriority(-1);
 		sceneCameraGO->setPosition(Vector3(0,50,1240));
 		sceneCameraGO->lookAt(Vector3(0,50,-300));
 		sceneCamera->setNearClipDistance(5);
@@ -34,7 +35,7 @@ namespace BansheeEditor
 		GameObjectHandle<TestTextSprite> textSprite = mSceneObject->addComponent<TestTextSprite>();
 		textSprite->initialize(mCamera->getViewport().get(), renderWindow.get());
 
-		textSprite->init(mCamera, "Testing in a new row, does this work?", sceneRenderTarget);
+		textSprite->init(sceneCamera, "Testing in a new row, does this work?", nullptr);
 	}
 
 	MainEditorWindow::~MainEditorWindow()

+ 4 - 2
CamelotClient/Source/CmTestTextSprite.cpp

@@ -14,6 +14,8 @@
 #include "BsGUITexture.h"
 #include "BsGUIArea.h"
 #include "BsGUILayout.h"
+#include "BsGUIViewport.h"
+#include "BsCamera.h"
 
 using namespace BansheeEngine;
 
@@ -34,8 +36,8 @@ namespace CamelotFramework
 
 		GUIArea* area = GUIArea::createStretchedXY(*this, 0, 0, 0, 0);
 
-		SpriteTexturePtr spriteTex = std::make_shared<SpriteTexture>(sceneView->getBindableColorTexture());
-		area->getLayout().addElement(GUITexture::create(*this, GUILayoutOptions::fixed(800, 600), spriteTex));
+		//SpriteTexturePtr spriteTex = std::make_shared<SpriteTexture>(sceneView->getBindableColorTexture());
+		area->getLayout().addElement(GUIViewport::create(*this, GUILayoutOptions::fixed(800, 600), camera, camera->getAspectRatio(), camera->getHorzFOV()));
 	}
 
 	void TestTextSprite::update()

+ 2 - 2
CamelotCore/Include/CmCoreThreadAccessor.h

@@ -174,9 +174,9 @@ namespace CamelotFramework
 		}
 
 		/** @copydoc RenderSystem::clear() */
-		void clear(RenderTargetPtr target, unsigned int buffers, const Color& color = Color::Black, float depth = 1.0f, unsigned short stencil = 0)
+		void clear(RenderTargetPtr target, UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0, const Rect& clearArea = Rect::EMPTY)
 		{
-			mCommandQueue->queue(boost::bind(&RenderSystem::clear, RenderSystem::instancePtr(), target, buffers, color, depth, stencil));
+			mCommandQueue->queue(boost::bind(&RenderSystem::clear, RenderSystem::instancePtr(), target, buffers, color, depth, stencil, boost::cref(clearArea)));
 		}
 
 		/** @copydoc RenderSystem::swapBuffers() */

+ 3 - 3
CamelotCore/Include/CmRenderSystem.h

@@ -258,7 +258,7 @@ namespace CamelotFramework
 		@param left, top, right, bottom The location of the corners of the rectangle, expressed in
 		<i>pixels</i>.
 		*/
-		virtual void setScissorRect(UINT32 left = 0, UINT32 top = 0, UINT32 right = 800, UINT32 bottom = 600) = 0;
+		virtual void setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom) = 0;
 
 		/** Clears the provided render target to the specified values
 		@param renderTarget Render target to clear. Entire surface will be cleared
@@ -269,9 +269,9 @@ namespace CamelotFramework
 		@param depth The value to initialise the depth buffer with, if enabled
 		@param stencil The value to initialise the stencil buffer with, if enabled.
 		*/
-		virtual void clear(RenderTargetPtr renderTarget, unsigned int buffers, 
+		virtual void clear(RenderTargetPtr renderTarget, UINT32 buffers, 
 			const Color& color = Color::Black, 
-			float depth = 1.0f, unsigned short stencil = 0) = 0;
+			float depth = 1.0f, UINT16 stencil = 0, const Rect& clearArea = Rect::EMPTY) = 0;
 
 		/**
          * Set current render target to target, enabling its device context if needed

+ 23 - 4
CamelotCore/Include/CmViewport.h

@@ -94,8 +94,6 @@ namespace CamelotFramework {
         */
         RenderTargetPtr getTarget(void) const;
 
-        /** Gets the Z-Order of this viewport. */
-		int getZOrder(void) const;
 		/** Gets one of the relative dimensions of the viewport,
             a value between 0.0 and 1.0.
         */
@@ -154,17 +152,38 @@ namespace CamelotFramework {
         */
 		const Rect& getDimensions() const { return mDimensions; }
 
+		const Color& getClearColor() const { return mClearColor; }
+		void setClearColor(const Color& clearColor) { mClearColor = clearColor; }
+
+		float getClearDepthValue() const { return mDepthClearValue; }
+		void getClearDepthValue(float value) { mDepthClearValue = value; }
+
+		UINT16 getClearStencilValue() const { return mStencilClearValue; }
+		void setStencilClearValue(UINT16 value) { mStencilClearValue = value; }
+
+		bool getRequiresColorClear() const { return mRequiresColorClear; }
+		void setRequiresColorClear(bool requiresClear) { mRequiresColorClear = requiresClear; }
+
+		bool getRequiresDepthClear() const { return mRequiresDepthClear; }
+		void setRequiresDepthClear(bool requiresClear) { mRequiresDepthClear = requiresClear; }
+
+		bool getRequiresStencilClear() const { return mRequiresStencilClear; }
+		void setRequiresStencilClear(bool requiresClear) { mRequiresStencilClear = requiresClear; }
+
     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;
+		Color mClearColor;
+		float mDepthClearValue;
+		UINT16 mStencilClearValue;
 
 		boost::signals::connection mTargetConn;
 
-        /// ZOrder
-        int mZOrder;
+		static const Color DefaultClearColor;
 
 		/** Notifies the viewport of a possible change in dimensions.
             @remarks

+ 14 - 9
CamelotCore/Source/CmViewport.cpp

@@ -34,14 +34,20 @@ THE SOFTWARE.
 
 namespace CamelotFramework 
 {
+	const Color Viewport::DefaultClearColor = Color(143.0f / 255.0f, 111.0f / 255.0f, 0);
+
 	Viewport::Viewport()
 		:mTarget(nullptr)
 		, mRelLeft(0)
 		, mRelTop(0)
 		, mRelWidth(0)
 		, mRelHeight(0)
-		// Actual dimensions will update later
-		, mZOrder(0)
+		, mClearColor(DefaultClearColor)
+		, mRequiresColorClear(true)
+		, mRequiresDepthClear(true)
+		, mRequiresStencilClear(false)
+		, mStencilClearValue(0)
+		, mDepthClearValue(1.0f)
 	{
 		// Calculate actual dimensions
 		updateDimensions();
@@ -53,8 +59,12 @@ namespace CamelotFramework
         , mRelTop(top)
         , mRelWidth(width)
         , mRelHeight(height)
-        // Actual dimensions will update later
-        , mZOrder(ZOrder)
+		, mClearColor(DefaultClearColor)
+		, mRequiresColorClear(true)
+		, mRequiresDepthClear(true)
+		, mRequiresStencilClear(false)
+		, mStencilClearValue(0)
+		, mDepthClearValue(1.0f)
     {
 		if(target != nullptr)
 		{
@@ -89,11 +99,6 @@ namespace CamelotFramework
 		}
     }
 
-	int Viewport::getZOrder(void) const
-	{
-		return mZOrder;
-	}
-
     RenderTargetPtr Viewport::getTarget(void) const
     {
         return mTarget;

+ 2 - 2
CamelotD3D11RenderSystem/Include/CmD3D11RenderSystem.h

@@ -30,11 +30,11 @@ namespace CamelotFramework
 
 		void beginFrame();
 		void endFrame();
-		void clear(RenderTargetPtr target, unsigned int buffers, const Color& color = Color::Black, float depth = 1.0f, unsigned short stencil = 0);
+		void clear(RenderTargetPtr target, UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0, const Rect& clearArea = Rect::EMPTY);
 
 		void setRenderTarget(RenderTargetPtr target);
 		void setViewport(ViewportPtr& vp);
-		void setScissorRect(UINT32 left = 0, UINT32 top = 0, UINT32 right = 800, UINT32 bottom = 600);
+		void setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom);
 
 		void setVertexBuffer(UINT32 index, const VertexBufferPtr& buffer);
 		void setIndexBuffer(const IndexBufferPtr& buffer);

+ 1 - 1
CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp

@@ -571,7 +571,7 @@ namespace CamelotFramework
 		mDevice->getImmediateContext()->RSSetScissorRects(1, &mScissorRect);
 	}
 
-	void D3D11RenderSystem::clear(RenderTargetPtr target, unsigned int buffers, const Color& color, float depth, unsigned short stencil)
+	void D3D11RenderSystem::clear(RenderTargetPtr target, UINT32 buffers, const Color& color, float depth, UINT16 stencil, const Rect& clearArea)
 	{
 		THROW_IF_NOT_CORE_THREAD;
 

+ 3 - 4
CamelotD3D9Renderer/Include/CmD3D9RenderSystem.h

@@ -148,10 +148,9 @@ namespace CamelotFramework
 		 */
 		void drawIndexed(UINT32 startIndex, UINT32 indexCount, UINT32 vertexCount);
 
-        void setScissorRect(UINT32 left = 0, UINT32 top = 0, UINT32 right = 800, UINT32 bottom = 600);
-        void clear(RenderTargetPtr target, unsigned int buffers, 
-            const Color& colour = Color::Black, 
-            float depth = 1.0f, unsigned short stencil = 0);
+        void setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom);
+        void clear(RenderTargetPtr target, UINT32 buffers, const Color& colour = Color::Black, 
+            float depth = 1.0f, UINT16 stencil = 0, const Rect& clearArea = Rect::EMPTY);
 
 		void convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest, bool forGpuProgram = false);
 

+ 2 - 2
CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp

@@ -1367,8 +1367,8 @@ namespace CamelotFramework
 		}
 	}
 	//---------------------------------------------------------------------
-	void D3D9RenderSystem::clear(RenderTargetPtr target, unsigned int buffers, 
-		const Color& colour, float depth, unsigned short stencil)
+	void D3D9RenderSystem::clear(RenderTargetPtr target, UINT32 buffers, 
+		const Color& colour, float depth, UINT16 stencil, const Rect& clearArea)
 	{
 		THROW_IF_NOT_CORE_THREAD;
 

+ 3 - 3
CamelotGLRenderer/Include/CmGLRenderSystem.h

@@ -84,7 +84,7 @@ namespace CamelotFramework {
         /**
 		 * @copydoc RenderSystem::setScissorRect()
 		 */
-        void setScissorRect(UINT32 left = 0, UINT32 top = 0, UINT32 right = 800, UINT32 bottom = 600) ;
+        void setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom);
 
 		/**
 		 * @copydoc RenderSystem::setTexture()
@@ -154,9 +154,9 @@ namespace CamelotFramework {
 		/**
 		 * @copydoc RenderSystem::clear()
 		 */
-        void clear(RenderTargetPtr target, unsigned int buffers, 
+        void clear(RenderTargetPtr target, UINT32 buffers, 
             const Color& colour = Color::Black, 
-            float depth = 1.0f, unsigned short stencil = 0);
+            float depth = 1.0f, UINT16 stencil = 0, const Rect& clearArea = Rect::EMPTY);
 
         /**
 		 * @copydoc RenderSystem::getColorVertexElementType()

+ 2 - 2
CamelotGLRenderer/Source/CmGLRenderSystem.cpp

@@ -727,8 +727,8 @@ namespace CamelotFramework
 		mScissorRight = right;
 	}
 	//---------------------------------------------------------------------
-	void GLRenderSystem::clear(RenderTargetPtr target, unsigned int buffers, 
-		const Color& colour, float depth, unsigned short stencil)
+	void GLRenderSystem::clear(RenderTargetPtr target, UINT32 buffers, 
+		const Color& colour, float depth, UINT16 stencil, const Rect& clearArea)
 	{
 		THROW_IF_NOT_CORE_THREAD;
 

+ 2 - 0
CamelotUtility/Include/CmRect.h

@@ -35,5 +35,7 @@ namespace CamelotFramework
 		{
 			return !(*this == rhs);
 		}
+
+		static const Rect EMPTY;
 	};
 }

+ 2 - 0
CamelotUtility/Source/CmRect.cpp

@@ -5,6 +5,8 @@
 
 namespace CamelotFramework
 {
+	const Rect Rect::EMPTY = Rect();
+
 	Rect::Rect()
 		:x(0), y(0), width(0), height(0)
 	{ }

+ 5 - 0
EditorWindowDock.txt

@@ -27,6 +27,11 @@ Drag and drop manager currently ignores the provided icon, but it should use it
 
 Prevent docking if available size is less than 20 pixels, otherwise there might be some weirdness
 
+GUIViewport:
+ - MAJOR TODO - Don't forget to update GUIViewport is to also gets updated when only mesh is dirty!
+ - Test DX11 and GL
+ - Clear the viewport before rendering. (Add Viewport.requiresClear)
+
 ------------------------
 
 Other things to remember: