فهرست منبع

First steps with the DebugDraw system

Marko Pintera 12 سال پیش
والد
کامیت
545fa74084

+ 9 - 36
BansheeEngine/Include/BsDebugDraw.h

@@ -7,49 +7,22 @@
 
 namespace BansheeEngine
 {
-	/**
-	 * @brief	Methods you can use for debugging. Quite inefficient way of rendering though,
-	 * 			so use them sparingly.
-	 * 			
-	 *			TODO - NOT THREAD SAFE
-	 */
 	class BS_EXPORT DebugDraw : public CM::Module<DebugDraw>
 	{
-		enum class DebugDrawType
-		{
-			Line, Triangle
-		};
-
-		struct DebugDrawCommand
-		{
-			DebugDrawType type;
-			float timeEnds;
-
-			CM::UINT32* indices;
-			CM::UINT8* vertices;
-			CM::UINT32 numElements;
-		};
-
 	public:
 		DebugDraw();
 
-		void draw2DLine(const CM::Vector2&a, const CM::Vector2& b, const CM::Color& color = CM::Color::Green, float timeout = 0.0f);
-		//void drawAABB(const AxisAlignedBox& aab, const Color& color = Color::Green, float timeout = 0.0f);
-		//void drawSphere(const Vector3& center, float radius, const Color& color = Color::Green, float timeout = 0.0f);
-
-		void render(const Camera* camera, CM::CoreAccessor& coreAccessor);
+		// TODO - Add a version that accepts 4 points
+		void quad2D(const CM::Vector2& pos, const CM::Vector2& size, CM::UINT8* outVertices, CM::UINT8* outColors, 
+			CM::UINT32 vertexOffset, CM::UINT32 vertexStride, CM::UINT32* outIndices, CM::UINT32 indexOffset, const CM::Color& color = CM::Color::White);
 
-	private:
-		CM::HMesh mTriangleMesh;
-		CM::HMesh mLineMesh;
-
-		CM::HMaterial mTriangleMaterial;
-		CM::HMaterial mLineMaterial;
+		// TODO - Need a version that accepts a camera otherwise they will draw on all cameras
+		void drawQuad2D(const CM::Vector2& pos, const CM::Vector2& size, const CM::Color& color = CM::Color::White, float timeout = 0.0f);
 
-		CM::Vector<DebugDrawCommand>::type mCommands;
+		void render(CM::RenderQueue& renderQueue);
 
-		static const int VertexSize = 16;
-
-		void updateMeshes();
+	private:
+		CM::HMaterial mMaterial;
+		CM::Vector<CM::HMesh>::type mMeshes;
 	};
 }

+ 5 - 0
BansheeEngine/Source/BsApplication.cpp

@@ -2,6 +2,7 @@
 #include "BsGUIMaterialManager.h"
 #include "BsGUIManager.h"
 #include "BsOverlayManager.h"
+#include "BsDebugDraw.h"
 #include "BsBuiltinMaterialManager.h"
 #include "BsD3D9BuiltinMaterialFactory.h"
 #include "BsD3D11BuiltinMaterialFactory.h"
@@ -44,6 +45,8 @@ namespace BansheeEngine
 		BuiltinMaterialManager::instance().addFactory(cm_new<GLBuiltinMaterialFactory>());
 		BuiltinMaterialManager::instance().setActive(desc.renderSystem);
 
+		DebugDraw::startUp(cm_new<DebugDraw>());
+
 		EngineGUI::startUp(new EngineGUI());
 
 		updateCallbackConn = CM::gApplication().mainLoopCallback.connect(boost::bind(&Application::update, this));
@@ -60,6 +63,8 @@ namespace BansheeEngine
 
 		EngineGUI::shutDown();
 
+		DebugDraw::shutDown();
+
 		GUIMaterialManager::instance().forceReleaseAllMaterials();
 
 		BuiltinMaterialManager::shutDown();

