Browse Source

Added UV to full screen quad
When vertex bindings don't match the shader print out more detailed information about the missing elements

BearishSun 10 years ago
parent
commit
e9e45b6d6b

+ 5 - 0
BansheeCore/Include/BsMesh.h

@@ -41,6 +41,11 @@ namespace BansheeEngine
 		 */
 		virtual SPtr<IndexBufferCore> getIndexBuffer() const override;
 
+		/**
+		 * @copydoc MeshCoreBase::getVertexDesc
+		 */
+		virtual SPtr<VertexDataDesc> getVertexDesc() const override;
+
 		/**
 		 * @brief	Updates a part of the current mesh with the provided data.
 		 *

+ 5 - 0
BansheeCore/Include/BsMeshBase.h

@@ -113,6 +113,11 @@ namespace BansheeEngine
 		 */
 		virtual UINT32 getIndexOffset() const { return 0; }
 
+		/**
+		 * @brief	Returns a structure that describes how are the vertices stored in the mesh's vertex buffer.
+		 */
+		virtual SPtr<VertexDataDesc> getVertexDesc() const = 0;
+
 		/**
 		 * @brief	Called whenever this mesh starts being used on the GPU.
 		 * 			

+ 5 - 0
BansheeCore/Include/BsMeshHeap.h

@@ -121,6 +121,11 @@ namespace BansheeEngine
 		 */
 		SPtr<IndexBufferCore> getIndexBuffer() const;
 
+		/**
+		 * @brief	Returns a structure that describes how are the vertices stored in the mesh's vertex buffer.
+		 */
+		SPtr<VertexDataDesc> getVertexDesc() const;
+
 		/**
 		 * @brief	Returns the offset in vertices from the start of the buffer
 		 *			to the first vertex of the mesh with the provided ID.

+ 10 - 1
BansheeCore/Include/BsRendererUtility.h

@@ -2,6 +2,8 @@
 
 #include "BsCorePrerequisites.h"
 #include "BsModule.h"
+#include "BsRect2.h"
+#include "BsVector2I.h"
 
 namespace BansheeEngine
 {
@@ -37,9 +39,16 @@ namespace BansheeEngine
 		/**
 		 * @brief	Draws a quad over the entire viewport in normalized device coordinates.
 		 * 			
+		 * @param	viewport	Destination viewport to draw the quad in.
+		 * @param	uv			UV coordinates to assign to the corners of the quad.
+		 * @param	textureSize	Size of the texture the UV coordinates are specified for. If the UV coordinates are already
+		 * 						in normalized (0, 1) range then keep this value as is. If the UV coordinates are in texels
+		 * 						then set this value to the texture size so they can be normalized internally.
+		 * 			
 		 * @note	Core thread.
 		 */
-		void drawScreenQuad(const ViewportCore& viewport);
+		void drawScreenQuad(const ViewportCore& viewport, const Rect2& uv = Rect2(0.0f, 0.0f, 1.0f, 1.0f), 
+			const Vector2I& textureSize = Vector2I(1, 1));
 
 	private:
 		SPtr<MeshCore> mFullScreenQuadMesh;

+ 16 - 11
BansheeCore/Include/BsTransientMesh.h

@@ -19,14 +19,19 @@ namespace BansheeEngine
 			UINT32 numIndices, const Vector<SubMesh>& subMeshes);
 
 		/**
-		 * @copydoc MeshBase::getVertexData
+		 * @copydoc MeshCoreBase::getVertexData
 		 */
-		SPtr<VertexData> getVertexData() const;
+		SPtr<VertexData> getVertexData() const override;
 
 		 /**
-		  * @copydoc MeshBase::getIndexData
+		  * @copydoc MeshCoreBase::getIndexData
 		  */
-		SPtr<IndexBufferCore> getIndexBuffer() const;
+		SPtr<IndexBufferCore> getIndexBuffer() const override;
+
+		/**
+		 * @copydoc MeshCoreBase::getVertexDesc
+		 */
+		SPtr<VertexDataDesc> getVertexDesc() const override;
 
 		/**
 		 * @brief	Returns the ID that uniquely identifies this mesh in the parent heap.
@@ -34,19 +39,19 @@ namespace BansheeEngine
 		UINT32 getMeshHeapId() const { return mId; }
 
 		/**
-		 * @copydoc MeshBase::getVertexOffset
+		 * @copydoc MeshCoreBase::getVertexOffset
 		 */
