Browse Source

Added basic 3D debug draw class

Marko Pintera 12 years ago
parent
commit
61fa789c39

+ 2 - 0
BansheeEngine/BansheeEngine.vcxproj

@@ -227,6 +227,7 @@
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClInclude Include="Include\BsApplication.h" />
+    <ClInclude Include="Include\BsDrawHelper3D.h" />
     <ClInclude Include="Include\BsDrawHelperTemplate.h" />
     <ClInclude Include="Include\BsDragAndDropManager.h" />
     <ClInclude Include="Include\BsDrawHelper2D.h" />
@@ -286,6 +287,7 @@
   <ItemGroup>
     <ClCompile Include="Source\BsApplication.cpp" />
     <ClCompile Include="Source\BsDrawHelper2D.cpp" />
+    <ClCompile Include="Source\BsDrawHelper3D.cpp" />
     <ClCompile Include="Source\BsDrawHelperTemplate.cpp" />
     <ClCompile Include="Source\BsDragAndDropManager.cpp" />
     <ClCompile Include="Source\BsEngineGUI.cpp" />

+ 6 - 0
BansheeEngine/BansheeEngine.vcxproj.filters

@@ -204,6 +204,9 @@
     <ClInclude Include="Include\BsDrawHelperTemplate.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsDrawHelper3D.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsGUIElement.cpp">
@@ -350,5 +353,8 @@
     <ClCompile Include="Source\BsDrawHelper2D.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsDrawHelper3D.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 7 - 0
BansheeEngine/Include/BsDrawHelper2D.h

@@ -117,5 +117,12 @@ namespace BansheeEngine
 
 		CM::FRect normalizedCoordToClipSpace(const CM::FRect& area) const;
 		CM::Vector2 normalizedCoordToClipSpace(const CM::Vector2& pos) const;
+
+	protected:
+		void line_AA(const CM::Vector2& a, const CM::Vector2& b, float width, float borderWidth, const CM::Color& color, CM::UINT8* outVertices, CM::UINT8* outColors, 
+			CM::UINT32 vertexOffset, CM::UINT32 vertexStride, CM::UINT32* outIndices, CM::UINT32 indexOffset);
+
+		void polygon_AA(const CM::Vector<CM::Vector2>::type& points, float borderWidth, const CM::Color& color, CM::UINT8* outVertices, CM::UINT8* outColors, 
+			CM::UINT32 vertexOffset, CM::UINT32 vertexStride, CM::UINT32* outIndices, CM::UINT32 indexOffset);
 	};
 }

+ 105 - 0
BansheeEngine/Include/BsDrawHelper3D.h

