Explorar o código

Adding scene color to deferred renderer, and sharing gbuffer depth for forward rendering (WIP part 2)

BearishSun %!s(int64=10) %!d(string=hai) anos
pai
achega
92ff9bb4b9

+ 21 - 3
BansheeCore/Include/BsCoreRenderer.h

@@ -100,6 +100,8 @@ namespace BansheeEngine
 		 *
 		 * @note	Sim thread.
 		 *			Internal method.
+		 *			
+		 * @see		RendererMeshData
 		 */
 		virtual RendererMeshDataPtr _createMeshData(UINT32 numVertices, UINT32 numIndices, VertexLayout layout, IndexType indexType = IT_32BIT);
 
@@ -108,6 +110,8 @@ namespace BansheeEngine
 		 *
 		 * @note	Sim thread.
 		 *			Internal method.
+		 *			
+		 * @see		RendererMeshData
 		 */
 		virtual RendererMeshDataPtr _createMeshData(const MeshDataPtr& meshData);
 
@@ -117,13 +121,18 @@ namespace BansheeEngine
 		 * @param	camera			Camera for which to trigger the callback.
 		 * @param	index			Index that determines the order of rendering when there are multiple registered callbacks.
 		 *							This must be unique. Lower indices get rendered sooner. Indices below 0 get rendered before the
-		 *							main viewport elements, while indices equal or greater to zero, after.
+		 *							main viewport elements, while indices equal or greater to zero after. 
 		 * @param	callback		Callback to trigger when the specified camera is being rendered.
+		 * @param	isOverlay		If true the render callback guarantees that it will only render overlay data. Overlay data doesn't
+		 * 							require a depth buffer, a multisampled render target and is usually cheaper to render (although
+		 * 							this depends on the exact renderer). 
+		 * 							
+		 *							Overlay callbacks are always rendered after all other callbacks, even if their index is negative.
 		 *
 		 * @note	Core thread.
 		 *			Internal method.
 		 */
-		void _registerRenderCallback(const CameraCore* camera, INT32 index, const std::function<void()>& callback);
+		void _registerRenderCallback(const CameraCore* camera, INT32 index, const std::function<void()>& callback, bool isOverlay = false);
 
 		/**
 		 * @brief	Removes a previously registered callback registered with "_registerRenderCallback".
@@ -141,6 +150,15 @@ namespace BansheeEngine
 		virtual SPtr<CoreRendererOptions> getOptions() const { return SPtr<CoreRendererOptions>(); }
 
 	protected:
-		UnorderedMap<const CameraCore*, Map<INT32, std::function<void()>>> mRenderCallbacks;
+		/**
+		 * @brief	Contains information about a render callback.
+		 */
+		struct RenderCallbackData
+		{
+			bool overlay;
+			std::function<void()> callback;
+		};
+
+		UnorderedMap<const CameraCore*, Map<INT32, RenderCallbackData>> mRenderCallbacks;
 	};
 }

+ 3 - 2
BansheeCore/Source/BsCoreRenderer.cpp

@@ -26,9 +26,10 @@ namespace BansheeEngine
 			RendererMeshData(meshData));
 	}
 
-	void CoreRenderer::_registerRenderCallback(const CameraCore* camera, INT32 index, const std::function<void()>& callback)
+	void CoreRenderer::_registerRenderCallback(const CameraCore* camera, INT32 index, 
+		const std::function<void()>& callback, bool isOverlay)
 	{
-		mRenderCallbacks[camera][index] = callback;
+		mRenderCallbacks[camera][index] = { isOverlay, callback };
 	}
 
 	void CoreRenderer::_unregisterRenderCallback(const CameraCore* camera, INT32 index)

+ 10 - 0
BansheeEngine/Include/BsCCamera.h

@@ -197,6 +197,16 @@ namespace BansheeEngine
 		 */
 		void setLayers(UINT64 layers) { mInternal->setLayers(layers); }
 
+		/**
+		 * @copydoc	Camera::getFlags
+		 */
+		CameraFlags getFlags() const { return mInternal->getFlags(); }
+
+		/**
+		 * @copydoc	Camera::setFlags
+		 */
+		void setFlags(const CameraFlags& flags) { mInternal->setFlags(flags); }
+
 		/**
 		 * @copydoc	Camera::worldToScreenPoint
 		 */

+ 21 - 0
BansheeEngine/Include/BsCamera.h