+ 12 - 9
BansheeEngine/Source/BsD3D11BuiltinMaterialFactory.cpp

@@ -201,20 +201,18 @@ namespace BansheeEngine
 	void D3D11BuiltinMaterialFactory::initDebugDrawShader()
 	{
 		String vsCode = "						\
-		float4x4 matViewProjection;				\
-												\
 		void vs_main(							\
-			in float4 inPos : POSITION,			\
-			in float4 color : COLOR,			\
+			in float3 inPos : POSITION,			\
+			in float4 color : COLOR0,			\
 			out float4 oPosition : SV_Position, \
-			out float4 oColor : COLOR)			\
+			out float4 oColor : COLOR0)			\
 		{										\
-			oPosition = mul(matViewProjection, inPos); \
+			oPosition = float4(inPos.xy, 0, 1); \
 			oColor = color;						\
 		}";
 
 		String psCode = "																		\
-		float4 ps_main(in float4 inPos : SV_Position, in float4 color : COLOR) : SV_Target		\
+		float4 ps_main(in float4 inPos : SV_Position, in float4 color : COLOR0) : SV_Target		\
 		{																						\
 			return color;																		\
 		}																						\
@@ -228,11 +226,16 @@ namespace BansheeEngine
 
 		mDebugDrawShader = Shader::create("DebugDrawShader");
 
-		mDebugDrawShader->addParameter("matViewProjection", "matViewProjection", GPDT_MATRIX_4X4);
-
 		TechniquePtr newTechnique = mDebugDrawShader->addTechnique("D3D11RenderSystem", RendererManager::getCoreRendererName()); 
 		PassPtr newPass = newTechnique->addPass();
 		newPass->setVertexProgram(vsProgram);
 		newPass->setFragmentProgram(psProgram);
+
+		DEPTH_STENCIL_STATE_DESC depthStateDesc;
+		depthStateDesc.depthReadEnable = false;
+		depthStateDesc.depthWriteEnable = false;
+
+		HDepthStencilState depthState = DepthStencilState::create(depthStateDesc);
+		newPass->setDepthStencilState(depthState);
 	}
 }

+ 55 - 156
BansheeEngine/Source/BsDebugDraw.cpp

@@ -5,6 +5,8 @@
 #include "CmMaterial.h"
 #include "CmPass.h"
 #include "CmApplication.h"
+#include "CmRenderQueue.h"
+#include "BsBuiltinMaterialManager.h"
 
 using namespace CamelotFramework;
 