@@ -0,0 +1,105 @@
+#pragma once
+
+#include "BsPrerequisites.h"
+#include "BsDrawHelperTemplate.h"
+#include "CmModule.h"
+#include "CmColor.h"
+#include "CmAABox.h"
+
+namespace BansheeEngine
+{
+	class BS_EXPORT DrawHelper3D : public DrawHelperTemplate<CM::Vector3>, public CM::Module<DrawHelper3D>
+	{
+	public:
+		/**
+		 * @brief	Fills the mesh data with vertices representing a per-pixel line.
+		 *
+		 * @param	a				Start point of the line.
+		 * @param	b				End point of the line.
+		 * @param	color			Color of the line.
+		 * @param	meshData		Mesh data that will be populated.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * 							
+		 * @note	Provided MeshData must have some specific elements at least:
+		 * 			  Vector3 VES_POSITION
+		 * 			  UINT32  VES_COLOR
+		 * 			  32bit index buffer
+		 * 			  Enough space for 2 vertices and 2 indices
+		 */
+		void line_Pixel(const CM::Vector3& a, const CM::Vector3& b, const CM::Color& color, const CM::MeshDataPtr& meshData, CM::UINT32 vertexOffset, CM::UINT32 indexOffset);
+
+		/**
+		 * @brief	Fills the mesh data with vertices representing an anti-aliased line of specific width. Antialiasing is done using alpha blending.
+		 *
+		 * @param	a				Start point of the line.
+		 * @param	b				End point of the line.
+		 * @param	width			Width of the line.
+		 * @param	borderWidth		Width of the anti-aliased border.
+		 * @param	color			Color of the line.
+		 * @param	meshData		Mesh data that will be populated by this method.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * 							
+		 * @note	Provided MeshData must have some specific elements at least:
+		 * 			  Vector3 VES_POSITION
+		 * 			  UINT32  VES_COLOR
+		 * 			  32bit index buffer
+		 *			  Enough space for 8 vertices and 30 indices
+		 */
+		void line_AA(const CM::Vector3& a, const CM::Vector3& b, float width, float borderWidth, const CM::Color& color, const CM::MeshDataPtr& meshData, CM::UINT32 vertexOffset, CM::UINT32 indexOffset);
+
+		/**
+		 * @brief	Fills the mesh data with vertices representing per-pixel lines.
+		 *
+		 * @param	linePoints		A list of start and end points for the lines. Must be a multiple of 2.
+		 * @param	color			Color of the line.
+		 * @param	meshData		Mesh data that will be populated.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * 							
+		 * @note	Provided MeshData must have some specific elements at least:
+		 * 			  Vector3 VES_POSITION
+		 * 			  UINT32  VES_COLOR
+		 * 			  32bit index buffer
+		 * 			  Enough space for (numLines * 2) vertices and (numLines * 2) indices
+		 */
+		void lineList_Pixel(const CM::Vector<CM::Vector3>::type& linePoints, const CM::Color& color, const CM::MeshDataPtr& meshData, CM::UINT32 vertexOffset, CM::UINT32 indexOffset);
+
+		/**
+		 * @brief	Fills the mesh data with vertices representing anti-aliased lines of specific width. Antialiasing is done using alpha blending.
+		 *
+		 * @param	linePoints		A list of start and end points for the lines. Must be a multiple of 2.
+		 * @param	width			Width of the line.
+		 * @param	borderWidth		Width of the anti-aliased border.
+		 * @param	color			Color of the line.
+		 * @param	meshData		Mesh data that will be populated by this method.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * 							
+		 * @note	Provided MeshData must have some specific elements at least:
+		 * 			  Vector3 VES_POSITION
+		 * 			  UINT32  VES_COLOR
+		 * 			  32bit index buffer
+		 *			  Enough space for (numLines * 8) vertices and (numLines * 30) indices
+		 */
+		void lineList_AA(const CM::Vector<CM::Vector3>::type& linePoints, float width, float borderWidth, const CM::Color& color, const CM::MeshDataPtr& meshData, CM::UINT32 vertexOffset, CM::UINT32 indexOffset);
+
+		void drawLine_Pixel(const HCamera& camera, const CM::Vector3& a, const CM::Vector3& b, const CM::Color& color = CM::Color::White, float timeout = 0.0f);
+		void drawLine_AA(const HCamera& camera, const CM::Vector3& a, const CM::Vector3& b, float width, float borderWidth, 
+			const CM::Color& color = CM::Color::White, float timeout = 0.0f);
+		void drawLineList_Pixel(const HCamera& camera, const CM::Vector<CM::Vector3>::type& linePoints, const CM::Color& color = CM::Color::White, float timeout = 0.0f);
+		void drawLineList_AA(const HCamera& camera, const CM::Vector<CM::Vector3>::type& linePoints, float width, float borderWidth, 
+			const CM::Color& color = CM::Color::White, float timeout = 0.0f);
+
+	private:
+		CM::Vector3 calcCenter(CM::UINT8* vertices, CM::UINT32 numVertices, CM::UINT32 vertexStride);
+
+	protected:
+		void line_AA(const CM::Vector3& a, const CM::Vector3& b, float width, float borderWidth, const CM::Color& color, CM::UINT8* outVertices, CM::UINT8* outColors, 
+			CM::UINT32 vertexOffset, CM::UINT32 vertexStride, CM::UINT32* outIndices, CM::UINT32 indexOffset);
+
+		void polygon_AA(const CM::Vector<CM::Vector3>::type& points, float borderWidth, const CM::Color& color, CM::UINT8* outVertices, CM::UINT8* outColors, 
+			CM::UINT32 vertexOffset, CM::UINT32 vertexStride, CM::UINT32* outIndices, CM::UINT32 indexOffset);
+	};
+}