-		virtual UINT32 getVertexOffset() const;
+		virtual UINT32 getVertexOffset() const override;
 
 		 /**
-		 * @copydoc MeshBase::getIndexOffset
+		 * @copydoc MeshCoreBase::getIndexOffset
 		 */
-		virtual UINT32 getIndexOffset() const;
+		virtual UINT32 getIndexOffset() const override;
 
 		 /**
-		 * @copydoc MeshBase::notifyUsedOnGPU
+		 * @copydoc MeshCoreBase::notifyUsedOnGPU
 		 */
-		virtual void _notifyUsedOnGPU();
+		virtual void _notifyUsedOnGPU() override;
 
 	protected:
 		friend class TransientMesh;
@@ -97,7 +102,7 @@ namespace BansheeEngine
 		/**
 		 * @copydoc	RenderTarget::createCore
 		 */
-		SPtr<CoreObjectCore> createCore() const;
+		SPtr<CoreObjectCore> createCore() const override;
 
 	protected:
 		bool mIsDestroyed;

+ 18 - 2
BansheeCore/Include/BsVertexDeclaration.h

@@ -198,6 +198,12 @@ namespace BansheeEngine
 		 */
 		bool isCompatible(const SPtr<VertexDeclarationCore>& shaderDecl);
 
+		/**
+		 * @brief	Returns a list of vertex elements that the provided shader's vertex declaration expects but aren't 
+		 * 			present in this vertex declaration.
+		 */
+		Vector<VertexElement> getMissingElements(const SPtr<VertexDeclarationCore>& shaderDecl);
+
     protected:
 		friend class HardwareBufferCoreManager;
 
@@ -245,7 +251,7 @@ namespace BansheeEngine
 		/**
 		 * @copydoc	CoreObject::createCore
 		 */
-		SPtr<CoreObjectCore> createCore() const;
+		SPtr<CoreObjectCore> createCore() const override;
 
 	protected:
 		VertexDeclarationProperties mProperties;
@@ -256,6 +262,16 @@ namespace BansheeEngine
 	public:
 		friend class VertexDeclarationRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
     };
+
+	/**
+	 * @brief	Converts a vertex semantic enum to a readable name.
+	 */
+	BS_CORE_EXPORT String toString(const VertexElementSemantic& val);
+
+	/**
+	 * @brief	Converts a vertex semantic enum to a readable name.
+	 */
+	BS_CORE_EXPORT WString toWString(const VertexElementSemantic& val);
 }

+ 7 - 0
BansheeCore/Source/BsMesh.cpp

@@ -85,6 +85,13 @@ namespace BansheeEngine
 		return mIndexBuffer;
 	}
 
+	SPtr<VertexDataDesc> MeshCore::getVertexDesc() const
+	{
+		THROW_IF_NOT_CORE_THREAD;
+
+		return mVertexDesc;
+	}
+
 	void MeshCore::writeSubresource(UINT32 subresourceIdx, const MeshData& meshData, bool discardEntireBuffer, bool performUpdateBounds)
 	{
 		THROW_IF_NOT_CORE_THREAD;

+ 5 - 0
BansheeCore/Source/BsMeshHeap.cpp

@@ -481,6 +481,11 @@ namespace BansheeEngine
 		return mIndexBuffer;
 	}
 