@@ -12,191 +14,88 @@ namespace BansheeEngine
 {
 	DebugDraw::DebugDraw()
 	{
-		// TODO - Create a fixed sized mesh and prevent updating the mesh completely every frame
-		mTriangleMesh = Mesh::create();
-		mLineMesh = Mesh::create();
-
-		// TODO - Init materials
-		//HMaterial mTriangleMaterial;
-		//HMaterial mLineMaterial;
+		mMaterial = BuiltinMaterialManager::instance().createDebugDrawMaterial();
 	}
 
-	void DebugDraw::draw2DLine(const Vector2&a, const Vector2& b, const Color& color, float timeout)
+	void DebugDraw::quad2D(const Vector2& pos, const Vector2& size, UINT8* outVertices, UINT8* outColors, 
+		UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, const Color& color)
 	{
-		UINT32* indices = cm_newN<UINT32, ScratchAlloc>(2);
-		UINT8* vertices = (UINT8*)cm_alloc<ScratchAlloc>(2 * VertexSize);
+		outVertices += vertexOffset;
+		outColors += vertexOffset;
 
-		DebugDrawCommand command;
-		command.indices = cm_newN<UINT32, ScratchAlloc>(2);
-		command.vertices = (UINT8*)cm_alloc<ScratchAlloc>(2 * VertexSize);
-		command.numElements = 1;
-		command.type = DebugDrawType::Line;
-		command.timeEnds = gTime().getTime() + timeout;
+		Vector3* vertices = (Vector3*)outVertices;
+		(*vertices) = Vector3(pos.x, pos.y, 0.0f);
 
-		command.indices[0] = 0;
-		command.indices[1] = 1;
+		vertices = (Vector3*)(outVertices + vertexStride);
+		(*vertices) = Vector3(pos.x + size.x, pos.y, 0.0f);
 
-		UINT8* vertDst = command.vertices;
-		RGBA color32 = color.getAsRGBA();
+		vertices = (Vector3*)(outVertices + vertexStride * 2);
+		(*vertices) = Vector3(pos.x, pos.y + size.y, 0.0f);
 
-		Vector3 pointA(a.x, a.y, 0.0f);
-		memcpy(vertDst, &pointA, sizeof(pointA));
-		vertDst += sizeof(pointA);
+		vertices = (Vector3*)(outVertices + vertexStride * 3);
+		(*vertices) = Vector3(pos.x + size.x, pos.y + size.y, 0.0f);
 
-		memcpy(vertDst, &color32, sizeof(color32));
-		vertDst += sizeof(color32);
+		UINT32* colors = (UINT32*)outColors;
+		(*colors) = color.getAsRGBA();
 
-		Vector3 pointB(b.x, b.y, 0.0f);
-		memcpy(vertDst, &pointB, sizeof(pointB));
-		vertDst += sizeof(pointB);
+		colors = (UINT32*)(outColors + vertexStride);
+		(*colors) = color.getAsRGBA();
+		
+		colors = (UINT32*)(outColors + vertexStride * 2);
+		(*colors) = color.getAsRGBA();
 
-		memcpy(vertDst, &color32, sizeof(color32));
-		vertDst += sizeof(color32);
+		colors = (UINT32*)(outColors + vertexStride * 3);
+		(*colors) = color.getAsRGBA();
 
-		mCommands.push_back(command);
+		outIndices += indexOffset;
+		outIndices[0] = vertexOffset + 0;
+		outIndices[1] = vertexOffset + 2;
+		outIndices[2] = vertexOffset + 1;
+		outIndices[3] = vertexOffset + 1;
+		outIndices[4] = vertexOffset + 2;
+		outIndices[5] = vertexOffset + 3;
 	}
 
-	void DebugDraw::updateMeshes()
+	void DebugDraw::drawQuad2D(const Vector2& pos, const Vector2& size, const CM::Color& color, float timeout)
 	{
-		if(mCommands.size() == 0)
-			return;
-
-		UINT32 totalNumLineIndices = 0;
-		UINT32 totalNumLineVertices = 0;
-		UINT32 totalNumTriangleIndices = 0;
-		UINT32 totalNumTriangleVertices = 0;
-
-		for(auto& command : mCommands)
-		{
-			if(command.type == DebugDrawType::Line)
-			{
-				totalNumLineIndices += command.numElements * 2;
-				totalNumLineVertices += command.numElements * 2;
-			}
-			else if(command.type == DebugDrawType::Triangle)
-			{
-				totalNumTriangleIndices += command.numElements * 3;
-				totalNumTriangleVertices += command.numElements * 3;
-			}
-		}
+		// TODO - DONT USE ONE MESH PER DRAW - Instead merge multiple elements into a single mesh
 
-		// TODO - Somehow avoid creating these every frame?
-		MeshDataPtr lineMeshData = cm_shared_ptr<MeshData, ScratchAlloc>(totalNumLineVertices);
-		MeshDataPtr triangleMeshData = cm_shared_ptr<MeshData, ScratchAlloc>(totalNumTriangleVertices);
+		MeshDataPtr meshData = cm_shared_ptr<MeshData, ScratchAlloc>(4);
 
-		lineMeshData->beginDesc();
+		meshData->beginDesc();
 
-		lineMeshData->addSubMesh(totalNumLineIndices);
-		lineMeshData->addVertElem(VET_FLOAT3, VES_POSITION);
-		lineMeshData->addVertElem(VET_COLOR, VES_COLOR);
+		meshData->addSubMesh(6);
+		meshData->addVertElem(VET_FLOAT3, VES_POSITION);
+		meshData->addVertElem(VET_COLOR, VES_COLOR);
 
-		lineMeshData->endDesc();
+		meshData->endDesc();
 
-		triangleMeshData->beginDesc();
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+		UINT8* colorData = meshData->getElementData(VES_COLOR);
 
-		triangleMeshData->addSubMesh(totalNumTriangleIndices);
-		triangleMeshData->addVertElem(VET_FLOAT3, VES_POSITION);
-		triangleMeshData->addVertElem(VET_COLOR, VES_COLOR);
+		quad2D(pos, size, positionData, colorData, 0, meshData->getVertexStride(), indexData, 0, color);
 
-		triangleMeshData->endDesc();
-
-		UINT32 lineIndexOffset = 0;
-		UINT32 lineVertexOffset = 0;
-		UINT32 triangleIndexOffset = 0;
-		UINT32 triangleVertexOffset = 0;
-		Vector<DebugDrawCommand>::type newCommands;
-		for(auto& command : mCommands)
-		{
-			if(command.type == DebugDrawType::Line)
-			{
-				UINT32 numIndices = command.numElements * 2;
-				UINT32 numVertices = command.numElements * 2;
-
-				UINT32* indexData = lineMeshData->getIndices32() + lineIndexOffset;
-				memcpy(indexData, command.indices, numIndices * sizeof(UINT32));
-
-				UINT8* vertexData = lineMeshData->getElementData(VES_POSITION) + lineVertexOffset * VertexSize;
-				memcpy(vertexData, command.vertices, numVertices * VertexSize);
-
-				lineIndexOffset += numIndices;
-				lineVertexOffset += numVertices;
-			}
-			else if(command.type == DebugDrawType::Triangle)
-			{
-				UINT32 numIndices = command.numElements * 3;
-				UINT32 numVertices = command.numElements * 3;
-
-				UINT32* indexData = triangleMeshData->getIndices32() + triangleIndexOffset;
-				memcpy(indexData, command.indices, numIndices * sizeof(UINT32));
-
-				UINT8* vertexData = triangleMeshData->getElementData(VES_POSITION) + triangleVertexOffset * VertexSize;
-				memcpy(vertexData, command.vertices, numVertices * VertexSize);
-
-				triangleIndexOffset += numIndices;
-				triangleVertexOffset += numVertices;
-			}
-
-			if(command.timeEnds < gTime().getTime())
-				newCommands.push_back(command);
-			else
-			{
-				UINT32 numIndices = 0;
-				if(command.type == DebugDrawType::Line)
-				{
-					numIndices = command.numElements * 2;
-				}
-				else if(command.type == DebugDrawType::Triangle)
-				{
-					numIndices = command.numElements * 3;
-				}
-
-				cm_deleteN<ScratchAlloc>(command.indices, numIndices);
-				cm_free<ScratchAlloc>(command.vertices);
-			}
-		}
-
-		gMainSyncedCA().writeSubresource(mLineMesh.getInternalPtr(), 0, *lineMeshData);
-		gMainSyncedCA().writeSubresource(mTriangleMesh.getInternalPtr(), 0, *triangleMeshData);
+		HMesh mesh = Mesh::create();
+		gMainSyncedCA().writeSubresource(mesh.getInternalPtr(), 0, *meshData);
 		gMainSyncedCA().submitToCoreThread(true);
+
+		// TODO - Timeout is ignored!
+		mMeshes.push_back(mesh);
 	}
 
-	void DebugDraw::render(const Camera* camera, CoreAccessor& coreAccessor)
+	void DebugDraw::render(CM::RenderQueue& renderQueue)
 	{
-		if(mCommands.size() == 0)
+		if(mMaterial == nullptr || !mMaterial.isLoaded())
 			return;
 
-		updateMeshes();
-
-		for(UINT32 i = 0; i < mLineMaterial->getNumPasses(); i++)
+		for(auto& mesh : mMeshes)
 		{
-			PassPtr pass = mLineMaterial->getPass(i);
-			pass->activate(coreAccessor);
-
-			PassParametersPtr paramsPtr = mLineMaterial->getPassParameters(i);
-			pass->bindParameters(coreAccessor, paramsPtr);
+			if(mesh == nullptr || !mesh.isLoaded())
+				continue;
 
-			coreAccessor.render(mLineMesh->getSubMeshData());
-		}
-
-		for(UINT32 i = 0; i < mTriangleMaterial->getNumPasses(); i++)
-		{
-			PassPtr pass = mTriangleMaterial->getPass(i);
-			pass->activate(coreAccessor);
-
-			PassParametersPtr paramsPtr = mTriangleMaterial->getPassParameters(i);
-			pass->bindParameters(coreAccessor, paramsPtr);
-
-			coreAccessor.render(mTriangleMesh->getSubMeshData());
+			// TODO - I'm not setting a world position
+			renderQueue.add(mMaterial, mesh->getSubMeshData(), Vector3::ZERO);
 		}
 	}
-
-	//void DebugDraw::drawAABB(const AxisAlignedBox& aab, const Color& color, float timeout)
-	//{
-
-	//}
-
-	//void DebugDraw::drawSphere(const Vector3& center, float radius, const Color& color, float timeout)
-	//{
-
-	//}
 }