+ 5 - 119
BansheeEngine/Include/BsDrawHelperTemplate.h

@@ -143,125 +143,11 @@ namespace BansheeEngine
 			outIndices[1] = vertexOffset + 1;
 		}
 
-		void line_AA(const T& a, const T& b, float width, float borderWidth, const CM::Color& color, CM::UINT8* outVertices, CM::UINT8* outColors, 
-			CM::UINT32 vertexOffset, CM::UINT32 vertexStride, CM::UINT32* outIndices, CM::UINT32 indexOffset)
-		{
-			T dir = b - a;
-			dir.normalize();
-
-			T nrm(dir.y, -dir.x); // TODO - Not properly ported
-
-			Vector<T>::type points(4);
-
-			float r = width - 1.0f;
-			r *= 0.5f;
-			if (r < 0.01f) 
-				r = 0.01f;
-
-			dir = dir * r;
-			nrm = nrm * r;
-
-			T v0 = a - dir - nrm;
-			T v1 = a - dir + nrm;
-			T v2 = b + dir + nrm;
-			T v3 = b + dir - nrm;
-
-			points[0] = v0;
-			points[1] = v1;
-			points[2] = v2;
-			points[3] = v3;
-
-			polygon_AA(points, borderWidth, color, outVertices, outColors, vertexOffset, vertexStride, outIndices, indexOffset);
-		}
-
-		void polygon_AA(const typename CM::Vector<T>::type& points, float borderWidth, const CM::Color& color, CM::UINT8* outVertices, CM::UINT8* outColors, 
-			CM::UINT32 vertexOffset, CM::UINT32 vertexStride, CM::UINT32* outIndices, CM::UINT32 indexOffset)
-		{
-			UINT32 numCoords = (UINT32)points.size();
-
-			outVertices += vertexOffset * vertexStride;
-			Vector<T>::type tempNormals(numCoords);
-
-			for(UINT32 i = 0, j = numCoords - 1; i < numCoords; j = i++)
-			{
-				const T& v0 = points[j];
-				const T& v1 = points[i];
-
-				T d = v1 - v0;
-				d.normalize();
-
-				// Rotate by 90 degrees
-				std::swap(d.x, d.y); // TODO - Not properly ported
-				d.y = -d.y;
-
-				tempNormals[j] = d;
-
-				// Also start populating the vertex array
-				T* vertices = (T*)outVertices;
-				*vertices = v1;
-
-				UINT32* colors = (UINT32*)outColors;
-				*colors = color.getAsRGBA();
-
-				outVertices += vertexStride;
-				outColors += vertexStride;
-			}
-
-			Color transparentColor = color;
-			transparentColor.a = 0.0f;
-
-			for(UINT32 i = 0, j = numCoords - 1; i < numCoords; j = i++)
-			{
-				const T& n0 = tempNormals[j];
-				const T& n1 = tempNormals[i];
-
-				T avgNrm = (n0 + n1) * 0.5f;
-				float magSqrd = avgNrm.squaredLength();
-
-				if (magSqrd > 0.000001f)
-				{
-					float scale = 1.0f / magSqrd;
-					if (scale > 10.0f) 
-						scale = 10.0f;
-
-					avgNrm = avgNrm * scale;
-				}
-
-				T tempCoord = points[i] + avgNrm * borderWidth;
-
-				// Move it to the vertex array
-				T* vertices = (T*)outVertices;
-				*vertices = tempCoord;
-
-				UINT32* colors = (UINT32*)outColors;
-				*colors = transparentColor.getAsRGBA();
-
-				outVertices += vertexStride;
-				outColors += vertexStride;
-			}
-
-			// Populate index buffer
-			outIndices += indexOffset;
-
-			UINT32 idxCnt = 0;
-			for(UINT32 i = 0, j = numCoords - 1; i < numCoords; j = i++)
-			{
-				outIndices[idxCnt++] = i;
-				outIndices[idxCnt++] = j;
-				outIndices[idxCnt++] = numCoords + j;
-
-				outIndices[idxCnt++] = numCoords + j;
-				outIndices[idxCnt++] = numCoords + i;
-				outIndices[idxCnt++] = i;
-			}
+		virtual void line_AA(const T& a, const T& b, float width, float borderWidth, const CM::Color& color, CM::UINT8* outVertices, CM::UINT8* outColors, 
+			CM::UINT32 vertexOffset, CM::UINT32 vertexStride, CM::UINT32* outIndices, CM::UINT32 indexOffset) = 0;
 
-			for(UINT32 i = 2; i < numCoords; ++i)
-			{
-				outIndices[idxCnt++] = 0;
-				outIndices[idxCnt++] = i - 1;
-				outIndices[idxCnt++] = i;
-			}
-		}
+		virtual void polygon_AA(const typename CM::Vector<T>::type& points, float borderWidth, const CM::Color& color, CM::UINT8* outVertices, CM::UINT8* outColors, 
+			CM::UINT32 vertexOffset, CM::UINT32 vertexStride, CM::UINT32* outIndices, CM::UINT32 indexOffset) = 0;
 
 		void polygonFill_Pixel(const typename CM::Vector<T>::type& points, CM::UINT8* outVertices, 
 			CM::UINT32 vertexOffset, CM::UINT32 vertexStride, CM::UINT32* outIndices, CM::UINT32 indexOffset)