@@ -36,6 +36,16 @@ namespace BansheeEngine
         FRUSTUM_PLANE_BOTTOM = 5
     };
 
+	/**
+	 * @brief	Flags that describe a camera.
+	 */
+	enum class CameraFlags
+	{
+		/** This flag is a signal to the renderer that his camera will only render overlays and doesn't require depth   
+		 * buffer or multi-sampled render targets. */
+		Overlay 
+	};
+
 	/**
 	 * @brief	Camera determines how is world geometry projected onto a 2D surface. You may
 	 *			position and orient it in space, set options like aspect ratio and field or view
@@ -313,6 +323,16 @@ namespace BansheeEngine
 		 */
 		void setLayers(UINT64 layers) { mLayers = layers; _markCoreDirty(); }
 
+		/**
+		 * @brief	Retrieves flags that define the camera.
+		 */
+		CameraFlags getFlags() const { return (CameraFlags)mCameraFlags; }
+
+		/**
+		 * @brief	Sets flags that define the camera.
+		 */
+		void setFlags(const CameraFlags& flags) { mCameraFlags = (UINT32)flags; _markCoreDirty(); }
+
 		/**
 		 * @brief	Converts a point in world space to screen coordinates (in pixels
 		 *			corresponding to the render target attached to the camera).
@@ -476,6 +496,7 @@ namespace BansheeEngine
 
     protected:
 		UINT64 mLayers; /**< Bitfield that can be used for filtering what objects the camera sees. */
+		UINT32 mCameraFlags; /**< Flags that further determine type of camera. */
 
 		Vector3 mPosition; /**< World space position. */
 		Quaternion mRotation; /**< World space rotation. */

+ 4 - 0
BansheeEngine/Include/BsCameraRTTI.h

@@ -15,6 +15,9 @@ namespace BansheeEngine
 		UINT64& getLayers(Camera* obj) { return obj->mLayers; }
 		void setLayers(Camera* obj, UINT64& val) { obj->mLayers = val; }
 
+		UINT32& getFlags(Camera* obj) { return obj->mCameraFlags; }
+		void setFlags(Camera* obj, UINT32& val) { obj->mCameraFlags = val; }
+
 		Vector3& getPosition(Camera* obj) { return obj->mPosition; }
 		void setPosition(Camera* obj, Vector3& val) { obj->mPosition = val; }
 
@@ -96,6 +99,7 @@ namespace BansheeEngine
 			addPlainField("mRight", 19, &CameraRTTI::getRight, &CameraRTTI::setRight);
 			addPlainField("mTop", 20, &CameraRTTI::getTop, &CameraRTTI::setTop);
 			addPlainField("mBottom", 21, &CameraRTTI::getBottom, &CameraRTTI::setBottom);
+			addPlainField("mFlags", 22, &CameraRTTI::getFlags, &CameraRTTI::setFlags);
 		}
 
 		virtual void onDeserializationEnded(IReflectable* obj) override

+ 4 - 3
BansheeEngine/Source/BsCamera.cpp

@@ -21,7 +21,7 @@ namespace BansheeEngine
 		:mProjType(PT_PERSPECTIVE), mHorzFOV(Radian(Math::PI / 4.0f)), mFarDist(1000.0f),
 		mNearDist(0.05f), mAspect(1.33333333333333f), mOrthoHeight(1000), mRecalcFrustum(true), mRecalcFrustumPlanes(true),
 		mCustomViewMatrix(false), mCustomProjMatrix(false), mFrustumExtentsManuallySet(false), mPriority(0), 