+	SPtr<VertexDataDesc> MeshHeapCore::getVertexDesc() const
+	{
+		return mVertexDesc;
+	}
+
 	UINT32 MeshHeapCore::getVertexOffset(UINT32 meshId) const
 	{
 		auto findIter = mMeshAllocData.find(meshId);

+ 30 - 26
BansheeCore/Source/BsRendererUtility.cpp

@@ -16,29 +16,7 @@ namespace BansheeEngine
 		vertexDesc->addVertElem(VET_FLOAT3, VES_POSITION);
 		vertexDesc->addVertElem(VET_FLOAT2, VES_TEXCOORD);
 
-		MeshDataPtr meshData = bs_shared_ptr_new<MeshData>(4, 6, vertexDesc);
-
-		auto vecIter = meshData->getVec3DataIter(VES_POSITION);
-		vecIter.setValue(Vector3(-1.0f, 1.0, 0));
-		vecIter.setValue(Vector3(1.0f, 1.0f, 0));
-		vecIter.setValue(Vector3(-1.0f, -1.0f, 0));
-		vecIter.setValue(Vector3(1.0f, -1.0f, 0));
-
-		auto uvIter = meshData->getVec2DataIter(VES_TEXCOORD);
-		uvIter.setValue(Vector2(0.0f, 0.0));
-		uvIter.setValue(Vector2(1.0f, 0.0f));
-		uvIter.setValue(Vector2(0.0f, 1.0f));
-		uvIter.setValue(Vector2(1.0f, 1.0f));
-
-		auto indices = meshData->getIndices32();
-		indices[0] = 0;
-		indices[1] = 1;
-		indices[2] = 2;
-		indices[3] = 1;
-		indices[4] = 3;
-		indices[5] = 2;
-
-		mFullScreenQuadMesh = MeshCore::create(meshData);
+		mFullScreenQuadMesh = MeshCore::create(4, 6, vertexDesc);
 	}
 
 	RendererUtility::~RendererUtility()
@@ -165,7 +143,7 @@ namespace BansheeEngine
 		mesh->_notifyUsedOnGPU();
 	}
 
-	void RendererUtility::drawScreenQuad(const ViewportCore& viewport)
+	void RendererUtility::drawScreenQuad(const ViewportCore& viewport, const Rect2& uv, const Vector2I& textureSize)
 	{
 		// Note: Consider drawing the quad using a single large triangle for possibly better performance
 		Rect2I viewArea = viewport.getArea();
@@ -177,17 +155,43 @@ namespace BansheeEngine
 		vertices[3] = Vector3((float)viewArea.x + (float)viewArea.width, (float)viewArea.y + (float)viewArea.width, 0.0f);
 
 		Vector2 uvs[4];
-		// TODO - Set UVs
+		uvs[0] = Vector2(uv.x, uv.y);
+		uvs[1] = Vector2(uv.x + uv.width, uv.y);
+		uvs[2] = Vector2(uv.x, uv.y + uv.height);
+		uvs[3] = Vector2(uv.x + uv.width, uv.y + uv.height);
 
 		auto targetProps = viewport.getTarget()->getProperties();;
-
 		RenderAPICore& rapi = RenderAPICore::instance();
 		for (int i = 0; i < 4; i++)
 		{
 			vertices[i].x = -1.0f + 2.0f * (vertices[i].x + rapi.getHorizontalTexelOffset()) / targetProps.getWidth();
 			vertices[i].y = 1.0f - 2.0f * (vertices[i].y + rapi.getVerticalTexelOffset()) / targetProps.getHeight();
+
+			uvs[i].x /= (float)textureSize.x;
+			uvs[i].y /= (float)textureSize.y;
 		}
 
+		SPtr<VertexDataDesc> vertexDesc = mFullScreenQuadMesh->getVertexDesc();
+		MeshDataPtr meshData = bs_shared_ptr_new<MeshData>(4, 6, vertexDesc);
+
+		auto vecIter = meshData->getVec3DataIter(VES_POSITION);
+		for (UINT32 i = 0; i < 4; i++)
+			vecIter.setValue(vertices[i]);
+
+		auto uvIter = meshData->getVec2DataIter(VES_TEXCOORD);
+		for (UINT32 i = 0; i < 4; i++)
+			uvIter.setValue(uvs[i]);
+
+		auto indices = meshData->getIndices32();
+		indices[0] = 0;
+		indices[1] = 1;
+		indices[2] = 2;
+		indices[3] = 1;
+		indices[4] = 3;
+		indices[5] = 2;
+
+		mFullScreenQuadMesh->writeSubresource(0, *meshData, true, false);
+
 		SPtr<VertexBufferCore> vb = mFullScreenQuadMesh->getVertexData()->getBuffer(0);
 		vb->writeData(0, sizeof(vertices), vertices, BufferWriteType::Discard);
 

+ 5 - 0
BansheeCore/Source/BsTransientMesh.cpp

@@ -33,6 +33,11 @@ namespace BansheeEngine
 		return mParentHeap->getIndexOffset(mId);
 	}
 
