瀏覽代碼

Added a priority to call custom render callbacks
Handles now properly render over all other geometry and effects

Marko Pintera 10 年之前
父節點
當前提交
2ed4268993

+ 23 - 18
BansheeCore/Include/BsCoreRenderer.h

@@ -97,6 +97,24 @@ namespace BansheeEngine
 		 */
 		virtual RendererMeshDataPtr _createMeshData(const MeshDataPtr& meshData);
 
+		/**
+		 * @brief	Registers a new callback that will be executed when the the specify camera is being rendered.
+		 *
+		 * @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 to greater to zero, after.
+		 * @param	callback		Callback to trigger when the specified camera is being rendered.
+		 *
+		 * @note	Core thread.
+		 *			Internal method.
+		 */
+		void _registerRenderCallback(const CameraHandlerCore* camera, INT32 index, const std::function<void()>& callback);
+
+		/**
+		 * @brief	Removes a previously registered callback registered with "_registerRenderCallback".
+		 */
+		void _unregisterRenderCallback(const CameraHandlerCore* camera, INT32 index);
 
 		/**
 		 * @brief	Activates the specified pass on the pipeline.
@@ -104,38 +122,25 @@ namespace BansheeEngine
 		 * @param	material	Parent material of the pass.
 		 * @param	passIdx		Index of the pass in the parent material.
 		 *
-		 * @note	Core thread only.
+		 * @note	Core thread.
 		 */
 		static void setPass(const SPtr<MaterialCore>& material, UINT32 passIdx);
 
 		/**
 		 * @brief	Draws the specified mesh proxy with last set pass.
 		 *
-		 * @note	Core thread only.
+		 * @note	Core thread.
 		 */
 		static void draw(const SPtr<MeshCoreBase>& mesh, const SubMesh& subMesh);
 
 		/**
 		 * @brief	Callback that gets triggered before a viewport gets rendered.
 		 *
-		 * @note	Sim thread only
+		 * @note	Sim thread.
 		 */
 		Event<void(const Viewport*, DrawList&)> onRenderViewport;
 
-		/**
-		 * @brief	Callback that gets triggered before main render queue items are rendered
-		 *			to the provided viewport, called from the core thread directly.
-		 *
-		 * @note	Core thread only.
-		 */
-		Event<void(const CameraHandlerCore&)> onCorePreRenderViewport;
-
-		/**
-		 * @brief	Callback that gets triggered after main render queue items are rendered,
-		 *			to the provided viewport, called from the core thread directly.
-		 *
-		 * @note	Core thread only.
-		 */
-		Event<void(const CameraHandlerCore&)> onCorePostRenderViewport;
+	protected:
+		UnorderedMap<const CameraHandlerCore*, Map<UINT32, std::function<void()>>> mRenderCallbacks;
 	};
 }

+ 17 - 0
BansheeCore/Source/BsCoreRenderer.cpp

@@ -22,6 +22,23 @@ namespace BansheeEngine
 			RendererMeshData(meshData));
 	}
 