+ 4 - 0
BansheeForwardRenderer/Source/BsForwardRenderer.cpp

@@ -14,6 +14,7 @@
 #include "CmRenderOperation.h"
 #include "CmDefaultRenderQueue.h"
 #include "BsOverlayManager.h"
+#include "BsDebugDraw.h"
 #include "BsGUIManager.h"
 
 using namespace CamelotFramework;
@@ -154,6 +155,9 @@ namespace BansheeEngine
 		// Get overlay render operations
 		OverlayManager::instance().render(camera->getViewport(), *mRenderQueue);
 
+		// Get debug render operations
+		DebugDraw::instance().render(*mRenderQueue);
+
 		// TODO - Material queue is completely ignored
 		mRenderQueue->sort();
 		const Vector<SortedRenderOp>::type& sortedROps =  mRenderQueue->getSortedRenderOps();

+ 5 - 2
CamelotClient/CamelotClient.cpp

@@ -23,6 +23,7 @@
 #include "CmFontImportOptions.h"
 #include "CmCommandQueue.h"
 #include "CmBlendState.h"
+#include "BsDebugDraw.h"
 
 // Editor includes
 #include "BsEditorWindowManager.h"
@@ -36,9 +37,9 @@
 #include "CmRTTIType.h"
 #include "CmCursor.h"
 
-//#define DX11
+#define DX11
 //#define DX9
-#define GL
+//#define GL
 
 using namespace CamelotFramework;
 using namespace BansheeEditor;
@@ -270,6 +271,8 @@ int CALLBACK WinMain(
 
 	dbgCursor.reset();
 
+	DebugDraw::instance().drawQuad2D(Vector2(-1.0f, 0.0f), Vector2(100, 50), Color::White);
+
 	/************************************************************************/
 	/* 								EDITOR INIT                      		*/
 	/************************************************************************/

+ 1 - 1
CamelotCore/Source/CmDefaultRenderQueue.cpp

@@ -20,7 +20,7 @@ namespace CamelotFramework
 			}
 		}
 
-		// TODO - Actually do some sorting
+		// TODO - Actually do some sorting. Use material options to sort (isTransparent, isOverlay(need to add this), etc.)
 		// Note: When sorting make sure not to change order of unsorted elements. Some outside managers (like overlay and GUI) will provide render ops which are already sorted
 	}
 }