-		mLayers(0xFFFFFFFFFFFFFFFF), mRecalcView(true)
+		mLayers(0xFFFFFFFFFFFFFFFF), mRecalcView(true), mCameraFlags(0)
 	{
 		mViewMatrix = Matrix4::ZERO;
 		mProjMatrixRS = Matrix4::ZERO;
@@ -722,6 +722,7 @@ namespace BansheeEngine
 		dataPtr = rttiReadElem(mCustomViewMatrix, dataPtr);
 		dataPtr = rttiReadElem(mCustomProjMatrix, dataPtr);
 		dataPtr = rttiReadElem(mFrustumExtentsManuallySet, dataPtr);
+		dataPtr = rttiReadElem(mCameraFlags, dataPtr);
 
 		mRecalcFrustum = true;
 		mRecalcFrustumPlanes = true;
@@ -792,11 +793,10 @@ namespace BansheeEngine
 		size += rttiGetElemSize(mAspect);
 		size += rttiGetElemSize(mOrthoHeight);
 		size += rttiGetElemSize(mPriority);
-
 		size += rttiGetElemSize(mCustomViewMatrix);
 		size += rttiGetElemSize(mCustomProjMatrix);
-
 		size += rttiGetElemSize(mFrustumExtentsManuallySet);
+		size += rttiGetElemSize(mCameraFlags);
 
 		UINT8* buffer = allocator->alloc(size);
 
@@ -814,6 +814,7 @@ namespace BansheeEngine
 		dataPtr = rttiWriteElem(mCustomViewMatrix, dataPtr);
 		dataPtr = rttiWriteElem(mCustomProjMatrix, dataPtr);
 		dataPtr = rttiWriteElem(mFrustumExtentsManuallySet, dataPtr);
+		dataPtr = rttiWriteElem(mCameraFlags, dataPtr);
 
 		return CoreSyncData(buffer, size);
 	}

+ 1 - 1
BansheeEngine/Source/BsGUIManager.cpp

@@ -1644,7 +1644,7 @@ namespace BansheeEngine
 					auto insertedData = mPerCameraData.insert(std::make_pair(newCameraData.first, Vector<RenderData>()));
 					renderData = &insertedData.first->second;
 
-					activeRenderer->_registerRenderCallback(camera.get(), -30, std::bind(&GUIManagerCore::render, this, camera));
+					activeRenderer->_registerRenderCallback(camera.get(), -30, std::bind(&GUIManagerCore::render, this, camera), true);
 					validCameras.insert(camera);
 				}
 

+ 27 - 9
RenderBeast/Source/BsRenderBeast.cpp

@@ -511,9 +511,8 @@ namespace BansheeEngine
 
 		mStaticHandler->updatePerCameraBuffers(cameraShaderData);
 
-		// Render scene objects to g-buffer if there are any
-		const Vector<RenderQueueElement>& opaqueElements = camData.opaqueQueue->getSortedElements();
-		bool hasGBuffer = opaqueElements.size() > 0;
+		// Render scene objects to g-buffer
+		bool hasGBuffer = ((UINT32)camera->getFlags() & (UINT32)CameraFlags::Overlay) == 0;
 
 		if (hasGBuffer)
 		{
@@ -530,6 +529,7 @@ namespace BansheeEngine
 			UINT32 clearBuffers = FBT_COLOR | FBT_DEPTH | FBT_STENCIL;
 			RenderAPICore::instance().clearViewport(clearBuffers, Color::ZERO, 1.0f, 0);
 
+			const Vector<RenderQueueElement>& opaqueElements = camData.opaqueQueue->getSortedElements();
 			for (auto iter = opaqueElements.begin(); iter != opaqueElements.end(); ++iter)
 			{
 				BeastRenderableElement* renderElem = static_cast<BeastRenderableElement*>(iter->renderElem);
@@ -592,10 +592,12 @@ namespace BansheeEngine
 		{
 			for (auto& callbackPair : iterCameraCallbacks->second)
 			{
-				if (callbackPair.first >= 0)
+				const RenderCallbackData& callbackData = callbackPair.second;
+
+				if (callbackData.overlay || callbackPair.first >= 0)
 					break;
 
-				callbackPair.second();
+				callbackData.callback();
 			}
 		}
 
@@ -680,15 +682,31 @@ namespace BansheeEngine
 		camData.opaqueQueue->clear();
 		camData.transparentQueue->clear();
 
-		// Render post-scene callbacks
+		// Render non-overlay post-scene callbacks
 		if (iterCameraCallbacks != mRenderCallbacks.end())
 		{
 			for (auto& callbackPair : iterCameraCallbacks->second)
 			{
-				if (callbackPair.first < 0)
-					continue;
+				const RenderCallbackData& callbackData = callbackPair.second;
+
+				if (callbackData.overlay || callbackPair.first < 0)
+					break;
+
+				callbackData.callback();
+			}
+		}
+
+		// Render overlay post-scene callbacks
+		if (iterCameraCallbacks != mRenderCallbacks.end())
+		{
+			for (auto& callbackPair : iterCameraCallbacks->second)
+			{
+				const RenderCallbackData& callbackData = callbackPair.second;
+
+				if (!callbackData.overlay)
+					break;
 
-				callbackPair.second();
+				callbackData.callback();
 			}
 		}