+	void CoreRenderer::_registerRenderCallback(const CameraHandlerCore* camera, INT32 index, const std::function<void()>& callback)
+	{
+		mRenderCallbacks[camera][index] = callback;
+	}
+
+	void CoreRenderer::_unregisterRenderCallback(const CameraHandlerCore* camera, INT32 index)
+	{
+		auto iterFind = mRenderCallbacks.find(camera);
+		if (iterFind != mRenderCallbacks.end())
+		{
+			iterFind->second.erase(index);
+
+			if (iterFind->second.empty())
+				mRenderCallbacks.erase(iterFind);
+		}
+	}
+
 	void CoreRenderer::setPass(const SPtr<MaterialCore>& material, UINT32 passIdx)
 	{
 		THROW_IF_NOT_CORE_THREAD;

+ 3 - 3
BansheeEditor/Include/BsGizmoManager.h

@@ -214,16 +214,16 @@ namespace BansheeEngine
 	private:
 		void initialize(const GizmoManager::CoreInitData& initData);
 
-		void render(const CameraHandlerCore& camera);
+		void render();
 		void renderGizmos(Matrix4 viewMatrix, Matrix4 projMatrix, SPtr<MeshCoreBase> mesh, GizmoManager::GizmoMaterial material);
 		void renderIconGizmos(Rect2I screenArea, SPtr<MeshCoreBase> mesh, GizmoManager::IconRenderDataVecPtr renderData, bool usePickingMaterial);
 
-		void updateData(const SPtr<RenderTargetCore>& rt, const SPtr<MeshCoreBase>& solidMesh, const SPtr<MeshCoreBase>& wireMesh,
+		void updateData(const SPtr<CameraHandlerCore>& camera, const SPtr<MeshCoreBase>& solidMesh, const SPtr<MeshCoreBase>& wireMesh,
 			const SPtr<MeshCoreBase>& iconMesh, const GizmoManager::IconRenderDataVecPtr& iconRenderData);
 
 		static const float PICKING_ALPHA_CUTOFF;
 
-		SPtr<RenderTargetCore> mSceneRenderTarget;
+		SPtr<CameraHandlerCore> mCamera;
 
 		SPtr<MeshCoreBase> mSolidMesh;
 		SPtr<MeshCoreBase> mWireMesh;

+ 3 - 3
BansheeEditor/Include/BsHandleDrawManager.h

@@ -84,10 +84,10 @@ namespace BansheeEngine
 
 		void initialize(const SPtr<MaterialCore>& wireMat, const SPtr<MaterialCore>& solidMat);
 
-		void updateData(const SPtr<RenderTargetCore>& rt, const Vector<MeshData>& meshes);
-		void render(const CameraHandlerCore& camera);
+		void updateData(const SPtr<CameraHandlerCore>& camera, const Vector<MeshData>& meshes);
+		void render();
 
-		SPtr<RenderTargetCore> mSceneRenderTarget;
+		SPtr<CameraHandlerCore> mCamera;
 		Vector<MeshData> mMeshes;
 
 		// Immutable

+ 3 - 3
BansheeEditor/Include/BsSelectionRenderer.h

@@ -44,11 +44,11 @@ namespace BansheeEngine
 	private:
 		void initialize(const SPtr<MaterialCore>& mat);
 
-		void render(const CameraHandlerCore& camera);
-		void updateData(const SPtr<RenderTargetCore>& rt, const Vector<SelectionRenderer::ObjectData>& objects);
+		void render();
+		void updateData(const SPtr<CameraHandlerCore>& camera, const Vector<SelectionRenderer::ObjectData>& objects);
 
-		SPtr<RenderTargetCore> mSceneRenderTarget;
 		Vector<SelectionRenderer::ObjectData> mObjects;
+		SPtr<CameraHandlerCore> mCamera;
 
 		// Immutable
 		SPtr<MaterialCore> mMaterial;

+ 21 - 16
BansheeEditor/Source/BsGizmoManager.cpp

@@ -235,7 +235,6 @@ namespace BansheeEngine
 		if (mIconMesh != nullptr)
 			mIconMeshHeap->dealloc(mIconMesh);
 
-		RenderTargetPtr rt = camera->getViewport()->getTarget();
 		IconRenderDataVecPtr iconRenderData;
 
 		mDrawHelper->buildMeshes();
@@ -264,7 +263,7 @@ namespace BansheeEngine
 		mIconMesh = buildIconMesh(camera, mIconData, false, iconRenderData);
 		SPtr<MeshCoreBase> iconMesh = mIconMesh->getCore();
 
-		gCoreAccessor().queueCommand(std::bind(&GizmoManagerCore::updateData, mCore, rt->getCore(), 
+		gCoreAccessor().queueCommand(std::bind(&GizmoManagerCore::updateData, mCore, camera->getCore(),
 			solidMesh, wireMesh, iconMesh, iconRenderData));
 	}
 
@@ -699,33 +698,39 @@ namespace BansheeEngine
 			mAlphaPickingMaterial.mFragParams->getParam("alphaCutoff", alphaCutoffParam);
 			alphaCutoffParam.set(PICKING_ALPHA_CUTOFF);
 		}
-
-		CoreRendererPtr activeRenderer = RendererManager::instance().getActive();
-		activeRenderer->onCorePostRenderViewport.connect(std::bind(&GizmoManagerCore::render, this, _1));
 	}
 
-	void GizmoManagerCore::updateData(const SPtr<RenderTargetCore>& rt, const SPtr<MeshCoreBase>& solidMesh, const SPtr<MeshCoreBase>& wireMesh,
+	void GizmoManagerCore::updateData(const SPtr<CameraHandlerCore>& camera, const SPtr<MeshCoreBase>& solidMesh, const SPtr<MeshCoreBase>& wireMesh,
 		const SPtr<MeshCoreBase>& iconMesh, const GizmoManager::IconRenderDataVecPtr& iconRenderData)
 	{
-		mSceneRenderTarget = rt;
+		if (mCamera != camera)
+		{
+			CoreRendererPtr activeRenderer = RendererManager::instance().getActive();
+			if (mCamera != nullptr)
+				activeRenderer->_unregisterRenderCallback(mCamera.get(), 0);
+
+			if (camera != nullptr)
+				activeRenderer->_registerRenderCallback(camera.get(), 0, std::bind(&GizmoManagerCore::render, this));
+		}
+
+		mCamera = camera;
 		mSolidMesh = solidMesh;
 		mWireMesh = wireMesh;
 		mIconMesh = iconMesh;
 		mIconRenderData = iconRenderData;
 	}
 
-	void GizmoManagerCore::render(const CameraHandlerCore& camera)
+	void GizmoManagerCore::render()
 	{
-		if (mSceneRenderTarget == nullptr)
+		if (mCamera == nullptr)
 			return;
 
-		if (camera.getViewport()->getTarget() != mSceneRenderTarget)
-			return;
+		SPtr<RenderTargetCore> renderTarget = mCamera->getViewport()->getTarget();
 
-		float width = (float)mSceneRenderTarget->getProperties().getWidth();
-		float height = (float)mSceneRenderTarget->getProperties().getHeight();
+		float width = (float)renderTarget->getProperties().getWidth();
+		float height = (float)renderTarget->getProperties().getHeight();
 
-		Rect2 normArea = camera.getViewport()->getNormArea();
+		Rect2 normArea = mCamera->getViewport()->getNormArea();
 
 		Rect2I screenArea;
 		screenArea.x = (int)(normArea.x * width);
@@ -734,10 +739,10 @@ namespace BansheeEngine
 		screenArea.height = (int)(normArea.height * height);
 
 		if (mSolidMesh != nullptr)
-			renderGizmos(camera.getViewMatrix(), camera.getProjectionMatrixRS(), mSolidMesh, GizmoManager::GizmoMaterial::Solid);
+			renderGizmos(mCamera->getViewMatrix(), mCamera->getProjectionMatrixRS(), mSolidMesh, GizmoManager::GizmoMaterial::Solid);
 
 		if (mWireMesh != nullptr)
-			renderGizmos(camera.getViewMatrix(), camera.getProjectionMatrixRS(), mWireMesh, GizmoManager::GizmoMaterial::Wire);
+			renderGizmos(mCamera->getViewMatrix(), mCamera->getProjectionMatrixRS(), mWireMesh, GizmoManager::GizmoMaterial::Wire);
 
 		if (mIconMesh != nullptr)
 			renderIconGizmos(screenArea, mIconMesh, mIconRenderData, false);

+ 20 - 16
BansheeEditor/Source/BsHandleDrawManager.cpp

@@ -175,10 +175,8 @@ namespace BansheeEngine
 			}
 		}
 
-		RenderTargetPtr sceneRenderTarget = camera->getViewport()->getTarget();
-
 		gCoreAccessor().queueCommand(std::bind(&HandleDrawManagerCore::updateData, mCore, 
-			sceneRenderTarget->getCore(), proxyData));
+			camera->getCore(), proxyData));
 
 		mDrawHelper->clear();
 	}