@@ -271,7 +157,7 @@ namespace BansheeEngine
 			for(auto& point : points)
 			{
 				T* vertices = (T*)outVertices;
-				(*vertices) = Vector2(point.x, point.y); // TODO - Not properly ported
+				(*vertices) = point;
 
 				outVertices += vertexStride;
 			}

+ 3 - 0
BansheeEngine/Source/BsApplication.cpp

@@ -3,6 +3,7 @@
 #include "BsGUIManager.h"
 #include "BsOverlayManager.h"
 #include "BsDrawHelper2D.h"
+#include "BsDrawHelper3D.h"
 #include "BsBuiltinMaterialManager.h"
 #include "BsD3D9BuiltinMaterialFactory.h"
 #include "BsD3D11BuiltinMaterialFactory.h"
@@ -46,6 +47,7 @@ namespace BansheeEngine
 		BuiltinMaterialManager::instance().setActive(desc.renderSystem);
 
 		DrawHelper2D::startUp(cm_new<DrawHelper2D>());
+		DrawHelper3D::startUp(cm_new<DrawHelper3D>());
 
 		EngineGUI::startUp(new EngineGUI());
 
@@ -63,6 +65,7 @@ namespace BansheeEngine
 
 		EngineGUI::shutDown();
 
+		DrawHelper3D::shutDown();
 		DrawHelper2D::shutDown();
 
 		GUIMaterialManager::instance().forceReleaseAllMaterials();

+ 120 - 0
BansheeEngine/Source/BsDrawHelper2D.cpp

@@ -330,6 +330,126 @@ namespace BansheeEngine
 		}
 	}
 
