Преглед изворни кода

Refactored renderer so that pre-processing operations can be executing when performing manual rendering over multiple views

BearishSun пре 9 година
родитељ
комит
88105afc5d

+ 23 - 4
Source/RenderBeast/Include/BsRenderBeast.h

@@ -57,6 +57,17 @@ namespace bs
 			UINT32 matVersion;
 			UINT32 matVersion;
 		};
 		};
 
 
+		/** Contains information global to an entire frame. */
+		struct FrameInfo
+		{
+			FrameInfo(float timeDelta, const RendererAnimationData& animData)
+				:timeDelta(timeDelta), animData(animData)
+			{ }
+
+			float timeDelta;
+			const RendererAnimationData& animData;
+		};
+
 	public:
 	public:
 		RenderBeast();
 		RenderBeast();
 		~RenderBeast() { }
 		~RenderBeast() { }
@@ -137,19 +148,26 @@ namespace bs
 		 */
 		 */
 		void renderAllCore(float time, float delta);
 		void renderAllCore(float time, float delta);
 
 
+		/**
+		 * Renders all provided views.
+		 * 
+		 * @note	Core thread only. 
+		 */
+		void renderViews(RendererCamera** views, UINT32 numViews, const FrameInfo& frameInfo);
+
 		/**
 		/**
 		 * Renders all objects visible by the provided view.
 		 * Renders all objects visible by the provided view.
 		 *			
 		 *			
 		 * @note	Core thread only.
 		 * @note	Core thread only.
 		 */
 		 */
-		void render(RendererCamera* viewInfo, float frameDelta);
+		void renderView(RendererCamera* viewInfo, float frameDelta);
 
 
 		/**
 		/**
-		 * Renders all overlay callbacks attached to the provided camera.
+		 * Renders all overlay callbacks of the provided view.
 		 * 					
 		 * 					
 		 * @note	Core thread only.
 		 * @note	Core thread only.
 		 */
 		 */
-		void renderOverlay(const Camera* camera, bool clear);
+		void renderOverlay(RendererCamera* viewInfo);
 
 
 		/** 
 		/** 
 		 * Renders a single element of a renderable object. 
 		 * Renders a single element of a renderable object. 
@@ -168,8 +186,9 @@ namespace bs
 		 * @param[in]	position	Position to capture the scene at.
 		 * @param[in]	position	Position to capture the scene at.
 		 * @param[in]	hdr			If true scene will be captured in a format that supports high dynamic range.
 		 * @param[in]	hdr			If true scene will be captured in a format that supports high dynamic range.
 		 * @param[in]	size		Cubemap face width/height in pixels.
 		 * @param[in]	size		Cubemap face width/height in pixels.
+		 * @param[in]	frameInfo	Global information about the the frame currently being rendered.
 		 */
 		 */
-		SPtr<Texture> captureSceneCubeMap(const Vector3& position, bool hdr, UINT32 size);
+		SPtr<Texture> captureSceneCubeMap(const Vector3& position, bool hdr, UINT32 size, const FrameInfo& frameInfo);
 
 
 		/**	Creates data used by the renderer on the core thread. */
 		/**	Creates data used by the renderer on the core thread. */
 		void initializeCore();
 		void initializeCore();

+ 7 - 5
Source/RenderBeast/Include/BsRendererCamera.h