@@ -199,31 +197,37 @@ namespace BansheeEngine
 
 			vertParams->getParam("matViewProj", mSolidMaterial.mViewProj);
 		}
-
-		CoreRendererPtr activeRenderer = RendererManager::instance().getActive();
-		activeRenderer->onCorePostRenderViewport.connect(std::bind(&HandleDrawManagerCore::render, this, _1));
 	}
 
-	void HandleDrawManagerCore::updateData(const SPtr<RenderTargetCore>& rt, const Vector<MeshData>& meshes)
+	void HandleDrawManagerCore::updateData(const SPtr<CameraHandlerCore>& camera, const Vector<MeshData>& meshes)
 	{
-		mSceneRenderTarget = rt;
+		if (mCamera != camera)
+		{
+			CoreRendererPtr activeRenderer = RendererManager::instance().getActive();
+			if (mCamera != nullptr)
+				activeRenderer->_unregisterRenderCallback(mCamera.get(), 20);
+
+			if (camera != nullptr)
+				activeRenderer->_registerRenderCallback(camera.get(), 20, std::bind(&HandleDrawManagerCore::render, this));
+		}
+
+		mCamera = camera;
 		mMeshes = meshes;
 	}
 
-	void HandleDrawManagerCore::render(const CameraHandlerCore& camera)
+	void HandleDrawManagerCore::render()
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
-		if (mSceneRenderTarget == nullptr)
+		if (mCamera == nullptr)
 			return;
 