+	SPtr<VertexDataDesc> TransientMeshCore::getVertexDesc() const
+	{
+		return mParentHeap->getVertexDesc();
+	}
+
 	void TransientMeshCore::_notifyUsedOnGPU()
 	{
 		mParentHeap->notifyUsedOnGPU(mId);

+ 60 - 3
BansheeCore/Source/BsVertexDeclaration.cpp

@@ -236,15 +236,38 @@ namespace BansheeEngine
 			}
 
 			if (foundElement == nullptr)
-			{
-				LOGWRN("Provided vertex buffer doesn't have a required input attribute: " + toString(shaderIter->getSemantic()) + toString(shaderIter->getSemanticIdx()));
 				return false;
-			}
 		}
 
 		return true;
 	}
 
+	Vector<VertexElement> VertexDeclarationCore::getMissingElements(const SPtr<VertexDeclarationCore>& shaderDecl)
+	{
+		Vector<VertexElement> missingElements;
+
+		const List<VertexElement>& shaderElems = shaderDecl->getProperties().getElements();
+		const List<VertexElement>& bufferElems = getProperties().getElements();
+
+		for (auto shaderIter = shaderElems.begin(); shaderIter != shaderElems.end(); ++shaderIter)
+		{
+			const VertexElement* foundElement = nullptr;
+			for (auto bufferIter = bufferElems.begin(); bufferIter != bufferElems.end(); ++bufferIter)
+			{
+				if (shaderIter->getSemantic() == bufferIter->getSemantic() && shaderIter->getSemanticIdx() == bufferIter->getSemanticIdx())
+				{
+					foundElement = &(*bufferIter);
+					break;
+				}
+			}
+
+			if (foundElement == nullptr)
+				missingElements.push_back(*shaderIter);
+		}
+
+		return missingElements;
+	}
+
 	VertexDeclaration::VertexDeclaration(const List<VertexElement>& elements)
 		:mProperties(elements)
 	{
@@ -278,4 +301,38 @@ namespace BansheeEngine
 	{
 		return getRTTIStatic();
 	}
+
+	String toString(const VertexElementSemantic& val)
+	{
+		switch (val)
+		{
+		case VES_POSITION:
+			return "POSITION";
+		case VES_BLEND_WEIGHTS:
+			return "BLEND_WEIGHTS";
+		case VES_BLEND_INDICES:
+			return "BLEND_INDICES";
+		case VES_NORMAL:
+			return "NORMAL";
+		case VES_COLOR:
+			return "COLOR";
+		case VES_TEXCOORD:
+			return "TEXCOORD";
+		case VES_BITANGENT:
+			return "BITANGENT";
+		case VES_TANGENT:
+			return "TANGENT";
+		case VES_POSITIONT:
+			return "POSITIONT";
+		case VES_PSIZE:
+			return "PSIZE";
+		}
+
+		return "";
+	}
+
+	WString toWString(const VertexElementSemantic& val)
+	{
+		return toWString(toString(val));
+	}
 }

+ 1 - 0
Game/Source/Main.cpp