+	void DrawHelper2D::line_AA(const Vector2& a, const Vector2& b, float width, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors, 
+		UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
+	{
+		Vector2 dir = b - a;
+		dir.normalize();
+
+		Vector2 nrm(dir.y, -dir.x);
+
+		Vector<Vector2>::type points(4);
+
+		float r = width - 1.0f;
+		r *= 0.5f;
+		if (r < 0.01f) 
+			r = 0.01f;
+
+		dir = dir * r;
+		nrm = nrm * r;
+
+		Vector2 v0 = a - dir - nrm;
+		Vector2 v1 = a - dir + nrm;
+		Vector2 v2 = b + dir + nrm;
+		Vector2 v3 = b + dir - nrm;
+
+		points[0] = v0;
+		points[1] = v1;
+		points[2] = v2;
+		points[3] = v3;
+
+		polygon_AA(points, borderWidth, color, outVertices, outColors, vertexOffset, vertexStride, outIndices, indexOffset);
+	}
+
+	void DrawHelper2D::polygon_AA(const Vector<Vector2>::type& points, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors, 
+		UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
+	{
+		UINT32 numCoords = (UINT32)points.size();
+
+		outVertices += vertexOffset * vertexStride;
+		Vector<Vector2>::type tempNormals(numCoords);
+
+		for(UINT32 i = 0, j = numCoords - 1; i < numCoords; j = i++)
+		{
+			const Vector2& v0 = points[j];
+			const Vector2& v1 = points[i];
+
+			Vector2 d = v1 - v0;
+			d.normalize();
+
+			// Rotate by 90 degrees
+			std::swap(d.x, d.y); // TODO - Not properly ported
+			d.y = -d.y;
+
+			tempNormals[j] = d;
+
+			// Also start populating the vertex array
+			Vector2* vertices = (Vector2*)outVertices;
+			*vertices = v1;
+
+			UINT32* colors = (UINT32*)outColors;
+			*colors = color.getAsRGBA();
+
+			outVertices += vertexStride;
+			outColors += vertexStride;
+		}
+
+		Color transparentColor = color;
+		transparentColor.a = 0.0f;
+
+		for(UINT32 i = 0, j = numCoords - 1; i < numCoords; j = i++)
+		{
+			const Vector2& n0 = tempNormals[j];
+			const Vector2& n1 = tempNormals[i];
+
+			Vector2 avgNrm = (n0 + n1) * 0.5f;
+			float magSqrd = avgNrm.squaredLength();
+
+			if (magSqrd > 0.000001f)
+			{
+				float scale = 1.0f / magSqrd;
+				if (scale > 10.0f) 
+					scale = 10.0f;
+
+				avgNrm = avgNrm * scale;
+			}
+
+			Vector2 tempCoord = points[i] + avgNrm * borderWidth;
+
+			// Move it to the vertex array
+			Vector2* vertices = (Vector2*)outVertices;
+			*vertices = tempCoord;
+
+			UINT32* colors = (UINT32*)outColors;
+			*colors = transparentColor.getAsRGBA();
+
+			outVertices += vertexStride;
+			outColors += vertexStride;
+		}
+
+		// Populate index buffer
+		outIndices += indexOffset;
+
+		UINT32 idxCnt = 0;
+		for(UINT32 i = 0, j = numCoords - 1; i < numCoords; j = i++)
+		{
+			outIndices[idxCnt++] = i;
+			outIndices[idxCnt++] = j;
+			outIndices[idxCnt++] = numCoords + j;
+
+			outIndices[idxCnt++] = numCoords + j;
+			outIndices[idxCnt++] = numCoords + i;
+			outIndices[idxCnt++] = i;
+		}
+
+		for(UINT32 i = 2; i < numCoords; ++i)
+		{
+			outIndices[idxCnt++] = 0;
+			outIndices[idxCnt++] = i - 1;
+			outIndices[idxCnt++] = i;
+		}
+	}
+
 	FRect DrawHelper2D::normalizedCoordToClipSpace(const FRect& area) const
 	{
 		FRect clipSpaceRect;

+ 209 - 0
BansheeEngine/Source/BsDrawHelper3D.cpp

@@ -0,0 +1,209 @@
+#include "BsDrawHelper3D.h"
+#include "CmFRect.h"
+#include "CmMesh.h"
+#include "CmTime.h"
+#include "CmVector2.h"
+#include "CmMaterial.h"
+#include "CmPass.h"
+#include "CmApplication.h"
+#include "CmRenderQueue.h"
+#include "CmException.h"
+#include "BsCamera.h"
+#include "BsBuiltinMaterialManager.h"
+
+using namespace CamelotFramework;
+
+namespace BansheeEngine
+{
+	void DrawHelper3D::line_Pixel(const Vector3& a, const Vector3& b, const CM::Color& color, const CM::MeshDataPtr& meshData, CM::UINT32 vertexOffset, CM::UINT32 indexOffset)
+	{
+		DrawHelperTemplate<Vector3>::line_Pixel(a, b, color, meshData, vertexOffset, indexOffset);
+	}
+
+	void DrawHelper3D::line_AA(const Vector3& a, const Vector3& b, float width, float borderWidth, const CM::Color& color, const CM::MeshDataPtr& meshData, CM::UINT32 vertexOffset, CM::UINT32 indexOffset)
+	{
+		DrawHelperTemplate<Vector3>::line_AA(a, b, width, borderWidth, color, meshData, vertexOffset, indexOffset);
+	}
+
+	void DrawHelper3D::lineList_Pixel(const CM::Vector<Vector3>::type& linePoints, const CM::Color& color, const CM::MeshDataPtr& meshData, CM::UINT32 vertexOffset, CM::UINT32 indexOffset)
+	{
+		DrawHelperTemplate<Vector3>::lineList_Pixel(linePoints, color, meshData, vertexOffset, indexOffset);
+	}
+
+	void DrawHelper3D::lineList_AA(const CM::Vector<Vector3>::type& linePoints, float width, float borderWidth, const CM::Color& color, const CM::MeshDataPtr& meshData, CM::UINT32 vertexOffset, CM::UINT32 indexOffset)
+	{
+		DrawHelperTemplate<Vector3>::lineList_AA(linePoints, width, borderWidth, color, meshData, vertexOffset, indexOffset);
+	}
+
+	/************************************************************************/
+	/* 								DRAW	                     			*/
+	/************************************************************************/
+
+	void DrawHelper3D::drawLine_Pixel(const HCamera& camera, const Vector3& a, const Vector3& b, const Color& color, float timeout)
+	{
+		const Viewport* viewport = camera->getViewport().get();
+
+		Vector<DebugDrawCommand>::type& commands = mCommandsPerViewport[viewport];
+
+		commands.push_back(DebugDrawCommand());
+		DebugDrawCommand& dbgCmd = commands.back();
+		dbgCmd.endTime = gTime().getTime() + timeout;
+
+		MeshDataPtr meshData = cm_shared_ptr<MeshData, ScratchAlloc>(2);
+
+		meshData->beginDesc();
+
+		meshData->addSubMesh(2, 0, DOT_LINE_LIST);
+		meshData->addVertElem(VET_FLOAT2, VES_POSITION);
+		meshData->addVertElem(VET_COLOR, VES_COLOR);
+
+		meshData->endDesc();
+
+		line_Pixel(a, b, color, meshData, 0, 0);
+
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+		dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), meshData->getVertexStride());
+
+		HMesh mesh = Mesh::create();
+
+		gMainSyncedCA().writeSubresource(mesh.getInternalPtr(), 0, *meshData);
+		gMainSyncedCA().submitToCoreThread(true);
+
+		dbgCmd.mesh = mesh;
+		dbgCmd.type = DebugDrawType::WorldSpace;
+		dbgCmd.material = BuiltinMaterialManager::instance().createDebugDraw3DMaterial();
+	}
+
+	void DrawHelper3D::drawLine_AA(const HCamera& camera, const Vector3& a, const Vector3& b, float width, float borderWidth, const Color& color, float timeout)
+	{
+		const Viewport* viewport = camera->getViewport().get();
+
+		Vector<DebugDrawCommand>::type& commands = mCommandsPerViewport[viewport];
+
+		commands.push_back(DebugDrawCommand());
+		DebugDrawCommand& dbgCmd = commands.back();
+		dbgCmd.endTime = gTime().getTime() + timeout;
+
+		MeshDataPtr meshData = cm_shared_ptr<MeshData, ScratchAlloc>(8);
+
+		meshData->beginDesc();
+
+		meshData->addSubMesh(30, 0, DOT_TRIANGLE_LIST);
+		meshData->addVertElem(VET_FLOAT2, VES_POSITION);
+		meshData->addVertElem(VET_COLOR, VES_COLOR);
+
+		meshData->endDesc();
+
+		line_AA(a, b, width, borderWidth, color, meshData, 0, 0);
+
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+		dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), meshData->getVertexStride());
+
+		HMesh mesh = Mesh::create();
+
+		gMainSyncedCA().writeSubresource(mesh.getInternalPtr(), 0, *meshData);
+		gMainSyncedCA().submitToCoreThread(true);
+
+		dbgCmd.mesh = mesh;
+		dbgCmd.type = DebugDrawType::WorldSpace;
+		dbgCmd.material = BuiltinMaterialManager::instance().createDebugDraw3DMaterial();
+	}
+
+	void DrawHelper3D::drawLineList_Pixel(const HCamera& camera, const Vector<Vector3>::type& linePoints, const Color& color, float timeout)
+	{
+		const Viewport* viewport = camera->getViewport().get();
+
+		Vector<DebugDrawCommand>::type& commands = mCommandsPerViewport[viewport];
+
+		commands.push_back(DebugDrawCommand());
+		DebugDrawCommand& dbgCmd = commands.back();
+		dbgCmd.endTime = gTime().getTime() + timeout;
+
+		MeshDataPtr meshData = cm_shared_ptr<MeshData, ScratchAlloc>((UINT32)(linePoints.size() * 2));
+
+		meshData->beginDesc();
+
+		meshData->addSubMesh((UINT32)(linePoints.size() * 2), 0, DOT_LINE_LIST);
+		meshData->addVertElem(VET_FLOAT2, VES_POSITION);
+		meshData->addVertElem(VET_COLOR, VES_COLOR);
+
+		meshData->endDesc();
+
+		lineList_Pixel(linePoints, color, meshData, 0, 0);
+
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+		dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), meshData->getVertexStride());
+
+		HMesh mesh = Mesh::create();
+
+		gMainSyncedCA().writeSubresource(mesh.getInternalPtr(), 0, *meshData);
+		gMainSyncedCA().submitToCoreThread(true);
+
+		dbgCmd.mesh = mesh;
+		dbgCmd.type = DebugDrawType::WorldSpace;
+		dbgCmd.material = BuiltinMaterialManager::instance().createDebugDraw3DMaterial();
+	}
+
+	void DrawHelper3D::drawLineList_AA(const HCamera& camera, const CM::Vector<CM::Vector3>::type& linePoints, float width, float borderWidth, 
+		const CM::Color& color, float timeout)
+	{
+		const Viewport* viewport = camera->getViewport().get();
+
+		Vector<DebugDrawCommand>::type& commands = mCommandsPerViewport[viewport];
+
+		commands.push_back(DebugDrawCommand());
+		DebugDrawCommand& dbgCmd = commands.back();
+		dbgCmd.endTime = gTime().getTime() + timeout;
+
+		MeshDataPtr meshData = cm_shared_ptr<MeshData, ScratchAlloc>((UINT32)(linePoints.size() * 4));
+
+		meshData->beginDesc();
+
+		meshData->addSubMesh((UINT32)(linePoints.size() * 15), 0, DOT_TRIANGLE_LIST);
+		meshData->addVertElem(VET_FLOAT2, VES_POSITION);
+		meshData->addVertElem(VET_COLOR, VES_COLOR);
+
+		meshData->endDesc();
+
+		lineList_AA(linePoints, width, borderWidth, color, meshData, 0, 0);	
+
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+		dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), meshData->getVertexStride());
+
+		HMesh mesh = Mesh::create();
+
+		gMainSyncedCA().writeSubresource(mesh.getInternalPtr(), 0, *meshData);
+		gMainSyncedCA().submitToCoreThread(true);
+
+		dbgCmd.mesh = mesh;
+		dbgCmd.type = DebugDrawType::WorldSpace;
+		dbgCmd.material = BuiltinMaterialManager::instance().createDebugDraw3DMaterial();
+	}
+
+	CM::Vector3 DrawHelper3D::calcCenter(UINT8* vertices, UINT32 numVertices, UINT32 vertexStride)
+	{
+		Vector3 center = Vector3::ZERO;
+		for(UINT32 i = 0; i < numVertices; i++)
+		{
+			Vector3* curVert = (Vector3*)vertices;
+			center += *curVert;
+
+			vertices += vertexStride;
+		}
+
+		center /= (float)numVertices;
+		return center;
+	}
+
+	void DrawHelper3D::line_AA(const CM::Vector3& a, const CM::Vector3& b, float width, float borderWidth, const CM::Color& color, CM::UINT8* outVertices, CM::UINT8* outColors, 
+		CM::UINT32 vertexOffset, CM::UINT32 vertexStride, CM::UINT32* outIndices, CM::UINT32 indexOffset)
+	{
+		CM_EXCEPT(NotImplementedException, "3D AA line drawing not implemented.");
+	}
+
+	void DrawHelper3D::polygon_AA(const CM::Vector<Vector3>::type& points, float borderWidth, const CM::Color& color, CM::UINT8* outVertices, CM::UINT8* outColors, 
+		CM::UINT32 vertexOffset, CM::UINT32 vertexStride, CM::UINT32* outIndices, CM::UINT32 indexOffset)
+	{
+		CM_EXCEPT(NotImplementedException, "3D AA polygon drawing not implemented.");
+	}
+}