@@ -95,7 +95,6 @@ namespace bs { namespace ct
 	struct VisibilityInfo
 	struct VisibilityInfo
 	{
 	{
 		Vector<bool> renderables;
 		Vector<bool> renderables;
-		Vector<bool> lights;
 	};
 	};
 
 
 	/** Information used for culling an object against a view. */
 	/** Information used for culling an object against a view. */
@@ -141,6 +140,9 @@ namespace bs { namespace ct
 		/** Returns true if the view requires high dynamic range rendering. */
 		/** Returns true if the view requires high dynamic range rendering. */
 		bool isHDR() const { return mViewDesc.isHDR; }
 		bool isHDR() const { return mViewDesc.isHDR; }
 
 
+		/** Returns true if this view only renders overlay, and not scene objects. */
+		bool isOverlay() const { return mViewDesc.isOverlay; }
+
 		/** Returns the texture to use for the skybox (if any). */
 		/** Returns the texture to use for the skybox (if any). */
 		SPtr<Texture> getSkybox() const { return mViewDesc.skyboxTexture; }
 		SPtr<Texture> getSkybox() const { return mViewDesc.skyboxTexture; }
 
 
@@ -165,10 +167,10 @@ namespace bs { namespace ct
 		/** 
 		/** 
 		 * Prepares render targets for rendering. When done call endRendering().
 		 * Prepares render targets for rendering. When done call endRendering().
 		 *
 		 *
-		 * @param[in]	useRenderTargets	If using the internal render targets containing the GBuffer (retrieved via
-		 *									getRenderTargets()) while rendering you must set this to true.
+		 * @param[in]	useGBuffer			Set to true if you will be rendering to internal render targets containing the
+		 *									GBuffer (retrieved via getRenderTargets()).
 		 */
 		 */
-		void beginRendering(bool useRenderTargets);
+		void beginRendering(bool useGBuffer);
 
 
 		/** Ends rendering and frees any acquired resources. */
 		/** Ends rendering and frees any acquired resources. */
 		void endRendering();
 		void endRendering();
@@ -244,7 +246,7 @@ namespace bs { namespace ct
 
 
 		SPtr<RenderTargets> mRenderTargets;
 		SPtr<RenderTargets> mRenderTargets;
 		PostProcessInfo mPostProcessInfo;
 		PostProcessInfo mPostProcessInfo;
-		bool mUsingRenderTargets;
+		bool mUsingGBuffer;
 
 
 		SPtr<GpuParamBlockBuffer> mParamBuffer;
 		SPtr<GpuParamBlockBuffer> mParamBuffer;
 		VisibilityInfo mVisibility;
 		VisibilityInfo mVisibility;

+ 73 - 71
Source/RenderBeast/Source/BsRenderBeast.cpp

@@ -627,38 +627,17 @@ namespace bs { namespace ct
 		// Update global per-frame hardware buffers
 		// Update global per-frame hardware buffers
 		mObjectRenderer->setParamFrameParams(time);
 		mObjectRenderer->setParamFrameParams(time);
 
 
-		// Generate render queues per camera
-		mRenderableVisibility.assign(mRenderableVisibility.size(), false);
-
-		for (auto& entry : mCameras)
-			entry.second->determineVisible(mRenderables, mRenderableCullInfos, &mRenderableVisibility);
-
 		// Retrieve animation data
 		// Retrieve animation data
 		AnimationManager::instance().waitUntilComplete();
 		AnimationManager::instance().waitUntilComplete();
 		const RendererAnimationData& animData = AnimationManager::instance().getRendererData();
 		const RendererAnimationData& animData = AnimationManager::instance().getRendererData();
-
-		// Update per-object, bone matrix and morph shape GPU buffers
-		UINT32 numRenderables = (UINT32)mRenderables.size();
-		for (UINT32 i = 0; i < numRenderables; i++)
-		{
-			if (!mRenderableVisibility[i])
-				continue;
-
-			// Note: Before uploading bone matrices perhaps check if they has actually been changed since last frame
-			mRenderables[i]->renderable->updateAnimationBuffers(animData);
-
-			// Note: Could this step be moved in notifyRenderableUpdated, so it only triggers when material actually gets
-			// changed? Although it shouldn't matter much because if the internal versions keeping track of dirty params.
-			for (auto& element : mRenderables[i]->elements)
-				element.material->updateParamsSet(element.params);
-
-			mRenderables[i]->perObjectParamBuffer->flushToGPU();
-		}
 		
 		
+		FrameInfo frameInfo(delta, animData);
+
 		//if (dbgSkyTex == nullptr)
 		//if (dbgSkyTex == nullptr)
-		//	dbgSkyTex = captureSceneCubeMap(Vector3(0, 2, 0), true, 1024);
+		//	dbgSkyTex = captureSceneCubeMap(Vector3(0, 2, 0), true, 1024, frameInfo);
 
 
-		// Render everything, target by target
+		// Gather all views
+		Vector<RendererCamera*> views;
 		for (auto& rtInfo : mRenderTargets)
 		for (auto& rtInfo : mRenderTargets)
 		{
 		{
 			SPtr<RenderTarget> target = rtInfo.target;
 			SPtr<RenderTarget> target = rtInfo.target;
@@ -667,22 +646,14 @@ namespace bs { namespace ct
 			UINT32 numCameras = (UINT32)cameras.size();
 			UINT32 numCameras = (UINT32)cameras.size();
 			for (UINT32 i = 0; i < numCameras; i++)
 			for (UINT32 i = 0; i < numCameras; i++)
 			{
 			{
-				bool isOverlayCamera = cameras[i]->getFlags().isSet(CameraFlag::Overlay);
-				if (!isOverlayCamera)
-				{
-					RendererCamera* viewInfo = mCameras[cameras[i]];
-
-					render(viewInfo, delta);
-				}
-				else
-				{
-					bool clear = i == 0;
-
-					renderOverlay(cameras[i], clear);
-				}
+				RendererCamera* viewInfo = mCameras[cameras[i]];
+				views.push_back(viewInfo);
 			}
 			}
 		}
 		}
 
 
+		// Render everything
+		renderViews(views.data(), (UINT32)views.size(), frameInfo);
+
 		gProfilerGPU().endFrame();
 		gProfilerGPU().endFrame();
 
 
 		// Present render targets with back buffers
 		// Present render targets with back buffers
@@ -695,7 +666,42 @@ namespace bs { namespace ct
 		gProfilerCPU().endSample("renderAllCore");
 		gProfilerCPU().endSample("renderAllCore");
 	}
 	}
 
 
-	void RenderBeast::render(RendererCamera* viewInfo, float frameDelta)
+	void RenderBeast::renderViews(RendererCamera** views, UINT32 numViews, const FrameInfo& frameInfo)
+	{
+		// Generate render queues per camera
+		mRenderableVisibility.assign(mRenderableVisibility.size(), false);
+
+		for(UINT32 i = 0; i < numViews; i++)
+			views[i]->determineVisible(mRenderables, mRenderableCullInfos, &mRenderableVisibility);
+
+		// Update per-object, bone matrix and morph shape GPU buffers
+		UINT32 numRenderables = (UINT32)mRenderables.size();
+		for (UINT32 i = 0; i < numRenderables; i++)
+		{
+			if (!mRenderableVisibility[i])
+				continue;
+
+			// Note: Before uploading bone matrices perhaps check if they has actually been changed since last frame
+			mRenderables[i]->renderable->updateAnimationBuffers(frameInfo.animData);
+
+			// Note: Could this step be moved in notifyRenderableUpdated, so it only triggers when material actually gets
+			// changed? Although it shouldn't matter much because if the internal versions keeping track of dirty params.
+			for (auto& element : mRenderables[i]->elements)
+				element.material->updateParamsSet(element.params);
+
+			mRenderables[i]->perObjectParamBuffer->flushToGPU();
+		}
+
+		for (UINT32 i = 0; i < numViews; i++)
+		{
+			if (views[i]->isOverlay())
+				renderOverlay(views[i]);
+			else
+				renderView(views[i], frameInfo.timeDelta);
+		}
+	}
+
+	void RenderBeast::renderView(RendererCamera* viewInfo, float frameDelta)
 	{
 	{
 		gProfilerCPU().beginSample("Render");
 		gProfilerCPU().beginSample("Render");
 
 
@@ -909,38 +915,32 @@ namespace bs { namespace ct
 		gProfilerCPU().endSample("Render");
 		gProfilerCPU().endSample("Render");
 	}
 	}
 
 
-	void RenderBeast::renderOverlay(const Camera* camera, bool clear)
+	void RenderBeast::renderOverlay(RendererCamera* viewInfo)
 	{
 	{
 		gProfilerCPU().beginSample("RenderOverlay");
 		gProfilerCPU().beginSample("RenderOverlay");
 
 
+		viewInfo->getPerViewBuffer()->flushToGPU();
+		viewInfo->beginRendering(false);
+
+		const Camera* camera = viewInfo->getSceneCamera();
+		SPtr<RenderTarget> target = viewInfo->getFinalTarget();
 		SPtr<Viewport> viewport = camera->getViewport();
 		SPtr<Viewport> viewport = camera->getViewport();
-		RendererCamera* rendererCam = mCameras[camera];
-		rendererCam->getPerViewBuffer()->flushToGPU();
 
 
-		rendererCam->beginRendering(false);
+		UINT32 clearBuffers = 0;
+		if (viewport->getRequiresColorClear())
+			clearBuffers |= FBT_COLOR;
 
 
-		SPtr<RenderTarget> target = camera->getViewport()->getTarget();
+		if (viewport->getRequiresDepthClear())
+			clearBuffers |= FBT_DEPTH;
 
 
-		// If first camera in render target, prepare the render target
-		if (clear)
+		if (viewport->getRequiresStencilClear())
+			clearBuffers |= FBT_STENCIL;
+
+		if (clearBuffers != 0)
 		{
 		{
 			RenderAPI::instance().setRenderTarget(target);
 			RenderAPI::instance().setRenderTarget(target);
-
-			UINT32 clearBuffers = 0;
-			if (viewport->getRequiresColorClear())
-				clearBuffers |= FBT_COLOR;
-
-			if (viewport->getRequiresDepthClear())
-				clearBuffers |= FBT_DEPTH;
-
-			if (viewport->getRequiresStencilClear())
-				clearBuffers |= FBT_STENCIL;
-
-			if (clearBuffers != 0)
-			{
-				RenderAPI::instance().clearViewport(clearBuffers, viewport->getClearColor(),
-					viewport->getClearDepthValue(), viewport->getClearStencilValue());
-			}
+			RenderAPI::instance().clearViewport(clearBuffers, viewport->getClearColor(),
+				viewport->getClearDepthValue(), viewport->getClearStencilValue());
 		}
 		}
 		else
 		else
 			RenderAPI::instance().setRenderTarget(target, false, RT_COLOR0);
 			RenderAPI::instance().setRenderTarget(target, false, RT_COLOR0);
@@ -964,7 +964,7 @@ namespace bs { namespace ct
 			++iterRenderCallback;
 			++iterRenderCallback;
 		}
 		}
 
 
-		rendererCam->endRendering();
+		viewInfo->endRendering();
 
 
 		gProfilerCPU().endSample("RenderOverlay");
 		gProfilerCPU().endSample("RenderOverlay");
 	}
 	}
@@ -986,7 +986,8 @@ namespace bs { namespace ct
 				element.morphVertexDeclaration);
 				element.morphVertexDeclaration);
 	}
 	}
 
 
-	SPtr<Texture> RenderBeast::captureSceneCubeMap(const Vector3& position, bool hdr, UINT32 size)
+	SPtr<Texture> RenderBeast::captureSceneCubeMap(const Vector3& position, bool hdr, UINT32 size, 
+												   const FrameInfo& frameInfo)
 	{
 	{
 		TEXTURE_DESC cubeMapDesc;
 		TEXTURE_DESC cubeMapDesc;
 		cubeMapDesc.type = TEX_TYPE_CUBE_MAP;
 		cubeMapDesc.type = TEX_TYPE_CUBE_MAP;
@@ -1045,7 +1046,7 @@ namespace bs { namespace ct
 
 
 		Matrix4 viewOffsetMat = Matrix4::translation(-position);
 		Matrix4 viewOffsetMat = Matrix4::translation(-position);
 
 
-		RendererCamera view(viewDesc);
+		RendererCamera views[6];
 		for(UINT32 i = 0; i < 6; i++)
 		for(UINT32 i = 0; i < 6; i++)
 		{
 		{
 			// Calculate view matrix
 			// Calculate view matrix
@@ -1106,13 +1107,14 @@ namespace bs { namespace ct
 			
 			
 			viewDesc.target.target = RenderTexture::create(cubeFaceRTDesc);
 			viewDesc.target.target = RenderTexture::create(cubeFaceRTDesc);
 
 
-			view.setView(viewDesc);
-			view.updatePerViewBuffer();
-			view.determineVisible(mRenderables, mRenderableCullInfos);
-
-			render(&view, 0.0f);
+			views[i].setView(viewDesc);
+			views[i].updatePerViewBuffer();
+			views[i].determineVisible(mRenderables, mRenderableCullInfos);
 		}
 		}
 
 
+		RendererCamera* viewPtrs[] = { &views[0], &views[1], &views[2], &views[3], &views[4], &views[5] };
+		renderViews(viewPtrs, 6, frameInfo);
+
 		ReflectionCubemap::filterCubemapForSpecular(cubemap);
 		ReflectionCubemap::filterCubemapForSpecular(cubemap);
 
 
 		return cubemap;
 		return cubemap;

+ 7 - 5
Source/RenderBeast/Source/BsRendererCamera.cpp

@@ -39,13 +39,13 @@ namespace bs { namespace ct
 	}
 	}
 
 
 	RendererCamera::RendererCamera()
 	RendererCamera::RendererCamera()
-		: mUsingRenderTargets(false)
+		: mUsingGBuffer(false)
 	{
 	{
 		mParamBuffer = gPerCameraParamDef.createBuffer();
 		mParamBuffer = gPerCameraParamDef.createBuffer();
 	}
 	}
 
 
 	RendererCamera::RendererCamera(const RENDERER_VIEW_DESC& desc)
 	RendererCamera::RendererCamera(const RENDERER_VIEW_DESC& desc)
-		: mViewDesc(desc), mUsingRenderTargets(false)
+		: mViewDesc(desc), mUsingGBuffer(false)
 	{
 	{
 		mParamBuffer = gPerCameraParamDef.createBuffer();
 		mParamBuffer = gPerCameraParamDef.createBuffer();
 
 
@@ -90,6 +90,8 @@ namespace bs { namespace ct
 	void RendererCamera::setView(const RENDERER_VIEW_DESC& desc)
 	void RendererCamera::setView(const RENDERER_VIEW_DESC& desc)
 	{
 	{
 		mViewDesc = desc;
 		mViewDesc = desc;
+
+		setStateReductionMode(desc.stateReduction);
 	}
 	}
 
 
 	void RendererCamera::beginRendering(bool useGBuffer)
 	void RendererCamera::beginRendering(bool useGBuffer)
@@ -105,7 +107,7 @@ namespace bs { namespace ct
 				mRenderTargets = RenderTargets::create(mViewDesc.target, mViewDesc.isHDR);
 				mRenderTargets = RenderTargets::create(mViewDesc.target, mViewDesc.isHDR);
 
 
 			mRenderTargets->allocate();
 			mRenderTargets->allocate();
-			mUsingRenderTargets = true;
+			mUsingGBuffer = true;
 		}
 		}
 	}
 	}
 
 
@@ -114,10 +116,10 @@ namespace bs { namespace ct
 		mOpaqueQueue->clear();
 		mOpaqueQueue->clear();
 		mTransparentQueue->clear();
 		mTransparentQueue->clear();
 
 
-		if(mUsingRenderTargets)
+		if(mUsingGBuffer)
 		{
 		{
 			mRenderTargets->release();
 			mRenderTargets->release();
-			mUsingRenderTargets = false;
+			mUsingGBuffer = false;
 		}
 		}
 	}
 	}