-		if (camera.getViewport()->getTarget() != mSceneRenderTarget)
-			return;
+		SPtr<RenderTargetCore> renderTarget = mCamera->getViewport()->getTarget();
 
-		float width = (float)mSceneRenderTarget->getProperties().getWidth();
-		float height = (float)mSceneRenderTarget->getProperties().getHeight();
+		float width = (float)renderTarget->getProperties().getWidth();
+		float height = (float)renderTarget->getProperties().getHeight();
 
-		Rect2 normArea = camera.getViewport()->getNormArea();
+		Rect2 normArea = mCamera->getViewport()->getNormArea();
 
 		Rect2I screenArea;
 		screenArea.x = (int)(normArea.x * width);
@@ -231,7 +235,7 @@ namespace BansheeEngine
 		screenArea.width = (int)(normArea.width * width);
 		screenArea.height = (int)(normArea.height * height);
 
-		Matrix4 viewProjMat = camera.getProjectionMatrixRS() * camera.getViewMatrix();
+		Matrix4 viewProjMat = mCamera->getProjectionMatrixRS() * mCamera->getViewMatrix();
 		mSolidMaterial.mViewProj.set(viewProjMat);
 		mWireMaterial.mViewProj.set(viewProjMat);
 

+ 17 - 14
BansheeEditor/Source/BsSelectionRenderer.cpp

@@ -43,7 +43,7 @@ namespace BansheeEngine
 
 	void SelectionRenderer::update(const CameraHandlerPtr& camera)
 	{
-		Vector<SelectionRenderer::ObjectData> objects;
+		Vector<ObjectData> objects;
 
 		const Vector<HSceneObject>& sceneObjects = Selection::instance().getSceneObjects();
 		for (auto& so : sceneObjects)
@@ -59,8 +59,7 @@ namespace BansheeEngine
 			}
 		}
 
-		RenderTargetPtr rt = camera->getViewport()->getTarget();
-		gCoreAccessor().queueCommand(std::bind(&SelectionRendererCore::updateData, mCore, rt->getCore(), objects));
+		gCoreAccessor().queueCommand(std::bind(&SelectionRendererCore::updateData, mCore, camera->getCore(), objects));
 	}
 
 	const Color SelectionRendererCore::SELECTION_COLOR = Color(1.0f, 1.0f, 1.0f, 0.3f);
@@ -80,28 +79,32 @@ namespace BansheeEngine
 
 		SPtr<GpuParamsCore> fragParams = mat->getPassParameters(0)->mFragParams;
 		fragParams->getParam("color", mColor);
-		
-		CoreRendererPtr activeRenderer = RendererManager::instance().getActive();
-		activeRenderer->onCorePostRenderViewport.connect(std::bind(&SelectionRendererCore::render, this, _1));
 	}
 