@@ -22,6 +22,7 @@ int CALLBACK WinMain(
 		renderWindowDesc.videoMode = VideoMode(200, 200); // TODO - Get desktop resolution
 		renderWindowDesc.title = "Banshee Game"; // TODO - Get this from game settings
 		renderWindowDesc.fullscreen = false; // TODO - Get this from game settings
+		renderWindowDesc.hideUntilSwap = true;
 
 		RenderAPIPlugin renderAPI = RenderAPIPlugin::DX11; // TODO - Get this from game settings
 

+ 46 - 0
MBansheeEditor/BuildWindow.cs

@@ -0,0 +1,46 @@
+using System;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /// <summary>
+    /// Provides options for customizing and activating the build process which will output an executable of the game for a 
+    /// specific platform, as well as any required resources.
+    /// </summary>
+    [DefaultSize(300, 200)]
+    internal sealed class BuildWindow : EditorWindow
+    {
+        /// <summary>
+        /// Opens the build window if its not open already.
+        /// </summary>
+        [MenuItem("Tools/Build", 9296)]
+        private static void OpenSettingsWindow()
+        {
+            OpenWindow<SettingsWindow>();
+        }
+
+        /// <inheritdoc/>
+        protected override LocString GetDisplayName()
+        {
+            return new LocEdString("Build");
+        }
+
+        private void OnInitialize()
+        {
+            GUILayoutX splitLayout = GUI.AddLayoutX();
+            GUILayoutY platformLayout = splitLayout.AddLayoutY();
+            GUILayoutY optionsLayout = splitLayout.AddLayoutY();
+
+            
+            GUITextField titleField = new GUITextField(new LocEdString("Title"));
+            GUITextureField iconField = new GUITextureField(new LocEdString("Icon"));
+            GUIToggleField debugToggle = new GUIToggleField(new LocEdString("Debug"));
+            GUIResourceField sceneField = new GUIResourceField(typeof(Prefab), new LocEdString("Startup scene"));
+        }
+
+        private void OnEditorUpdate()
+        {
+
+        }
+    }
+}

+ 1 - 0
MBansheeEditor/MBansheeEditor.csproj

@@ -42,6 +42,7 @@
     <Compile Include="AboutBox.cs" />
     <Compile Include="BrowseDialog.cs" />
     <Compile Include="BuildManager.cs" />
+    <Compile Include="BuildWindow.cs" />
     <Compile Include="CodeEditor.cs" />
     <Compile Include="ColorPicker.cs" />
     <Compile Include="ConsoleWindow.cs" />

+ 1 - 1
MBansheeEditor/SettingsWindow.cs

@@ -4,7 +4,7 @@ using BansheeEngine;
 namespace BansheeEditor
 {
     /// <summary>
-    /// Displays project and editor settings
+    /// Displays project and editor settings.
     /// </summary>
     [DefaultSize(300, 200)]
     internal sealed class SettingsWindow : EditorWindow

+ 13 - 3
RenderBeast/Source/BsRenderBeast.cpp

@@ -155,16 +155,26 @@ namespace BansheeEngine
 					{
 						SPtr<PassCore> pass = renElement.material->getPass(j);
 
-						if (!vertexDecl->isCompatible(pass->getVertexProgram()->getInputDeclaration()))
+						SPtr<VertexDeclarationCore> shaderDecl = pass->getVertexProgram()->getInputDeclaration();
+						if (!vertexDecl->isCompatible(shaderDecl))
 						{
 							renElement.material = nullptr;
-							LOGWRN("Provided mesh is missing required vertex attributes to render with the provided shader.");
-							// TODO - Print mesh & shader names, as well as the exact attributes that are missing
+
+							Vector<VertexElement> missingElements = vertexDecl->getMissingElements(shaderDecl);
+
+							StringStream wrnStream;
+							wrnStream << "Provided mesh is missing required vertex attributes to render with the provided shader. Missing elements: " << std::endl;
+
+							for (auto& entry : missingElements)
+								wrnStream << "\t" << toString(entry.getSemantic()) << entry.getSemanticIdx() << std::endl;
+
+							LOGWRN(wrnStream.str());
 							break;
 						}
 					}
 				}
 
+				// If no material use the default material (two separate versions one depending if mesh has normals or not)
 				if (renElement.material == nullptr)
 				{
 					SPtr<VertexData> vertexData = mesh->getVertexData();

+ 0 - 2
TODOExperimentation.txt

@@ -15,8 +15,6 @@ Assign ViewOrigin, PreViewTranslation, TransViewProj
  
 Next week:
  - Default(dummy) shaders need to render to gbuffer
- - Draw fullscreen needs UVs
- - When input layout mismatch is found found print mesh & shader names, as well as the exact attributes that are missing
  - Finish up DefferedPointLightPass by generating cone geometry in shader
  - Modify Light so it generated adequate number of vertices required for cone geometry, without actually creating the cone
  - Think about how to handle post-processing shaders (HDR tone mapping)