Browse Source

Refactored draw helpers so they are fully static and just provide geometry data and don't do any drawing

Marko Pintera 11 years ago
parent
commit
0dac075862

+ 11 - 11
BansheeEditor/Source/BsGizmoManager.cpp

@@ -3,7 +3,7 @@
 #include "BsAABox.h"
 #include "BsSphere.h"
 #include "BsVertexDataDesc.h"
-#include "BsDrawHelper3D.h"
+#include "BsShapeMeshes3D.h"
 #include "BsMeshHeap.h"
 #include "BsCamera.h"
 #include "BsSpriteTexture.h"
@@ -184,7 +184,7 @@ namespace BansheeEngine
 		sphereData.pickable = mPickable;
 
 		UINT32 numVertices, numIndices;
-		DrawHelper3D::getNumElementsSphere(SPHERE_QUALITY, numVertices, numIndices);
+		ShapeMeshes3D::getNumElementsSphere(SPHERE_QUALITY, numVertices, numIndices);
 
 		mTotalRequiredSolidVertices += numVertices;
 		mTotalRequiredSolidIndices += numIndices;
@@ -219,7 +219,7 @@ namespace BansheeEngine
 		sphereData.pickable = mPickable;
 
 		UINT32 numVertices, numIndices;
-		DrawHelper3D::getNumElementsWireSphere(SPHERE_QUALITY, numVertices, numIndices);
+		ShapeMeshes3D::getNumElementsWireSphere(SPHERE_QUALITY, numVertices, numIndices);
 
 		mTotalRequiredWireVertices += numVertices;
 		mTotalRequiredWireIndices += numIndices;
@@ -391,7 +391,7 @@ namespace BansheeEngine
 		for (auto& cubeData : cubeData)
 		{
 			AABox box(cubeData.position - cubeData.extents, cubeData.position + cubeData.extents);
-			DrawHelper3D::instance().solidAABox(box, meshData, curVertexOffset, curIndexOffet); // TODO - These should be static methods
+			ShapeMeshes3D::solidAABox(box, meshData, curVertexOffset, curIndexOffet);
 
 			Matrix4 transformIT = cubeData.transform.inverseAffine().transpose();
 			RGBA color = cubeData.color.getAsRGBA();
@@ -412,12 +412,12 @@ namespace BansheeEngine
 		}
 
 		UINT32 numSphereVertices, numSphereIndices;
