Bläddra i källkod

Made deferred rendering default (things are still VERY shakey)

BearishSun 10 år sedan
förälder
incheckning
bad12b1889

+ 2 - 1
BansheeCore/Source/BsMaterial.cpp

@@ -460,7 +460,8 @@ namespace BansheeEngine
 	template<bool Core>
 	UINT32 TMaterial<Core>::getNumPasses() const
 	{
-		throwIfNotInitialized();
+		if (mShader == nullptr)
+			return 0;
 
 		return mShader->getBestTechnique()->getNumPasses();
 	}

+ 9 - 3
BansheeCore/Source/BsMaterialParam.cpp

@@ -12,6 +12,9 @@ namespace BansheeEngine
 	template<class T, bool Core>
 	void TMaterialDataParam<T, Core>::set(const T& value, UINT32 arrayIdx)
 	{
+		if (mParams == nullptr)
+			return;
+
 		for (auto& param : *mParams)
 			param.set(value, arrayIdx);
 	}
@@ -19,7 +22,7 @@ namespace BansheeEngine
 	template<class T, bool Core>
 	T TMaterialDataParam<T, Core>::get(UINT32 arrayIdx)
 	{
-		if (mParams->size() == 0)
+		if (mParams == nullptr || mParams->size() == 0)
 			return T();
 
 		return (*mParams)[0].get(arrayIdx); // They should all have the same value
@@ -33,6 +36,9 @@ namespace BansheeEngine
 	template<bool Core>
 	void TMaterialParamStruct<Core>::set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx)
 	{
+		if (mParams == nullptr)
+			return;
+
 		for (auto& param : *mParams)
 			param.set(value, sizeBytes, arrayIdx);
 	}