-	void SelectionRendererCore::updateData(const SPtr<RenderTargetCore>& rt, const Vector<SelectionRenderer::ObjectData>& objects)
+	void SelectionRendererCore::updateData(const SPtr<CameraHandlerCore>& camera, const Vector<SelectionRenderer::ObjectData>& objects)
 	{
-		mSceneRenderTarget = rt;
+		if (mCamera != camera)
+		{
+			CoreRendererPtr activeRenderer = RendererManager::instance().getActive();
+			if (mCamera != nullptr)
+				activeRenderer->_unregisterRenderCallback(mCamera.get(), 10);
+
+			if (camera != nullptr)
+				activeRenderer->_registerRenderCallback(camera.get(), 10, std::bind(&SelectionRendererCore::render, this));
+		}
+
+		mCamera = camera;
 		mObjects = objects;
 	}
 
-	void SelectionRendererCore::render(const CameraHandlerCore& camera)
+	void SelectionRendererCore::render()
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
-		if (mSceneRenderTarget == nullptr)
-			return;
-
-		if (camera.getViewport()->getTarget() != mSceneRenderTarget)
+		if (mCamera == nullptr)
 			return;
 
-		Matrix4 viewProjMat = camera.getProjectionMatrixRS() * camera.getViewMatrix();
+		Matrix4 viewProjMat = mCamera->getProjectionMatrixRS() * mCamera->getViewMatrix();
 
 		for (auto& objData : mObjects)
 		{

+ 1 - 1
BansheeRenderer/Include/BsBansheeRenderer.h

@@ -127,7 +127,7 @@ namespace BansheeEngine
 		 *
 		 * @note	Core thread only.
 		 */
-		virtual void render(const CameraHandlerCore& camera, const RenderQueuePtr& renderQueue);
+		virtual void render(const CameraHandlerCore& camera, RenderQueuePtr& renderQueue);
 
 		/**
 		 * @brief	Creates data used by the renderer on the core thread.

+ 24 - 3
BansheeRenderer/Source/BsBansheeRenderer.cpp

@@ -289,7 +289,7 @@ namespace BansheeEngine
 		mRenderTargets.clear();
 	}
 
-	void BansheeRenderer::render(const CameraHandlerCore& camera, const RenderQueuePtr& renderQueue)
+	void BansheeRenderer::render(const CameraHandlerCore& camera, RenderQueuePtr& renderQueue)
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
@@ -300,7 +300,18 @@ namespace BansheeEngine
 
 		Matrix4 viewProjMatrix = projMatrixCstm * viewMatrixCstm;
 
-		onCorePreRenderViewport(camera);
+		// Trigger pre-render callbacks
+		auto iterCameraCallbacks = mRenderCallbacks.find(&camera);
+		if (iterCameraCallbacks != mRenderCallbacks.end())
+		{
+			for (auto& callbackPair : iterCameraCallbacks->second)
+			{
+				if (callbackPair.first >= 0)
+					break;
+
+				callbackPair.second();
+			}
+		}
 
 		if (!camera.getIgnoreSceneRenderables())
 		{
@@ -373,7 +384,17 @@ namespace BansheeEngine
 
 		renderQueue->clear();
 
-		onCorePostRenderViewport(camera);
+		// Trigger post-render callbacks
+		if (iterCameraCallbacks != mRenderCallbacks.end())
+		{
+			for (auto& callbackPair : iterCameraCallbacks->second)
+			{
+				if (callbackPair.first < 0)
+					continue;
+
+				callbackPair.second();
+			}
+		}
 	}
 
 	SPtr<ShaderCore> BansheeRenderer::createDefaultShader()

+ 1 - 2
TODO.txt

@@ -59,8 +59,7 @@ Polish stage 1
 Fix DX11 (and possibly DX9) rendering
 After undocking ProjectWindow the auto-scroll seems to be stuck in up position
 Decent looking default layout
-When selecting an gizmo icon the selection seems delayed and its gizmos flash for a frame before hiding
-Make sure that scene camera controls only work when scene view is in focus
+When selecting an gizmo icon the selection seems delayed and its gizmos flash for a frame before hiding (Can't reproduce atm but I saw it)
 Make proper window names instead of InspectorWindow
 Selection wireframe seems to render in front of handles