-		DrawHelper3D::getNumElementsSphere(SPHERE_QUALITY, numSphereVertices, numSphereIndices);
+		ShapeMeshes3D::getNumElementsSphere(SPHERE_QUALITY, numSphereVertices, numSphereIndices);
 
 		for (auto& sphereData : sphereData)
 		{
 			Sphere sphere(sphereData.position, sphereData.radius);
-			DrawHelper3D::instance().solidSphere(sphere, meshData, curVertexOffset, curIndexOffet, SPHERE_QUALITY);
+			ShapeMeshes3D::solidSphere(sphere, meshData, curVertexOffset, curIndexOffet, SPHERE_QUALITY);
 
 			Matrix4 transformIT = sphereData.transform.inverseAffine().transpose();
 			RGBA color = sphereData.color.getAsRGBA();
@@ -453,7 +453,7 @@ namespace BansheeEngine
 		for (auto& cubeData : cubeData)
 		{
 			AABox box(cubeData.position - cubeData.extents, cubeData.position + cubeData.extents);
-			DrawHelper3D::instance().wireAABox(box, meshData, curVertexOffset, curIndexOffet); // TODO - These should be static methods
+			ShapeMeshes3D::wireAABox(box, meshData, curVertexOffset, curIndexOffet);
 
 			RGBA color = cubeData.color.getAsRGBA();
 
@@ -471,12 +471,12 @@ namespace BansheeEngine
 		}
 
 		UINT32 numSphereVertices, numSphereIndices;
-		DrawHelper3D::getNumElementsWireSphere(SPHERE_QUALITY, numSphereVertices, numSphereIndices);
+		ShapeMeshes3D::getNumElementsWireSphere(SPHERE_QUALITY, numSphereVertices, numSphereIndices);
 
 		for (auto& sphereData : sphereData)
 		{
 			Sphere sphere(sphereData.position, sphereData.radius);
-			DrawHelper3D::instance().wireSphere(sphere, meshData, curVertexOffset, curIndexOffet, SPHERE_QUALITY);
+			ShapeMeshes3D::wireSphere(sphere, meshData, curVertexOffset, curIndexOffet, SPHERE_QUALITY);
 
 			RGBA color = sphereData.color.getAsRGBA();
 			for (UINT32 i = 0; i < numSphereVertices; i++)
@@ -493,7 +493,7 @@ namespace BansheeEngine
 
 		for (auto& lineData : lineData)
 		{
-			DrawHelper3D::instance().pixelLine(lineData.start, lineData.end, meshData, curVertexOffset, curIndexOffet);
+			ShapeMeshes3D::pixelLine(lineData.start, lineData.end, meshData, curVertexOffset, curIndexOffet);
 
 			RGBA color = lineData.color.getAsRGBA();
 			for (UINT32 i = 0; i < 2; i++)
@@ -510,7 +510,7 @@ namespace BansheeEngine
 
 		for (auto& frustumData : frustumData)
 		{
-			DrawHelper3D::instance().wireFrustum(frustumData.aspect, frustumData.FOV, frustumData.near, 
+			ShapeMeshes3D::wireFrustum(frustumData.aspect, frustumData.FOV, frustumData.near, 
 				frustumData.far, meshData, curVertexOffset, curIndexOffet);
 
 			RGBA color = frustumData.color.getAsRGBA();

+ 2 - 2
BansheeEditor/Source/BsMainEditorWindow.cpp

@@ -16,8 +16,8 @@
 
 // DEBUG ONLY
 #include "BsTestTextSprite.h"
-#include "BsDrawHelper2D.h"
-#include "BsDrawHelper3D.h"
+#include "BsShapeMeshes2D.h"
+#include "BsShapeMeshes3D.h"
 #include "BsRect2.h"
 #include "BsProfilerOverlay.h"
 #include "BsPlatform.h"

+ 13 - 13
BansheeEditor/Source/BsSceneGrid.cpp

@@ -1,6 +1,6 @@
 #include "BsSceneGrid.h"
 #include "BsMath.h"
-#include "BsDrawHelper3D.h"
+#include "BsShapeMeshes3D.h"
 #include "BsVertexDataDesc.h"
 #include "BsMaterial.h"
 #include "BsMesh.h"
@@ -93,8 +93,8 @@ namespace BansheeEngine
 		float maxX = (startX + numLines) * mSpacing;
 		float maxZ = (startZ + numLines) * mSpacing;
 
-		UINT32 totalNumVertices = DrawHelper3D::NUM_VERTICES_AA_LINE * (numLines + 1) * 2;
-		UINT32 totalNumIndices = DrawHelper3D::NUM_INDICES_AA_LINE * (numLines + 1) * 2;
+		UINT32 totalNumVertices = ShapeMeshes3D::NUM_VERTICES_AA_LINE * (numLines + 1) * 2;
+		UINT32 totalNumIndices = ShapeMeshes3D::NUM_INDICES_AA_LINE * (numLines + 1) * 2;
 
 		MeshDataPtr meshData = bs_shared_ptr<MeshData, PoolAlloc>(totalNumVertices, totalNumIndices, mVertexDesc);
 		UINT32 vertexOffset = 0;
@@ -110,22 +110,22 @@ namespace BansheeEngine
 
 			if (x % mAxisMarkerSpacing == 0)
 			{
-				DrawHelper3D::instance().antialiasedLine(lineStartX, lineEndX, Vector3::UNIT_Y, AXIS_MARKER_WIDTH, 
+				ShapeMeshes3D::antialiasedLine(lineStartX, lineEndX, Vector3::UNIT_Y, AXIS_MARKER_WIDTH, 
 					AXIS_MARKER_BORDER_WIDTH, AXIS_X_MARKER_COLOR, meshData, vertexOffset, indexOffset);
 			}
 			else if (x % mMajorAxisSpacing == 0)
 			{
-				DrawHelper3D::instance().antialiasedLine(lineStartX, lineEndX, Vector3::UNIT_Y, MAJOR_AXIS_WIDTH,
+				ShapeMeshes3D::antialiasedLine(lineStartX, lineEndX, Vector3::UNIT_Y, MAJOR_AXIS_WIDTH,
 					MAJOR_AXIS_BORDER_WIDTH, Color::White, meshData, vertexOffset, indexOffset);
 			}
 			else
 			{
-				DrawHelper3D::instance().antialiasedLine(lineStartX, lineEndX, Vector3::UNIT_Y, LINE_WIDTH,
+				ShapeMeshes3D::antialiasedLine(lineStartX, lineEndX, Vector3::UNIT_Y, LINE_WIDTH,
 					LINE_BORDER_WIDTH, Color::White, meshData, vertexOffset, indexOffset);
 			}
 
-			vertexOffset += DrawHelper3D::NUM_VERTICES_AA_LINE;
-			indexOffset += DrawHelper3D::NUM_INDICES_AA_LINE;
+			vertexOffset += ShapeMeshes3D::NUM_VERTICES_AA_LINE;
+			indexOffset += ShapeMeshes3D::NUM_INDICES_AA_LINE;
 
 			INT32 z = startZ + i;
 			float linePosZ = z * mSpacing;
@@ -135,22 +135,22 @@ namespace BansheeEngine
 
 			if (z % mAxisMarkerSpacing == 0)
 			{
-				DrawHelper3D::instance().antialiasedLine(lineStartZ, lineEndZ, Vector3::UNIT_Y, AXIS_MARKER_WIDTH,
+				ShapeMeshes3D::antialiasedLine(lineStartZ, lineEndZ, Vector3::UNIT_Y, AXIS_MARKER_WIDTH,
 					AXIS_MARKER_BORDER_WIDTH, AXIS_Z_MARKER_COLOR, meshData, vertexOffset, indexOffset);
 			}
 			else if (z % mMajorAxisSpacing == 0)
 			{
-				DrawHelper3D::instance().antialiasedLine(lineStartZ, lineEndZ, Vector3::UNIT_Y, MAJOR_AXIS_WIDTH,
+				ShapeMeshes3D::antialiasedLine(lineStartZ, lineEndZ, Vector3::UNIT_Y, MAJOR_AXIS_WIDTH,
 					MAJOR_AXIS_BORDER_WIDTH, Color::White, meshData, vertexOffset, indexOffset);
 			}
 			else
 			{
-				DrawHelper3D::instance().antialiasedLine(lineStartZ, lineEndZ, Vector3::UNIT_Y, LINE_WIDTH,
+				ShapeMeshes3D::antialiasedLine(lineStartZ, lineEndZ, Vector3::UNIT_Y, LINE_WIDTH,
 					LINE_BORDER_WIDTH, Color::White, meshData, vertexOffset, indexOffset);
 			}
 
-			vertexOffset += DrawHelper3D::NUM_VERTICES_AA_LINE;
-			indexOffset += DrawHelper3D::NUM_INDICES_AA_LINE;
+			vertexOffset += ShapeMeshes3D::NUM_VERTICES_AA_LINE;
+			indexOffset += ShapeMeshes3D::NUM_INDICES_AA_LINE;
 		}
 
 		mGridMesh = Mesh::create(meshData);

+ 4 - 6
BansheeEngine/BansheeEngine.vcxproj

@@ -235,10 +235,9 @@
     <ClCompile Include="Source\BsVirtualInput.cpp" />
     <ClInclude Include="Include\BsApplication.h" />
     <ClInclude Include="Include\BsCursor.h" />
-    <ClInclude Include="Include\BsDrawHelper3D.h" />
-    <ClInclude Include="Include\BsDrawHelperTemplate.h" />
+    <ClInclude Include="Include\BsShapeMeshes3D.h" />
     <ClInclude Include="Include\BsDragAndDropManager.h" />
-    <ClInclude Include="Include\BsDrawHelper2D.h" />
+    <ClInclude Include="Include\BsShapeMeshes2D.h" />
     <ClInclude Include="Include\BsBuiltinResources.h" />
     <ClInclude Include="Include\BsEnums.h" />
     <ClInclude Include="Include\BsGUIArea.h" />
@@ -315,9 +314,8 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsApplication.cpp" />
-    <ClCompile Include="Source\BsDrawHelper2D.cpp" />
-    <ClCompile Include="Source\BsDrawHelper3D.cpp" />
-    <ClCompile Include="Source\BsDrawHelperTemplate.cpp" />
+    <ClCompile Include="Source\BsShapeMeshes2D.cpp" />
+    <ClCompile Include="Source\BsShapeMeshes3D.cpp" />
     <ClCompile Include="Source\BsDragAndDropManager.cpp" />
     <ClCompile Include="Source\BsBuiltinResources.cpp" />
     <ClCompile Include="Source\BsGUIArea.cpp" />

+ 12 - 18
BansheeEngine/BansheeEngine.vcxproj.filters

@@ -174,15 +174,6 @@
     <ClInclude Include="Include\BsGUIViewport.h">
       <Filter>Header Files\GUI</Filter>
     </ClInclude>
-    <ClInclude Include="Include\BsDrawHelper2D.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsDrawHelperTemplate.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsDrawHelper3D.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="Include\BsGUIDropDownBox.h">
       <Filter>Header Files\GUI</Filter>
     </ClInclude>
@@ -273,6 +264,12 @@
     <ClInclude Include="Include\BsGUILayoutUtility.h">
       <Filter>Header Files\GUI</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsShapeMeshes2D.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsShapeMeshes3D.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsGUIElement.cpp">
@@ -389,15 +386,6 @@
     <ClCompile Include="Source\BsGUIViewport.cpp">
       <Filter>Source Files\GUI</Filter>
     </ClCompile>
-    <ClCompile Include="Source\BsDrawHelperTemplate.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsDrawHelper2D.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsDrawHelper3D.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="Source\BsGUIDropDownBox.cpp">
       <Filter>Source Files\GUI</Filter>
     </ClCompile>
@@ -470,5 +458,11 @@
     <ClCompile Include="Source\BsGUILayoutUtility.cpp">
       <Filter>Source Files\GUI</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsShapeMeshes2D.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsShapeMeshes3D.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 0 - 39
BansheeEngine/Include/BsBuiltinResources.h

@@ -90,21 +90,6 @@ namespace BansheeEngine
 		 */
 		GUIMaterialInfo createSpriteImageMaterial() const;
 
-		/**
-		 * @brief	Creates a material used for debug drawing in clip space (e.g. 2D shapes that resize with the viewport).
-		 */
-		DebugDraw2DClipSpaceMatInfo createDebugDraw2DClipSpaceMaterial() const;
-
-		/**
-		 * @brief	Creates a material used for debug drawing in screen space (e.g. 2D shapes of fixed pixel size).
-		 */
-		DebugDraw2DScreenSpaceMatInfo createDebugDraw2DScreenSpaceMaterial() const;
-
-		/**
-		 * @brief	Creates a material used for debug drawing in 3D.
-		 */
-		DebugDraw3DMatInfo createDebugDraw3DMaterial() const;
-
 		/**
 		 * @brief	Creates a material used as a replacement when no other material is usable.
 		 */
@@ -158,21 +143,6 @@ namespace BansheeEngine
 		 */
 		void initSpriteImageShader();
 
-		/**
-		 * @brief	Loads an compiles a shader for debug 2D clip space rendering.
-		 */
-		void initDebugDraw2DClipSpaceShader();
-
-		/**
-		 * @brief	Loads an compiles a shader for debug 2D screen space rendering.
-		 */
-		void initDebugDraw2DScreenSpaceShader();
-
-		/**
-		 * @brief	Loads an compiles a shader for debug 3D rendering.
-		 */
-		void initDebugDraw3DShader();
-
 		/**
 		 * @brief	Loads an compiles a simple shader to be used with no other is usable.
 		 */
@@ -197,9 +167,6 @@ namespace BansheeEngine
 
 		ShaderPtr mShaderSpriteText;
 		ShaderPtr mShaderSpriteImage;
-		ShaderPtr mShaderDebugDraw2DClipSpace;
-		ShaderPtr mShaderDebugDraw2DScreenSpace;
-		ShaderPtr mShaderDebugDraw3D;
 		ShaderPtr mShaderDummy;
 
 		WString mActiveShaderSubFolder;
@@ -310,12 +277,6 @@ namespace BansheeEngine
 		static const WString ShaderSpriteTextPSFile;
 		static const WString ShaderSpriteImageVSFile;
 		static const WString ShaderSpriteImagePSFile;
-		static const WString ShaderDebugDraw2DClipSpaceVSFile;
-		static const WString ShaderDebugDraw2DClipSpacePSFile;
-		static const WString ShaderDebugDraw2DScreenSpaceVSFile;
-		static const WString ShaderDebugDraw2DScreenSpacePSFile;
-		static const WString ShaderDebugDraw3DVSFile;
-		static const WString ShaderDebugDraw3DPSFile;
 		static const WString ShaderDockOverlayVSFile;
 		static const WString ShaderDockOverlayPSFile;
 		static const WString ShaderDummyVSFile;

+ 0 - 159
BansheeEngine/Include/BsDrawHelper2D.h

@@ -1,159 +0,0 @@
-#pragma once
-
-#include "BsPrerequisites.h"
-#include "BsDrawHelperTemplate.h"
-#include "BsModule.h"
-#include "BsColor.h"
-#include "BsAABox.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Helper class that makes it easy to construct and render various common 2D shapes.
-	 */
-	class BS_EXPORT DrawHelper2D : public DrawHelperTemplate<Vector2>, public Module<DrawHelper2D>
-	{
-	public:
-		DrawHelper2D();
-
-		/**
-		 * @brief	Fills the mesh data with vertices representing a quad (2 triangles).
-		 *
-		 * @param	area			Area in which to draw the quad.
-		 * @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:
-		 * 			  Vector2 VES_POSITION
-		 * 			  32bit index buffer
-		 * 			  Enough space for 4 vertices and 6 indices
-		 *
-		 *			Primitives are output in the form of a triangle list.
-		 */
-		void solidQuad(const Rect2& area, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * @copydoc	DrawHelperTemplate::pixelLine
-		 */
-		void pixelLine(const Vector2& a, const Vector2& b, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * @copydoc	DrawHelperTemplate::antialiasedLine
-		 */
-		void antialiasedLine(const Vector2& a, const Vector2& b, float width, float borderWidth, const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * @copydoc	DrawHelperTemplate::pixelLineList
-		 */
-		void pixelLineList(const Vector<Vector2>& linePoints, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * @copydoc	DrawHelperTemplate::antialiasedLineList
-		 */
-		void antialiasedLineList(const Vector<Vector2>& linePoints, float width, float borderWidth, const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * @brief	Constructs a quad and draws it in the specified camera. 
-		 *
-		 * @param	camera		Camera to draw the quad in.
-		 * @param	area		Area of the quad. Coordinates must be normalized in ([0, 1], [0, 1]) range. Coordinate origin is top left of the camera viewport.
-		 * @param	color		Color of the quad.
-		 * @param	coordType	How to handle viewport resizing. If mode is Pixel the quad will always retain its size in pixels, and if mode is Normalized
-		 *						the quad will stretch with the viewport so its normalized coordinates stay the same.
-		 * @param	timeout		Optional timeout on how long to display the quad in seconds. If 0 the quad will be displayed one frame.
-		 */
-		void drawSolidQuad(const HCamera& camera, const Rect2& area, const Color& color = Color::White, DebugDrawCoordType coordType = DebugDrawCoordType::Pixel, float timeout = 0.0f);
-
-		/**
-		 * @brief	Constructs a pixel perfect line and draws it in the specified camera. 
-		 *
-		 * @param	camera		Camera to draw the line in.
-		 * @param	x			Starting position of the line. Coordinates must be normalized in [0, 1] range. Coordinate origin is top left of the camera viewport.
-		 * @param	y			End position of the line. Coordinates must be normalized in [0, 1] range. Coordinate origin is top left of the camera viewport.
-		 * @param	color		Color of the line.
-		 * @param	coordType	How to handle viewport resizing. If mode is Pixel the line will always retain its size in pixels, and if mode is Normalized
-		 *						the line will stretch with the viewport so its normalized coordinates stay the same.
-		 * @param	timeout		Optional timeout on how long to display the line in seconds. If 0 the line will be displayed one frame.
-		 */
-		void drawPixelLine(const HCamera& camera, const Vector2& a, const Vector2& b, const Color& color = Color::White, 
-			DebugDrawCoordType coordType = DebugDrawCoordType::Pixel, float timeout = 0.0f);
-
-		/**
-		 * @brief	Constructs an antialiased line with custom width and draws it in the specified camera. 
-		 *
-		 * @param	camera		Camera to draw the line in.
-		 * @param	x			Starting position of the line. Coordinates must be normalized in [0, 1] range. Coordinate origin is top left of the camera viewport.
-		 * @param	y			End position of the line. Coordinates must be normalized in [0, 1] range. Coordinate origin is top left of the camera viewport.
-		 * @param	width		Width of the line in pixels.
-		 * @param	borderWidth	Width of the antialiased border in pixels.
-		 * @param	color		Color of the line.
-		 * @param	coordType	How to handle viewport resizing. If mode is Pixel the line will always retain its size in pixels, and if mode is Normalized
-		 *						the line will stretch with the viewport so its normalized coordinates stay the same.
-		 * @param	timeout		Optional timeout on how long to display the line in seconds. If 0 the line will be displayed one frame.
-		 */
-		void drawAntialiasedLine(const HCamera& camera, const Vector2& a, const Vector2& b, float width, float borderWidth, 
-			const Color& color = Color::White, DebugDrawCoordType coordType = DebugDrawCoordType::Pixel, float timeout = 0.0f);
-
-		/**
-		 * @brief	Constructs a pixel perfect list of lines and draws them in the specified camera. 
-		 *
-		 * @param	camera		Camera to draw the line list in.
-		 * @param	linePoints	List of line start and end points. This list must be a multiple of 2, where each start point is followed by and end point.
-		 *						Coordinates must be normalized in ([0, 1], [0, 1]) range. Coordinate origin is top left of the camera viewport.
-		 * @param	color		Color of the line list.
-		 * @param	coordType	How to handle viewport resizing. If mode is Pixel the line list will always retain its size in pixels, and if mode is Normalized
-		 *						the line list will stretch with the viewport so its normalized coordinates stay the same.
-		 * @param	timeout		Optional timeout on how long to display the line list in seconds. If 0 the line list will be displayed one frame.
-		 */
-		void drawPixelLineList(const HCamera& camera, const Vector<Vector2>& linePoints, const Color& color = Color::White, 
-			DebugDrawCoordType coordType = DebugDrawCoordType::Pixel, float timeout = 0.0f);
-
-		/**
-		 * @brief	Constructs an list of antialiased lines with custom width and draws them in the specified camera. 
-		 *
-		 * @param	camera		Camera to draw the line list in.
-		 * @param	linePoints	List of line start and end points. This list must be a multiple of 2, where each start point is followed by and end point.
-		 *						Coordinates must be normalized in ([0, 1], [0, 1]) range. Coordinate origin is top left of the camera viewport.
-		 * @param	width		Width of the line in pixels.
-		 * @param	borderWidth	Width of the antialiased border in pixels.
-		 * @param	color		Color of the line list.
-		 * @param	coordType	How to handle viewport resizing. If mode is Pixel the line list will always retain its size in pixels, and if mode is Normalized
-		 *						the line list will stretch with the viewport so its normalized coordinates stay the same.
-		 * @param	timeout		Optional timeout on how long to display the line list in seconds. If 0 the line list will be displayed one frame.
-		 */
-		void drawAntialiasedLineList(const HCamera& camera, const Vector<Vector2>& linePoints, float width, float borderWidth, 
-			const Color& color = Color::White, DebugDrawCoordType coordType = DebugDrawCoordType::Pixel, float timeout = 0.0f);
-
-	protected:
-		/**
-		 * @copydoc	DrawHelperTemplate::antialiasedLine(const Vector2&, const Vector2&, const Vector2&, float, float, const Color&, UINT8*, UINT8*, UINT32, UINT32, UINT32*, UINT32)
-		 */
-		void antialiasedLine(const Vector2& a, const Vector2& b, const Vector2& up, float width, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors, 
-			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
-
-		/**
-		 * @copydoc	DrawHelperTemplate::antialiasedPolygon(const Vector<Vector2>&, const Vector2&, float, const Color&, UINT8*, UINT8*, UINT32, UINT32, UINT32*, UINT32)
-		 */
-		void antialiasedPolygon(const Vector<Vector2>& points, const Vector2& up, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors,
-			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
-
-	private:
-		/**
-		 * @brief	Converts an area with normalized ([0, 1] range) coordinates and returns
-		 *			area in clip space coordinates.
-		 */
-		Rect2 normalizedCoordToClipSpace(const Rect2& area) const;
-
-		/**
-		 * @brief	Converts a point with normalized ([0, 1] range) coordinates and returns
-		 *			a point in clip space coordinates.
-		 */
-		Vector2 normalizedCoordToClipSpace(const Vector2& pos) const;
-
-	private:
-		DebugDraw2DClipSpaceMatInfo mMaterial2DClipSpace;
-
-		VertexDataDescPtr mVertexDesc;
-	};
-}

+ 4 - 294
BansheeEngine/Include/BsDrawHelperTemplate.h

@@ -7,309 +7,19 @@
 
 namespace BansheeEngine
 {
-	/**
-	 * @brief	Types of coordinates used in 2D debug drawing.
-	 */
-	enum class DebugDrawCoordType
-	{
-		Pixel,
-		Normalized
-	};
-
-	/**
-	 * @brief	Internal type that determines how is a debug object drawn.
-	 */
-	enum class DebugDrawType
-	{
-		ClipSpace,
-		ScreenSpace,
-		WorldSpace
-	};
-
-	/**
-	 * @brief	Command containing all data requires for drawing a single
-	 *			debug draw object.
-	 */
-	struct DebugDrawCommand
-	{
-		HMesh mesh;
-
-		DebugDraw2DClipSpaceMatInfo matInfo2DClipSpace;
-		DebugDraw2DScreenSpaceMatInfo matInfo2DScreenSpace;
-		DebugDraw3DMatInfo matInfo3D;
-
-		DebugDrawType type;
-		Vector3 worldCenter;
-		float endTime;
-	};
-
-	/**
-	 * @brief	Abstract interface for a draw helper class. Allows a set of draw commands to be queued
-	 *			and retrieved by the renderer.
-	 */
-	class BS_EXPORT DrawHelperTemplateBase
-	{
-	public:
-		static const UINT32 NUM_VERTICES_AA_LINE;
-		static const UINT32 NUM_INDICES_AA_LINE;
-
-		/**
-		 * @brief	Called by the renderer when it is ready to render objects into the provided camera.
-		 */
-		void render(const HCamera& camera, DrawList& drawList);
-
-	protected:
-		UnorderedMap<const Viewport*, Vector<DebugDrawCommand>> mCommandsPerViewport;
-	};
-
 	/**
 	 * @brief	Provides dimension-independant methods used for creating geometry 
-	 *			and drawing various common objects.
+	 *			for various common shapes.
 	 */
 	template <class T>
-	class BS_EXPORT DrawHelperTemplate : public DrawHelperTemplateBase
+	class BS_EXPORT DrawHelperTemplate
 	{
 	protected:
-		/**
-		 * @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	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:
-		 * 			  T		  VES_POSITION
-		 * 			  32bit index buffer
-		 * 			  Enough space for 2 vertices and 2 indices
-		 *
-		 *			Primitives are output in the form of a line list.
-		 */
-		void pixelLine(const T& a, const T& b, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
-		{
-			UINT32* indexData = meshData->getIndices32();
-			UINT8* positionData = meshData->getElementData(VES_POSITION);
-
-			assert((vertexOffset + 2) <= meshData->getNumVertices());
-			assert((indexOffset + 2) <= meshData->getNumIndices());
-
-			pixelLine(a, b, positionData, vertexOffset, meshData->getVertexDesc()->getVertexStride(), indexData, 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	up				Up direction to which the line will run perpendicular to.
-		 * @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:
-		 * 			  T		  VES_POSITION
-		 * 			  UINT32  VES_COLOR
-		 * 			  32bit index buffer
-		 *			  Enough space for 8 vertices and 30 indices
-		 *
-		 *			Primitives are output in the form of a triangle list.
-		 */
-		void antialiasedLine(const T& a, const T& b, const T& up, float width, float borderWidth, const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
-		{
-			UINT32* indexData = meshData->getIndices32();
-			UINT8* positionData = meshData->getElementData(VES_POSITION);
-			UINT8* colorData = meshData->getElementData(VES_COLOR);
-
-			assert((vertexOffset + NUM_VERTICES_AA_LINE) <= meshData->getNumVertices());
-			assert((indexOffset + NUM_INDICES_AA_LINE) <= meshData->getNumIndices());
-
-			antialiasedLine(a, b, up, width, borderWidth, color, positionData, colorData, vertexOffset, meshData->getVertexDesc()->getVertexStride(), indexData, 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	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:
-		 * 			  T		  VES_POSITION
-		 * 			  32bit index buffer
-		 * 			  Enough space for (numLines * 2) vertices and (numLines * 2) indices
-		 *
-		 *			Primitives are output in the form of a line list.
-		 */
-		void pixelLineList(const typename Vector<T>& linePoints, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
-		{
-			assert(linePoints.size() % 2 == 0);
-
-			assert((vertexOffset + linePoints.size() * 2) <= meshData->getNumVertices());
-			assert((indexOffset + linePoints.size() * 2) <= meshData->getNumIndices());
-
-			UINT32 curVertOffset = vertexOffset;
-			UINT32 curIdxOffset = indexOffset;
-
-			UINT32* indexData = meshData->getIndices32();
-			UINT8* positionData = meshData->getElementData(VES_POSITION);
-
-			UINT32 numPoints = (UINT32)linePoints.size();
-			for(UINT32 i = 0; i < numPoints; i += 2)
-			{
-				pixelLine(linePoints[i], linePoints[i + 1], positionData, curVertOffset, meshData->getVertexDesc()->getVertexStride(), indexData, curIdxOffset);
-
-				curVertOffset += 2;
-				curIdxOffset += 2;
-			}
-		}
-
-		/**
-		 * @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	up				Up direction to which the line will run perpendicular to.
-		 * @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:
-		 * 			  T		  VES_POSITION
-		 * 			  UINT32  VES_COLOR
-		 * 			  32bit index buffer
-		 *			  Enough space for (numLines * 8) vertices and (numLines * 30) indices
-		 *
-		 *			Primitives are output in the form of a triangle list.
-		 */
-		void antialiasedLineList(const typename Vector<T>& linePoints, const T& up, float width, float borderWidth, const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
-		{
-			assert(linePoints.size() % 2 == 0);
-
-			assert((vertexOffset + linePoints.size() * 4) <= meshData->getNumVertices());
-			assert((indexOffset + linePoints.size() * 15) <= meshData->getNumIndices());
-
-			UINT32 curVertOffset = vertexOffset;
-			UINT32 curIdxOffset = indexOffset;
-
-			UINT32* indexData = meshData->getIndices32();
-			UINT8* positionData = meshData->getElementData(VES_POSITION);
-			UINT8* colorData = meshData->getElementData(VES_COLOR);
-
-			UINT32 numPoints = (UINT32)linePoints.size();
-			for(UINT32 i = 0; i < numPoints; i += 2)
-			{
-				antialiasedLine(linePoints[i], linePoints[i + 1], up, width, borderWidth, color, positionData, colorData, curVertOffset, meshData->getVertexDesc()->getVertexStride(), indexData, curIdxOffset);
-
-				curVertOffset += NUM_VERTICES_AA_LINE;
-				curIdxOffset += NUM_INDICES_AA_LINE;
-			}
-		}
-
+		
 	protected:
-		/**
-		 * @brief	Fills the provided buffers with vertices representing a per-pixel line.
-		 *
-		 * @param	a				Start point of the line.
-		 * @param	b				End point of the line.
-		 * @param	outVertices		Output buffer that will store the vertex position data.
-		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
-		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
-		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 */
-		void pixelLine(const T& a, const T& b, UINT8* outVertices,  
-			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
-		{
-			outVertices += (vertexOffset * vertexStride);
-
-			T* vertices = (T*)outVertices;
-			(*vertices) = a;
-
-			vertices = (T*)(outVertices + vertexStride);
-			(*vertices) = b;
-
-			outIndices += indexOffset;
-			outIndices[0] = vertexOffset + 0;
-			outIndices[1] = vertexOffset + 1;
-		}
-
-		/**
-		 * @brief	Fills the provided buffers with vertices representing an antialiased line with a custom width.
-		 *
-		 * @param	a				Start point of the line.
-		 * @param	b				End point of the line.
-		 * @param	up				Up direction to which the line will run perpendicular to.
-		 * @param	width			Width of the line.
-		 * @param	borderWidth		Width of the anti-aliased border.
-		 * @param	color			Color of the line.
-		 * @param	outVertices		Output buffer that will store the vertex position data.
-		 * @param	outColors		Output buffer that will store the vertex color data.
-		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
-		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
-		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 */
-		virtual void antialiasedLine(const T& a, const T& b, const T& up, float width, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors, 
-			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset) = 0;
+		
 
-		/**
-		 * @brief	Fills the provided buffers with vertices representing an antialiased polygon.
-		 *
-		 * @param	points			Points defining the polygon. First point is assumed to be the start and end point.
-		 * @param	up				Up direction to which the polygon will run perpendicular to.
-		 * @param	borderWidth		Width of the anti-aliased border.
-		 * @param	color			Color of the polygon.
-		 * @param	outVertices		Output buffer that will store the vertex position data.
-		 * @param	outColors		Output buffer that will store the vertex color data.
-		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
-		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
-		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 */
-		virtual void antialiasedPolygon(const typename Vector<T>& points, const T& up, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors,
-			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset) = 0;
 
-		/**
-		 * @brief	Fills the provided buffers with position data and indices representing an inner 
-		 *			area of a polygon (basically a normal non-antialiased polygon).
-		 *
-		 * @param	points			Points defining the polygon. First point is assumed to be the start and end point.
-		 * @param	outVertices		Output buffer that will store the vertex position data.
-		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
-		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
-		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 */
-		void pixelSolidPolygon(const typename Vector<T>& points, UINT8* outVertices, 
-			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
-		{
-			outVertices += (vertexOffset * vertexStride);
-
-			for(auto& point : points)
-			{
-				T* vertices = (T*)outVertices;
-				(*vertices) = point;
-
-				outVertices += vertexStride;
-			}
-
-			outIndices += indexOffset;
-			INT32 numPoints = (INT32)points.size();
-			UINT32 idxCnt = 0;
-			for(int i = 2; i < numPoints; i++)
-			{
-				outIndices[idxCnt++] = vertexOffset;
-				outIndices[idxCnt++] = vertexOffset + i - 1;
-				outIndices[idxCnt++] = vertexOffset + i;
-			}
-		}
 
 		/**
 		 * @brief	Fills the provided buffers with vertices representing a pixel-wide polygon border.

+ 202 - 0
BansheeEngine/Include/BsShapeMeshes2D.h

@@ -0,0 +1,202 @@
+#pragma once
+
+#include "BsPrerequisites.h"
+#include "BsColor.h"
+#include "BsAABox.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Helper class for easily creating common 2D shapes.
+	 */
+	class BS_EXPORT ShapeMeshes2D
+	{
+	public:
+		/**
+		 * @brief	Fills the mesh data with vertices representing a quad (2 triangles).
+		 *
+		 * @param	area			Area in which to draw the quad.
+		 * @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:
+		 * 			  Vector2 VES_POSITION
+		 * 			  32bit index buffer
+		 * 			  Enough space for 4 vertices and 6 indices
+		 *
+		 *			Primitives are output in the form of a triangle list.
+		 */
+		static void solidQuad(const Rect2& area, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
+
+		/**
+		 * @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	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:
+		 * 			  Vector2 VES_POSITION
+		 * 			  32bit index buffer
+		 * 			  Enough space for 2 vertices and 2 indices
+		 *
+		 *			Primitives are output in the form of a line list.
+		 */
+		static void pixelLine(const Vector2& a, const Vector2& b, const MeshDataPtr& meshData, UINT32 vertexOffset, 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:
+		 * 			  Vector2 VES_POSITION
+		 * 			  UINT32  VES_COLOR
+		 * 			  32bit index buffer
+		 *			  Enough space for 8 vertices and 30 indices
+		 *
+		 *			Primitives are output in the form of a triangle list.
+		 */
+		static void antialiasedLine(const Vector2& a, const Vector2& b, float width, float borderWidth, const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, 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	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:
+		 * 			  Vector2  VES_POSITION
+		 * 			  32bit index buffer
+		 * 			  Enough space for (numLines * 2) vertices and (numLines * 2) indices
+		 *
+		 *			Primitives are output in the form of a line list.
+		 */
+		static void pixelLineList(const Vector<Vector2>& linePoints, const MeshDataPtr& meshData, UINT32 vertexOffset, 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:
+		 * 			  Vector2 VES_POSITION
+		 * 			  UINT32  VES_COLOR
+		 * 			  32bit index buffer
+		 *			  Enough space for (numLines * 8) vertices and (numLines * 30) indices
+		 *
+		 *			Primitives are output in the form of a triangle list.
+		 */
+		static void antialiasedLineList(const Vector<Vector2>& linePoints, float width, float borderWidth, const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
+
+		static const UINT32 NUM_VERTICES_AA_LINE;
+		static const UINT32 NUM_INDICES_AA_LINE;
+	protected:
+		/**
+		 * @brief	Fills the provided buffers with vertices representing a per-pixel line.
+		 *
+		 * @param	a				Start point of the line.
+		 * @param	b				End point of the line.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void pixelLine(const Vector2& a, const Vector2& b, UINT8* outVertices,
+			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * @brief	Fills the provided buffers with vertices representing an antialiased line with a custom width.
+		 *
+		 * @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	outVertices		Output buffer that will store the vertex position data.
+		 * @param	outColors		Output buffer that will store the vertex color data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void antialiasedLine(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);
+
+		/**
+		 * @brief	Fills the provided buffers with vertices representing an antialiased polygon.
+		 *
+		 * @param	points			Points defining the polygon. First point is assumed to be the start and end point.
+		 * @param	borderWidth		Width of the anti-aliased border.
+		 * @param	color			Color of the polygon.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	outColors		Output buffer that will store the vertex color data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void antialiasedPolygon(const Vector<Vector2>& points, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors,
+			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * @brief	Fills the provided buffers with position data and indices representing an inner 
+		 *			area of a polygon (basically a normal non-antialiased polygon).
+		 *
+		 * @param	points			Points defining the polygon. First point is assumed to be the start and end point.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void pixelSolidPolygon(const Vector<Vector2>& points, UINT8* outVertices,
+			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * @brief	Fills the provided buffers with vertices representing a pixel-wide polygon border.
+		 *
+		 * @param	points			Points defining the polygon. First point is assumed to be the start and end point.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	outColors		Output buffer that will store the vertex color data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void pixelWirePolygon(const Vector<Vector2>& points, UINT8* outVertices, UINT8* outColors,
+			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
+
+	private:
+		/**
+		 * @brief	Converts an area with normalized ([0, 1] range) coordinates and returns
+		 *			area in clip space coordinates.
+		 */
+		static Rect2 normalizedCoordToClipSpace(const Rect2& area);
+
+		/**
+		 * @brief	Converts a point with normalized ([0, 1] range) coordinates and returns
+		 *			a point in clip space coordinates.
+		 */
+		static Vector2 normalizedCoordToClipSpace(const Vector2& pos);
+	};
+}

+ 636 - 576
BansheeEngine/Include/BsDrawHelper3D.h → BansheeEngine/Include/BsShapeMeshes3D.h

@@ -1,577 +1,637 @@
-#pragma once
-
-#include "BsPrerequisites.h"
-#include "BsDrawHelperTemplate.h"
-#include "BsModule.h"
-#include "BsColor.h"
-#include "BsAABox.h"
-#include "BsRect3.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Helper class that makes it easy to construct and render various common 3D shapes.
-	 */
-	class BS_EXPORT DrawHelper3D : public DrawHelperTemplate<Vector3>, public Module<DrawHelper3D>
-	{
-	public:
-		DrawHelper3D();
-
-		/**
-		 * @brief	Fills the mesh data with vertices representing an outline of axis aligned box.
-		 *
-		 * @param	aabox			Axis aligned box to create the mesh data for
-		 * @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
-		 * 			  32bit index buffer
-		 * 			  Enough space for 8 vertices and 24 indices
-		 *
-		 *			Primitives are output in the form of a line list.
-		 */
-		void wireAABox(const AABox& box, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * @brief	Fills the mesh data with vertices representing a solid axis aligned box.
-		 *
-		 * @param	aabox			Axis aligned box to create the mesh data for
-		 * @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
-		 *			  Vector3 VES_NORMAL
-		 * 			  32bit index buffer
-		 * 			  Enough space for 24 vertices and 36 indices
-		 *
-		 *			Primitives are output in the form of a triangle list.
-		 */
-		void solidAABox(const AABox& box, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * @brief	Fills the mesh data with vertices representing an outline of a sphere.
-		 *
-		 * @param	sphere			Sphere to get the mesh data for
-		 * @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.
-		 * @param	quality			Represents the level of tessellation the sphere will have. Higher level means higher quality
-		 *							but also more vertices and primitives.
-		 *
-		 * @note	Provided MeshData must have some specific elements at least:
-		 * 			  Vector3 VES_POSITION
-		 * 			  32bit index buffer
-		 * 			  Enough space for 3 * ((quality + 1) * 5) vertices 
-		 *			  Enough space for 6 * ((quality + 1) * 5 - 1) indices
-		 *
-		 *			Primitives are output in the form of a line list.
-		 */
-		void wireSphere(const Sphere& sphere, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
-
-		/**
-		 * @brief	Fills the mesh data with vertices representing a sphere.
-		 *
-		 * @param	sphere			Sphere to get the mesh data for
-		 * @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.
-		 * @param	quality			Represents the level of tessellation the sphere will have. Higher level means higher quality
-		 *							but also more vertices and primitives.
-		 *
-		 * @note	Provided MeshData must have some specific elements at least:
-		 * 			  Vector3 VES_POSITION
-		 *			  Vector3 VES_NORMAL
-		 * 			  32bit index buffer
-		 * 			  Enough space for 20 * (4 * (3 ^ quality)) vertices 
-		 *			  Enough space for 20 * (4 * (3 ^ quality)) indices
-		 *
-		 *			Primitives are output in the form of a triangle list.
-		 */
-		void solidSphere(const Sphere& sphere, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 1);
-
-		/**
-		 * @brief	Fills the mesh data with vertices representing an outline of an arc.
-		 *
-		 * @param	center			Center of the arc to generate geometry for.
-		 * @param	radius			Radius of the arc to generate geometry for.
-		 * @param	normal			Normal around which the arc is generated. Arc geometry will be perpendicular to the normal.
-		 * @param	startAngle		Angle at which the arc starts.
-		 * @param	amountAngle		Angle that the arc spans.
-		 * @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.
-		 * @param	quality			Represents the level of tessellation the arc will have. Higher level means higher quality
-		 *							but also more vertices and primitives.
-		 *
-		 * @note	Provided MeshData must have some specific elements at least:
-		 * 			  Vector3 VES_POSITION
-		 * 			  32bit index buffer
-		 * 			  Enough space for ((quality + 1) * 5) vertices 
-		 *			  Enough space for (((quality + 1) * 5 - 1) * 2) indices
-		 *
-		 *			Primitives are output in the form of a line list.
-		 */
-		void wireArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
-			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
-
-		/**
-		 * @brief	Fills the mesh data with vertices representing a solid arc.
-		 *
-		 * @param	center			Center of the arc to generate geometry for.
-		 * @param	radius			Radius of the arc to generate geometry for.
-		 * @param	normal			Normal around which the arc is generated. Arc geometry will be perpendicular to the normal.
-		 * @param	startAngle		Angle at which the arc starts.
-		 * @param	amountAngle		Angle that the arc spans.
-		 * @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.
-		 * @param	quality			Represents the level of tessellation the arc will have. Higher level means higher quality
-		 *							but also more vertices and primitives.
-		 *
-		 * @note	Provided MeshData must have some specific elements at least:
-		 * 			  Vector3 VES_POSITION
-		 *			  Vector3 VES_NORMAL
-		 * 			  32bit index buffer
-		 * 			  Enough space for ((quality + 1) * 5 + 1) vertices 
-		 *			  Enough space for (((quality + 1) * 5 - 1) * 3) indices
-		 *
-		 *			Primitives are output in the form of a triangle list.
-		 */
-		void solidArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
-			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
-
-		/**
-		 * @brief	Fills the mesh data with vertices representing an outline of a disc.
-		 *
-		 * @param	center			Center of the disc to generate geometry for.
-		 * @param	radius			Radius of the disc to generate geometry for.
-		 * @param	normal			Normal around which the disc is generated. Disc geometry will be perpendicular to the normal.
-		 * @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.
-		 * @param	quality			Represents the level of tessellation the disc will have. Higher level means higher quality
-		 *							but also more vertices and primitives.
-		 *
-		 * @note	Provided MeshData must have some specific elements at least:
-		 * 			  Vector3 VES_POSITION
-		 * 			  32bit index buffer
-		 * 			  Enough space for ((quality + 1) * 5) vertices 
-		 *			  Enough space for (((quality + 1) * 5 - 1) * 2) indices
-		 *
-		 *			Primitives are output in the form of a line list.
-		 */
-		void wireDisc(const Vector3& center, float radius, const Vector3& normal, const MeshDataPtr& meshData, 
-			UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
-
-		/**
-		 * @brief	Fills the mesh data with vertices representing a solid disc.
-		 *
-		 * @param	center			Center of the disc to generate geometry for.
-		 * @param	radius			Radius of the disc to generate geometry for.
-		 * @param	normal			Normal around which the disc is generated. Disc geometry will be perpendicular to the normal.
-		 * @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.
-		 * @param	quality			Represents the level of tessellation the disc will have. Higher level means higher quality
-		 *							but also more vertices and primitives.
-		 *
-		 * @note	Provided MeshData must have some specific elements at least:
-		 * 			  Vector3 VES_POSITION
-		 *			  Vector3 VES_NORMAL
-		 * 			  32bit index buffer
-		 * 			  Enough space for ((quality + 1) * 5 + 1) vertices 
-		 *			  Enough space for (((quality + 1) * 5 - 1) * 3) indices
-		 *
-		 *			Primitives are output in the form of a triangle list.
-		 */
-		void solidDisc(const Vector3& center, float radius, const Vector3& normal, const MeshDataPtr& meshData, 
-			UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
-
-		/**
-		 * @brief	Fills the mesh data with vertices representing an outline of an camera frustum. Frustum will
-		 *			be facing -z and be positioned at world origin.
-		 *
-		 * @param	aspect			Aspect ratio (width / height).
-		 * @param	FOV				Horizontal field of view angle.
-		 * @param	near			Distance to near clipping plane.
-		 * @param	far				Distance to far clipping plane.
-		 * @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
-		 * 			  32bit index buffer
-		 * 			  Enough space for 8 vertices and 24 indices
-		 *
-		 *			Primitives are output in the form of a line list.
-		 */
-		void wireFrustum(float aspect, Degree FOV, float near, float far,
-			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * @brief	Fills the mesh data with vertices representing a solid cone.
-		 *
-		 * @param	base			World position of the cone base.
-		 * @param	normal			Direction of the pointed part of the cone.
-		 * @param	height			Cone height (distance from base to the top).
-		 * @param	radius			Cone radius (distance from base center to outer edge).
-		 * @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.
-		 * @param	quality			Represents the level of tessellation the cone will have. Higher level means higher quality
-		 *							but also more vertices and primitives.
-		 *
-		 * @note	Provided MeshData must have some specific elements at least:
-		 * 			  Vector3 VES_POSITION
-		 *			  Vector3 VES_NORMAL
-		 * 			  32bit index buffer
-		 * 			  Enough space for ((quality + 1) * 4 + 1) * 2 vertices 
-		 *			  Enough space for (((quality + 1) * 4 - 1) * 6) indices
-		 *
-		 *			Primitives are output in the form of a triangle list.
-		 */
-		void solidCone(const Vector3& base, const Vector3& normal, float height, float radius,
-			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
-
-		/**
-		 * @brief	Fills the mesh data with vertices representing a quad (2 triangles).
-		 *
-		 * @param	area			Area in which to draw the quad.
-		 * @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
-		 *			  Vector3 VES_NORMAL
-		 * 			  32bit index buffer
-		 * 			  Enough space for 4 vertices and 6 indices
-		 *
-		 *			Primitives are output in the form of a triangle list.
-		 */
-		void solidQuad(const Rect3& area, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * @copydoc	DrawHelperTemplate::pixelLine
-		 */
-		void pixelLine(const Vector3& a, const Vector3& b, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * @copydoc	DrawHelperTemplate::antialiasedLine
-		 */
-		void antialiasedLine(const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, const Color& color, 
-			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * @copydoc	DrawHelperTemplate::pixelLineList
-		 */
-		void pixelLineList(const Vector<Vector3>& linePoints, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * @copydoc	DrawHelperTemplate::antialiasedLineList
-		 */
-		void antialiasedLineList(const Vector<Vector3>& linePoints, const Vector3& up, float width, float borderWidth, 
-			const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * @brief	Calculates number of vertices and indices required for geometry of a solid sphere
-		 *			of the specified quality.
-		 */
-		static void getNumElementsSphere(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
-
-		/**
-		 * @brief	Calculates number of vertices and indices required for geometry of a wire sphere
-		 *			of the specified quality.
-		 */
-		static void getNumElementsWireSphere(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
-
-		/**
-		 * @brief	Calculates number of vertices and indices required for geometry of a solid arc
-		 *			of the specified quality.
-		 */
-		static void getNumElementsArc(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
-
-		/**
-		 * @brief	Calculates number of vertices and indices required for geometry of a wire arc
-		 *			of the specified quality.
-		 */
-		static void getNumElementsWireArc(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
-
-		/**
-		 * @brief	Calculates number of vertices and indices required for geometry of a solid desc
-		 *			of the specified quality.
-		 */
-		static void getNumElementsDisc(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
-
-		/**
-		 * @brief	Calculates number of vertices and indices required for geometry of a wire disc
-		 *			of the specified quality.
-		 */
-		static void getNumElementsWireDisc(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
-
-		/**
-		 * @brief	Calculates number of vertices and indices required for geometry of a cone
-		 *			of the specified quality.
-		 */
-		static void getNumElementsCone(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
-
-		/**
-		 * @brief	Constructs a one-pixel wide line and draws it in the specified camera. 
-		 *
-		 * @param	camera		Camera to draw the line in.
-		 * @param	x			Starting position of the line. Coordinates must be normalized in [0, 1] range. Coordinate origin is top left of the camera viewport.
-		 * @param	y			End position of the line. Coordinates must be normalized in [0, 1] range. Coordinate origin is top left of the camera viewport.
-		 * @param	color		Color of the line.
-		 * @param	timeout		Optional timeout on how long to display the line in seconds. If 0 the line will be displayed one frame.
-		 */
-		void drawPixelLine(const HCamera& camera, const Vector3& a, const Vector3& b, const Color& color = Color::White, float timeout = 0.0f);
-
-		/**
-		 * @brief	Constructs an antialiased line with custom width and draws it in the specified camera. 
-		 *
-		 * @param	camera		Camera to draw the line in.
-		 * @param	x			Starting position of the line. Coordinates must be normalized in [0, 1] range. Coordinate origin is top left of the camera viewport.
-		 * @param	y			End position of the line. Coordinates must be normalized in [0, 1] range. Coordinate origin is top left of the camera viewport.
-		 * @param	up			Up direction to which the line will run perpendicular to.
-		 * @param	width		Width of the line in pixels.
-		 * @param	borderWidth	Width of the antialiased border in pixels.
-		 * @param	color		Color of the line.
-		 * @param	timeout		Optional timeout on how long to display the line in seconds. If 0 the line will be displayed one frame.
-		 */
-		void drawAntialiasedLine(const HCamera& camera, const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, 
-			const Color& color = Color::White, float timeout = 0.0f);
-
-		/**
-		 * @brief	Constructs a pixel perfect list of lines and draws them in the specified camera. 
-		 *
-		 * @param	camera		Camera to draw the line list in.
-		 * @param	linePoints	List of line start and end points. This list must be a multiple of 2, where each start point is followed by and end point.
-		 *						Coordinates must be normalized in ([0, 1], [0, 1]) range. Coordinate origin is top left of the camera viewport.
-		 * @param	color		Color of the line list.
-		 * @param	timeout		Optional timeout on how long to display the line list in seconds. If 0 the line list will be displayed one frame.
-		 */
-		void drawPixelLineList(const HCamera& camera, const Vector<Vector3>& linePoints, const Color& color = Color::White, float timeout = 0.0f);
-
-		/**
-		 * @brief	Constructs an list of antialiased lines with custom width and draws them in the specified camera. 
-		 *
-		 * @param	camera		Camera to draw the line list in.
-		 * @param	linePoints	List of line start and end points. This list must be a multiple of 2, where each start point is followed by and end point.
-		 *						Coordinates must be normalized in ([0, 1], [0, 1]) range. Coordinate origin is top left of the camera viewport.
-		 * @param	up			Up direction to which the line will run perpendicular to.
-		 * @param	width		Width of the line in pixels.
-		 * @param	borderWidth	Width of the antialiased border in pixels.
-		 * @param	color		Color of the line list.
-		 * @param	timeout		Optional timeout on how long to display the line list in seconds. If 0 the line list will be displayed one frame.
-		 */
-		void drawAntialiasedLineList(const HCamera& camera, const Vector<Vector3>& linePoints, const Vector3& up, float width, float borderWidth, 
-			const Color& color = Color::White, float timeout = 0.0f);
-
-		/**
-		 * @brief	Constructs an axis aligned box and draws it in the specified camera.
-		 *
-		 * @param	camera		Camera to draw the box in.
-		 * @param	box			Box to draw.
-		 * @param	color		Color of the box.
-		 * @param	timeout		Optional timeout on how long to display the box in seconds. If 0 the box will be displayed one frame.
-		 */
-		void drawWireAABox(const HCamera& camera, const AABox& box, const Color& color = Color::White, float timeout = 0.0f);
-
-	protected:
-		/**
-		 * @copydoc	DrawHelperTemplate::antialiasedLine(const Vector3&, const Vector3&, const Vector3&, float, float, const Color&, UINT8*, UINT8*, UINT32, UINT32, UINT32*, UINT32)
-		 */
-		void antialiasedLine(const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors, 
-			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
-
-		/**
-		 * @copydoc	DrawHelperTemplate::antialiasedPolygon(const Vector<Vector3>&, const Vector3&, float, const Color&, UINT8*, UINT8*, UINT32, UINT32, UINT32*, UINT32)
-		 */
-		void antialiasedPolygon(const Vector<Vector3>& points, const Vector3& up, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors, 
-			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
-
-		/**
-		 * @brief	Fills the provided buffers with position and index data representing an outline of an axis aligned box.
-		 *
-		 * @param	box				Box to create geometry for.
-		 * @param	outVertices		Output buffer that will store the vertex position data.
-		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param	vertexStride	Size of a single vertex, in bytes.
-		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
-		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 */
-		void wireAABox(const AABox& box, UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, 
-			UINT32* outIndices, UINT32 indexOffset);
-
-		/**
-		 * @brief	Fills the provided buffers with position and index data representing a solid axis aligned box.
-		 *
-		 * @param	box				Box to create geometry for.
-		 * @param	outVertices		Output buffer that will store the vertex position data.
-		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
-		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
-		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 */
-		void solidAABox(const AABox& box, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, 
-			UINT32* outIndices, UINT32 indexOffset);
-
-		/**
-		 * @brief	Fills the provided buffers with position and index data representing a sphere.
-		 *
-		 * @param	sphere			Sphere to create geometry for.
-		 * @param	outVertices		Output buffer that will store the vertex position data.
-		 * @param	outNormals		Output buffer that will store the vertex normal data.
-		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
-		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
-		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * @param	quality			Represents the level of tessellation the sphere will have. Higher level means higher quality
-		 *							but also more vertices and primitives.
-		 */
-		void solidSphere(const Sphere& sphere, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride,
-			UINT32* outIndices, UINT32 indexOffset, UINT32 quality);
-
-		/**
-		 * @brief	Fills the provided buffers with position and index data representing an outline of an arc.
-		 *
-		 * @param	center			Center of the arc to generate geometry for.
-		 * @param	radius			Radius of the arc to generate geometry for.
-		 * @param	normal			Normal around which the arc is generated. Arc geometry will be perpendicular to the normal.
-		 * @param	startAngle		Angle at which the arc starts.
-		 * @param	amountAngle		Angle that the arc spans.
-		 * @param	outVertices		Output buffer that will store the vertex position data.
-		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param	vertexStride	Size of a single vertex, in bytes.
-		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
-		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * @param	quality			Represents the level of tessellation the arc will have. Higher level means higher quality
-		 *							but also more vertices and primitives.
-		 */
-		void wireArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle, 
-			UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality);
-
-		/**
-		 * @brief	Fills the provided buffers with position and index data representing a solid arc.
-		 *
-		 * @param	center			Center of the arc to generate geometry for.
-		 * @param	radius			Radius of the arc to generate geometry for.
-		 * @param	normal			Normal around which the arc is generated. Arc geometry will be perpendicular to the normal.
-		 * @param	startAngle		Angle at which the arc starts.
-		 * @param	amountAngle		Angle that the arc spans.
-		 * @param	outVertices		Output buffer that will store the vertex position data.
-		 * @param	outNormals		Output buffer that will store the vertex normal data.
-		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
-		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
-		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * @param	quality			Represents the level of tessellation the arc will have. Higher level means higher quality
-		 *							but also more vertices and primitives.
-		 */
-		void solidArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle, 
-			UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality);
-
-		/**
-		 * @brief	Fills the provided buffers with position and index data representing an outline of an axis aligned box.
-		 *
-		 * @param	aspect			Aspect ratio (width / height).
-		 * @param	FOV				Horizontal field of view angle.
-		 * @param	near			Distance to near clipping plane.
-		 * @param	far				Distance to far clipping plane.
-		 * @param	outVertices		Output buffer that will store the vertex position data.
-		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param	vertexStride	Size of a single vertex, in bytes.
-		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
-		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 */
-		void wireFrustum(float aspect, Degree FOV, float near, float far,
-			UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
-
-		/**
-		 * @brief	Fills the provided buffers with position and index data representing a solid cone.
-		 *
-		 * @param	base			World position of the cone base.
-		 * @param	normal			Direction of the pointed part of the cone.
-		 * @param	height			Cone height (distance from base to the top).
-		 * @param	radius			Cone radius (distance from base center to outer edge).
-		 * @param	outVertices		Output buffer that will store the vertex position data.
-		 * @param	outNormals		Output buffer that will store the vertex normal data.
-		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
-		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
-		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * @param	quality			Represents the level of tessellation the cone will have. Higher level means higher quality
-		 *							but also more vertices and primitives.
-		 */
-		void solidCone(const Vector3& base, const Vector3& normal, float height, float radius,
-			UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality);
-
-		/**
-		 * @brief	Fills the provided buffers with position and index data representing a solid quad.
-		 *
-		 * @param	area			Area covered by the quad.
-		 * @param	outVertices		Output buffer that will store the vertex position data.
-		 * @param	outNormals		Output buffer that will store the vertex normal data.
-		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
-		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
-		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 */
-		void solidQuad(const Rect3& area, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
-
-	private:
-		/**
-		 * @brief	Calculates the center of the provided vertices.
-		 * 
-		 * @param	vertices		Buffer containing vertices. Vertices must be of three dimensions at least.
-		 * @param	numVertices		Number of vertices to calculate the center for.
-		 * @param	vertexStride	Number of bytes between two vertices in the buffer.
-		 *
-		 * @returns	Center point of the vertices.
-		 */
-		Vector3 calcCenter(UINT8* vertices, UINT32 numVertices, UINT32 vertexStride);
-
-		/**
-		 * @brief	Subdivides the provided triangle so it approximates a curved surface of a sphere.
-		 *
-		 * @param	center			Center of the sphere to approximate.
-		 * @param	radius			Radius of the sphere to approximate.
-		 * @param	numLevels		Number of times to subdivide the triangle. Higher number means better approximation.
-		 * @param	a				First corner of the triangle. Must be normalized.
-		 * @param	b				Second corner of the triangle. Must be normalized.
-		 * @param	c				Third corner of the triangle. Must be normalized.
-		 * @param	outVertices		Output buffer that will store the vertex position data.
-		 * @param	outNormals		Output buffer that will store the vertex normal data.
-		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
-		 *
-		 * @returns	Number of vertices generated (3 * (4 ^ numLevels)).
-		 */
-		UINT32 subdivideTriangleOnSphere(const Vector3& center, float radius, UINT32 numLevels,
-			const Vector3& a, const Vector3& b, const Vector3& c,
-			UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride);
-
-		/**
-		 * @brief	Generates vertices that are part of an arc approximation.
-		 *
-		 * @param	center		Determines world position of the arc.
-		 * @param	up			Determines rotation of the arc. Arc vertices will be perpendicular to this direction.
-		 * @param	radius		Distance of arc vertices from the center.
-		 * @param	startAngle	Angle in degrees to start the arc at.
-		 * @param	angleAmount	Angle in degrees to extend the arc from the start angle.
-		 * @param	numVertices	Number of vertices to generate for the arc. Higher number means better arc approximation. Must be 2 or higher.
-		 * @param	outVertices		Output buffer that will store the vertex position data.
-		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
-		 */
-		void generateArcVertices(const Vector3& center, const Vector3& up, float radius, Degree startAngle, Degree angleAmount, UINT32 numVertices,
-			UINT8* outvertices, UINT32 vertexOffset, UINT32 vertexStride);
-
-		VertexDataDescPtr mVertexDesc;
-	};
+#pragma once
+
+#include "BsPrerequisites.h"
+#include "BsColor.h"
+#include "BsAABox.h"
+#include "BsRect3.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Helper class for easily creating common 3D shapes.
+	 */
+	class BS_EXPORT ShapeMeshes3D
+	{
+	public:
+		/**
+		 * @brief	Fills the mesh data with vertices representing an outline of axis aligned box.
+		 *
+		 * @param	aabox			Axis aligned box to create the mesh data for
+		 * @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
+		 * 			  32bit index buffer
+		 * 			  Enough space for 8 vertices and 24 indices
+		 *
+		 *			Primitives are output in the form of a line list.
+		 */
+		static void wireAABox(const AABox& box, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
+
+		/**
+		 * @brief	Fills the mesh data with vertices representing a solid axis aligned box.
+		 *
+		 * @param	aabox			Axis aligned box to create the mesh data for
+		 * @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
+		 *			  Vector3 VES_NORMAL
+		 * 			  32bit index buffer
+		 * 			  Enough space for 24 vertices and 36 indices
+		 *
+		 *			Primitives are output in the form of a triangle list.
+		 */
+		static void solidAABox(const AABox& box, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
+
+		/**
+		 * @brief	Fills the mesh data with vertices representing an outline of a sphere.
+		 *
+		 * @param	sphere			Sphere to get the mesh data for
+		 * @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.
+		 * @param	quality			Represents the level of tessellation the sphere will have. Higher level means higher quality
+		 *							but also more vertices and primitives.
+		 *
+		 * @note	Provided MeshData must have some specific elements at least:
+		 * 			  Vector3 VES_POSITION
+		 * 			  32bit index buffer
+		 * 			  Enough space for 3 * ((quality + 1) * 5) vertices 
+		 *			  Enough space for 6 * ((quality + 1) * 5 - 1) indices
+		 *
+		 *			Primitives are output in the form of a line list.
+		 */
+		static void wireSphere(const Sphere& sphere, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
+
+		/**
+		 * @brief	Fills the mesh data with vertices representing a sphere.
+		 *
+		 * @param	sphere			Sphere to get the mesh data for
+		 * @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.
+		 * @param	quality			Represents the level of tessellation the sphere will have. Higher level means higher quality
+		 *							but also more vertices and primitives.
+		 *
+		 * @note	Provided MeshData must have some specific elements at least:
+		 * 			  Vector3 VES_POSITION
+		 *			  Vector3 VES_NORMAL
+		 * 			  32bit index buffer
+		 * 			  Enough space for 20 * (4 * (3 ^ quality)) vertices 
+		 *			  Enough space for 20 * (4 * (3 ^ quality)) indices
+		 *
+		 *			Primitives are output in the form of a triangle list.
+		 */
+		static void solidSphere(const Sphere& sphere, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 1);
+
+		/**
+		 * @brief	Fills the mesh data with vertices representing an outline of an arc.
+		 *
+		 * @param	center			Center of the arc to generate geometry for.
+		 * @param	radius			Radius of the arc to generate geometry for.
+		 * @param	normal			Normal around which the arc is generated. Arc geometry will be perpendicular to the normal.
+		 * @param	startAngle		Angle at which the arc starts.
+		 * @param	amountAngle		Angle that the arc spans.
+		 * @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.
+		 * @param	quality			Represents the level of tessellation the arc will have. Higher level means higher quality
+		 *							but also more vertices and primitives.
+		 *
+		 * @note	Provided MeshData must have some specific elements at least:
+		 * 			  Vector3 VES_POSITION
+		 * 			  32bit index buffer
+		 * 			  Enough space for ((quality + 1) * 5) vertices 
+		 *			  Enough space for (((quality + 1) * 5 - 1) * 2) indices
+		 *
+		 *			Primitives are output in the form of a line list.
+		 */
+		static void wireArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
+			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
+
+		/**
+		 * @brief	Fills the mesh data with vertices representing a solid arc.
+		 *
+		 * @param	center			Center of the arc to generate geometry for.
+		 * @param	radius			Radius of the arc to generate geometry for.
+		 * @param	normal			Normal around which the arc is generated. Arc geometry will be perpendicular to the normal.
+		 * @param	startAngle		Angle at which the arc starts.
+		 * @param	amountAngle		Angle that the arc spans.
+		 * @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.
+		 * @param	quality			Represents the level of tessellation the arc will have. Higher level means higher quality
+		 *							but also more vertices and primitives.
+		 *
+		 * @note	Provided MeshData must have some specific elements at least:
+		 * 			  Vector3 VES_POSITION
+		 *			  Vector3 VES_NORMAL
+		 * 			  32bit index buffer
+		 * 			  Enough space for ((quality + 1) * 5 + 1) vertices 
+		 *			  Enough space for (((quality + 1) * 5 - 1) * 3) indices
+		 *
+		 *			Primitives are output in the form of a triangle list.
+		 */
+		static void solidArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
+			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
+
+		/**
+		 * @brief	Fills the mesh data with vertices representing an outline of a disc.
+		 *
+		 * @param	center			Center of the disc to generate geometry for.
+		 * @param	radius			Radius of the disc to generate geometry for.
+		 * @param	normal			Normal around which the disc is generated. Disc geometry will be perpendicular to the normal.
+		 * @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.
+		 * @param	quality			Represents the level of tessellation the disc will have. Higher level means higher quality
+		 *							but also more vertices and primitives.
+		 *
+		 * @note	Provided MeshData must have some specific elements at least:
+		 * 			  Vector3 VES_POSITION
+		 * 			  32bit index buffer
+		 * 			  Enough space for ((quality + 1) * 5) vertices 
+		 *			  Enough space for (((quality + 1) * 5 - 1) * 2) indices
+		 *
+		 *			Primitives are output in the form of a line list.
+		 */
+		static void wireDisc(const Vector3& center, float radius, const Vector3& normal, const MeshDataPtr& meshData,
+			UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
+
+		/**
+		 * @brief	Fills the mesh data with vertices representing a solid disc.
+		 *
+		 * @param	center			Center of the disc to generate geometry for.
+		 * @param	radius			Radius of the disc to generate geometry for.
+		 * @param	normal			Normal around which the disc is generated. Disc geometry will be perpendicular to the normal.
+		 * @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.
+		 * @param	quality			Represents the level of tessellation the disc will have. Higher level means higher quality
+		 *							but also more vertices and primitives.
+		 *
+		 * @note	Provided MeshData must have some specific elements at least:
+		 * 			  Vector3 VES_POSITION
+		 *			  Vector3 VES_NORMAL
+		 * 			  32bit index buffer
+		 * 			  Enough space for ((quality + 1) * 5 + 1) vertices 
+		 *			  Enough space for (((quality + 1) * 5 - 1) * 3) indices
+		 *
+		 *			Primitives are output in the form of a triangle list.
+		 */
+		static void solidDisc(const Vector3& center, float radius, const Vector3& normal, const MeshDataPtr& meshData,
+			UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
+
+		/**
+		 * @brief	Fills the mesh data with vertices representing an outline of an camera frustum. Frustum will
+		 *			be facing -z and be positioned at world origin.
+		 *
+		 * @param	aspect			Aspect ratio (width / height).
+		 * @param	FOV				Horizontal field of view angle.
+		 * @param	near			Distance to near clipping plane.
+		 * @param	far				Distance to far clipping plane.
+		 * @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
+		 * 			  32bit index buffer
+		 * 			  Enough space for 8 vertices and 24 indices
+		 *
+		 *			Primitives are output in the form of a line list.
+		 */
+		static void wireFrustum(float aspect, Degree FOV, float near, float far,
+			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
+
+		/**
+		 * @brief	Fills the mesh data with vertices representing a solid cone.
+		 *
+		 * @param	base			World position of the cone base.
+		 * @param	normal			Direction of the pointed part of the cone.
+		 * @param	height			Cone height (distance from base to the top).
+		 * @param	radius			Cone radius (distance from base center to outer edge).
+		 * @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.
+		 * @param	quality			Represents the level of tessellation the cone will have. Higher level means higher quality
+		 *							but also more vertices and primitives.
+		 *
+		 * @note	Provided MeshData must have some specific elements at least:
+		 * 			  Vector3 VES_POSITION
+		 *			  Vector3 VES_NORMAL
+		 * 			  32bit index buffer
+		 * 			  Enough space for ((quality + 1) * 4 + 1) * 2 vertices 
+		 *			  Enough space for (((quality + 1) * 4 - 1) * 6) indices
+		 *
+		 *			Primitives are output in the form of a triangle list.
+		 */
+		static void solidCone(const Vector3& base, const Vector3& normal, float height, float radius,
+			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
+
+		/**
+		 * @brief	Fills the mesh data with vertices representing a quad (2 triangles).
+		 *
+		 * @param	area			Area in which to draw the quad.
+		 * @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
+		 *			  Vector3 VES_NORMAL
+		 * 			  32bit index buffer
+		 * 			  Enough space for 4 vertices and 6 indices
+		 *
+		 *			Primitives are output in the form of a triangle list.
+		 */
+		static void solidQuad(const Rect3& area, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
+
+		/**
+		 * @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	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
+		 * 			  32bit index buffer
+		 * 			  Enough space for 2 vertices and 2 indices
+		 *
+		 *			Primitives are output in the form of a line list.
+		 */
+		static void pixelLine(const Vector3& a, const Vector3& b, const MeshDataPtr& meshData, UINT32 vertexOffset, 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	up				Up direction to which the line will run perpendicular to.
+		 * @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
+		 *
+		 *			Primitives are output in the form of a triangle list.
+		 */
+		static void antialiasedLine(const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, const Color& color,
+			const MeshDataPtr& meshData, UINT32 vertexOffset, 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	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
+		 * 			  32bit index buffer
+		 * 			  Enough space for (numLines * 2) vertices and (numLines * 2) indices
+		 *
+		 *			Primitives are output in the form of a line list.
+		 */
+		static void pixelLineList(const Vector<Vector3>& linePoints, const MeshDataPtr& meshData, UINT32 vertexOffset, 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	up				Up direction to which the line will run perpendicular to.
+		 * @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
+		 *
+		 *			Primitives are output in the form of a triangle list.
+		 */
+		static void antialiasedLineList(const Vector<Vector3>& linePoints, const Vector3& up, float width, float borderWidth,
+			const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
+
+		/**
+		 * @brief	Calculates number of vertices and indices required for geometry of a solid sphere
+		 *			of the specified quality.
+		 */
+		static void getNumElementsSphere(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
+
+		/**
+		 * @brief	Calculates number of vertices and indices required for geometry of a wire sphere
+		 *			of the specified quality.
+		 */
+		static void getNumElementsWireSphere(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
+
+		/**
+		 * @brief	Calculates number of vertices and indices required for geometry of a solid arc
+		 *			of the specified quality.
+		 */
+		static void getNumElementsArc(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
+
+		/**
+		 * @brief	Calculates number of vertices and indices required for geometry of a wire arc
+		 *			of the specified quality.
+		 */
+		static void getNumElementsWireArc(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
+
+		/**
+		 * @brief	Calculates number of vertices and indices required for geometry of a solid desc
+		 *			of the specified quality.
+		 */
+		static void getNumElementsDisc(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
+
+		/**
+		 * @brief	Calculates number of vertices and indices required for geometry of a wire disc
+		 *			of the specified quality.
+		 */
+		static void getNumElementsWireDisc(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
+
+		/**
+		 * @brief	Calculates number of vertices and indices required for geometry of a cone
+		 *			of the specified quality.
+		 */
+		static void getNumElementsCone(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
+
+		static const UINT32 NUM_VERTICES_AA_LINE;
+		static const UINT32 NUM_INDICES_AA_LINE;
+
+	protected:
+		/**
+		 * @brief	Fills the provided buffers with vertices representing a per-pixel line.
+		 *
+		 * @param	a				Start point of the line.
+		 * @param	b				End point of the line.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void pixelLine(const Vector3& a, const Vector3& b, UINT8* outVertices,
+			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * @brief	Fills the provided buffers with vertices representing an antialiased line with a custom width.
+		 *
+		 * @param	a				Start point of the line.
+		 * @param	b				End point of the line.
+		 * @param	up				Up direction to which the line will run perpendicular to.
+		 * @param	width			Width of the line.
+		 * @param	borderWidth		Width of the anti-aliased border.
+		 * @param	color			Color of the line.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	outColors		Output buffer that will store the vertex color data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void antialiasedLine(const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors,
+			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * @brief	Fills the provided buffers with position data and indices representing an inner 
+		 *			area of a polygon (basically a normal non-antialiased polygon).
+		 *
+		 * @param	points			Points defining the polygon. First point is assumed to be the start and end point.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void pixelSolidPolygon(const Vector<Vector3>& points, UINT8* outVertices,
+			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * @brief	Fills the provided buffers with vertices representing a pixel-wide polygon border.
+		 *
+		 * @param	points			Points defining the polygon. First point is assumed to be the start and end point.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void pixelWirePolygon(const Vector<Vector3>& points, UINT8* outVertices,
+			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * @brief	Fills the provided buffers with vertices representing an antialiased polygon.
+		 *
+		 * @param	points			Points defining the polygon. First point is assumed to be the start and end point.
+		 * @param	up				Up direction to which the polygon will run perpendicular to.
+		 * @param	borderWidth		Width of the anti-aliased border.
+		 * @param	color			Color of the polygon.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	outColors		Output buffer that will store the vertex color data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void antialiasedPolygon(const Vector<Vector3>& points, const Vector3& up, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors,
+			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * @brief	Fills the provided buffers with position and index data representing an outline of an axis aligned box.
+		 *
+		 * @param	box				Box to create geometry for.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes.
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void wireAABox(const AABox& box, UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride,
+			UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * @brief	Fills the provided buffers with position and index data representing a solid axis aligned box.
+		 *
+		 * @param	box				Box to create geometry for.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void solidAABox(const AABox& box, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride,
+			UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * @brief	Fills the provided buffers with position and index data representing a sphere.
+		 *
+		 * @param	sphere			Sphere to create geometry for.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	outNormals		Output buffer that will store the vertex normal data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * @param	quality			Represents the level of tessellation the sphere will have. Higher level means higher quality
+		 *							but also more vertices and primitives.
+		 */
+		static void solidSphere(const Sphere& sphere, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride,
+			UINT32* outIndices, UINT32 indexOffset, UINT32 quality);
+
+		/**
+		 * @brief	Fills the provided buffers with position and index data representing an outline of an arc.
+		 *
+		 * @param	center			Center of the arc to generate geometry for.
+		 * @param	radius			Radius of the arc to generate geometry for.
+		 * @param	normal			Normal around which the arc is generated. Arc geometry will be perpendicular to the normal.
+		 * @param	startAngle		Angle at which the arc starts.
+		 * @param	amountAngle		Angle that the arc spans.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes.
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * @param	quality			Represents the level of tessellation the arc will have. Higher level means higher quality
+		 *							but also more vertices and primitives.
+		 */
+		static void wireArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
+			UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality);
+
+		/**
+		 * @brief	Fills the provided buffers with position and index data representing a solid arc.
+		 *
+		 * @param	center			Center of the arc to generate geometry for.
+		 * @param	radius			Radius of the arc to generate geometry for.
+		 * @param	normal			Normal around which the arc is generated. Arc geometry will be perpendicular to the normal.
+		 * @param	startAngle		Angle at which the arc starts.
+		 * @param	amountAngle		Angle that the arc spans.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	outNormals		Output buffer that will store the vertex normal data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * @param	quality			Represents the level of tessellation the arc will have. Higher level means higher quality
+		 *							but also more vertices and primitives.
+		 */
+		static void solidArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
+			UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality);
+
+		/**
+		 * @brief	Fills the provided buffers with position and index data representing an outline of an axis aligned box.
+		 *
+		 * @param	aspect			Aspect ratio (width / height).
+		 * @param	FOV				Horizontal field of view angle.
+		 * @param	near			Distance to near clipping plane.
+		 * @param	far				Distance to far clipping plane.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes.
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void wireFrustum(float aspect, Degree FOV, float near, float far,
+			UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * @brief	Fills the provided buffers with position and index data representing a solid cone.
+		 *
+		 * @param	base			World position of the cone base.
+		 * @param	normal			Direction of the pointed part of the cone.
+		 * @param	height			Cone height (distance from base to the top).
+		 * @param	radius			Cone radius (distance from base center to outer edge).
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	outNormals		Output buffer that will store the vertex normal data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * @param	quality			Represents the level of tessellation the cone will have. Higher level means higher quality
+		 *							but also more vertices and primitives.
+		 */
+		static void solidCone(const Vector3& base, const Vector3& normal, float height, float radius,
+			UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality);
+
+		/**
+		 * @brief	Fills the provided buffers with position and index data representing a solid quad.
+		 *
+		 * @param	area			Area covered by the quad.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	outNormals		Output buffer that will store the vertex normal data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
+		 * @param	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void solidQuad(const Rect3& area, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
+
+	private:
+		/**
+		 * @brief	Calculates the center of the provided vertices.
+		 * 
+		 * @param	vertices		Buffer containing vertices. Vertices must be of three dimensions at least.
+		 * @param	numVertices		Number of vertices to calculate the center for.
+		 * @param	vertexStride	Number of bytes between two vertices in the buffer.
+		 *
+		 * @returns	Center point of the vertices.
+		 */
+		static Vector3 calcCenter(UINT8* vertices, UINT32 numVertices, UINT32 vertexStride);
+
+		/**
+		 * @brief	Subdivides the provided triangle so it approximates a curved surface of a sphere.
+		 *
+		 * @param	center			Center of the sphere to approximate.
+		 * @param	radius			Radius of the sphere to approximate.
+		 * @param	numLevels		Number of times to subdivide the triangle. Higher number means better approximation.
+		 * @param	a				First corner of the triangle. Must be normalized.
+		 * @param	b				Second corner of the triangle. Must be normalized.
+		 * @param	c				Third corner of the triangle. Must be normalized.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	outNormals		Output buffer that will store the vertex normal data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 *
+		 * @returns	Number of vertices generated (3 * (4 ^ numLevels)).
+		 */
+		static UINT32 subdivideTriangleOnSphere(const Vector3& center, float radius, UINT32 numLevels,
+			const Vector3& a, const Vector3& b, const Vector3& c,
+			UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride);
+
+		/**
+		 * @brief	Generates vertices that are part of an arc approximation.
+		 *
+		 * @param	center		Determines world position of the arc.
+		 * @param	up			Determines rotation of the arc. Arc vertices will be perpendicular to this direction.
+		 * @param	radius		Distance of arc vertices from the center.
+		 * @param	startAngle	Angle in degrees to start the arc at.
+		 * @param	angleAmount	Angle in degrees to extend the arc from the start angle.
+		 * @param	numVertices	Number of vertices to generate for the arc. Higher number means better arc approximation. Must be 2 or higher.
+		 * @param	outVertices		Output buffer that will store the vertex position data.
+		 * @param	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 */
+		static void generateArcVertices(const Vector3& center, const Vector3& up, float radius, Degree startAngle, Degree angleAmount, UINT32 numVertices,
+			UINT8* outvertices, UINT32 vertexOffset, UINT32 vertexStride);
+	};
 }

+ 2 - 8
BansheeEngine/Source/BsApplication.cpp

@@ -2,8 +2,8 @@
 #include "BsGUIMaterialManager.h"
 #include "BsGUIManager.h"
 #include "BsOverlayManager.h"
-#include "BsDrawHelper2D.h"
-#include "BsDrawHelper3D.h"
+#include "BsShapeMeshes2D.h"
+#include "BsShapeMeshes3D.h"
 #include "BsBuiltinResources.h"
 #include "BsScriptManager.h"
 #include "BsProfilingManager.h"
@@ -39,9 +39,6 @@ namespace BansheeEngine
 		GUIMaterialManager::startUp();
 		OverlayManager::startUp();
 
-		DrawHelper2D::startUp();
-		DrawHelper3D::startUp();
-
 		Cursor::startUp();
 
 #if BS_VER == BS_VER_DEV
@@ -59,9 +56,6 @@ namespace BansheeEngine
 
 		Cursor::shutDown();
 
-		DrawHelper3D::shutDown();
-		DrawHelper2D::shutDown();
-
 		GUIMaterialManager::instance().forceReleaseAllMaterials();
 
 		OverlayManager::shutDown();

+ 0 - 139
BansheeEngine/Source/BsBuiltinResources.cpp

@@ -155,12 +155,6 @@ namespace BansheeEngine
 	const WString BuiltinResources::ShaderSpriteTextPSFile = L"spriteTextPS.gpuprog";
 	const WString BuiltinResources::ShaderSpriteImageVSFile = L"spriteImageVS.gpuprog";
 	const WString BuiltinResources::ShaderSpriteImagePSFile = L"spriteImagePS.gpuprog";
-	const WString BuiltinResources::ShaderDebugDraw2DClipSpaceVSFile = L"debugDraw2DClipSpaceVS.gpuprog";
-	const WString BuiltinResources::ShaderDebugDraw2DClipSpacePSFile = L"debugDraw2DClipSpacePS.gpuprog";
-	const WString BuiltinResources::ShaderDebugDraw2DScreenSpaceVSFile = L"debugDraw2DScreenSpaceVS.gpuprog";
-	const WString BuiltinResources::ShaderDebugDraw2DScreenSpacePSFile = L"debugDraw2DScreenSpacePS.gpuprog";
-	const WString BuiltinResources::ShaderDebugDraw3DVSFile = L"debugDraw3DVS.gpuprog";
-	const WString BuiltinResources::ShaderDebugDraw3DPSFile = L"debugDraw3DPS.gpuprog";
 	const WString BuiltinResources::ShaderDockOverlayVSFile = L"dockDropOverlayVS.gpuprog";
 	const WString BuiltinResources::ShaderDockOverlayPSFile = L"dockDropOverlayPS.gpuprog";
 	const WString BuiltinResources::ShaderDummyVSFile = L"dummyVS.gpuprog";
@@ -203,9 +197,6 @@ namespace BansheeEngine
 
 		initSpriteTextShader();
 		initSpriteImageShader();
-		initDebugDraw2DClipSpaceShader();
-		initDebugDraw2DScreenSpaceShader();
-		initDebugDraw3DShader();
 		initDummyShader();
 
 		mWhiteSpriteTexture = getSkinTexture(WhiteTex);
@@ -642,36 +633,18 @@ namespace BansheeEngine
 			{ ShaderSpriteTextPSFile,				"ps_main",		GPT_FRAGMENT_PROGRAM,	GPP_PS_4_0, "hlsl", HLSL11ShaderSubFolder },
 			{ ShaderSpriteImageVSFile,				"vs_main",		GPT_VERTEX_PROGRAM,		GPP_VS_4_0, "hlsl", HLSL11ShaderSubFolder },
 			{ ShaderSpriteImagePSFile,				"ps_main",		GPT_FRAGMENT_PROGRAM,	GPP_PS_4_0, "hlsl", HLSL11ShaderSubFolder },
-			{ ShaderDebugDraw2DClipSpaceVSFile,		"vs_main",		GPT_VERTEX_PROGRAM,		GPP_VS_4_0, "hlsl", HLSL11ShaderSubFolder },
-			{ ShaderDebugDraw2DClipSpacePSFile,		"ps_main",		GPT_FRAGMENT_PROGRAM,	GPP_PS_4_0, "hlsl", HLSL11ShaderSubFolder },
-			{ ShaderDebugDraw2DScreenSpaceVSFile,	"vs_main",		GPT_VERTEX_PROGRAM,		GPP_VS_4_0, "hlsl", HLSL11ShaderSubFolder },
-			{ ShaderDebugDraw2DScreenSpacePSFile,	"ps_main",		GPT_FRAGMENT_PROGRAM,	GPP_PS_4_0, "hlsl", HLSL11ShaderSubFolder },
-			{ ShaderDebugDraw3DVSFile,				"vs_main",		GPT_VERTEX_PROGRAM,		GPP_VS_4_0, "hlsl", HLSL11ShaderSubFolder },
-			{ ShaderDebugDraw3DPSFile,				"ps_main",		GPT_FRAGMENT_PROGRAM,	GPP_PS_4_0, "hlsl", HLSL11ShaderSubFolder },
 			{ ShaderDummyVSFile,					"vs_main",		GPT_VERTEX_PROGRAM,		GPP_VS_4_0, "hlsl", HLSL11ShaderSubFolder },
 			{ ShaderDummyPSFile,					"ps_main",		GPT_FRAGMENT_PROGRAM,	GPP_PS_4_0, "hlsl", HLSL11ShaderSubFolder },
 			{ ShaderSpriteTextVSFile,				"vs_main",		GPT_VERTEX_PROGRAM,		GPP_VS_2_0, "hlsl", HLSL9ShaderSubFolder },
 			{ ShaderSpriteTextPSFile,				"ps_main",		GPT_FRAGMENT_PROGRAM,	GPP_PS_2_0, "hlsl", HLSL9ShaderSubFolder },
 			{ ShaderSpriteImageVSFile,				"vs_main",		GPT_VERTEX_PROGRAM,		GPP_VS_2_0, "hlsl", HLSL9ShaderSubFolder },
 			{ ShaderSpriteImagePSFile,				"ps_main",		GPT_FRAGMENT_PROGRAM,	GPP_PS_2_0, "hlsl", HLSL9ShaderSubFolder },
-			{ ShaderDebugDraw2DClipSpaceVSFile,		"vs_main",		GPT_VERTEX_PROGRAM,		GPP_VS_2_0, "hlsl", HLSL9ShaderSubFolder },
-			{ ShaderDebugDraw2DClipSpacePSFile,		"ps_main",		GPT_FRAGMENT_PROGRAM,	GPP_PS_2_0, "hlsl", HLSL9ShaderSubFolder },
-			{ ShaderDebugDraw2DScreenSpaceVSFile,	"vs_main",		GPT_VERTEX_PROGRAM,		GPP_VS_2_0, "hlsl", HLSL9ShaderSubFolder },
-			{ ShaderDebugDraw2DScreenSpacePSFile,	"ps_main",		GPT_FRAGMENT_PROGRAM,	GPP_PS_2_0, "hlsl", HLSL9ShaderSubFolder },
-			{ ShaderDebugDraw3DVSFile,				"vs_main",		GPT_VERTEX_PROGRAM,		GPP_VS_2_0, "hlsl", HLSL9ShaderSubFolder },
-			{ ShaderDebugDraw3DPSFile,				"ps_main",		GPT_FRAGMENT_PROGRAM,	GPP_PS_2_0, "hlsl", HLSL9ShaderSubFolder },
 			{ ShaderDummyVSFile,					"vs_main",		GPT_VERTEX_PROGRAM,		GPP_VS_2_0, "hlsl", HLSL9ShaderSubFolder },
 			{ ShaderDummyPSFile,					"ps_main",		GPT_FRAGMENT_PROGRAM,	GPP_PS_2_0, "hlsl", HLSL9ShaderSubFolder },
 			{ ShaderSpriteTextVSFile,				"main",			GPT_VERTEX_PROGRAM,		GPP_VS_4_0, "glsl", GLSLShaderSubFolder },
 			{ ShaderSpriteTextPSFile,				"main",			GPT_FRAGMENT_PROGRAM,	GPP_PS_4_0, "glsl", GLSLShaderSubFolder },
 			{ ShaderSpriteImageVSFile,				"main",			GPT_VERTEX_PROGRAM,		GPP_VS_4_0, "glsl", GLSLShaderSubFolder },
 			{ ShaderSpriteImagePSFile,				"main",			GPT_FRAGMENT_PROGRAM,	GPP_PS_4_0, "glsl", GLSLShaderSubFolder },
-			{ ShaderDebugDraw2DClipSpaceVSFile,		"main",			GPT_VERTEX_PROGRAM,		GPP_VS_4_0, "glsl", GLSLShaderSubFolder },
-			{ ShaderDebugDraw2DClipSpacePSFile,		"main",			GPT_FRAGMENT_PROGRAM,	GPP_PS_4_0, "glsl", GLSLShaderSubFolder },
-			{ ShaderDebugDraw2DScreenSpaceVSFile,	"main",			GPT_VERTEX_PROGRAM,		GPP_VS_4_0, "glsl", GLSLShaderSubFolder },
-			{ ShaderDebugDraw2DScreenSpacePSFile,	"main",			GPT_FRAGMENT_PROGRAM,	GPP_PS_4_0, "glsl", GLSLShaderSubFolder },
-			{ ShaderDebugDraw3DVSFile,				"main",			GPT_VERTEX_PROGRAM,		GPP_VS_4_0, "glsl", GLSLShaderSubFolder },
-			{ ShaderDebugDraw3DPSFile,				"main",			GPT_FRAGMENT_PROGRAM,	GPP_PS_4_0, "glsl", GLSLShaderSubFolder },
 			{ ShaderDummyVSFile,					"main",			GPT_VERTEX_PROGRAM,		GPP_VS_4_0, "glsl", GLSLShaderSubFolder },
 			{ ShaderDummyPSFile,					"main",			GPT_FRAGMENT_PROGRAM,	GPP_PS_4_0, "glsl", GLSLShaderSubFolder },
 		};
@@ -909,91 +882,6 @@ namespace BansheeEngine
 		newPass->setDepthStencilState(depthState);
 	}
 
-	void BuiltinResources::initDebugDraw2DClipSpaceShader()
-	{
-		HGpuProgram vsProgram = getGpuProgram(ShaderDebugDraw2DClipSpaceVSFile);
-		HGpuProgram psProgram = getGpuProgram(ShaderDebugDraw2DClipSpacePSFile);
-
-		mShaderDebugDraw2DClipSpace = Shader::create("DebugDraw2DClipSpaceShader");
-
-		TechniquePtr newTechnique = mShaderDebugDraw2DClipSpace->addTechnique(mActiveRenderSystem, RendererInvariant);
-		PassPtr newPass = newTechnique->addPass();
-		newPass->setVertexProgram(vsProgram);
-		newPass->setFragmentProgram(psProgram);
-
-		BLEND_STATE_DESC desc;
-		desc.renderTargetDesc[0].blendEnable = true;
-		desc.renderTargetDesc[0].srcBlend = BF_SOURCE_ALPHA;
-		desc.renderTargetDesc[0].dstBlend = BF_INV_SOURCE_ALPHA;
-		desc.renderTargetDesc[0].blendOp = BO_ADD;
-
-		HBlendState blendState = BlendState::create(desc);
-		newPass->setBlendState(blendState);
-
-		DEPTH_STENCIL_STATE_DESC depthStateDesc;
-		depthStateDesc.depthReadEnable = false;
-		depthStateDesc.depthWriteEnable = false;
-
-		HDepthStencilState depthState = DepthStencilState::create(depthStateDesc);
-		newPass->setDepthStencilState(depthState);
-	}
-
-	void BuiltinResources::initDebugDraw2DScreenSpaceShader()
-	{
-		HGpuProgram vsProgram = getGpuProgram(ShaderDebugDraw2DScreenSpaceVSFile);
-		HGpuProgram psProgram = getGpuProgram(ShaderDebugDraw2DScreenSpacePSFile);
-
-		mShaderDebugDraw2DScreenSpace = Shader::create("DebugDraw2DScreenSpaceShader");
-
-		mShaderDebugDraw2DScreenSpace->addParameter("invViewportWidth", "invViewportWidth", GPDT_FLOAT1);
-		mShaderDebugDraw2DScreenSpace->addParameter("invViewportHeight", "invViewportHeight", GPDT_FLOAT1);
-
-		TechniquePtr newTechnique = mShaderDebugDraw2DScreenSpace->addTechnique(mActiveRenderSystem, RendererInvariant);
-		PassPtr newPass = newTechnique->addPass();
-		newPass->setVertexProgram(vsProgram);
-		newPass->setFragmentProgram(psProgram);
-
-		BLEND_STATE_DESC desc;
-		desc.renderTargetDesc[0].blendEnable = true;
-		desc.renderTargetDesc[0].srcBlend = BF_SOURCE_ALPHA;
-		desc.renderTargetDesc[0].dstBlend = BF_INV_SOURCE_ALPHA;
-		desc.renderTargetDesc[0].blendOp = BO_ADD;
-
-		HBlendState blendState = BlendState::create(desc);
-		newPass->setBlendState(blendState);
-
-		DEPTH_STENCIL_STATE_DESC depthStateDesc;
-		depthStateDesc.depthReadEnable = false;
-		depthStateDesc.depthWriteEnable = false;
-
-		HDepthStencilState depthState = DepthStencilState::create(depthStateDesc);
-		newPass->setDepthStencilState(depthState);
-	}
-
-	void BuiltinResources::initDebugDraw3DShader()
-	{
-		HGpuProgram vsProgram = getGpuProgram(ShaderDebugDraw3DVSFile);
-		HGpuProgram psProgram = getGpuProgram(ShaderDebugDraw3DPSFile);
-
-		mShaderDebugDraw3D = Shader::create("DebugDraw3DShader");
-
-		mShaderDebugDraw3D->addParameter("matViewProj", "matViewProj", GPDT_MATRIX_4X4);
-
-		TechniquePtr newTechnique = mShaderDebugDraw3D->addTechnique(mActiveRenderSystem, RendererInvariant);
-		PassPtr newPass = newTechnique->addPass();
-		newPass->setVertexProgram(vsProgram);
-		newPass->setFragmentProgram(psProgram);
-
-		BLEND_STATE_DESC desc;
-		desc.renderTargetDesc[0].blendEnable = true;
-		desc.renderTargetDesc[0].srcBlend = BF_SOURCE_ALPHA;
-		desc.renderTargetDesc[0].dstBlend = BF_INV_SOURCE_ALPHA;
-		desc.renderTargetDesc[0].blendOp = BO_ADD;
-
-		HBlendState blendState = BlendState::create(desc);
-		newPass->setBlendState(blendState);
-	}
-
 	void BuiltinResources::initDummyShader()
 	{
 		HGpuProgram vsProgram = getGpuProgram(ShaderDummyVSFile);
@@ -1097,33 +985,6 @@ namespace BansheeEngine
 		return info;
 	}
 
-	DebugDraw2DClipSpaceMatInfo BuiltinResources::createDebugDraw2DClipSpaceMaterial() const
-	{
-		DebugDraw2DClipSpaceMatInfo info;
-		info.material = Material::create(mShaderDebugDraw2DClipSpace);
-
-		return info;
-	}
-
-	DebugDraw2DScreenSpaceMatInfo BuiltinResources::createDebugDraw2DScreenSpaceMaterial() const
-	{
-		DebugDraw2DScreenSpaceMatInfo info;
-		info.material = Material::create(mShaderDebugDraw2DScreenSpace);
-		info.invViewportWidth = info.material->getParamFloat("invViewportWidth");
-		info.invViewportHeight = info.material->getParamFloat("invViewportHeight");
-
-		return info;
-	}
-
-	DebugDraw3DMatInfo BuiltinResources::createDebugDraw3DMaterial() const
-	{
-		DebugDraw3DMatInfo info;
-		info.material = Material::create(mShaderDebugDraw3D);
-		info.matViewProj = info.material->getParamMat4("matViewProj");
-
-		return info;
-	}
-
 	HMaterial BuiltinResources::createDummyMaterial() const
 	{
 		return Material::create(mShaderDummy);

+ 0 - 431
BansheeEngine/Source/BsDrawHelper2D.cpp

@@ -1,431 +0,0 @@
-#include "BsDrawHelper2D.h"
-#include "BsRect2.h"
-#include "BsMesh.h"
-#include "BsTime.h"
-#include "BsVector2.h"
-#include "BsMaterial.h"
-#include "BsPass.h"
-#include "BsCoreApplication.h"
-#include "BsRenderQueue.h"
-#include "BsCamera.h"
-#include "BsCoreThreadAccessor.h"
-#include "BsBuiltinResources.h"
-#include "BsVertexDataDesc.h"
-
-namespace BansheeEngine
-{
-	DrawHelper2D::DrawHelper2D()
-	{
-		mMaterial2DClipSpace = BuiltinResources::instance().createDebugDraw2DClipSpaceMaterial();
-
-		mVertexDesc = bs_shared_ptr<VertexDataDesc>();
-		mVertexDesc->addVertElem(VET_FLOAT2, VES_POSITION);
-		mVertexDesc->addVertElem(VET_COLOR, VES_COLOR);
-	}
-
-	void DrawHelper2D::solidQuad(const Rect2& area, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
-	{
-		UINT32* indexData = meshData->getIndices32();
-		UINT8* positionData = meshData->getElementData(VES_POSITION);
-
-		assert((vertexOffset + 4) <= meshData->getNumVertices());
-		assert((indexOffset + 6) <= meshData->getNumIndices());
-
-		Vector<Vector2> points;
-		points.push_back(Vector2(area.x, area.y));
-		points.push_back(Vector2(area.x + area.width, area.y));
-		points.push_back(Vector2(area.x + area.width, area.y + area.height));
-		points.push_back(Vector2(area.x, area.y + area.height));	
-
-		pixelSolidPolygon(points, positionData, vertexOffset, meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset);
-	}
-
-	void DrawHelper2D::pixelLine(const Vector2& a, const Vector2& b, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
-	{
-		DrawHelperTemplate<Vector2>::pixelLine(a, b, meshData, vertexOffset, indexOffset);
-	}
-
-	void DrawHelper2D::antialiasedLine(const Vector2& a, const Vector2& b, float width, float borderWidth, const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
-	{
-		DrawHelperTemplate<Vector2>::antialiasedLine(a, b, Vector2::ZERO, width, borderWidth, color, meshData, vertexOffset, indexOffset);
-	}
-
-	void DrawHelper2D::pixelLineList(const Vector<Vector2>& linePoints, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
-	{
-		DrawHelperTemplate<Vector2>::pixelLineList(linePoints, meshData, vertexOffset, indexOffset);
-	}
-
-	void DrawHelper2D::antialiasedLineList(const Vector<Vector2>& linePoints, float width, float borderWidth, const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
-	{
-		DrawHelperTemplate<Vector2>::antialiasedLineList(linePoints, Vector2::ZERO, width, borderWidth, color, meshData, vertexOffset, indexOffset);
-	}
-
-	/************************************************************************/
-	/* 								2D - DRAW	                     		*/
-	/************************************************************************/
-
-	void DrawHelper2D::drawSolidQuad(const HCamera& camera, const Rect2& area, const Color& color, DebugDrawCoordType coordType, float timeout)
-	{
-		const Viewport* viewport = camera->getViewport().get();
-
-		Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
-
-		commands.push_back(DebugDrawCommand());
-		DebugDrawCommand& dbgCmd = commands.back();
-		dbgCmd.endTime = gTime().getTime() + timeout;
-
-		MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>(4, 6, mVertexDesc);
-
-		Rect2 actualArea = area;
-		if(coordType == DebugDrawCoordType::Normalized)
-			actualArea = normalizedCoordToClipSpace(area);
-
-		solidQuad(actualArea, meshData, 0, 0);
-
-		UINT32 vertexStride = mVertexDesc->getVertexStride();
-		UINT8* colorData = meshData->getElementData(VES_COLOR);
-
-		UINT32* colors = (UINT32*)colorData;
-		(*colors) = color.getAsRGBA();
-
-		colors = (UINT32*)(colorData + vertexStride);
-		(*colors) = color.getAsRGBA();
-
-		colors = (UINT32*)(colorData + vertexStride * 2);
-		(*colors) = color.getAsRGBA();
-
-		colors = (UINT32*)(colorData + vertexStride * 3);
-		(*colors) = color.getAsRGBA();
-
-		HMesh mesh = Mesh::create(meshData);
-
-		dbgCmd.mesh = mesh;
-		dbgCmd.worldCenter = Vector3::ZERO;
-
-		if(coordType == DebugDrawCoordType::Normalized)
-		{
-			dbgCmd.type = DebugDrawType::ClipSpace;
-			dbgCmd.matInfo2DClipSpace = mMaterial2DClipSpace;
-		}
-		else
-		{
-			dbgCmd.type = DebugDrawType::ScreenSpace;
-			dbgCmd.matInfo2DScreenSpace = BuiltinResources::instance().createDebugDraw2DScreenSpaceMaterial();
-		}
-	}
-
-	void DrawHelper2D::drawPixelLine(const HCamera& camera, const Vector2& a, const Vector2& b, const Color& color, DebugDrawCoordType coordType, float timeout)
-	{
-		const Viewport* viewport = camera->getViewport().get();
-
-		Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
-
-		commands.push_back(DebugDrawCommand());
-		DebugDrawCommand& dbgCmd = commands.back();
-		dbgCmd.endTime = gTime().getTime() + timeout;
-
-		MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>(2, 2, mVertexDesc);
-
-		Vector2 actualA = a;
-		Vector2 actualB = b;
-		if(coordType == DebugDrawCoordType::Normalized)
-		{
-			actualA = normalizedCoordToClipSpace(a);
-			actualB = normalizedCoordToClipSpace(b);
-		}
-
-		auto colorIter = meshData->getDWORDDataIter(VES_COLOR);
-		RGBA rgba = color.getAsRGBA();
-		colorIter.addValue(rgba);
-		colorIter.addValue(rgba);
-
-		pixelLine(actualA, actualB, meshData, 0, 0);
-
-		HMesh mesh = Mesh::create(meshData, MeshBufferType::Static, DOT_LINE_LIST);
-
-		dbgCmd.mesh = mesh;
-		dbgCmd.worldCenter = Vector3::ZERO;
-
-		if(coordType == DebugDrawCoordType::Normalized)
-		{
-			dbgCmd.type = DebugDrawType::ClipSpace;
-			dbgCmd.matInfo2DClipSpace = mMaterial2DClipSpace;
-		}
-		else
-		{
-			dbgCmd.type = DebugDrawType::ScreenSpace;
-			dbgCmd.matInfo2DScreenSpace = BuiltinResources::instance().createDebugDraw2DScreenSpaceMaterial();
-		}
-	}
-
-	void DrawHelper2D::drawAntialiasedLine(const HCamera& camera, const Vector2& a, const Vector2& b, float width, float borderWidth, const Color& color, DebugDrawCoordType coordType, float timeout)
-	{
-		const Viewport* viewport = camera->getViewport().get();
-
-		Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
-
-		commands.push_back(DebugDrawCommand());
-		DebugDrawCommand& dbgCmd = commands.back();
-		dbgCmd.endTime = gTime().getTime() + timeout;
-
-		MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>(8, 30, mVertexDesc);
-
-		Vector2 actualA = a;
-		Vector2 actualB = b;
-		if(coordType == DebugDrawCoordType::Normalized)
-		{
-			actualA = normalizedCoordToClipSpace(a);
-			actualB = normalizedCoordToClipSpace(b);
-		}
-
-		antialiasedLine(actualA, actualB, width, borderWidth, color, meshData, 0, 0);
-
-		HMesh mesh = Mesh::create(meshData);
-
-		dbgCmd.mesh = mesh;
-		dbgCmd.worldCenter = Vector3::ZERO;
-
-		if(coordType == DebugDrawCoordType::Normalized)
-		{
-			dbgCmd.type = DebugDrawType::ClipSpace;
-			dbgCmd.matInfo2DClipSpace = mMaterial2DClipSpace;
-		}
-		else
-		{
-			dbgCmd.type = DebugDrawType::ScreenSpace;
-			dbgCmd.matInfo2DScreenSpace = BuiltinResources::instance().createDebugDraw2DScreenSpaceMaterial();
-		}
-	}
-
-	void DrawHelper2D::drawPixelLineList(const HCamera& camera, const Vector<Vector2>& linePoints, const Color& color, 
-		DebugDrawCoordType coordType, float timeout)
-	{
-		const Viewport* viewport = camera->getViewport().get();
-
-		Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
-
-		commands.push_back(DebugDrawCommand());
-		DebugDrawCommand& dbgCmd = commands.back();
-		dbgCmd.endTime = gTime().getTime() + timeout;
-
-		MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>(
-			(UINT32)(linePoints.size() * 2), (UINT32)(linePoints.size() * 2), mVertexDesc);
-
-		auto colorIter = meshData->getDWORDDataIter(VES_COLOR);
-		RGBA rgba = color.getAsRGBA();
-
-		for (UINT32 i = 0; i < (UINT32)linePoints.size(); i++)
-			colorIter.addValue(rgba);
-
-		if(coordType == DebugDrawCoordType::Normalized)
-		{
-			Vector<Vector2> points;
-			UINT32 numPoints = (UINT32)linePoints.size();
-			for(UINT32 i = 0; i < numPoints; i++)
-				points.push_back(normalizedCoordToClipSpace(linePoints[i]));
-
-			pixelLineList(points, meshData, 0, 0);
-		}
-		else
-		{
-			pixelLineList(linePoints, meshData, 0, 0);
-		}		
-
-		HMesh mesh = Mesh::create(meshData, MeshBufferType::Static, DOT_LINE_LIST);
-
-		dbgCmd.mesh = mesh;
-		dbgCmd.worldCenter = Vector3::ZERO;
-
-		if(coordType == DebugDrawCoordType::Normalized)
-		{
-			dbgCmd.type = DebugDrawType::ClipSpace;
-			dbgCmd.matInfo2DClipSpace = mMaterial2DClipSpace;
-		}
-		else
-		{
-			dbgCmd.type = DebugDrawType::ScreenSpace;
-			dbgCmd.matInfo2DScreenSpace = BuiltinResources::instance().createDebugDraw2DScreenSpaceMaterial();
-		}
-	}
-
-	void DrawHelper2D::drawAntialiasedLineList(const HCamera& camera, const Vector<Vector2>& linePoints, float width, float borderWidth, 
-		const Color& color, DebugDrawCoordType coordType, float timeout)
-	{
-		const Viewport* viewport = camera->getViewport().get();
-
-		Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
-
-		commands.push_back(DebugDrawCommand());
-		DebugDrawCommand& dbgCmd = commands.back();
-		dbgCmd.endTime = gTime().getTime() + timeout;
-
-		MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>((UINT32)(linePoints.size() * 4), (UINT32)(linePoints.size() * 15), mVertexDesc);
-
-		if(coordType == DebugDrawCoordType::Normalized)
-		{
-			Vector<Vector2> points;
-			UINT32 numPoints = (UINT32)linePoints.size();
-			for(UINT32 i = 0; i < numPoints; i++)
-				points.push_back(normalizedCoordToClipSpace(linePoints[i]));
-
-			antialiasedLineList(points, width, borderWidth, color, meshData, 0, 0);
-		}
-		else
-		{
-			antialiasedLineList(linePoints, width, borderWidth, color, meshData, 0, 0);
-		}		
-
-		HMesh mesh = Mesh::create(meshData);
-
-		dbgCmd.mesh = mesh;
-		dbgCmd.worldCenter = Vector3::ZERO;
-
-		if(coordType == DebugDrawCoordType::Normalized)
-		{
-			dbgCmd.type = DebugDrawType::ClipSpace;
-			dbgCmd.matInfo2DClipSpace = mMaterial2DClipSpace;
-		}
-		else
-		{
-			dbgCmd.type = DebugDrawType::ScreenSpace;
-			dbgCmd.matInfo2DScreenSpace = BuiltinResources::instance().createDebugDraw2DScreenSpaceMaterial();
-		}
-	}
-
-	void DrawHelper2D::antialiasedLine(const Vector2& a, const Vector2& b, const Vector2& up, 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> 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;
-
-		antialiasedPolygon(points, up, borderWidth, color, outVertices, outColors, vertexOffset, vertexStride, outIndices, indexOffset);
-	}
-
-	void DrawHelper2D::antialiasedPolygon(const Vector<Vector2>& points, const Vector2& up, 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;
-		outColors += vertexOffset * vertexStride;
-		Vector<Vector2> 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++] = vertexOffset + i;
-			outIndices[idxCnt++] = vertexOffset + j;
-			outIndices[idxCnt++] = vertexOffset + numCoords + j;
-
-			outIndices[idxCnt++] = vertexOffset + numCoords + j;
-			outIndices[idxCnt++] = vertexOffset + numCoords + i;
-			outIndices[idxCnt++] = vertexOffset + i;
-		}
-
-		for(UINT32 i = 2; i < numCoords; ++i)
-		{
-			outIndices[idxCnt++] = vertexOffset + 0;
-			outIndices[idxCnt++] = vertexOffset + i - 1;
-			outIndices[idxCnt++] = vertexOffset + i;
-		}
-	}
-
-	Rect2 DrawHelper2D::normalizedCoordToClipSpace(const Rect2& area) const
-	{
-		Rect2 clipSpaceRect;
-		clipSpaceRect.x = area.x * 2.0f - 1.0f;
-		clipSpaceRect.width = area.width * 2.0f;
-		clipSpaceRect.y = -area.y * 2.0f + 1.0f;
-		clipSpaceRect.height = area.height * -2.0f;
-
-		return clipSpaceRect;
-	}
-
-	Vector2 DrawHelper2D::normalizedCoordToClipSpace(const Vector2& pos) const
-	{
-		return Vector2(pos.x * 2.0f - 1.0f, -pos.y * 2.0f + 1.0f);
-	}
-}

+ 1 - 64
BansheeEngine/Source/BsDrawHelperTemplate.cpp

@@ -12,68 +12,5 @@
 
 namespace BansheeEngine
 {
-	const UINT32 DrawHelperTemplateBase::NUM_VERTICES_AA_LINE = 8;
-	const UINT32 DrawHelperTemplateBase::NUM_INDICES_AA_LINE = 30;
-
-	void DrawHelperTemplateBase::render(const HCamera& camera, DrawList& drawList)
-	{
-		const Viewport* viewport = camera->getViewport().get();
-		Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
-
-		Matrix4 projMatrixCstm = camera->getProjectionMatrix();
-		Matrix4 viewMatrixCstm = camera->getViewMatrix();
-		Matrix4 viewProjMatrix = projMatrixCstm * viewMatrixCstm;
-
-		float invViewportWidth = 1.0f / (viewport->getWidth() * 0.5f);
-		float invViewportHeight = 1.0f / (viewport->getHeight() * 0.5f);
-
-		for(auto& cmd : commands)
-		{
-			if(cmd.mesh == nullptr || !cmd.mesh.isLoaded() || !cmd.mesh->isInitialized())
-				continue;
-
-			if(cmd.type == DebugDrawType::ClipSpace)
-			{
-				HMaterial mat = cmd.matInfo2DClipSpace.material;
-
-				if(mat == nullptr || !mat.isLoaded() || !mat->isInitialized())
-					continue;
-
-				drawList.add(mat.getInternalPtr(), cmd.mesh.getInternalPtr(), 0, cmd.worldCenter);
-			}
-			else if(cmd.type == DebugDrawType::ScreenSpace)
-			{
-				HMaterial mat = cmd.matInfo2DScreenSpace.material;
-
-				if(mat == nullptr || !mat.isLoaded() || !mat->isInitialized())
-					continue;
-
-				cmd.matInfo2DScreenSpace.invViewportWidth.set(invViewportWidth);
-				cmd.matInfo2DScreenSpace.invViewportHeight.set(invViewportHeight);
-
-				drawList.add(mat.getInternalPtr(), cmd.mesh.getInternalPtr(), 0, cmd.worldCenter);
-			}
-			else if(cmd.type == DebugDrawType::WorldSpace)
-			{
-				HMaterial mat = cmd.matInfo3D.material;
-
-				if(mat == nullptr || !mat.isLoaded() || !mat->isInitialized())
-					continue;
-
-				cmd.matInfo3D.matViewProj.set(viewProjMatrix);
-
-				drawList.add(mat.getInternalPtr(), cmd.mesh.getInternalPtr(), 0, cmd.worldCenter);
-			}
-		}
-
-		float curTime = gTime().getTime();
-		Vector<DebugDrawCommand> newCommands;
-		for(auto& cmd : commands)
-		{
-			if(cmd.endTime > curTime)
-				newCommands.push_back(cmd);
-		}
-
-		commands.swap(newCommands);
-	}
+	
 }

+ 299 - 0
BansheeEngine/Source/BsShapeMeshes2D.cpp

@@ -0,0 +1,299 @@
+#include "BsShapeMeshes2D.h"
+#include "BsRect2.h"
+#include "BsMesh.h"
+#include "BsTime.h"
+#include "BsVector2.h"
+#include "BsMaterial.h"
+#include "BsPass.h"
+#include "BsCoreApplication.h"
+#include "BsRenderQueue.h"
+#include "BsCamera.h"
+#include "BsCoreThreadAccessor.h"
+#include "BsBuiltinResources.h"
+#include "BsVertexDataDesc.h"
+
+namespace BansheeEngine
+{
+	const UINT32 ShapeMeshes2D::NUM_VERTICES_AA_LINE = 8;
+	const UINT32 ShapeMeshes2D::NUM_INDICES_AA_LINE = 30;
+
+	void ShapeMeshes2D::solidQuad(const Rect2& area, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
+	{
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+
+		assert((vertexOffset + 4) <= meshData->getNumVertices());
+		assert((indexOffset + 6) <= meshData->getNumIndices());
+
+		Vector<Vector2> points;
+		points.push_back(Vector2(area.x, area.y));
+		points.push_back(Vector2(area.x + area.width, area.y));
+		points.push_back(Vector2(area.x + area.width, area.y + area.height));
+		points.push_back(Vector2(area.x, area.y + area.height));	
+
+		pixelSolidPolygon(points, positionData, vertexOffset, meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset);
+	}
+
+	void ShapeMeshes2D::pixelLine(const Vector2& a, const Vector2& b, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
+	{
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+
+		assert((vertexOffset + 2) <= meshData->getNumVertices());
+		assert((indexOffset + 2) <= meshData->getNumIndices());
+
+		pixelLine(a, b, positionData, vertexOffset, meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset);
+	}
+
+	void ShapeMeshes2D::antialiasedLine(const Vector2& a, const Vector2& b, float width, float borderWidth, const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
+	{
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+		UINT8* colorData = meshData->getElementData(VES_COLOR);
+
+		assert((vertexOffset + NUM_VERTICES_AA_LINE) <= meshData->getNumVertices());
+		assert((indexOffset + NUM_INDICES_AA_LINE) <= meshData->getNumIndices());
+
+		antialiasedLine(a, b, width, borderWidth, color, positionData, colorData, vertexOffset, meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset);
+	}
+
+	void ShapeMeshes2D::pixelLineList(const Vector<Vector2>& linePoints, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
+	{
+		assert(linePoints.size() % 2 == 0);
+
+		assert((vertexOffset + linePoints.size() * 2) <= meshData->getNumVertices());
+		assert((indexOffset + linePoints.size() * 2) <= meshData->getNumIndices());
+
+		UINT32 curVertOffset = vertexOffset;
+		UINT32 curIdxOffset = indexOffset;
+
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+
+		UINT32 numPoints = (UINT32)linePoints.size();
+		for(UINT32 i = 0; i < numPoints; i += 2)
+		{
+			pixelLine(linePoints[i], linePoints[i + 1], positionData, curVertOffset, meshData->getVertexDesc()->getVertexStride(), indexData, curIdxOffset);
+
+			curVertOffset += 2;
+			curIdxOffset += 2;
+		}
+	}
+
+	void ShapeMeshes2D::antialiasedLineList(const Vector<Vector2>& linePoints, float width, float borderWidth, const Color& color,
+		const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
+	{
+		assert(linePoints.size() % 2 == 0);
+
+		assert((vertexOffset + linePoints.size() * 4) <= meshData->getNumVertices());
+		assert((indexOffset + linePoints.size() * 15) <= meshData->getNumIndices());
+
+		UINT32 curVertOffset = vertexOffset;
+		UINT32 curIdxOffset = indexOffset;
+
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+		UINT8* colorData = meshData->getElementData(VES_COLOR);
+
+		UINT32 numPoints = (UINT32)linePoints.size();
+		for(UINT32 i = 0; i < numPoints; i += 2)
+		{
+			antialiasedLine(linePoints[i], linePoints[i + 1], width, borderWidth, color, positionData, colorData, 
+				curVertOffset, meshData->getVertexDesc()->getVertexStride(), indexData, curIdxOffset);
+
+			curVertOffset += NUM_VERTICES_AA_LINE;
+			curIdxOffset += NUM_INDICES_AA_LINE;
+		}
+	}
+
+	void ShapeMeshes2D::pixelWirePolygon(const Vector<Vector2>& points, UINT8* outVertices, UINT8* outColors,
+		UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
+	{
+		INT32 numPoints = (INT32)points.size();
+		UINT32 curVertOffset = vertexOffset;
+		UINT32 curIdxOffset = indexOffset;
+		for (INT32 i = 0, j = numPoints - 1; i < numPoints; j = i++)
+		{
+			pixelLine(points[j], points[i], outVertices, curVertOffset, vertexStride, outIndices, curIdxOffset);
+			curVertOffset += 2;
+			curIdxOffset += 2;
+		}
+	}
+
+	void ShapeMeshes2D::pixelSolidPolygon(const Vector<Vector2>& points, UINT8* outVertices,
+		UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
+	{
+		outVertices += (vertexOffset * vertexStride);
+
+		for (auto& point : points)
+		{
+			Vector2* vertices = (Vector2*)outVertices;
+			(*vertices) = point;
+
+			outVertices += vertexStride;
+		}
+
+		outIndices += indexOffset;
+		INT32 numPoints = (INT32)points.size();
+		UINT32 idxCnt = 0;
+		for (int i = 2; i < numPoints; i++)
+		{
+			outIndices[idxCnt++] = vertexOffset;
+			outIndices[idxCnt++] = vertexOffset + i - 1;
+			outIndices[idxCnt++] = vertexOffset + i;
+		}
+	}
+
+	void ShapeMeshes2D::pixelLine(const Vector2& a, const Vector2& b, UINT8* outVertices,
+		UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
+	{
+		outVertices += (vertexOffset * vertexStride);
+
+		Vector2* vertices = (Vector2*)outVertices;
+		(*vertices) = a;
+
+		vertices = (Vector2*)(outVertices + vertexStride);
+		(*vertices) = b;
+
+		outIndices += indexOffset;
+		outIndices[0] = vertexOffset + 0;
+		outIndices[1] = vertexOffset + 1;
+	}
+
+	void ShapeMeshes2D::antialiasedLine(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> 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;
+
+		antialiasedPolygon(points, borderWidth, color, outVertices, outColors, vertexOffset, vertexStride, outIndices, indexOffset);
+	}
+
+	void ShapeMeshes2D::antialiasedPolygon(const Vector<Vector2>& 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;
+		outColors += vertexOffset * vertexStride;
+		Vector<Vector2> 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++] = vertexOffset + i;
+			outIndices[idxCnt++] = vertexOffset + j;
+			outIndices[idxCnt++] = vertexOffset + numCoords + j;
+
+			outIndices[idxCnt++] = vertexOffset + numCoords + j;
+			outIndices[idxCnt++] = vertexOffset + numCoords + i;
+			outIndices[idxCnt++] = vertexOffset + i;
+		}
+
+		for(UINT32 i = 2; i < numCoords; ++i)
+		{
+			outIndices[idxCnt++] = vertexOffset + 0;
+			outIndices[idxCnt++] = vertexOffset + i - 1;
+			outIndices[idxCnt++] = vertexOffset + i;
+		}
+	}
+
+	Rect2 ShapeMeshes2D::normalizedCoordToClipSpace(const Rect2& area)
+	{
+		Rect2 clipSpaceRect;
+		clipSpaceRect.x = area.x * 2.0f - 1.0f;
+		clipSpaceRect.width = area.width * 2.0f;
+		clipSpaceRect.y = -area.y * 2.0f + 1.0f;
+		clipSpaceRect.height = area.height * -2.0f;
+
+		return clipSpaceRect;
+	}
+
+	Vector2 ShapeMeshes2D::normalizedCoordToClipSpace(const Vector2& pos)
+	{
+		return Vector2(pos.x * 2.0f - 1.0f, -pos.y * 2.0f + 1.0f);
+	}
+}

+ 938 - 987
BansheeEngine/Source/BsDrawHelper3D.cpp → BansheeEngine/Source/BsShapeMeshes3D.cpp

@@ -1,988 +1,939 @@
-#include "BsDrawHelper3D.h"
-#include "BsRect2.h"
-#include "BsMesh.h"
-#include "BsTime.h"
-#include "BsVector2.h"
-#include "BsQuaternion.h"
-#include "BsSphere.h"
-#include "BsMaterial.h"
-#include "BsPass.h"
-#include "BsCoreApplication.h"
-#include "BsRenderQueue.h"
-#include "BsException.h"
-#include "BsCamera.h"
-#include "BsBuiltinResources.h"
-#include "BsVertexDataDesc.h"
-
-namespace BansheeEngine
-{
-	inline UINT8* writeVector3(UINT8* buffer, UINT32 stride, const Vector3& value)
-	{
-		*(Vector3*)buffer = value;
-		return buffer + stride;
-	}
-
-	DrawHelper3D::DrawHelper3D()
-	{
-		mVertexDesc = bs_shared_ptr<VertexDataDesc>();
-		mVertexDesc->addVertElem(VET_FLOAT2, VES_POSITION);
-		mVertexDesc->addVertElem(VET_COLOR, VES_COLOR);
-	}
-
-	void DrawHelper3D::wireAABox(const AABox& box, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
-	{
-		UINT32* indexData = meshData->getIndices32();
-		UINT8* positionData = meshData->getElementData(VES_POSITION);
-
-		assert((vertexOffset + 8) <= meshData->getNumVertices());
-		assert((indexOffset + 24) <= meshData->getNumIndices());	
-
-		wireAABox(box, positionData, vertexOffset, meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset);
-	}
-
-	void DrawHelper3D::solidAABox(const AABox& box, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
-	{
-		UINT32* indexData = meshData->getIndices32();
-		UINT8* positionData = meshData->getElementData(VES_POSITION);
-		UINT8* normalData = meshData->getElementData(VES_NORMAL);
-
-		assert((vertexOffset + 24) <= meshData->getNumVertices());
-		assert((indexOffset + 36) <= meshData->getNumIndices());
-
-		solidAABox(box, positionData, normalData, vertexOffset, meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset);
-	}
-
-	void DrawHelper3D::wireSphere(const Sphere& sphere, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality)
-	{
-		UINT32* indexData = meshData->getIndices32();
-		UINT8* positionData = meshData->getElementData(VES_POSITION);
-
-		UINT32 requiredNumVertices, requiredNumIndices;
-		getNumElementsWireSphere(quality, requiredNumVertices, requiredNumIndices);
-
-		assert((vertexOffset + requiredNumVertices) <= meshData->getNumVertices());
-		assert((indexOffset + requiredNumIndices) <= meshData->getNumIndices());
-
-		UINT32 verticesPerArc = (quality + 1) * 5;
-		UINT32 indicesPerArc = (verticesPerArc - 1) * 2;
-
-		wireDisc(sphere.getCenter(), sphere.getRadius(), Vector3::UNIT_X, meshData,
-			vertexOffset, indexOffset, quality);
-
-		wireDisc(sphere.getCenter(), sphere.getRadius(), Vector3::UNIT_Y, meshData,
-			vertexOffset + verticesPerArc, indexOffset + indicesPerArc, quality);
-
-		wireDisc(sphere.getCenter(), sphere.getRadius(), Vector3::UNIT_Z, meshData,
-			vertexOffset + verticesPerArc * 2, indexOffset + indicesPerArc * 2, quality);
-	}
-
-	void DrawHelper3D::solidSphere(const Sphere& sphere, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality)
-	{
-		UINT32* indexData = meshData->getIndices32();
-		UINT8* positionData = meshData->getElementData(VES_POSITION);
-		UINT8* normalData = meshData->getElementData(VES_NORMAL);
-
-		UINT32 requiredNumVertices, requiredNumIndices;
-		getNumElementsSphere(quality, requiredNumVertices, requiredNumIndices);
-
-		assert((vertexOffset + requiredNumVertices) <= meshData->getNumVertices());
-		assert((indexOffset + requiredNumIndices) <= meshData->getNumIndices());
-
-		solidSphere(sphere, positionData, normalData, vertexOffset, 
-			meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset, quality);
-	}
-
-	void DrawHelper3D::wireDisc(const Vector3& center, float radius, const Vector3& normal, const MeshDataPtr& meshData,
-		UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality)
-	{
-		wireArc(center, radius, normal, Degree(0), Degree(360), meshData, vertexOffset, indexOffset, quality);
-	}
-
-	void DrawHelper3D::solidDisc(const Vector3& center, float radius, const Vector3& normal, const MeshDataPtr& meshData,
-		UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality)
-	{
-		solidArc(center, radius, normal, Degree(0), Degree(360), meshData, vertexOffset, indexOffset, quality);
-	}
-
-	void DrawHelper3D::wireArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
-		const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality)
-	{
-		UINT32* indexData = meshData->getIndices32();
-		UINT8* positionData = meshData->getElementData(VES_POSITION);
-
-		UINT32 requiredNumVertices, requiredNumIndices;
-		getNumElementsWireArc(quality, requiredNumVertices, requiredNumIndices);
-
-		assert((vertexOffset + requiredNumVertices) <= meshData->getNumVertices());
-		assert((indexOffset + requiredNumIndices) <= meshData->getNumIndices());
-
-		wireArc(center, radius, normal, startAngle, amountAngle, positionData, vertexOffset,
-			meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset, quality);
-	}
-
-	void DrawHelper3D::solidArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
-		const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality)
-	{
-		UINT32* indexData = meshData->getIndices32();
-		UINT8* positionData = meshData->getElementData(VES_POSITION);
-		UINT8* normalData = meshData->getElementData(VES_NORMAL);
-
-		UINT32 requiredNumVertices, requiredNumIndices;
-		getNumElementsArc(quality, requiredNumVertices, requiredNumIndices);
-
-		assert((vertexOffset + requiredNumVertices) <= meshData->getNumVertices());
-		assert((indexOffset + requiredNumIndices) <= meshData->getNumIndices());
-
-		solidArc(center, radius, normal, startAngle, amountAngle, positionData, normalData, vertexOffset,
-			meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset, quality);
-	}
-
-	void DrawHelper3D::wireFrustum(float aspect, Degree FOV, float near, float far,
-		const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
-	{
-		UINT32* indexData = meshData->getIndices32();
-		UINT8* positionData = meshData->getElementData(VES_POSITION);
-
-		assert((vertexOffset + 8) <= meshData->getNumVertices());
-		assert((indexOffset + 24) <= meshData->getNumIndices());
-
-		wireFrustum(aspect, FOV, near, far, positionData, vertexOffset, meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset);
-	}
-
-	void DrawHelper3D::solidCone(const Vector3& base, const Vector3& normal, float height, float radius,
-		const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality)
-	{
-		UINT32* indexData = meshData->getIndices32();
-		UINT8* positionData = meshData->getElementData(VES_POSITION);
-		UINT8* normalData = meshData->getElementData(VES_NORMAL);
-
-		UINT32 requiredNumVertices, requiredNumIndices;
-		getNumElementsCone(quality, requiredNumVertices, requiredNumIndices);
-
-		assert((vertexOffset + requiredNumVertices) <= meshData->getNumVertices());
-		assert((indexOffset + requiredNumIndices) <= meshData->getNumIndices());
-
-		solidCone(base, normal, height, radius, positionData, normalData, vertexOffset,
-			meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset, quality);
-	}
-
-	void DrawHelper3D::solidQuad(const Rect3& area, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
-	{
-		UINT32* indexData = meshData->getIndices32();
-		UINT8* positionData = meshData->getElementData(VES_POSITION);
-		UINT8* normalData = meshData->getElementData(VES_NORMAL);
-
-		assert((vertexOffset + 4) <= meshData->getNumVertices());
-		assert((indexOffset + 6) <= meshData->getNumIndices());
-
-		solidQuad(area, positionData, normalData, vertexOffset,
-			meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset);
-	}
-
-	void DrawHelper3D::pixelLine(const Vector3& a, const Vector3& b, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
-	{
-		DrawHelperTemplate<Vector3>::pixelLine(a, b, meshData, vertexOffset, indexOffset);
-	}
-
-	void DrawHelper3D::antialiasedLine(const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, 
-		const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
-	{
-		DrawHelperTemplate<Vector3>::antialiasedLine(a, b, up, width, borderWidth, color, meshData, vertexOffset, indexOffset);
-	}
-
-	void DrawHelper3D::pixelLineList(const Vector<Vector3>& linePoints, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
-	{
-		DrawHelperTemplate<Vector3>::pixelLineList(linePoints, meshData, vertexOffset, indexOffset);
-	}
-
-	void DrawHelper3D::antialiasedLineList(const Vector<Vector3>& linePoints, const Vector3& up, float width, float borderWidth, 
-		const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
-	{
-		DrawHelperTemplate<Vector3>::antialiasedLineList(linePoints, up, width, borderWidth, color, meshData, vertexOffset, indexOffset);
-	}
-
-	/************************************************************************/
-	/* 								ELEMENT COUNT                      		*/
-	/************************************************************************/
-
-	void DrawHelper3D::getNumElementsSphere(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
-	{
-		numVertices = 20 * (4 * ((UINT32)std::pow(3, quality)));
-		numIndices = numVertices;
-	}
-
-	void DrawHelper3D::getNumElementsWireSphere(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
-	{
-		numVertices = 3 * ((quality + 1) * 4);
-		numIndices = 6 * ((quality + 1) * 4);
-	}
-
-	void DrawHelper3D::getNumElementsArc(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
-	{
-		numVertices = (quality + 1) * 5 + 1;
-		numIndices = ((quality + 1) * 5 - 1) * 3;
-	}
-
-	void DrawHelper3D::getNumElementsWireArc(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
-	{
-		numVertices = (quality + 1) * 5;
-		numIndices = ((quality + 1) * 5 - 1) * 2;
-	}
-
-	void DrawHelper3D::getNumElementsDisc(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
-	{
-		getNumElementsArc(quality, numVertices, numIndices);
-	}
-
-	void DrawHelper3D::getNumElementsWireDisc(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
-	{
-		getNumElementsWireArc(quality, numVertices, numIndices);
-	}
-
-	void DrawHelper3D::getNumElementsCone(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
-	{
-		numVertices = ((quality + 1) * 4 + 1) * 2;
-		numIndices = ((quality + 1) * 4 - 1) * 6;
-	}
-
-	/************************************************************************/
-	/* 								DRAW	                     			*/
-	/************************************************************************/
-
-	void DrawHelper3D::drawPixelLine(const HCamera& camera, const Vector3& a, const Vector3& b, const Color& color, float timeout)
-	{
-		const Viewport* viewport = camera->getViewport().get();
-
-		Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
-
-		commands.push_back(DebugDrawCommand());
-		DebugDrawCommand& dbgCmd = commands.back();
-		dbgCmd.endTime = gTime().getTime() + timeout;
-
-		MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>(2, 2, mVertexDesc);
-
-		auto colorIter = meshData->getDWORDDataIter(VES_COLOR);
-		RGBA rgba = color.getAsRGBA();
-
-		colorIter.addValue(rgba);
-		colorIter.addValue(rgba);
-
-		pixelLine(a, b, meshData, 0, 0);
-
-		UINT8* positionData = meshData->getElementData(VES_POSITION);
-		dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), mVertexDesc->getVertexStride());
-
-		HMesh mesh = Mesh::create(meshData, MeshBufferType::Static, DOT_LINE_LIST);
-
-		dbgCmd.mesh = mesh;
-		dbgCmd.type = DebugDrawType::WorldSpace;
-		dbgCmd.matInfo3D = BuiltinResources::instance().createDebugDraw3DMaterial();
-	}
-
-	void DrawHelper3D::drawAntialiasedLine(const HCamera& camera, const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, const Color& color, float timeout)
-	{
-		const Viewport* viewport = camera->getViewport().get();
-
-		Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
-
-		commands.push_back(DebugDrawCommand());
-		DebugDrawCommand& dbgCmd = commands.back();
-		dbgCmd.endTime = gTime().getTime() + timeout;
-
-		MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>(8, 30, mVertexDesc);
-
-		antialiasedLine(a, b, up, width, borderWidth, color, meshData, 0, 0);
-
-		UINT8* positionData = meshData->getElementData(VES_POSITION);
-		dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), mVertexDesc->getVertexStride());
-
-		HMesh mesh = Mesh::create(meshData);
-
-		dbgCmd.mesh = mesh;
-		dbgCmd.type = DebugDrawType::WorldSpace;
-		dbgCmd.matInfo3D = BuiltinResources::instance().createDebugDraw3DMaterial();
-	}
-
-	void DrawHelper3D::drawPixelLineList(const HCamera& camera, const Vector<Vector3>& linePoints, const Color& color, float timeout)
-	{
-		const Viewport* viewport = camera->getViewport().get();
-
-		Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
-
-		commands.push_back(DebugDrawCommand());
-		DebugDrawCommand& dbgCmd = commands.back();
-		dbgCmd.endTime = gTime().getTime() + timeout;
-
-		MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>(
-			(UINT32)(linePoints.size() * 2), (UINT32)(linePoints.size() * 2), mVertexDesc);
-
-		auto colorIter = meshData->getDWORDDataIter(VES_COLOR);
-		RGBA rgba = color.getAsRGBA();
-
-		for (UINT32 i = 0; i < (UINT32)linePoints.size(); i++)
-			colorIter.addValue(rgba);
-
-		pixelLineList(linePoints, meshData, 0, 0);
-
-		UINT8* positionData = meshData->getElementData(VES_POSITION);
-		dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), mVertexDesc->getVertexStride());
-
-		HMesh mesh = Mesh::create(meshData, MeshBufferType::Static, DOT_LINE_LIST);
-
-		dbgCmd.mesh = mesh;
-		dbgCmd.type = DebugDrawType::WorldSpace;
-		dbgCmd.matInfo3D = BuiltinResources::instance().createDebugDraw3DMaterial();
-	}
-
-	void DrawHelper3D::drawAntialiasedLineList(const HCamera& camera, const Vector<Vector3>& linePoints, const Vector3& up, float width, float borderWidth,
-		const Color& color, float timeout)
-	{
-		const Viewport* viewport = camera->getViewport().get();
-
-		Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
-
-		commands.push_back(DebugDrawCommand());
-		DebugDrawCommand& dbgCmd = commands.back();
-		dbgCmd.endTime = gTime().getTime() + timeout;
-
-		MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>((UINT32)(linePoints.size() * 4), (UINT32)(linePoints.size() * 15), mVertexDesc);
-
-		antialiasedLineList(linePoints, up, width, borderWidth, color, meshData, 0, 0);	
-
-		UINT8* positionData = meshData->getElementData(VES_POSITION);
-		dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), mVertexDesc->getVertexStride());
-
-		HMesh mesh = Mesh::create(meshData);
-
-		dbgCmd.mesh = mesh;
-		dbgCmd.type = DebugDrawType::WorldSpace;
-		dbgCmd.matInfo3D = BuiltinResources::instance().createDebugDraw3DMaterial();
-	}
-
-	void DrawHelper3D::drawWireAABox(const HCamera& camera, const AABox& box, const Color& color, float timeout)
-	{
-		const Viewport* viewport = camera->getViewport().get();
-
-		Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
-
-		commands.push_back(DebugDrawCommand());
-		DebugDrawCommand& dbgCmd = commands.back();
-		dbgCmd.endTime = gTime().getTime() + timeout;
-
-		MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>(8, 24, mVertexDesc);
-
-		wireAABox(box, meshData, 0, 0);	
-
-		UINT32 vertexStride = mVertexDesc->getVertexStride();
-		UINT8* colorData = meshData->getElementData(VES_COLOR);
-
-		for(UINT32 i = 0; i < meshData->getNumVertices(); i++)
-		{
-			UINT32* colors = (UINT32*)colorData;
-			(*colors) = color.getAsRGBA();
-
-			colorData += vertexStride;
-		}
-
-		UINT8* positionData = meshData->getElementData(VES_POSITION);
-		dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), mVertexDesc->getVertexStride());
-
-		HMesh mesh = Mesh::create(meshData, MeshBufferType::Static, DOT_LINE_LIST);
-
-		dbgCmd.mesh = mesh;
-		dbgCmd.type = DebugDrawType::WorldSpace;
-		dbgCmd.matInfo3D = BuiltinResources::instance().createDebugDraw3DMaterial();
-	}
-
-	void DrawHelper3D::wireAABox(const AABox& box, UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
-	{
-		outVertices += vertexOffset * vertexStride;
-
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_LEFT_BOTTOM));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_RIGHT_BOTTOM));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_RIGHT_TOP));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_LEFT_TOP));
-
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_RIGHT_BOTTOM));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_LEFT_BOTTOM));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_LEFT_TOP));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_RIGHT_TOP));
-
-		outIndices += indexOffset;
-
-		// Front
-		outIndices[0] = vertexOffset + 0;
-		outIndices[1] = vertexOffset + 1;
-
-		outIndices[2] = vertexOffset + 1;
-		outIndices[3] = vertexOffset + 2;
-
-		outIndices[4] = vertexOffset + 2;
-		outIndices[5] = vertexOffset + 3;
-
-		outIndices[6] = vertexOffset + 3;
-		outIndices[7] = vertexOffset + 0;
-
-		// Center
-		outIndices[8] = vertexOffset + 0;
-		outIndices[9] = vertexOffset + 5;
-
-		outIndices[10] = vertexOffset + 1;
-		outIndices[11] = vertexOffset + 4;
-
-		outIndices[12] = vertexOffset + 2;
-		outIndices[13] = vertexOffset + 7;
-
-		outIndices[14] = vertexOffset + 3;
-		outIndices[15] = vertexOffset + 6;
-
-		// Back
-		outIndices[16] = vertexOffset + 4;
-		outIndices[17] = vertexOffset + 5;
-
-		outIndices[18] = vertexOffset + 5;
-		outIndices[19] = vertexOffset + 6;
-
-		outIndices[20] = vertexOffset + 6;
-		outIndices[21] = vertexOffset + 7;
-
-		outIndices[22] = vertexOffset + 7;
-		outIndices[23] = vertexOffset + 4;
-	}
-
-	void DrawHelper3D::solidAABox(const AABox& box, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride,
-		UINT32* outIndices, UINT32 indexOffset)
-	{
-		outVertices += (vertexOffset * vertexStride);
-		Vector3* corners = (Vector3*)outVertices;
-
-		// Front face
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_LEFT_BOTTOM));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_RIGHT_BOTTOM));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_RIGHT_TOP));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_LEFT_TOP));
-
-		// Back face
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_RIGHT_BOTTOM));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_LEFT_BOTTOM));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_LEFT_TOP));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_RIGHT_TOP));
-
-		// Left face
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_LEFT_BOTTOM));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_LEFT_BOTTOM));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_LEFT_TOP));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_LEFT_TOP));
-
-		// Right face
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_RIGHT_BOTTOM));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_RIGHT_BOTTOM));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_RIGHT_TOP));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_RIGHT_TOP));
-
-		// Top face
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_LEFT_TOP));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_LEFT_TOP));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_RIGHT_TOP));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_RIGHT_TOP));
-
-		// Bottom face
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_LEFT_TOP));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_LEFT_TOP));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_RIGHT_TOP));
-		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_RIGHT_TOP));
-
-		static const Vector3 faceNormals[6] = 
-		{
-			Vector3(0, 0, 1),
-			Vector3(0, 0, -1),
-			Vector3(0, 1, 0),
-			Vector3(0, -1, 0),
-			Vector3(1, 0, 0),
-			Vector3(-1, 0, 0)
-		};
-
-		outNormals += (vertexOffset + vertexStride);
-		for (UINT32 face = 0; face < 6; face++)
-		{
-			outNormals = writeVector3(outNormals, vertexStride, faceNormals[face]);
-			outNormals = writeVector3(outNormals, vertexStride, faceNormals[face]);
-			outNormals = writeVector3(outNormals, vertexStride, faceNormals[face]);
-			outNormals = writeVector3(outNormals, vertexStride, faceNormals[face]);
-		}
-
-		UINT32* indices = outIndices + indexOffset;
-		for (UINT32 face = 0; face < 6; face++)
-		{
-			UINT32 faceVertOffset = vertexOffset + face * 4;
-
-			indices[face * 6 + 0] = faceVertOffset + 0;
-			indices[face * 6 + 1] = faceVertOffset + 1;
-			indices[face * 6 + 2] = faceVertOffset + 2;
-			indices[face * 6 + 3] = faceVertOffset + 2;
-			indices[face * 6 + 3] = faceVertOffset + 3;
-			indices[face * 6 + 3] = faceVertOffset + 0;
-		}
-	}
-
-	void DrawHelper3D::solidSphere(const Sphere& sphere, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, 
-		UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality)
-	{
-		// Create icosahedron
-		static const float x = 0.525731112119133606f;
-		static const float z = 0.850650808352039932f;
-
-		static const Vector3 vertices[12] = 
-		{
-			Vector3(-x,		0.0f,	z),
-			Vector3(x,		0.0f,	z),
-			Vector3(-x,		0.0f,	-z),
-			Vector3(x,		0.0f,	-z),
-			Vector3(0.0f,	z,		x),
-			Vector3(0.0f,	z,		-x),
-			Vector3(0.0f,	-z,		x),
-			Vector3(0.0f,	-z,		-x),
-			Vector3(z,		x,		0.0f),
-			Vector3(-z,		x,		0.0f),
-			Vector3(z,		-x,		0.0f),
-			Vector3(-z,		-x,		0.0f)
-		};
-
-		static const UINT32 triangles[20][3] = 
-		{
-				{ 0, 4, 1 },  { 0, 9, 4 },	{ 9, 5, 4 },	{ 4, 5, 8 },
-				{ 4, 8, 1 },  { 8, 10, 1 }, { 8, 3, 10 },	{ 5, 3, 8 },
-				{ 5, 2, 3 },  { 2, 7, 3 },	{ 7, 10, 3 },	{ 7, 6, 10 },
-				{ 7, 11, 6 }, { 11, 0, 6 }, { 0, 1, 6 },	{ 6, 1, 10 },
-				{ 9, 0, 11 }, { 9, 11, 2 }, { 9, 2, 5 },	{ 7, 2, 11 }
-		};
-
-		// Tessellate it
-		UINT32 curVertOffset = vertexOffset;
-		for (int i = 0; i < 20; ++i) 
-		{
-			curVertOffset += subdivideTriangleOnSphere(sphere.getCenter(), sphere.getRadius(), quality,
-				vertices[triangles[i][0]], vertices[triangles[i][1]], vertices[triangles[i][2]],
-				outVertices, outNormals, curVertOffset, vertexStride);
-		}
-
-		// Create indices
-		outIndices += indexOffset;
-
-		UINT32 numTriangles = 20 * (3 * ((UINT32)std::pow(4L, (long)quality)));
-		for (UINT32 i = 0; i < numTriangles * 3; i += 3)
-		{
-			outIndices[i] = vertexOffset + i;
-			outIndices[i + 1] = vertexOffset + i + 1;
-			outIndices[i + 2] = vertexOffset + i + 2;
-		}
-	}
-
-	void DrawHelper3D::wireArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle, 
-		UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality)
-	{
-		UINT32 numVertices = (quality + 1) * 5;
-
-		generateArcVertices(center, normal, radius, startAngle, amountAngle,
-			numVertices, outVertices, vertexOffset, vertexStride);
-
-		outIndices += indexOffset;
-		UINT32 numLines = numVertices - 1;
-		for (UINT32 i = 0; i < numLines; i++)
-		{
-			outIndices[i * 2 + 0] = vertexOffset + i;
-			outIndices[i * 2 + 1] = vertexOffset + i + 1;
-		}
-	}
-
-	void DrawHelper3D::solidArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle, 
-		UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality)
-	{
-		Vector3* centerVertex = (Vector3*)(outVertices + (vertexOffset * vertexStride));
-		*centerVertex = center;
-
-		UINT32 numArcVertices = (quality + 1) * 5;
-		generateArcVertices(center, normal, radius, startAngle, amountAngle,
-			numArcVertices, outVertices, vertexOffset + 1, vertexStride);
-
-		UINT32 totalNumVertices = numArcVertices + 1;
-		outNormals += vertexOffset * vertexStride;
-		for (UINT32 i = 0; i < totalNumVertices; i++)
-		{
-			outNormals = writeVector3(outNormals, vertexStride, normal);
-		}
-
-		outIndices += indexOffset;
-		UINT32 numTriangles = numArcVertices - 1;
-		for (UINT32 i = 0; i < numTriangles; i++)
-		{
-			outIndices[i * 3 + 0] = vertexOffset + 0;
-			outIndices[i * 3 + 1] = vertexOffset + i;
-			outIndices[i * 3 + 2] = vertexOffset + i + 1;
-		}
-	}
-
-	void DrawHelper3D::wireFrustum(float aspect, Degree FOV, float near, float far,
-		UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
-	{
-		float fovTan = Math::tan(FOV);
-
-		Vector3 nearPoint(0, 0, near);
-		Vector3 nearWidth(near * fovTan * aspect, 0, 0);
-		Vector3 nearHeight(0, (near * fovTan) / aspect, 0);
-
-		Vector3 farPoint(0, 0, far);
-		Vector3 farWidth(far * fovTan * aspect, 0, 0);
-		Vector3 farHeight(0, (far * fovTan) / aspect, 0);
-
-		Vector3 points[8] = 
-		{
-			nearPoint + nearWidth + nearHeight,
-			nearPoint - nearWidth + nearHeight,
-			nearPoint - nearWidth - nearHeight,
-			nearPoint + nearWidth - nearHeight,
-			farPoint + farWidth + farHeight,
-			farPoint - farWidth + farHeight,
-			farPoint - farWidth - farHeight,
-			farPoint + farWidth - farHeight
-		};
-
-		outVertices += vertexOffset * vertexStride;
-
-		for (UINT32 i = 0; i < 8; i++)
-			outVertices = writeVector3(outVertices, vertexStride, points[i]);
-
-		outIndices += indexOffset;
-
-		// Front
-		outIndices[0] = vertexOffset + 0; outIndices[1] = vertexOffset + 1;
-		outIndices[2] = vertexOffset + 1; outIndices[3] = vertexOffset + 2;
-		outIndices[4] = vertexOffset + 2; outIndices[5] = vertexOffset + 3;
-		outIndices[6] = vertexOffset + 3; outIndices[7] = vertexOffset + 0;
-
-		// Center
-		outIndices[8] = vertexOffset + 0; outIndices[9] = vertexOffset + 4;
-		outIndices[10] = vertexOffset + 1; outIndices[11] = vertexOffset + 5;
-		outIndices[12] = vertexOffset + 2; outIndices[13] = vertexOffset + 6;
-		outIndices[14] = vertexOffset + 3; outIndices[15] = vertexOffset + 7;
-
-		// Back
-		outIndices[16] = vertexOffset + 4; outIndices[17] = vertexOffset + 5;
-		outIndices[18] = vertexOffset + 5; outIndices[19] = vertexOffset + 6;
-		outIndices[20] = vertexOffset + 6; outIndices[21] = vertexOffset + 7;
-		outIndices[22] = vertexOffset + 7; outIndices[23] = vertexOffset + 4;
-	}
-
-	void DrawHelper3D::solidCone(const Vector3& base, const Vector3& normal, float height, float radius,
-		UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality)
-	{
-		outVertices += vertexOffset * vertexStride;
-		outNormals += vertexOffset * vertexStride;
-		outIndices += indexOffset;
-
-		// Generate base disc
-		UINT32 numArcVertices = (quality + 1) * 4;
-
-		generateArcVertices(base, normal, radius, Degree(0), Degree(360),
-			numArcVertices + 1, outVertices, 0, vertexStride);
-
-		outVertices += numArcVertices * vertexStride;
-		outVertices = writeVector3(outVertices, vertexStride, base); // Write base vertex
-
-		UINT32 baseIdx = numArcVertices;
-
-		UINT32 totalNumBaseVertices = numArcVertices + 1;
-		for (UINT32 i = 0; i < totalNumBaseVertices; i++)
-		{
-			outNormals = writeVector3(outNormals, vertexStride, -normal);
-		}
-
-		UINT32 numTriangles = numArcVertices;
-		for (UINT32 i = 0; i < numTriangles; i++)
-		{
-			outIndices[i * 3 + 0] = vertexOffset + baseIdx;
-			outIndices[i * 3 + 1] = vertexOffset + i;
-			outIndices[i * 3 + 2] = vertexOffset + i + 1;
-		}
-
-		// Generate cone
-		generateArcVertices(base, normal, radius, Degree(0), Degree(360),
-			numArcVertices + 1, outVertices, 0, vertexStride);
-
-		Vector3 topVertex = base + normal * height;
-
-		UINT32 totalNumConeVertices = numArcVertices;
-		for (UINT32 i = 0; i < totalNumConeVertices; i++)
-		{
-			int offsetA = i;
-			int offsetB = (i + 1) % totalNumConeVertices;
-
-			Vector3* a = (Vector3*)(outVertices + (offsetA * vertexStride));
-			Vector3* b = (Vector3*)(outVertices + (offsetB * vertexStride));
-
-			Vector3 triNormal = *a - topVertex;
-			triNormal = triNormal.cross(*b - topVertex);
-			triNormal.normalize();
-
-			outNormals = writeVector3(outNormals, vertexStride, triNormal); // TODO - Smooth normals?
-		}
-
-		*(Vector3*)outNormals = normal;
-
-		outVertices += numArcVertices * vertexStride;
-		outVertices = writeVector3(outVertices, vertexStride, topVertex); // Write top vertex
-		UINT32 topIdx = numArcVertices * 2 + 2;
-
-		outIndices += numTriangles * 3;
-		UINT32 curVertOffset = vertexOffset + numArcVertices + 1;
-		for (UINT32 i = 0; i < numTriangles; i++)
-		{
-			outIndices[i * 3 + 0] = curVertOffset + topIdx;
-			outIndices[i * 3 + 1] = curVertOffset + i;
-			outIndices[i * 3 + 2] = curVertOffset + i + 1;
-		}
-	}
-
-	void DrawHelper3D::solidQuad(const Rect3& area, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
-	{
-		outVertices += (vertexOffset * vertexStride);
-
-		Vector3 topLeft = area.getCenter() - area.getAxisHorz() * area.getExtentHorz() + area.getAxisVert() * area.getExtentVertical();
-		Vector3 topRight = area.getCenter() + area.getAxisHorz() * area.getExtentHorz() + area.getAxisVert() * area.getExtentVertical();
-		Vector3 botRight = area.getCenter() + area.getAxisHorz() * area.getExtentHorz() - area.getAxisVert() * area.getExtentVertical();
-		Vector3 botLeft = area.getCenter() - area.getAxisHorz() * area.getExtentHorz() - area.getAxisVert() * area.getExtentVertical();
-
-		outVertices = writeVector3(outVertices, vertexStride, topLeft);
-		outVertices = writeVector3(outVertices, vertexStride, topRight);
-		outVertices = writeVector3(outVertices, vertexStride, botRight);
-		outVertices = writeVector3(outVertices, vertexStride, botLeft);
-
-		Vector3 normal = area.getAxisHorz().cross(area.getAxisVert());
-
-		outNormals += (vertexOffset + vertexStride);
-		outNormals = writeVector3(outNormals, vertexStride, normal);
-		outNormals = writeVector3(outNormals, vertexStride, normal);
-		outNormals = writeVector3(outNormals, vertexStride, normal);
-		outNormals = writeVector3(outNormals, vertexStride, normal);
-
-		outIndices += indexOffset;
-		outIndices[0] = vertexOffset;
-		outIndices[1] = vertexOffset + 1;
-		outIndices[2] = vertexOffset + 2;
-
-		outIndices[3] = vertexOffset;
-		outIndices[4] = vertexOffset + 2;
-		outIndices[5] = vertexOffset + 3;
-	}
-
-	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::antialiasedLine(const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors,
-		UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
-	{
-		Vector3 dir = b - a;
-		dir.normalize();
-
-		Vector3 right = dir.cross(up);
-		right.normalize();
-
-		Vector<Vector3> points(4);
-
-		float r = width * 0.5f;
-		dir = dir * r;
-		right = right * r;
-
-		Vector3 v0 = a - dir - right;
-		Vector3 v1 = a - dir + right;
-		Vector3 v2 = b + dir + right;
-		Vector3 v3 = b + dir - right;
-
-		points[0] = v0;
-		points[1] = v1;
-		points[2] = v2;
-		points[3] = v3;
-
-		antialiasedPolygon(points, up, borderWidth, color, outVertices, outColors, vertexOffset, vertexStride, outIndices, indexOffset);
-	}
-
-	void DrawHelper3D::antialiasedPolygon(const Vector<Vector3>& points, const Vector3& up, 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;
-		outColors += vertexOffset * vertexStride;
-		Vector<Vector3> tempNormals(numCoords);
-
-		for (UINT32 i = 0, j = numCoords - 1; i < numCoords; j = i++)
-		{
-			const Vector3& v0 = points[j];
-			const Vector3& v1 = points[i];
-
-			Vector3 dir = v1 - v0;
-			Vector3 right = dir.cross(up);
-			right.normalize();
-
-			tempNormals[j] = right;
-
-			// Also start populating the vertex array
-			Vector3* vertices = (Vector3*)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 Vector3& n0 = tempNormals[j];
-			const Vector3& n1 = tempNormals[i];
-
-			Vector3 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;
-			}
-
-			Vector3 tempCoord = points[i] + avgNrm * borderWidth;
-
-			// Move it to the vertex array
-			Vector3* vertices = (Vector3*)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++] = vertexOffset + i;
-			outIndices[idxCnt++] = vertexOffset + j;
-			outIndices[idxCnt++] = vertexOffset + numCoords + j;
-
-			outIndices[idxCnt++] = vertexOffset + numCoords + j;
-			outIndices[idxCnt++] = vertexOffset + numCoords + i;
-			outIndices[idxCnt++] = vertexOffset + i;
-		}
-
-		for (UINT32 i = 2; i < numCoords; ++i)
-		{
-			outIndices[idxCnt++] = vertexOffset + 0;
-			outIndices[idxCnt++] = vertexOffset + i - 1;
-			outIndices[idxCnt++] = vertexOffset + i;
-		}
-	}
-
-	UINT32 DrawHelper3D::subdivideTriangleOnSphere(const Vector3& center, float radius, UINT32 numLevels,
-		const Vector3& a, const Vector3& b, const Vector3& c,
-		UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride)
-	{
-		outVertices += (vertexOffset * vertexStride);
-		outNormals += (vertexOffset * vertexStride);
-
-		UINT32 numVertices = 0;
-
-		if (numLevels > 0)
-		{
-			Vector3 sub1 = Vector3::normalize((a + b) * 0.5f);
-			Vector3 sub2 = Vector3::normalize((b + c) * 0.5f);
-			Vector3 sub3 = Vector3::normalize((c + a) * 0.5f);
-
-			numLevels--;
-			UINT32 curVertOffset = vertexOffset + numVertices;
-
-			numVertices += subdivideTriangleOnSphere(center, radius, numLevels, a, sub1, sub3, outVertices, 
-				outNormals, vertexOffset + numVertices, vertexStride);
-			numVertices += subdivideTriangleOnSphere(center, radius, numLevels, sub1, b, sub2, outVertices, 
-				outNormals, vertexOffset + numVertices, vertexStride);
-			numVertices += subdivideTriangleOnSphere(center, radius, numLevels, sub1, sub2, sub3, outVertices, 
-				outNormals, vertexOffset + numVertices, vertexStride);
-			numVertices += subdivideTriangleOnSphere(center, radius, numLevels, sub3, sub2, c, outVertices, 
-				outNormals, vertexOffset + numVertices, vertexStride);
-		}
-		else
-		{
-			*((Vector3*)outVertices) = center + a * radius;
-			*((Vector3*)outNormals) = a;
-
-			outVertices += vertexStride;
-			outNormals += vertexStride;
-
-			*((Vector3*)outVertices) = center + b * radius;
-			*((Vector3*)outNormals) = b;
-
-			outVertices += vertexStride;
-			outNormals += vertexStride;
-
-			*((Vector3*)outVertices) = center + c * radius;
-			*((Vector3*)outNormals) = c;
-
-			outVertices += vertexStride;
-			outNormals += vertexStride;
-
-			numVertices += 3;
-		}
-
-		return numVertices;
-	}
-
-	void DrawHelper3D::generateArcVertices(const Vector3& center, const Vector3& up, float radius, Degree startAngle, Degree angleAmount, UINT32 numVertices,
-		UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride)
-	{
-		assert(numVertices >= 2);
-
-		Vector3 normalizedUp = Vector3::normalize(up);
-		Vector3 right;
-
-		if (Math::abs(normalizedUp.dot(Vector3::UNIT_Z)) <= 0.95f)
-			right = normalizedUp.cross(Vector3::UNIT_Z);
-		else
-			right = normalizedUp.cross(Vector3::UNIT_Y);
-
-		right.normalize();
-		Quaternion moveToStart(up, startAngle);
-		Vector3 start = moveToStart.rotate(right);
-
-		Quaternion increment(up, angleAmount / (float)(numVertices - 1));
-
-		outVertices += vertexOffset * vertexStride;
-		Vector3 curDirection = start * radius;
-		for (UINT32 i = 0; i < numVertices; i++)
-		{
-			outVertices = writeVector3(outVertices, vertexStride, center + curDirection);
-			curDirection = increment.rotate(curDirection);
-		}
-	}
+#include "BsShapeMeshes3D.h"
+#include "BsRect2.h"
+#include "BsMesh.h"
+#include "BsTime.h"
+#include "BsVector2.h"
+#include "BsQuaternion.h"
+#include "BsSphere.h"
+#include "BsMaterial.h"
+#include "BsPass.h"
+#include "BsCoreApplication.h"
+#include "BsRenderQueue.h"
+#include "BsException.h"
+#include "BsCamera.h"
+#include "BsBuiltinResources.h"
+#include "BsVertexDataDesc.h"
+
+namespace BansheeEngine
+{
+	const UINT32 ShapeMeshes3D::NUM_VERTICES_AA_LINE = 8;
+	const UINT32 ShapeMeshes3D::NUM_INDICES_AA_LINE = 30;
+
+	inline UINT8* writeVector3(UINT8* buffer, UINT32 stride, const Vector3& value)
+	{
+		*(Vector3*)buffer = value;
+		return buffer + stride;
+	}
+
+	void ShapeMeshes3D::wireAABox(const AABox& box, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
+	{
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+
+		assert((vertexOffset + 8) <= meshData->getNumVertices());
+		assert((indexOffset + 24) <= meshData->getNumIndices());	
+
+		wireAABox(box, positionData, vertexOffset, meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset);
+	}
+
+	void ShapeMeshes3D::solidAABox(const AABox& box, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
+	{
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+		UINT8* normalData = meshData->getElementData(VES_NORMAL);
+
+		assert((vertexOffset + 24) <= meshData->getNumVertices());
+		assert((indexOffset + 36) <= meshData->getNumIndices());
+
+		solidAABox(box, positionData, normalData, vertexOffset, meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset);
+	}
+
+	void ShapeMeshes3D::wireSphere(const Sphere& sphere, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality)
+	{
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+
+		UINT32 requiredNumVertices, requiredNumIndices;
+		getNumElementsWireSphere(quality, requiredNumVertices, requiredNumIndices);
+
+		assert((vertexOffset + requiredNumVertices) <= meshData->getNumVertices());
+		assert((indexOffset + requiredNumIndices) <= meshData->getNumIndices());
+
+		UINT32 verticesPerArc = (quality + 1) * 5;
+		UINT32 indicesPerArc = (verticesPerArc - 1) * 2;
+
+		wireDisc(sphere.getCenter(), sphere.getRadius(), Vector3::UNIT_X, meshData,
+			vertexOffset, indexOffset, quality);
+
+		wireDisc(sphere.getCenter(), sphere.getRadius(), Vector3::UNIT_Y, meshData,
+			vertexOffset + verticesPerArc, indexOffset + indicesPerArc, quality);
+
+		wireDisc(sphere.getCenter(), sphere.getRadius(), Vector3::UNIT_Z, meshData,
+			vertexOffset + verticesPerArc * 2, indexOffset + indicesPerArc * 2, quality);
+	}
+
+	void ShapeMeshes3D::solidSphere(const Sphere& sphere, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality)
+	{
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+		UINT8* normalData = meshData->getElementData(VES_NORMAL);
+
+		UINT32 requiredNumVertices, requiredNumIndices;
+		getNumElementsSphere(quality, requiredNumVertices, requiredNumIndices);
+
+		assert((vertexOffset + requiredNumVertices) <= meshData->getNumVertices());
+		assert((indexOffset + requiredNumIndices) <= meshData->getNumIndices());
+
+		solidSphere(sphere, positionData, normalData, vertexOffset, 
+			meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset, quality);
+	}
+
+	void ShapeMeshes3D::wireDisc(const Vector3& center, float radius, const Vector3& normal, const MeshDataPtr& meshData,
+		UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality)
+	{
+		wireArc(center, radius, normal, Degree(0), Degree(360), meshData, vertexOffset, indexOffset, quality);
+	}
+
+	void ShapeMeshes3D::solidDisc(const Vector3& center, float radius, const Vector3& normal, const MeshDataPtr& meshData,
+		UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality)
+	{
+		solidArc(center, radius, normal, Degree(0), Degree(360), meshData, vertexOffset, indexOffset, quality);
+	}
+
+	void ShapeMeshes3D::wireArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
+		const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality)
+	{
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+
+		UINT32 requiredNumVertices, requiredNumIndices;
+		getNumElementsWireArc(quality, requiredNumVertices, requiredNumIndices);
+
+		assert((vertexOffset + requiredNumVertices) <= meshData->getNumVertices());
+		assert((indexOffset + requiredNumIndices) <= meshData->getNumIndices());
+
+		wireArc(center, radius, normal, startAngle, amountAngle, positionData, vertexOffset,
+			meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset, quality);
+	}
+
+	void ShapeMeshes3D::solidArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
+		const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality)
+	{
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+		UINT8* normalData = meshData->getElementData(VES_NORMAL);
+
+		UINT32 requiredNumVertices, requiredNumIndices;
+		getNumElementsArc(quality, requiredNumVertices, requiredNumIndices);
+
+		assert((vertexOffset + requiredNumVertices) <= meshData->getNumVertices());
+		assert((indexOffset + requiredNumIndices) <= meshData->getNumIndices());
+
+		solidArc(center, radius, normal, startAngle, amountAngle, positionData, normalData, vertexOffset,
+			meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset, quality);
+	}
+
+	void ShapeMeshes3D::wireFrustum(float aspect, Degree FOV, float near, float far,
+		const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
+	{
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+
+		assert((vertexOffset + 8) <= meshData->getNumVertices());
+		assert((indexOffset + 24) <= meshData->getNumIndices());
+
+		wireFrustum(aspect, FOV, near, far, positionData, vertexOffset, meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset);
+	}
+
+	void ShapeMeshes3D::solidCone(const Vector3& base, const Vector3& normal, float height, float radius,
+		const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality)
+	{
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+		UINT8* normalData = meshData->getElementData(VES_NORMAL);
+
+		UINT32 requiredNumVertices, requiredNumIndices;
+		getNumElementsCone(quality, requiredNumVertices, requiredNumIndices);
+
+		assert((vertexOffset + requiredNumVertices) <= meshData->getNumVertices());
+		assert((indexOffset + requiredNumIndices) <= meshData->getNumIndices());
+
+		solidCone(base, normal, height, radius, positionData, normalData, vertexOffset,
+			meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset, quality);
+	}
+
+	void ShapeMeshes3D::solidQuad(const Rect3& area, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
+	{
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+		UINT8* normalData = meshData->getElementData(VES_NORMAL);
+
+		assert((vertexOffset + 4) <= meshData->getNumVertices());
+		assert((indexOffset + 6) <= meshData->getNumIndices());
+
+		solidQuad(area, positionData, normalData, vertexOffset,
+			meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset);
+	}
+
+	void ShapeMeshes3D::pixelLine(const Vector3& a, const Vector3& b, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
+	{
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+
+		assert((vertexOffset + 2) <= meshData->getNumVertices());
+		assert((indexOffset + 2) <= meshData->getNumIndices());
+
+		pixelLine(a, b, positionData, vertexOffset, meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset);
+	}
+
+	void ShapeMeshes3D::antialiasedLine(const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, 
+		const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
+	{
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+		UINT8* colorData = meshData->getElementData(VES_COLOR);
+
+		assert((vertexOffset + NUM_VERTICES_AA_LINE) <= meshData->getNumVertices());
+		assert((indexOffset + NUM_INDICES_AA_LINE) <= meshData->getNumIndices());
+
+		antialiasedLine(a, b, up, width, borderWidth, color, positionData, colorData, vertexOffset, meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset);
+	}
+
+	void ShapeMeshes3D::pixelLineList(const Vector<Vector3>& linePoints, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
+	{
+		assert(linePoints.size() % 2 == 0);
+
+		assert((vertexOffset + linePoints.size() * 2) <= meshData->getNumVertices());
+		assert((indexOffset + linePoints.size() * 2) <= meshData->getNumIndices());
+
+		UINT32 curVertOffset = vertexOffset;
+		UINT32 curIdxOffset = indexOffset;
+
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+
+		UINT32 numPoints = (UINT32)linePoints.size();
+		for (UINT32 i = 0; i < numPoints; i += 2)
+		{
+			pixelLine(linePoints[i], linePoints[i + 1], positionData, curVertOffset, meshData->getVertexDesc()->getVertexStride(), indexData, curIdxOffset);
+
+			curVertOffset += 2;
+			curIdxOffset += 2;
+		}
+	}
+
+	void ShapeMeshes3D::antialiasedLineList(const Vector<Vector3>& linePoints, const Vector3& up, float width, float borderWidth, 
+		const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
+	{
+		assert(linePoints.size() % 2 == 0);
+
+		assert((vertexOffset + linePoints.size() * 4) <= meshData->getNumVertices());
+		assert((indexOffset + linePoints.size() * 15) <= meshData->getNumIndices());
+
+		UINT32 curVertOffset = vertexOffset;
+		UINT32 curIdxOffset = indexOffset;
+
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+		UINT8* colorData = meshData->getElementData(VES_COLOR);
+
+		UINT32 numPoints = (UINT32)linePoints.size();
+		for (UINT32 i = 0; i < numPoints; i += 2)
+		{
+			antialiasedLine(linePoints[i], linePoints[i + 1], up, width, borderWidth, color, positionData, colorData, curVertOffset, meshData->getVertexDesc()->getVertexStride(), indexData, curIdxOffset);
+
+			curVertOffset += NUM_VERTICES_AA_LINE;
+			curIdxOffset += NUM_INDICES_AA_LINE;
+		}
+	}
+
+	/************************************************************************/
+	/* 								ELEMENT COUNT                      		*/
+	/************************************************************************/
+
+	void ShapeMeshes3D::getNumElementsSphere(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
+	{
+		numVertices = 20 * (4 * ((UINT32)std::pow(3, quality)));
+		numIndices = numVertices;
+	}
+
+	void ShapeMeshes3D::getNumElementsWireSphere(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
+	{
+		numVertices = 3 * ((quality + 1) * 4);
+		numIndices = 6 * ((quality + 1) * 4);
+	}
+
+	void ShapeMeshes3D::getNumElementsArc(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
+	{
+		numVertices = (quality + 1) * 5 + 1;
+		numIndices = ((quality + 1) * 5 - 1) * 3;
+	}
+
+	void ShapeMeshes3D::getNumElementsWireArc(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
+	{
+		numVertices = (quality + 1) * 5;
+		numIndices = ((quality + 1) * 5 - 1) * 2;
+	}
+
+	void ShapeMeshes3D::getNumElementsDisc(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
+	{
+		getNumElementsArc(quality, numVertices, numIndices);
+	}
+
+	void ShapeMeshes3D::getNumElementsWireDisc(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
+	{
+		getNumElementsWireArc(quality, numVertices, numIndices);
+	}
+
+	void ShapeMeshes3D::getNumElementsCone(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
+	{
+		numVertices = ((quality + 1) * 4 + 1) * 2;
+		numIndices = ((quality + 1) * 4 - 1) * 6;
+	}
+
+	void ShapeMeshes3D::wireAABox(const AABox& box, UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
+	{
+		outVertices += vertexOffset * vertexStride;
+
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_LEFT_BOTTOM));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_RIGHT_BOTTOM));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_RIGHT_TOP));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_LEFT_TOP));
+
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_RIGHT_BOTTOM));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_LEFT_BOTTOM));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_LEFT_TOP));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_RIGHT_TOP));
+
+		outIndices += indexOffset;
+
+		// Front
+		outIndices[0] = vertexOffset + 0;
+		outIndices[1] = vertexOffset + 1;
+
+		outIndices[2] = vertexOffset + 1;
+		outIndices[3] = vertexOffset + 2;
+
+		outIndices[4] = vertexOffset + 2;
+		outIndices[5] = vertexOffset + 3;
+
+		outIndices[6] = vertexOffset + 3;
+		outIndices[7] = vertexOffset + 0;
+
+		// Center
+		outIndices[8] = vertexOffset + 0;
+		outIndices[9] = vertexOffset + 5;
+
+		outIndices[10] = vertexOffset + 1;
+		outIndices[11] = vertexOffset + 4;
+
+		outIndices[12] = vertexOffset + 2;
+		outIndices[13] = vertexOffset + 7;
+
+		outIndices[14] = vertexOffset + 3;
+		outIndices[15] = vertexOffset + 6;
+
+		// Back
+		outIndices[16] = vertexOffset + 4;
+		outIndices[17] = vertexOffset + 5;
+
+		outIndices[18] = vertexOffset + 5;
+		outIndices[19] = vertexOffset + 6;
+
+		outIndices[20] = vertexOffset + 6;
+		outIndices[21] = vertexOffset + 7;
+
+		outIndices[22] = vertexOffset + 7;
+		outIndices[23] = vertexOffset + 4;
+	}
+
+	void ShapeMeshes3D::solidAABox(const AABox& box, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride,
+		UINT32* outIndices, UINT32 indexOffset)
+	{
+		outVertices += (vertexOffset * vertexStride);
+		Vector3* corners = (Vector3*)outVertices;
+
+		// Front face
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_LEFT_BOTTOM));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_RIGHT_BOTTOM));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_RIGHT_TOP));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_LEFT_TOP));
+
+		// Back face
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_RIGHT_BOTTOM));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_LEFT_BOTTOM));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_LEFT_TOP));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_RIGHT_TOP));
+
+		// Left face
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_LEFT_BOTTOM));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_LEFT_BOTTOM));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_LEFT_TOP));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_LEFT_TOP));
+
+		// Right face
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_RIGHT_BOTTOM));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_RIGHT_BOTTOM));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_RIGHT_TOP));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_RIGHT_TOP));
+
+		// Top face
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_LEFT_TOP));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_LEFT_TOP));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_RIGHT_TOP));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_RIGHT_TOP));
+
+		// Bottom face
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_LEFT_TOP));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_LEFT_TOP));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::NEAR_RIGHT_TOP));
+		outVertices = writeVector3(outVertices, vertexStride, box.getCorner(AABox::FAR_RIGHT_TOP));
+
+		static const Vector3 faceNormals[6] = 
+		{
+			Vector3(0, 0, 1),
+			Vector3(0, 0, -1),
+			Vector3(0, 1, 0),
+			Vector3(0, -1, 0),
+			Vector3(1, 0, 0),
+			Vector3(-1, 0, 0)
+		};
+
+		outNormals += (vertexOffset + vertexStride);
+		for (UINT32 face = 0; face < 6; face++)
+		{
+			outNormals = writeVector3(outNormals, vertexStride, faceNormals[face]);
+			outNormals = writeVector3(outNormals, vertexStride, faceNormals[face]);
+			outNormals = writeVector3(outNormals, vertexStride, faceNormals[face]);
+			outNormals = writeVector3(outNormals, vertexStride, faceNormals[face]);
+		}
+
+		UINT32* indices = outIndices + indexOffset;
+		for (UINT32 face = 0; face < 6; face++)
+		{
+			UINT32 faceVertOffset = vertexOffset + face * 4;
+
+			indices[face * 6 + 0] = faceVertOffset + 0;
+			indices[face * 6 + 1] = faceVertOffset + 1;
+			indices[face * 6 + 2] = faceVertOffset + 2;
+			indices[face * 6 + 3] = faceVertOffset + 2;
+			indices[face * 6 + 3] = faceVertOffset + 3;
+			indices[face * 6 + 3] = faceVertOffset + 0;
+		}
+	}
+
+	void ShapeMeshes3D::solidSphere(const Sphere& sphere, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, 
+		UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality)
+	{
+		// Create icosahedron
+		static const float x = 0.525731112119133606f;
+		static const float z = 0.850650808352039932f;
+
+		static const Vector3 vertices[12] = 
+		{
+			Vector3(-x,		0.0f,	z),
+			Vector3(x,		0.0f,	z),
+			Vector3(-x,		0.0f,	-z),
+			Vector3(x,		0.0f,	-z),
+			Vector3(0.0f,	z,		x),
+			Vector3(0.0f,	z,		-x),
+			Vector3(0.0f,	-z,		x),
+			Vector3(0.0f,	-z,		-x),
+			Vector3(z,		x,		0.0f),
+			Vector3(-z,		x,		0.0f),
+			Vector3(z,		-x,		0.0f),
+			Vector3(-z,		-x,		0.0f)
+		};
+
+		static const UINT32 triangles[20][3] = 
+		{
+				{ 0, 4, 1 },  { 0, 9, 4 },	{ 9, 5, 4 },	{ 4, 5, 8 },
+				{ 4, 8, 1 },  { 8, 10, 1 }, { 8, 3, 10 },	{ 5, 3, 8 },
+				{ 5, 2, 3 },  { 2, 7, 3 },	{ 7, 10, 3 },	{ 7, 6, 10 },
+				{ 7, 11, 6 }, { 11, 0, 6 }, { 0, 1, 6 },	{ 6, 1, 10 },
+				{ 9, 0, 11 }, { 9, 11, 2 }, { 9, 2, 5 },	{ 7, 2, 11 }
+		};
+
+		// Tessellate it
+		UINT32 curVertOffset = vertexOffset;
+		for (int i = 0; i < 20; ++i) 
+		{
+			curVertOffset += subdivideTriangleOnSphere(sphere.getCenter(), sphere.getRadius(), quality,
+				vertices[triangles[i][0]], vertices[triangles[i][1]], vertices[triangles[i][2]],
+				outVertices, outNormals, curVertOffset, vertexStride);
+		}
+
+		// Create indices
+		outIndices += indexOffset;
+
+		UINT32 numTriangles = 20 * (3 * ((UINT32)std::pow(4L, (long)quality)));
+		for (UINT32 i = 0; i < numTriangles * 3; i += 3)
+		{
+			outIndices[i] = vertexOffset + i;
+			outIndices[i + 1] = vertexOffset + i + 1;
+			outIndices[i + 2] = vertexOffset + i + 2;
+		}
+	}
+
+	void ShapeMeshes3D::wireArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle, 
+		UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality)
+	{
+		UINT32 numVertices = (quality + 1) * 5;
+
+		generateArcVertices(center, normal, radius, startAngle, amountAngle,
+			numVertices, outVertices, vertexOffset, vertexStride);
+
+		outIndices += indexOffset;
+		UINT32 numLines = numVertices - 1;
+		for (UINT32 i = 0; i < numLines; i++)
+		{
+			outIndices[i * 2 + 0] = vertexOffset + i;
+			outIndices[i * 2 + 1] = vertexOffset + i + 1;
+		}
+	}
+
+	void ShapeMeshes3D::solidArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle, 
+		UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality)
+	{
+		Vector3* centerVertex = (Vector3*)(outVertices + (vertexOffset * vertexStride));
+		*centerVertex = center;
+
+		UINT32 numArcVertices = (quality + 1) * 5;
+		generateArcVertices(center, normal, radius, startAngle, amountAngle,
+			numArcVertices, outVertices, vertexOffset + 1, vertexStride);
+
+		UINT32 totalNumVertices = numArcVertices + 1;
+		outNormals += vertexOffset * vertexStride;
+		for (UINT32 i = 0; i < totalNumVertices; i++)
+		{
+			outNormals = writeVector3(outNormals, vertexStride, normal);
+		}
+
+		outIndices += indexOffset;
+		UINT32 numTriangles = numArcVertices - 1;
+		for (UINT32 i = 0; i < numTriangles; i++)
+		{
+			outIndices[i * 3 + 0] = vertexOffset + 0;
+			outIndices[i * 3 + 1] = vertexOffset + i;
+			outIndices[i * 3 + 2] = vertexOffset + i + 1;
+		}
+	}
+
+	void ShapeMeshes3D::wireFrustum(float aspect, Degree FOV, float near, float far,
+		UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
+	{
+		float fovTan = Math::tan(FOV);
+
+		Vector3 nearPoint(0, 0, near);
+		Vector3 nearWidth(near * fovTan * aspect, 0, 0);
+		Vector3 nearHeight(0, (near * fovTan) / aspect, 0);
+
+		Vector3 farPoint(0, 0, far);
+		Vector3 farWidth(far * fovTan * aspect, 0, 0);
+		Vector3 farHeight(0, (far * fovTan) / aspect, 0);
+
+		Vector3 points[8] = 
+		{
+			nearPoint + nearWidth + nearHeight,
+			nearPoint - nearWidth + nearHeight,
+			nearPoint - nearWidth - nearHeight,
+			nearPoint + nearWidth - nearHeight,
+			farPoint + farWidth + farHeight,
+			farPoint - farWidth + farHeight,
+			farPoint - farWidth - farHeight,
+			farPoint + farWidth - farHeight
+		};
+
+		outVertices += vertexOffset * vertexStride;
+
+		for (UINT32 i = 0; i < 8; i++)
+			outVertices = writeVector3(outVertices, vertexStride, points[i]);
+
+		outIndices += indexOffset;
+
+		// Front
+		outIndices[0] = vertexOffset + 0; outIndices[1] = vertexOffset + 1;
+		outIndices[2] = vertexOffset + 1; outIndices[3] = vertexOffset + 2;
+		outIndices[4] = vertexOffset + 2; outIndices[5] = vertexOffset + 3;
+		outIndices[6] = vertexOffset + 3; outIndices[7] = vertexOffset + 0;
+
+		// Center
+		outIndices[8] = vertexOffset + 0; outIndices[9] = vertexOffset + 4;
+		outIndices[10] = vertexOffset + 1; outIndices[11] = vertexOffset + 5;
+		outIndices[12] = vertexOffset + 2; outIndices[13] = vertexOffset + 6;
+		outIndices[14] = vertexOffset + 3; outIndices[15] = vertexOffset + 7;
+
+		// Back
+		outIndices[16] = vertexOffset + 4; outIndices[17] = vertexOffset + 5;
+		outIndices[18] = vertexOffset + 5; outIndices[19] = vertexOffset + 6;
+		outIndices[20] = vertexOffset + 6; outIndices[21] = vertexOffset + 7;
+		outIndices[22] = vertexOffset + 7; outIndices[23] = vertexOffset + 4;
+	}
+
+	void ShapeMeshes3D::solidCone(const Vector3& base, const Vector3& normal, float height, float radius,
+		UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality)
+	{
+		outVertices += vertexOffset * vertexStride;
+		outNormals += vertexOffset * vertexStride;
+		outIndices += indexOffset;
+
+		// Generate base disc
+		UINT32 numArcVertices = (quality + 1) * 4;
+
+		generateArcVertices(base, normal, radius, Degree(0), Degree(360),
+			numArcVertices + 1, outVertices, 0, vertexStride);
+
+		outVertices += numArcVertices * vertexStride;
+		outVertices = writeVector3(outVertices, vertexStride, base); // Write base vertex
+
+		UINT32 baseIdx = numArcVertices;
+
+		UINT32 totalNumBaseVertices = numArcVertices + 1;
+		for (UINT32 i = 0; i < totalNumBaseVertices; i++)
+		{
+			outNormals = writeVector3(outNormals, vertexStride, -normal);
+		}
+
+		UINT32 numTriangles = numArcVertices;
+		for (UINT32 i = 0; i < numTriangles; i++)
+		{
+			outIndices[i * 3 + 0] = vertexOffset + baseIdx;
+			outIndices[i * 3 + 1] = vertexOffset + i;
+			outIndices[i * 3 + 2] = vertexOffset + i + 1;
+		}
+
+		// Generate cone
+		generateArcVertices(base, normal, radius, Degree(0), Degree(360),
+			numArcVertices + 1, outVertices, 0, vertexStride);
+
+		Vector3 topVertex = base + normal * height;
+
+		UINT32 totalNumConeVertices = numArcVertices;
+		for (UINT32 i = 0; i < totalNumConeVertices; i++)
+		{
+			int offsetA = i;
+			int offsetB = (i + 1) % totalNumConeVertices;
+
+			Vector3* a = (Vector3*)(outVertices + (offsetA * vertexStride));
+			Vector3* b = (Vector3*)(outVertices + (offsetB * vertexStride));
+
+			Vector3 triNormal = *a - topVertex;
+			triNormal = triNormal.cross(*b - topVertex);
+			triNormal.normalize();
+
+			outNormals = writeVector3(outNormals, vertexStride, triNormal); // TODO - Smooth normals?
+		}
+
+		*(Vector3*)outNormals = normal;
+
+		outVertices += numArcVertices * vertexStride;
+		outVertices = writeVector3(outVertices, vertexStride, topVertex); // Write top vertex
+		UINT32 topIdx = numArcVertices * 2 + 2;
+
+		outIndices += numTriangles * 3;
+		UINT32 curVertOffset = vertexOffset + numArcVertices + 1;
+		for (UINT32 i = 0; i < numTriangles; i++)
+		{
+			outIndices[i * 3 + 0] = curVertOffset + topIdx;
+			outIndices[i * 3 + 1] = curVertOffset + i;
+			outIndices[i * 3 + 2] = curVertOffset + i + 1;
+		}
+	}
+
+	void ShapeMeshes3D::solidQuad(const Rect3& area, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
+	{
+		outVertices += (vertexOffset * vertexStride);
+
+		Vector3 topLeft = area.getCenter() - area.getAxisHorz() * area.getExtentHorz() + area.getAxisVert() * area.getExtentVertical();
+		Vector3 topRight = area.getCenter() + area.getAxisHorz() * area.getExtentHorz() + area.getAxisVert() * area.getExtentVertical();
+		Vector3 botRight = area.getCenter() + area.getAxisHorz() * area.getExtentHorz() - area.getAxisVert() * area.getExtentVertical();
+		Vector3 botLeft = area.getCenter() - area.getAxisHorz() * area.getExtentHorz() - area.getAxisVert() * area.getExtentVertical();
+
+		outVertices = writeVector3(outVertices, vertexStride, topLeft);
+		outVertices = writeVector3(outVertices, vertexStride, topRight);
+		outVertices = writeVector3(outVertices, vertexStride, botRight);
+		outVertices = writeVector3(outVertices, vertexStride, botLeft);
+
+		Vector3 normal = area.getAxisHorz().cross(area.getAxisVert());
+
+		outNormals += (vertexOffset + vertexStride);
+		outNormals = writeVector3(outNormals, vertexStride, normal);
+		outNormals = writeVector3(outNormals, vertexStride, normal);
+		outNormals = writeVector3(outNormals, vertexStride, normal);
+		outNormals = writeVector3(outNormals, vertexStride, normal);
+
+		outIndices += indexOffset;
+		outIndices[0] = vertexOffset;
+		outIndices[1] = vertexOffset + 1;
+		outIndices[2] = vertexOffset + 2;
+
+		outIndices[3] = vertexOffset;
+		outIndices[4] = vertexOffset + 2;
+		outIndices[5] = vertexOffset + 3;
+	}
+
+	Vector3 ShapeMeshes3D::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 ShapeMeshes3D::pixelLine(const Vector3& a, const Vector3& b, UINT8* outVertices,
+		UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
+	{
+		outVertices += (vertexOffset * vertexStride);
+
+		Vector3* vertices = (Vector3*)outVertices;
+		(*vertices) = a;
+
+		vertices = (Vector3*)(outVertices + vertexStride);
+		(*vertices) = b;
+
+		outIndices += indexOffset;
+		outIndices[0] = vertexOffset + 0;
+		outIndices[1] = vertexOffset + 1;
+	}
+
+	void ShapeMeshes3D::antialiasedLine(const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors,
+		UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
+	{
+		Vector3 dir = b - a;
+		dir.normalize();
+
+		Vector3 right = dir.cross(up);
+		right.normalize();
+
+		Vector<Vector3> points(4);
+
+		float r = width * 0.5f;
+		dir = dir * r;
+		right = right * r;
+
+		Vector3 v0 = a - dir - right;
+		Vector3 v1 = a - dir + right;
+		Vector3 v2 = b + dir + right;
+		Vector3 v3 = b + dir - right;
+
+		points[0] = v0;
+		points[1] = v1;
+		points[2] = v2;
+		points[3] = v3;
+
+		antialiasedPolygon(points, up, borderWidth, color, outVertices, outColors, vertexOffset, vertexStride, outIndices, indexOffset);
+	}
+
+	void ShapeMeshes3D::pixelSolidPolygon(const Vector<Vector3>& points, UINT8* outVertices,
+		UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
+	{
+		outVertices += (vertexOffset * vertexStride);
+
+		for (auto& point : points)
+		{
+			Vector3* vertices = (Vector3*)outVertices;
+			(*vertices) = point;
+
+			outVertices += vertexStride;
+		}
+
+		outIndices += indexOffset;
+		INT32 numPoints = (INT32)points.size();
+		UINT32 idxCnt = 0;
+		for (int i = 2; i < numPoints; i++)
+		{
+			outIndices[idxCnt++] = vertexOffset;
+			outIndices[idxCnt++] = vertexOffset + i - 1;
+			outIndices[idxCnt++] = vertexOffset + i;
+		}
+	}
+
+	void ShapeMeshes3D::pixelWirePolygon(const Vector<Vector3>& points, UINT8* outVertices,
+		UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
+	{
+		INT32 numPoints = (INT32)points.size();
+		UINT32 curVertOffset = vertexOffset;
+		UINT32 curIdxOffset = indexOffset;
+		for (INT32 i = 0, j = numPoints - 1; i < numPoints; j = i++)
+		{
+			pixelLine(points[j], points[i], outVertices, curVertOffset, vertexStride, outIndices, curIdxOffset);
+			curVertOffset += 2;
+			curIdxOffset += 2;
+		}
+	}
+
+	void ShapeMeshes3D::antialiasedPolygon(const Vector<Vector3>& points, const Vector3& up, 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;
+		outColors += vertexOffset * vertexStride;
+		Vector<Vector3> tempNormals(numCoords);
+
+		for (UINT32 i = 0, j = numCoords - 1; i < numCoords; j = i++)
+		{
+			const Vector3& v0 = points[j];
+			const Vector3& v1 = points[i];
+
+			Vector3 dir = v1 - v0;
+			Vector3 right = dir.cross(up);
+			right.normalize();
+
+			tempNormals[j] = right;
+
+			// Also start populating the vertex array
+			Vector3* vertices = (Vector3*)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 Vector3& n0 = tempNormals[j];
+			const Vector3& n1 = tempNormals[i];
+
+			Vector3 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;
+			}
+
+			Vector3 tempCoord = points[i] + avgNrm * borderWidth;
+
+			// Move it to the vertex array
+			Vector3* vertices = (Vector3*)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++] = vertexOffset + i;
+			outIndices[idxCnt++] = vertexOffset + j;
+			outIndices[idxCnt++] = vertexOffset + numCoords + j;
+
+			outIndices[idxCnt++] = vertexOffset + numCoords + j;
+			outIndices[idxCnt++] = vertexOffset + numCoords + i;
+			outIndices[idxCnt++] = vertexOffset + i;
+		}
+
+		for (UINT32 i = 2; i < numCoords; ++i)
+		{
+			outIndices[idxCnt++] = vertexOffset + 0;
+			outIndices[idxCnt++] = vertexOffset + i - 1;
+			outIndices[idxCnt++] = vertexOffset + i;
+		}
+	}
+
+	UINT32 ShapeMeshes3D::subdivideTriangleOnSphere(const Vector3& center, float radius, UINT32 numLevels,
+		const Vector3& a, const Vector3& b, const Vector3& c,
+		UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride)
+	{
+		outVertices += (vertexOffset * vertexStride);
+		outNormals += (vertexOffset * vertexStride);
+
+		UINT32 numVertices = 0;
+
+		if (numLevels > 0)
+		{
+			Vector3 sub1 = Vector3::normalize((a + b) * 0.5f);
+			Vector3 sub2 = Vector3::normalize((b + c) * 0.5f);
+			Vector3 sub3 = Vector3::normalize((c + a) * 0.5f);
+
+			numLevels--;
+			UINT32 curVertOffset = vertexOffset + numVertices;
+
+			numVertices += subdivideTriangleOnSphere(center, radius, numLevels, a, sub1, sub3, outVertices, 
+				outNormals, vertexOffset + numVertices, vertexStride);
+			numVertices += subdivideTriangleOnSphere(center, radius, numLevels, sub1, b, sub2, outVertices, 
+				outNormals, vertexOffset + numVertices, vertexStride);
+			numVertices += subdivideTriangleOnSphere(center, radius, numLevels, sub1, sub2, sub3, outVertices, 
+				outNormals, vertexOffset + numVertices, vertexStride);
+			numVertices += subdivideTriangleOnSphere(center, radius, numLevels, sub3, sub2, c, outVertices, 
+				outNormals, vertexOffset + numVertices, vertexStride);
+		}
+		else
+		{
+			*((Vector3*)outVertices) = center + a * radius;
+			*((Vector3*)outNormals) = a;
+
+			outVertices += vertexStride;
+			outNormals += vertexStride;
+
+			*((Vector3*)outVertices) = center + b * radius;
+			*((Vector3*)outNormals) = b;
+
+			outVertices += vertexStride;
+			outNormals += vertexStride;
+
+			*((Vector3*)outVertices) = center + c * radius;
+			*((Vector3*)outNormals) = c;
+
+			outVertices += vertexStride;
+			outNormals += vertexStride;
+
+			numVertices += 3;
+		}
+
+		return numVertices;
+	}
+
+	void ShapeMeshes3D::generateArcVertices(const Vector3& center, const Vector3& up, float radius, Degree startAngle, Degree angleAmount, UINT32 numVertices,
+		UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride)
+	{
+		assert(numVertices >= 2);
+
+		Vector3 normalizedUp = Vector3::normalize(up);
+		Vector3 right;
+
+		if (Math::abs(normalizedUp.dot(Vector3::UNIT_Z)) <= 0.95f)
+			right = normalizedUp.cross(Vector3::UNIT_Z);
+		else
+			right = normalizedUp.cross(Vector3::UNIT_Y);
+
+		right.normalize();
+		Quaternion moveToStart(up, startAngle);
+		Vector3 start = moveToStart.rotate(right);
+
+		Quaternion increment(up, angleAmount / (float)(numVertices - 1));
+
+		outVertices += vertexOffset * vertexStride;
+		Vector3 curDirection = start * radius;
+		for (UINT32 i = 0; i < numVertices; i++)
+		{
+			outVertices = writeVector3(outVertices, vertexStride, center + curDirection);
+			curDirection = increment.rotate(curDirection);
+		}
+	}
 }

+ 0 - 6
BansheeRenderer/Source/BsBansheeRenderer.cpp

@@ -14,8 +14,6 @@
 #include "BsRenderTarget.h"
 #include "BsRenderQueue.h"
 #include "BsOverlayManager.h"
-#include "BsDrawHelper2D.h"
-#include "BsDrawHelper3D.h"
 #include "BsGUIManager.h"
 #include "BsCoreThread.h"
 #include "BsGpuParams.h"
@@ -333,10 +331,6 @@ namespace BansheeEngine
 			// Get overlay render operations
 			OverlayManager::instance().render(camera->getViewport(), *drawList);
 
-			// Get debug render operations
-			DrawHelper3D::instance().render(camera, *drawList);
-			DrawHelper2D::instance().render(camera, *drawList);
-
 			// Get any operations from hooked up callbacks
 			const Viewport* viewportRawPtr = camera->getViewport().get();
 			onRenderViewport(viewportRawPtr, *drawList);