+ 2 - 0
BansheeForwardRenderer/Source/BsForwardRenderer.cpp

@@ -15,6 +15,7 @@
 #include "CmDefaultRenderQueue.h"
 #include "BsOverlayManager.h"
 #include "BsDrawHelper2D.h"
+#include "BsDrawHelper3D.h"
 #include "BsGUIManager.h"
 
 using namespace CamelotFramework;
@@ -156,6 +157,7 @@ namespace BansheeEngine
 		OverlayManager::instance().render(camera->getViewport(), *mRenderQueue);
 
 		// Get debug render operations
+		DrawHelper3D::instance().render(camera, *mRenderQueue);
 		DrawHelper2D::instance().render(camera, *mRenderQueue);
 
 		// TODO - Material queue is completely ignored

+ 4 - 22
DrawHelper.txt

@@ -1,29 +1,11 @@
-Add class DrawHelper:
- - Line2D_AA - Creates an emulated AA line using triangles. See Recast/imguiRenderGL::drawPolygon for implementation. Line vertices and colors
-      are appended in the specified buffer. No actual drawing is done.
- - Line2D_Pixel - Creates a simple line using LINE primitive topology. Line vertices and colors are appended in the specified buffer.
- - Quad2D 
- - QuadBorder2D_AA
- - QuadBorder2D_Pixel
- - LineList2D_AA
- - LineList2D_Pixel
- - RoundedRect2D - Also copy from Recast/imguiRenderGL::drawRoundedRect
- - Also 3D equivalents
-  - Line, Quad, QuadBorder, Box, BoxBorder
-
- - Then I also need draw* equivalents of those methods. draw equivalents will also create the buffer and submit the draw call.
-
 --------------------------
 
  Only one material per viewport needs to exist, no need for separate material for each element
 
 -------------------------
 
-AA lines render but look a bit off.
-
-
----------
+AA line stuff doesn't work in 3d unless I specify a plane :/
+ - A better way might be to draw two lines in an X (for lines)
+ - And for polygons use the normal formed by their triangle
 
-Num verts/indices for polygon2d_AA method:
-(n * 2) vertices
-(n * 6) + max(0, n - 2) * 3
+Need support for drawing AABox