@@ -40,7 +46,7 @@ namespace BansheeEngine
 	template<bool Core>
 	void TMaterialParamStruct<Core>::get(void* value, UINT32 sizeBytes, UINT32 arrayIdx)
 	{
-		if (mParams->size() == 0)
+		if (mParams == nullptr || mParams->size() == 0)
 		{
 			value = nullptr;
 			return;
@@ -52,7 +58,7 @@ namespace BansheeEngine
 	template<bool Core>
 	UINT32 TMaterialParamStruct<Core>::getElementSize() const
 	{
-		if (mParams->size() == 0)
+		if (mParams == nullptr || mParams->size() == 0)
 			return 0;
 
 		return (*mParams)[0].getElementSize();

+ 1 - 1
BansheeCore/Source/BsMultiRenderTexture.cpp

@@ -47,7 +47,7 @@ namespace BansheeEngine
 			return;
 
 		mWidth = props->getWidth();
-		mHeight = props->getWidth();
+		mHeight = props->getHeight();
 		mColorDepth = PixelUtil::getNumElemBits(props->getFormat());
 		mActive = true;
 		mHwGamma = props->isHardwareGammaEnabled();

+ 0 - 13
RenderBeast/Include/BsRenderBeast.h

@@ -23,9 +23,6 @@ namespace BansheeEngine
 	/** Basic shader that is used when no other is available. */
 	class DefaultMaterial : public RendererMaterial<DefaultMaterial> { RMAT_DEF("Default.bsl"); };
 
-	/** Basic shader that is used when no other is available, and the rendered mesh has no normal information. */
-	class DefaultMaterialNoNormal : public RendererMaterial<DefaultMaterialNoNormal> { RMAT_DEF("DefaultNoNormal.bsl"); };
-
 	/**
 	 * @brief	Data used by the renderer when rendering renderable handlers.
 	 */
@@ -228,15 +225,6 @@ namespace BansheeEngine
 		 */
 		void render(RenderTargetData& rtData, UINT32 camIdx);
 
-		/**
-		 * @brief	Renders all objects visible by the provided camera.
-		 *
-		 * @param	camera			Camera used for determining destination render target and visibility.
-		 *
-		 * @note	Core thread only.
-		 */
-		void renderOLD(const CameraCore& camera);
-
 		/**
 		 * @brief	Creates data used by the renderer on the core thread.
 		 */
@@ -309,7 +297,6 @@ namespace BansheeEngine
 		SPtr<RenderBeastOptions> mCoreOptions; // Core thread
 
 		DefaultMaterial* mDefaultMaterial; // Core thread
-		DefaultMaterialNoNormal* mDefaultNoNormalMaterial; // Core thread
 		PointLightMat* mPointLightMat; // Core thread
 		DirectionalLightMat* mDirLightMat; // Core thread
 

+ 1 - 0
RenderBeast/Include/BsRenderBeastOptions.h

@@ -39,6 +39,7 @@ namespace BansheeEngine
 		 */
 
 		UINT32 msaa = 1;
+
 		/** 
 		 * All colors output from shaders will be automatically converted to gamma 
 		 * space when written to render target(s). Normally used when the renderer

+ 11 - 147
RenderBeast/Source/BsRenderBeast.cpp

@@ -41,7 +41,7 @@ namespace BansheeEngine
 {
 	RenderBeast::RenderBeast()
 		:mOptions(bs_shared_ptr_new<RenderBeastOptions>()), mOptionsDirty(true), mStaticHandler(nullptr),
-		mDefaultMaterial(nullptr), mDefaultNoNormalMaterial(nullptr), mPointLightMat(nullptr), mDirLightMat(nullptr)
+		mDefaultMaterial(nullptr), mPointLightMat(nullptr), mDirLightMat(nullptr)
 	{
 
 	}
@@ -75,7 +75,6 @@ namespace BansheeEngine
 		mStaticHandler = bs_new<StaticRenderableHandler>();
 
 		mDefaultMaterial = bs_new<DefaultMaterial>();
-		mDefaultNoNormalMaterial = bs_new<DefaultMaterialNoNormal>();
 		mPointLightMat = bs_new<PointLightMat>();
 		mDirLightMat = bs_new<DirectionalLightMat>();
 
@@ -94,7 +93,6 @@ namespace BansheeEngine
 		RenderTexturePool::shutDown();
 
 		bs_delete(mDefaultMaterial);
-		bs_delete(mDefaultNoNormalMaterial);
 		bs_delete(mPointLightMat);
 		bs_delete(mDirLightMat);
 
@@ -147,6 +145,9 @@ namespace BansheeEngine
 				if (renElement.material == nullptr)
 					renElement.material = renderable->getMaterial(0);
 
+				if (renElement.material->getShader() == nullptr)
+					renElement.material = nullptr;
+
 				// Validate mesh <-> shader vertex bindings
 				if (renElement.material != nullptr)
 				{
@@ -174,17 +175,9 @@ namespace BansheeEngine
 					}
 				}
 
-				// If no material use the default material (two separate versions one depending if mesh has normals or not)
+				// If no material use the default material
 				if (renElement.material == nullptr)
-				{
-					SPtr<VertexData> vertexData = mesh->getVertexData();
-					const VertexDeclarationProperties& vertexProps = vertexData->vertexDeclaration->getProperties();
-
-					if (vertexProps.findElementBySemantic(VES_NORMAL))
-						renElement.material = mDefaultMaterial->getMaterial();
-					else
-						renElement.material = mDefaultNoNormalMaterial->getMaterial();
-				}
+					renElement.material = mDefaultMaterial->getMaterial();
 
 				auto iterFind = mSamplerOverrides.find(renElement.material);
 				if (iterFind != mSamplerOverrides.end())
@@ -483,33 +476,9 @@ namespace BansheeEngine
 
 			RenderAPICore::instance().beginFrame();
 
-			//UINT32 numCameras = (UINT32)cameras.size();
-			//for (UINT32 i = 0; i < numCameras; i++)
-			//	render(renderTargetData, i);
-
-			// BEGIN OLD STUFF
-			RenderAPICore::instance().setRenderTarget(target);
-			for(auto& camera : cameras)
-			{
-				SPtr<ViewportCore> viewport = camera->getViewport();
-				RenderAPICore::instance().setViewport(viewport->getNormArea());
-
-				UINT32 clearBuffers = 0;
-				if(viewport->getRequiresColorClear())
-					clearBuffers |= FBT_COLOR;
-
-				if(viewport->getRequiresDepthClear())
-					clearBuffers |= FBT_DEPTH;
-
-				if(viewport->getRequiresStencilClear())
-					clearBuffers |= FBT_STENCIL;
-
-				if(clearBuffers != 0)
-					RenderAPICore::instance().clearViewport(clearBuffers, viewport->getClearColor(), viewport->getClearDepthValue(), viewport->getClearStencilValue());
-
-				renderOLD(*camera);
-			}
-			// END OLD STUFF
+			UINT32 numCameras = (UINT32)cameras.size();
+			for (UINT32 i = 0; i < numCameras; i++)
+				render(renderTargetData, i);
 
 			RenderAPICore::instance().endFrame();
 			RenderAPICore::instance().swapBuffers(target);
@@ -542,7 +511,7 @@ namespace BansheeEngine
 			camData.gbuffer->bind();
 
 			UINT32 clearBuffers = FBT_COLOR | FBT_DEPTH | FBT_STENCIL;
-			RenderAPICore::instance().clearViewport(clearBuffers, Color::ZERO, 0.0f, 0);
+			RenderAPICore::instance().clearViewport(clearBuffers, Color::ZERO, 1.0f, 0);
 
 			for (auto iter = opaqueElements.begin(); iter != opaqueElements.end(); ++iter)
 			{
@@ -704,112 +673,7 @@ namespace BansheeEngine
 			}
 		}
 	}
-
-	void RenderBeast::renderOLD(const CameraCore& camera)
-	{
-		THROW_IF_NOT_CORE_THREAD;
-
-		RenderAPICore& rs = RenderAPICore::instance();
-		CameraData& cameraData = mCameraData[&camera];
-
-		CameraShaderData cameraShaderData = getCameraShaderData(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();
-			}
-		}
-
-		// Render opaque
-
-		//// Update global per-frame hardware buffers
-		mStaticHandler->updatePerCameraBuffers(cameraShaderData);
-
-		// TODO - This bit can be removed once I fully switch to deferred
-		const Vector<RenderQueueElement>& opaqueElements = cameraData.opaqueQueue->getSortedElements();
-		for(auto iter = opaqueElements.begin(); iter != opaqueElements.end(); ++iter)
-		{
-			BeastRenderableElement* renderElem = static_cast<BeastRenderableElement*>(iter->renderElem);
-			SPtr<MaterialCore> material = renderElem->material;
-
-			UINT32 rendererId = renderElem->renderableId;
-			Matrix4 worldViewProjMatrix = cameraShaderData.viewProj * mRenderableShaderData[rendererId].worldTransform;
-
-			mStaticHandler->updatePerObjectBuffers(*renderElem, mRenderableShaderData[rendererId], worldViewProjMatrix);
-			mStaticHandler->bindGlobalBuffers(*renderElem); // Note: If I can keep global buffer slot indexes the same between shaders I could only bind these once
-			mStaticHandler->bindPerObjectBuffers(*renderElem);
-
-			if (iter->applyPass)
-			{
-				SPtr<PassCore> pass = material->getPass(iter->passIdx);
-				setPass(pass);
-			}
-
-			{
-				SPtr<PassParametersCore> passParams = material->getPassParameters(iter->passIdx);
-
-				if (renderElem->samplerOverrides != nullptr)
-					setPassParams(passParams, &renderElem->samplerOverrides->passes[iter->passIdx]);
-				else
-					setPassParams(passParams, nullptr);
-			}
-
-			gRendererUtility().draw(iter->renderElem->mesh, iter->renderElem->subMesh);
-		}
-
-		// Render transparent
-		const Vector<RenderQueueElement>& transparentElements = cameraData.transparentQueue->getSortedElements();
-		for (auto iter = transparentElements.begin(); iter != transparentElements.end(); ++iter)
-		{
-			BeastRenderableElement* renderElem = static_cast<BeastRenderableElement*>(iter->renderElem);
-			SPtr<MaterialCore> material = renderElem->material;
-
-			UINT32 rendererId = renderElem->renderableId;
-			Matrix4 worldViewProjMatrix = cameraShaderData.viewProj * mRenderableShaderData[rendererId].worldTransform;
-
-			mStaticHandler->updatePerObjectBuffers(*renderElem, mRenderableShaderData[rendererId], worldViewProjMatrix);
-			mStaticHandler->bindGlobalBuffers(*renderElem); // Note: If I can keep global buffer slot indexes the same between shaders I could only bind these once
-			mStaticHandler->bindPerObjectBuffers(*renderElem);
-
-			if (iter->applyPass)
-			{
-				SPtr<PassCore> pass = material->getPass(iter->passIdx);
-				setPass(pass);
-			}
-
-			SPtr<PassParametersCore> passParams = material->getPassParameters(iter->passIdx);
-
-			if (renderElem->samplerOverrides != nullptr)
-				setPassParams(passParams, &renderElem->samplerOverrides->passes[iter->passIdx]);
-			else
-				setPassParams(passParams, nullptr);
-
-			gRendererUtility().draw(iter->renderElem->mesh, iter->renderElem->subMesh);
-		}
-
-		cameraData.opaqueQueue->clear();
-		cameraData.transparentQueue->clear();
-
-		// Trigger post-render callbacks
-		if (iterCameraCallbacks != mRenderCallbacks.end())
-		{
-			for (auto& callbackPair : iterCameraCallbacks->second)
-			{
-				if (callbackPair.first < 0)
-					continue;
-
-				callbackPair.second();
-			}
-		}
-	}
-
+	
 	void RenderBeast::determineVisible(const CameraCore& camera)
 	{
 		CameraData& cameraData = mCameraData[&camera];

+ 1 - 1
RenderBeast/Source/BsStaticRenderableHandler.cpp

@@ -116,7 +116,7 @@ namespace BansheeEngine
 		mPerCameraParams.gMatView.set(cameraData.view);
 		mPerCameraParams.gMatProj.set(cameraData.proj);
 		mPerCameraParams.gMatViewProj.set(cameraData.viewProj);
-		mPerCameraParams.gMatViewProj.set(cameraData.invProj);
+		mPerCameraParams.gMatInvProj.set(cameraData.invProj);
 		mPerCameraParams.gDeviceZToWorldZ.set(cameraData.deviceZToWorldZ);
 		mPerCameraParams.gClipToUVScaleOffset.set(cameraData.clipToUVScaleOffset);
 	}

+ 11 - 0
TODO.txt

@@ -18,7 +18,12 @@ Stage 2 polish:
  - Game publishing (Build window, collect resources, output exe, default viewport) (described below)
 
 Optional:
+ - Undocking of editor window doesn't work (they just get lost)
+ - Crash when adding a new directional light and then shutting down
  - Start editor in fullscreen
+ - If user clears the default shader he has no way of re-assigning it - add default shader to project folder?
+ - Toggle to enable/disable SceneObject in Inspector
+ - Resource import options don't get saved
  - Undo/Redo
   - CmdRecordSO records an SO and all its children but it should only record a single SO
   - CmdRecordSO should instead of recording the entire object record a diff
@@ -28,6 +33,7 @@ Optional:
  - Add "focus on object" key (F) - animate it: rotate camera towards then speed towards while zooming in (+ menu entry)
  - Ortographic camera views (+ gizmo in scene view corner that shows camera orientation) (Use custom handles and implement this?)
  - Cursors should be replaced with better ones, or at least hot-spots fixed
+ - Drag and drop of a mesh into Hierarchy doesn't instantiate it
  - Drag and dropping a prefab onto the scene (or hierarchy) should work the same as with meshes
  - Add tooltips to toolbar items and other buttons with icons
  - Either disable light tool icons before release or make them functional (With gizmos)
@@ -41,6 +47,11 @@ Optional:
  - MenuBar - will likely need a way to mark elements as disabled when not appropriate (e.g. no "frame selected unless scene is focused")
    - Likely use a user-provided callback to trigger when populating the menus (I already added a callback to MenuItem, just need to implement it)
  - Need to list all script components in the Components menu
+ - Slow camera rotation at high fps (just limit FPS probably)
+ - Word wrap weirdness
+   - When a GUI element containing a long piece of text is created, and it has flexible size, the initial optimal size
+     calculation will try to fit all the text in one row, even if during the actual size calculation that turns out to be impossible.
+     What happens then is that the text is rendered into multiple rows but its visible area only shows the first row.
 
 Seriously optional:
  - Drag to select in scene view

+ 3 - 2
TODOExperimentation.txt

@@ -14,11 +14,12 @@ Assign ViewOrigin, PreViewTranslation, TransViewProj
  - Do this after I have basic rendering working, to avoid additional issues when I'm initially trying to get it to work
  
 Next week:
- - Modify default shaders so they use deferred base pass and properly render to albedo/normal textures
  - With no light in the scene nothing renders, but it should at least render everything with constant ambient (just for debug until I implement GI)
- - Get rid of old code path
+ - I have removed DefaultNoNormal shader as support deferred rendering with no normals complicates the pipeline too much. I should instead
+   ensure meshes always have dummy normal data. (Right now mesh with no normals/tangents keeps spamming DX11 warnings)
 
 Later:
+ - Lights already existing in scene on load don't seem to render'
  - I changed how unsupported texture formats work, I should test if I didn't break OpenGL
  - Positioning of meshes seems slightly broken (selecting the dragon will sometimes select the wall behind it, and handle is displayed at wrong position)
  - When rendering lights right now I need to bind Gbuffer and light parameters to material, and then bind the material parameters to the pipeline