Explorar o código

Better scene grid shader/rendering + selection rendering

Marko Pintera %!s(int64=10) %!d(string=hai) anos
pai
achega
3270121b9d

+ 2 - 0
BansheeEditor/BansheeEditor.vcxproj

@@ -341,6 +341,7 @@
     <ClInclude Include="Include\BsSceneGrid.h" />
     <ClInclude Include="Include\BsSceneViewHandler.h" />
     <ClInclude Include="Include\BsSelection.h" />
+    <ClInclude Include="Include\BsSelectionRenderer.h" />
     <ClInclude Include="Include\BsTestTextSprite.h" />
     <ClInclude Include="Include\DbgEditorWidget1.h" />
     <ClInclude Include="Include\DbgEditorWidget2.h" />
@@ -410,6 +411,7 @@
     <ClCompile Include="Source\BsSceneGrid.cpp" />
     <ClCompile Include="Source\BsSceneViewHandler.cpp" />
     <ClCompile Include="Source\BsSelection.cpp" />
+    <ClCompile Include="Source\BsSelectionRenderer.cpp" />
     <ClCompile Include="Source\BsUndoRedo.cpp" />
     <ClCompile Include="Source\BsEditorApplication.cpp" />
     <ClCompile Include="Source\BsTestTextSprite.cpp" />

+ 6 - 0
BansheeEditor/BansheeEditor.vcxproj.filters

@@ -273,6 +273,9 @@
     <ClInclude Include="Include\BsBuildDataRTTI.h">
       <Filter>Header Files\Editor\RTTI</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsSelectionRenderer.h">
+      <Filter>Header Files\Editor</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsEditorWidgetContainer.cpp">
@@ -479,5 +482,8 @@
     <ClCompile Include="Source\BsPlatformInfo.cpp">
       <Filter>Source Files\Editor</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsSelectionRenderer.cpp">
+      <Filter>Source Files\Editor</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 13 - 0
BansheeEditor/Include/BsBuiltinEditorResources.h

@@ -69,6 +69,11 @@ namespace BansheeEngine
 		 */
 		HMaterial createSolidHandleMat() const;
 
+		/**
+		 * @brief	Creates a material used for displaying selected objects.
+		 */
+		HMaterial createSelectionMat() const;
+
 		static const String ObjectFieldStyleName;
 		static const String ObjectFieldLabelStyleName;
 		static const String ObjectFieldDropBtnStyleName;
@@ -155,6 +160,11 @@ namespace BansheeEngine
 		 */
 		void initSolidHandleShader();
 
+		/**
+		 * @brief	Loads and compiles a shader used for displaying selected objects.
+		 */
+		void initSelectionShader();
+
 		RenderSystemPlugin mRenderSystemPlugin;
 		WString mActiveShaderSubFolder;
 		String mActiveRenderSystem;
@@ -170,6 +180,7 @@ namespace BansheeEngine
 		HShader mShaderGizmoAlphaPicking;
 		HShader mShaderHandleSolid;
 		HShader mShaderHandleWire;
+		HShader mShaderSelection;
 
 		GUISkin mSkin;
 
@@ -332,5 +343,7 @@ namespace BansheeEngine
 		static const WString GizmoPickingPSFile;
 		static const WString GizmoPickingAlphaVSFile;
 		static const WString GizmoPickingAlphaPSFile;
+		static const WString SelectionVSFile;
+		static const WString SelectionPSFile;
 	};
 }

+ 1 - 0
BansheeEditor/Include/BsEditorPrerequisites.h

@@ -66,6 +66,7 @@ namespace BansheeEngine
 	class SceneCameraController;
 	class EditorSettings;
 	class SceneViewHandler;
+	class SelectionRenderer;
 
 	typedef std::shared_ptr<ProjectResourceMeta> ProjectResourceMetaPtr;
 	typedef std::shared_ptr<DockManagerLayout> DockManagerLayoutPtr;

+ 9 - 0
BansheeEditor/Include/BsSceneGrid.h

@@ -28,6 +28,12 @@ namespace BansheeEngine
 		HMesh mGridMesh;
 		HMaterial mGridMaterial;
 		MaterialParamMat4 mViewProjParam;
+		MaterialParamVec4 mWorldCameraPosParam;
+		MaterialParamColor mGridColorParam;
+		MaterialParamFloat mGridSpacingParam;
+		MaterialParamFloat mGridBorderWidthParam;
+		MaterialParamFloat mGridFadeOutStartParam;
+		MaterialParamFloat mGridFadeOutEndParam;
 		VertexDataDescPtr mVertexDesc;
 
 		EditorSettingsPtr mSettings;
@@ -39,6 +45,7 @@ namespace BansheeEngine
 		UINT32 mMajorAxisSpacing = 10;
 		UINT32 mAxisMarkerSpacing = 25;
 
+		static const Color GRID_LINE_COLOR;
 		static const float LINE_WIDTH;
 		static const float LINE_BORDER_WIDTH;
 		static const float MAJOR_AXIS_WIDTH;
@@ -47,5 +54,7 @@ namespace BansheeEngine
 		static const float AXIS_MARKER_BORDER_WIDTH;
 		static const Color AXIS_X_MARKER_COLOR;
 		static const Color AXIS_Z_MARKER_COLOR;
+		static const float FADE_OUT_START;
+		static const float FADE_OUT_END;
 	};
 }

+ 1 - 0
BansheeEditor/Include/BsSceneViewHandler.h

@@ -27,6 +27,7 @@ namespace BansheeEngine
 		EditorWidgetBase* mParentWidget;
 		SPtr<CameraHandler> mCamera;
 		SceneGrid* mSceneGrid;
+		SelectionRenderer* mSelectionRenderer;
 		HEvent mRenderCallback;
 
 		Vector2I mMouseDeltaCompensate;

+ 60 - 0
BansheeEditor/Include/BsSelectionRenderer.h

@@ -0,0 +1,60 @@
+#pragma once
+
+#include "BsEditorPrerequisites.h"
+#include "BsColor.h"
+#include "BsMatrix4.h"
+#include "BsGpuParam.h"
+
+namespace BansheeEngine
+{
+	class SelectionRendererCore;
+
+	class SelectionRenderer
+	{
+		struct ObjectData
+		{
+			SPtr<MeshCoreBase> mesh;
+			Matrix4 worldTfrm;
+		};
+
+	public:
+		SelectionRenderer();
+		~SelectionRenderer();
+
+		void update(const CameraHandlerPtr& camera);
+
+	private:
+		friend class SelectionRendererCore;
+
+		void initializeCore(const SPtr<MaterialCore>& mat);
+		void destroyCore(SelectionRendererCore* core);
+
+		SelectionRendererCore* mCore;
+	};
+
+	class SelectionRendererCore
+	{
+		friend class SelectionRenderer;
+		
+		struct PrivatelyConstuct { };
+
+	public:
+		SelectionRendererCore(const PrivatelyConstuct& dummy);
+
+	private:
+		void initialize(const SPtr<MaterialCore>& mat);
+
+		void render(const CameraHandlerCore& camera);
+		void updateData(const SPtr<RenderTargetCore>& rt, const Vector<SelectionRenderer::ObjectData>& objects);
+
+		SPtr<RenderTargetCore> mSceneRenderTarget;
+		Vector<SelectionRenderer::ObjectData> mObjects;
+
+		// Immutable
+		SPtr<MaterialCore> mMaterial;
+		GpuParamMat4Core mMatWorldViewProj;
+		GpuParamColorCore mColor;
+
+		static const Color SELECTION_COLOR;
+	};
+}

+ 63 - 2
BansheeEditor/Source/BsBuiltinEditorResources.cpp

@@ -219,6 +219,8 @@ namespace BansheeEngine
 	const WString BuiltinEditorResources::GizmoPickingPSFile = L"pickingGizmoPS.gpuprog";
 	const WString BuiltinEditorResources::GizmoPickingAlphaVSFile = L"pickingGizmoAlphaVS.gpuprog";
 	const WString BuiltinEditorResources::GizmoPickingAlphaPSFile = L"pickingGizmoAlphaPS.gpuprog";
+	const WString BuiltinEditorResources::SelectionVSFile = L"selectionVS.gpuprog";
+	const WString BuiltinEditorResources::SelectionPSFile = L"selectionPS.gpuprog";
 
 	BuiltinEditorResources::BuiltinEditorResources(RenderSystemPlugin activeRSPlugin)
 		:mRenderSystemPlugin(activeRSPlugin)
@@ -256,6 +258,7 @@ namespace BansheeEngine
 		initGizmoPickingAlphaShader();
 		initWireHandleShader();
 		initSolidHandleShader();
+		initSelectionShader();
 
 		Path fontPath = FileSystem::getWorkingDirectoryPath();
 		fontPath.append(DefaultSkinFolder);
@@ -1211,6 +1214,8 @@ namespace BansheeEngine
 			{ GizmoPickingPSFile,		"ps_main",	GPT_FRAGMENT_PROGRAM,	GPP_FS_4_0,		"hlsl", HLSL11ShaderSubFolder },
 			{ GizmoPickingAlphaVSFile,	"vs_main",	GPT_VERTEX_PROGRAM,		GPP_VS_4_0,		"hlsl", HLSL11ShaderSubFolder },
 			{ GizmoPickingAlphaPSFile,	"ps_main",	GPT_FRAGMENT_PROGRAM,	GPP_FS_4_0,		"hlsl", HLSL11ShaderSubFolder },
+			{ SelectionVSFile,			"vs_main",	GPT_VERTEX_PROGRAM,		GPP_VS_4_0,		"hlsl", HLSL11ShaderSubFolder },
+			{ SelectionPSFile,			"ps_main",	GPT_FRAGMENT_PROGRAM,	GPP_FS_4_0,		"hlsl", HLSL11ShaderSubFolder },
 			{ SceneGridVSFile,			"vs_main",	GPT_VERTEX_PROGRAM,		GPP_VS_2_0,		"hlsl", HLSL9ShaderSubFolder },
 			{ SceneGridPSFile,			"ps_main",	GPT_FRAGMENT_PROGRAM,	GPP_FS_2_0,		"hlsl", HLSL9ShaderSubFolder },
 			{ ShaderDockOverlayVSFile,	"vs_main",	GPT_VERTEX_PROGRAM,		GPP_VS_2_0,		"hlsl", HLSL9ShaderSubFolder },
@@ -1231,8 +1236,10 @@ namespace BansheeEngine
 			{ GizmoPickingPSFile,		"ps_main",	GPT_FRAGMENT_PROGRAM,	GPP_FS_3_0,		"hlsl", HLSL9ShaderSubFolder },
 			{ GizmoPickingAlphaVSFile,	"vs_main",	GPT_VERTEX_PROGRAM,		GPP_VS_3_0,		"hlsl", HLSL9ShaderSubFolder },
 			{ GizmoPickingAlphaPSFile,	"ps_main",	GPT_FRAGMENT_PROGRAM,	GPP_FS_3_0,		"hlsl", HLSL9ShaderSubFolder },
-			{ SceneGridVSFile,			"main",		GPT_VERTEX_PROGRAM,		GPP_VS_4_0,		"glsl", GLSLShaderSubFolder },
-			{ SceneGridPSFile,			"main",		GPT_FRAGMENT_PROGRAM,	GPP_FS_4_0,		"glsl", GLSLShaderSubFolder },
+			{ SelectionVSFile,			"vs_main",	GPT_VERTEX_PROGRAM,		GPP_VS_2_0,		"hlsl", HLSL9ShaderSubFolder },
+			{ SelectionPSFile,			"ps_main",	GPT_FRAGMENT_PROGRAM,	GPP_FS_2_0,		"hlsl", HLSL9ShaderSubFolder },
+			{ SceneGridVSFile,			"main",		GPT_VERTEX_PROGRAM,		GPP_VS_2_0,		"glsl", GLSLShaderSubFolder },
+			{ SceneGridPSFile,			"main",		GPT_FRAGMENT_PROGRAM,	GPP_FS_2_0,		"glsl", GLSLShaderSubFolder },
 			{ ShaderDockOverlayVSFile,	"main",		GPT_VERTEX_PROGRAM,		GPP_VS_4_0,		"glsl", GLSLShaderSubFolder },
 			{ ShaderDockOverlayPSFile,	"main",		GPT_FRAGMENT_PROGRAM,	GPP_FS_4_0,		"glsl", GLSLShaderSubFolder },
 			{ PickingVSFile,			"main",		GPT_VERTEX_PROGRAM,		GPP_VS_4_0,		"glsl", GLSLShaderSubFolder },
@@ -1251,6 +1258,8 @@ namespace BansheeEngine
 			{ GizmoPickingPSFile,		"main",		GPT_FRAGMENT_PROGRAM,	GPP_FS_4_0,		"glsl", GLSLShaderSubFolder },
 			{ GizmoPickingAlphaVSFile,	"main",		GPT_VERTEX_PROGRAM,		GPP_VS_4_0,		"glsl", GLSLShaderSubFolder },
 			{ GizmoPickingAlphaPSFile,	"main",		GPT_FRAGMENT_PROGRAM,	GPP_FS_4_0,		"glsl", GLSLShaderSubFolder },
+			{ SelectionVSFile,			"main",		GPT_VERTEX_PROGRAM,		GPP_VS_4_0,		"glsl", GLSLShaderSubFolder },
+			{ SelectionPSFile,			"main",		GPT_FRAGMENT_PROGRAM,	GPP_FS_4_0,		"glsl", GLSLShaderSubFolder },
 		};
 
 		if (FileSystem::exists(DefaultSkinFolderRaw))
@@ -1433,17 +1442,29 @@ namespace BansheeEngine
 
 		HRasterizerState rasterizerState = RasterizerState::create(rasterizerDesc);
 
+		DEPTH_STENCIL_STATE_DESC depthStencilDesc;
+		depthStencilDesc.depthWriteEnable = false;
+
+		HDepthStencilState depthStencilState = DepthStencilState::create(depthStencilDesc);
+
 		PASS_DESC passDesc;
 		passDesc.vertexProgram = vsProgram;
 		passDesc.fragmentProgram = psProgram;
 		passDesc.blendState = blendState;
 		passDesc.rasterizerState = rasterizerState;
+		passDesc.depthStencilState = depthStencilState;
 
 		PassPtr newPass = Pass::create(passDesc);
 		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass });
 
 		SHADER_DESC shaderDesc;
 		shaderDesc.addParameter("matViewProj", "matViewProj", GPDT_MATRIX_4X4);
+		shaderDesc.addParameter("worldCameraPos", "worldCameraPos", GPDT_FLOAT4);
+		shaderDesc.addParameter("gridColor", "gridColor", GPDT_FLOAT4);
+		shaderDesc.addParameter("gridSpacing", "gridSpacing", GPDT_FLOAT1);
+		shaderDesc.addParameter("gridBorderWidth", "gridBorderWidth", GPDT_FLOAT1);
+		shaderDesc.addParameter("gridFadeOutStart", "gridFadeOutStart", GPDT_FLOAT1);
+		shaderDesc.addParameter("gridFadeOutEnd", "gridFadeOutEnd", GPDT_FLOAT1);
 
 		mShaderSceneGrid = Shader::create("SceneGridShader", shaderDesc, { newTechnique });
 	}
@@ -1723,6 +1744,41 @@ namespace BansheeEngine
 		mShaderGizmoAlphaPicking = Shader::create("GizmoPickingAlphaShader", shaderDesc, { newTechnique });
 	}
 
+	void BuiltinEditorResources::initSelectionShader()
+	{
+		HGpuProgram vsProgram = getGpuProgram(SelectionVSFile);
+		HGpuProgram psProgram = getGpuProgram(SelectionPSFile);
+
+		RASTERIZER_STATE_DESC rasterizerDesc;
+		rasterizerDesc.polygonMode = PM_WIREFRAME;
+		rasterizerDesc.depthBias = 10000;
+
+		HRasterizerState rasterizerState = RasterizerState::create(rasterizerDesc);
+
+		BLEND_STATE_DESC blendDesc;
+		blendDesc.renderTargetDesc[0].blendEnable = true;
+		blendDesc.renderTargetDesc[0].srcBlend = BF_SOURCE_ALPHA;
+		blendDesc.renderTargetDesc[0].dstBlend = BF_INV_SOURCE_ALPHA;
+		blendDesc.renderTargetDesc[0].blendOp = BO_ADD;
+
+		HBlendState blendState = BlendState::create(blendDesc);
+
+		PASS_DESC passDesc;
+		passDesc.vertexProgram = vsProgram;
+		passDesc.fragmentProgram = psProgram;
+		passDesc.rasterizerState = rasterizerState;
+		passDesc.blendState = blendState;
+
+		PassPtr newPass = Pass::create(passDesc);
+		TechniquePtr newTechnique = Technique::create(mActiveRenderSystem, RendererInvariant, { newPass });
+
+		SHADER_DESC shaderDesc;
+		shaderDesc.addParameter("matWorldViewProj", "matWorldViewProj", GPDT_MATRIX_4X4);
+		shaderDesc.addParameter("color", "color", GPDT_FLOAT4);
+
+		mShaderSelection = Shader::create("Selection", shaderDesc, { newTechnique });
+	}
+
 	HMaterial BuiltinEditorResources::createDockDropOverlayMaterial() const
 	{
 		return Material::create(mShaderDockOverlay);
@@ -1781,4 +1837,9 @@ namespace BansheeEngine
 	{
 		return Material::create(mShaderHandleSolid);
 	}
+
+	HMaterial BuiltinEditorResources::createSelectionMat() const
+	{
+		return Material::create(mShaderSelection);
+	}
 }

+ 30 - 75
BansheeEditor/Source/BsSceneGrid.cpp

@@ -7,27 +7,37 @@
 #include "BsDrawList.h"
 #include "BsBuiltinEditorResources.h"
 #include "BsCamera.h"
+#include "BsRect3.h"
 #include "BsEditorSettings.h"
 
 namespace BansheeEngine
 {
+	const Color SceneGrid::GRID_LINE_COLOR = Color(1.0f, 1.0f, 1.0f);
 	const float SceneGrid::LINE_WIDTH = 0.025f;
-	const float SceneGrid::LINE_BORDER_WIDTH = 0.005f;
+	const float SceneGrid::LINE_BORDER_WIDTH = 0.0075f;
 	const float SceneGrid::MAJOR_AXIS_WIDTH = 0.075f;
 	const float SceneGrid::MAJOR_AXIS_BORDER_WIDTH = 0.015f;
 	const float SceneGrid::AXIS_MARKER_WIDTH = 0.1f;
 	const float SceneGrid::AXIS_MARKER_BORDER_WIDTH = 0.02f;
 	const Color SceneGrid::AXIS_X_MARKER_COLOR = Color::Red;
 	const Color SceneGrid::AXIS_Z_MARKER_COLOR = Color::Blue;
+	const float SceneGrid::FADE_OUT_START = 5.0f;
+	const float SceneGrid::FADE_OUT_END = 40.0f;
 
 	SceneGrid::SceneGrid()
 	{
 		mVertexDesc = bs_shared_ptr<VertexDataDesc>();
 		mVertexDesc->addVertElem(VET_FLOAT3, VES_POSITION);
-		mVertexDesc->addVertElem(VET_COLOR, VES_COLOR);
+		mVertexDesc->addVertElem(VET_FLOAT3, VES_NORMAL);
 
 		mGridMaterial = BuiltinEditorResources::instance().createSceneGridMaterial();
 		mViewProjParam = mGridMaterial->getParamMat4("matViewProj");
+		mWorldCameraPosParam = mGridMaterial->getParamVec4("worldCameraPos");
+		mGridColorParam = mGridMaterial->getParamColor("gridColor");
+		mGridSpacingParam = mGridMaterial->getParamFloat("gridSpacing");
+		mGridBorderWidthParam = mGridMaterial->getParamFloat("gridBorderWidth");
+		mGridFadeOutStartParam = mGridMaterial->getParamFloat("gridFadeOutStart");
+		mGridFadeOutEndParam = mGridMaterial->getParamFloat("gridFadeOutEnd");
 
 		updateGridMesh();
 	}
@@ -61,6 +71,7 @@ namespace BansheeEngine
 
 	void SceneGrid::setMajorAxisSpacing(UINT32 spacing)
 	{
+		// TODO - Ignored with the current shader
 		if (mMajorAxisSpacing != spacing)
 		{
 			mMajorAxisSpacing = spacing;
@@ -70,6 +81,7 @@ namespace BansheeEngine
 
 	void SceneGrid::setAxisMarkerSpacing(UINT32 spacing)
 	{
+		// TODO - Ignored with the current shader
 		if (mAxisMarkerSpacing != spacing)
 		{
 			mAxisMarkerSpacing = spacing;
@@ -100,6 +112,13 @@ namespace BansheeEngine
 		Matrix4 viewProjMatrix = projMatrix * viewMatrix;
 		mViewProjParam.set(viewProjMatrix);
 
+		mWorldCameraPosParam.set(Vector4(camera->getPosition(), 1.0f));
+		mGridColorParam.set(GRID_LINE_COLOR);
+		mGridSpacingParam.set(mSpacing);
+		mGridBorderWidthParam.set(LINE_BORDER_WIDTH);
+		mGridFadeOutStartParam.set(FADE_OUT_START);
+		mGridFadeOutEndParam.set(FADE_OUT_END);
+
 		drawList.add(mat, mesh, 0, Vector3::ZERO);
 	}
 
@@ -115,82 +134,18 @@ namespace BansheeEngine
 
 	void SceneGrid::updateGridMesh()
 	{
-		UINT32 numLines = (UINT32)Math::roundToInt(mSize / mSpacing);
-		if (numLines % 2 != 0)
-			numLines++;
-
-		INT32 originX = Math::roundToInt(mOrigin.x / mSpacing);
-		INT32 originZ = Math::roundToInt(mOrigin.y / mSpacing);
-
-		INT32 startX = originX - numLines / 2;
-		INT32 startZ = originZ - numLines / 2;
-
-		float minX = startX * mSpacing;
-		float minZ = startZ * mSpacing;
+		std::array<Vector3, 2> axes;
+		axes[0] = Vector3::UNIT_X;
+		axes[1] = Vector3::UNIT_Z;
 
-		float maxX = (startX + numLines) * mSpacing;
-		float maxZ = (startZ + numLines) * mSpacing;
+		std::array<float, 2> extents;
+		extents[0] = mSize * 0.5f;
+		extents[1] = mSize * 0.5f;
 
-		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;
-		UINT32 indexOffset = 0;
-
-		for (UINT32 i = 0; i <= numLines; i++)
-		{
-			INT32 x = startX + i;
-			float linePosX = x * mSpacing;
-
-			Vector3 lineStartX(linePosX, 0, minZ);
-			Vector3 lineEndX(linePosX, 0, maxZ);
-
-			if (x % mAxisMarkerSpacing == 0)
-			{
-				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)
-			{
-				ShapeMeshes3D::antialiasedLine(lineStartX, lineEndX, Vector3::UNIT_Y, MAJOR_AXIS_WIDTH,
-					MAJOR_AXIS_BORDER_WIDTH, Color::White, meshData, vertexOffset, indexOffset);
-			}
-			else
-			{
-				ShapeMeshes3D::antialiasedLine(lineStartX, lineEndX, Vector3::UNIT_Y, LINE_WIDTH,
-					LINE_BORDER_WIDTH, Color::White, meshData, vertexOffset, indexOffset);
-			}
-
-			vertexOffset += ShapeMeshes3D::NUM_VERTICES_AA_LINE;
-			indexOffset += ShapeMeshes3D::NUM_INDICES_AA_LINE;
-
-			INT32 z = startZ + i;
-			float linePosZ = z * mSpacing;
-
-			Vector3 lineStartZ(minX, 0, linePosZ);
-			Vector3 lineEndZ(maxX, 0, linePosZ);
-
-			if (z % mAxisMarkerSpacing == 0)
-			{
-				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)
-			{
-				ShapeMeshes3D::antialiasedLine(lineStartZ, lineEndZ, Vector3::UNIT_Y, MAJOR_AXIS_WIDTH,
-					MAJOR_AXIS_BORDER_WIDTH, Color::White, meshData, vertexOffset, indexOffset);
-			}
-			else
-			{
-				ShapeMeshes3D::antialiasedLine(lineStartZ, lineEndZ, Vector3::UNIT_Y, LINE_WIDTH,
-					LINE_BORDER_WIDTH, Color::White, meshData, vertexOffset, indexOffset);
-			}
-
-			vertexOffset += ShapeMeshes3D::NUM_VERTICES_AA_LINE;
-			indexOffset += ShapeMeshes3D::NUM_INDICES_AA_LINE;
-		}
+		Rect3 quad(mOrigin, axes, extents);
+		MeshDataPtr meshData = bs_shared_ptr<MeshData, PoolAlloc>(8, 12, mVertexDesc);
 
+		ShapeMeshes3D::solidQuad(quad, meshData, 0, 0);
 		mGridMesh = Mesh::create(meshData);
 	}
 }

+ 4 - 0
BansheeEditor/Source/BsSceneViewHandler.cpp

@@ -12,6 +12,7 @@
 #include "BsEditorWindowBase.h"
 #include "BsRenderWindow.h"
 #include "BsCursor.h"
+#include "BsSelectionRenderer.h"
 
 #include "BsDebug.h"
 
@@ -23,6 +24,7 @@ namespace BansheeEngine
 		:mCamera(camera), mSceneGrid(nullptr), mParentWidget(parentWidget)
 	{
 		mRenderCallback = RendererManager::instance().getActive()->onRenderViewport.connect(std::bind(&SceneViewHandler::render, this, _1, _2));
+		mSelectionRenderer = bs_new<SelectionRenderer>();
 		mSceneGrid = bs_new<SceneGrid>();
 		mSceneGrid->setSettings(gEditorApplication().getEditorSettings());
 		HandleManager::instance().setSettings(gEditorApplication().getEditorSettings());
@@ -31,6 +33,7 @@ namespace BansheeEngine
 	SceneViewHandler::~SceneViewHandler()
 	{
 		bs_delete(mSceneGrid);
+		bs_delete(mSelectionRenderer);
 		mRenderCallback.disconnect();
 
 		if (GizmoManager::isStarted()) // If not active, we don't care
@@ -39,6 +42,7 @@ namespace BansheeEngine
 
 	void SceneViewHandler::update()
 	{
+		mSelectionRenderer->update(mCamera);
 		GizmoManager::instance().update(mCamera);
 		mSceneGrid->update();
 	}

+ 117 - 0
BansheeEditor/Source/BsSelectionRenderer.cpp

@@ -0,0 +1,117 @@
+#include "BsSelectionRenderer.h"
+#include "BsMesh.h"
+#include "BsVertexDataDesc.h"
+#include "BsCamera.h"
+#include "BsCoreThread.h"
+#include "BsBuiltinEditorResources.h"
+#include "BsMaterial.h"
+#include "BsGpuParams.h"
+#include "BsRenderAPI.h"
+#include "BsCoreRenderer.h"
+#include "BsRendererManager.h"
+#include "BsSelection.h"
+#include "BsSceneObject.h"
+#include "BsRenderable.h"
+
+using namespace std::placeholders;
+
+namespace BansheeEngine
+{
+	SelectionRenderer::SelectionRenderer()
+		:mCore(nullptr)
+	{
+		HMaterial selectionMat = BuiltinEditorResources::instance().createSelectionMat();
+			
+		mCore = bs_new<SelectionRendererCore>(SelectionRendererCore::PrivatelyConstuct());
+		gCoreAccessor().queueCommand(std::bind(&SelectionRenderer::initializeCore, this, selectionMat->getCore()));;
+	}
+
+	SelectionRenderer::~SelectionRenderer()
+	{
+		gCoreAccessor().queueCommand(std::bind(&SelectionRenderer::destroyCore, this, mCore));
+	}
+
+	void SelectionRenderer::initializeCore(const SPtr<MaterialCore>& initData)
+	{
+		mCore->initialize(initData);
+	}
+
+	void SelectionRenderer::destroyCore(SelectionRendererCore* core)
+	{
+		bs_delete(core);
+	}
+
+	void SelectionRenderer::update(const CameraHandlerPtr& camera)
+	{
+		Vector<SelectionRenderer::ObjectData> objects;
+
+		const Vector<HSceneObject>& sceneObjects = Selection::instance().getSceneObjects();
+		for (auto& so : sceneObjects)
+		{
+			HRenderable renderable = so->getComponent<Renderable>();
+			if (renderable != nullptr && renderable->getMesh() != nullptr)
+			{
+				objects.push_back(ObjectData());
+
+				ObjectData& newObjData = objects.back();
+				newObjData.worldTfrm = so->getWorldTfrm();
+				newObjData.mesh = renderable->getMesh()->getCore();
+			}
+		}
+
+		RenderTargetPtr rt = camera->getViewport()->getTarget();
+		gCoreAccessor().queueCommand(std::bind(&SelectionRendererCore::updateData, mCore, rt->getCore(), objects));
+	}
+
+	const Color SelectionRendererCore::SELECTION_COLOR = Color(1.0f, 1.0f, 1.0f, 0.3f);
+
+	SelectionRendererCore::SelectionRendererCore(const PrivatelyConstuct& dummy)
+	{
+	}
+
+	void SelectionRendererCore::initialize(const SPtr<MaterialCore>& mat)
+	{
+		THROW_IF_NOT_CORE_THREAD;
+
+		mMaterial = mat;
+
+		SPtr<GpuParamsCore> vertParams = mat->getPassParameters(0)->mVertParams;
+		vertParams->getParam("matWorldViewProj", mMatWorldViewProj);
+
+		SPtr<GpuParamsCore> fragParams = mat->getPassParameters(0)->mFragParams;
+		fragParams->getParam("color", mColor);
+		
+		CoreRendererPtr activeRenderer = RendererManager::instance().getActive();
+		activeRenderer->onCorePostRenderViewport.connect(std::bind(&SelectionRendererCore::render, this, _1));
+	}
+
+	void SelectionRendererCore::updateData(const SPtr<RenderTargetCore>& rt, const Vector<SelectionRenderer::ObjectData>& objects)
+	{
+		mSceneRenderTarget = rt;
+		mObjects = objects;
+	}
+
+	void SelectionRendererCore::render(const CameraHandlerCore& camera)
+	{
+		THROW_IF_NOT_CORE_THREAD;
+
+		if (mSceneRenderTarget == nullptr)
+			return;
+
+		if (camera.getViewport()->getTarget() != mSceneRenderTarget)
+			return;
+
+		Matrix4 viewProjMat = camera.getProjectionMatrixRS() * camera.getViewMatrix();
+
+		for (auto& objData : mObjects)
+		{
+			Matrix4 worldViewProjMat = viewProjMat * objData.worldTfrm;
+
+			mMatWorldViewProj.set(worldViewProjMat);
+			mColor.set(SELECTION_COLOR);
+
+			CoreRenderer::setPass(mMaterial, 0);
+			CoreRenderer::draw(objData.mesh, objData.mesh->getProperties().getSubMesh(0));
+		}
+	}
+}

+ 1 - 1
BansheeEngine/Source/BsGUIElement.cpp

@@ -240,7 +240,7 @@ namespace BansheeEngine
 	void GUIElement::_refreshStyle()
 	{
 		const GUIElementStyle* newStyle = nullptr;
-		if(_getParentWidget() != nullptr)
+		if(_getParentWidget() != nullptr && !mStyleName.empty())
 			newStyle = _getParentWidget()->getSkin().getStyle(mStyleName);
 		else
 			newStyle = &GUISkin::DefaultStyle;

+ 33 - 37
TODO.txt

@@ -18,38 +18,6 @@ Figure out how to create a C# BuiltinResources class. It should be able to load
 My GUID generation is screwed up. If multiple GUIDs are generated in succession then the timestamp will remain
 the same and the only variable will be the 4byte random number, which can sometimes end up identical to the previous number.
 
-----------------------------------------------------------------------
-MenuItem
-
-TEST the new MenuItem (C#) and menu shortcut GUI, and menu shortcut functionality
-
-When closing a sub-menu I think I need to call "GUIDropDownBoxManager::instance().closeDropDownBox();" at some point (i.e. when last sub-menu is closed?).
- - Also when a submenu is closed or opened I should set some kind of focus on it, so it knows to accept/reject keyboard input
- - "Esc" should move back one sub-menu instead of closing all of it
-
-LATER: Add keyboard controls to GUIMenuBar (left/right arrows should move between entries if user is not browsing a sub-menu)
- - esc should cancel out of the menu bar
- - alt should focus the menu bar
-
-----------------------------------------------------------------------
-VisualStudio integration
-
-VS integration will likely not work with VSExpress or Community edition
- - VSExpress doesn't support EnvDTE so the only option is to open it using a shell command which doesn't seem to offer precise parameters
- - Community edition should work similarily to Pro, but might have a different executable and/or registry paths
-
-For later:
- - Make sure that 3rd party assemblies can be imported in the project, and that they are properly referenced in VS project generation and compilation
-
-----------------------------------------------------------------------
-Script compilation
-
-For later:
- - I need to hook up script compilation with assembly refresh, and the build system.
-   - e.g. when recompiling inside the editor it should automatically start compiling when changes are detected,
-     show some kind of visual indicator and refresh assemblies when its done. When publishing it should recompile
-	 assemblies for release. Also hook up console to compiler output?
-
 ----------------------------------------------------------------------
 BuiltinResources
  - All data in ..\..\BuiltinData (if we start in /bin/Release/BansheeEd.exe)
@@ -140,6 +108,16 @@ Need a way to drag and drop items from Scene tree view to Scene view
 ----------------------------------------------------------------------
 Other
 
+Constant errors when rendering in DX11, and assert in DX9 when attempting to bind a texture to a shader
+Check in new grid and selection shaders
+ - Test DX9 grid shader
+
+Test selection DX9 and DX11
+
+Grid shader:
+ - Jaggies are significantly more noticable here than in Unity
+ - It doesn't render properly when intersecting geometry
+
 Got a crash on shutdown that was caused by locking a mutex in an Event destructor. Event was Platform::onMouseCaptureChanged. 
 Issue happened when I closed the app via the X button (if that's relevant). It doesn't seem to happen always.
 
@@ -175,9 +153,27 @@ Mono cannot marshal structures? Taken from their documentation:
  (excluding the system types like int32, int64, etc) must be passed as a pointer, in C# this means passing the value as a "ref" or "out" parameter.
 
 ----------------------------------------------------------------------
-SelectionRenderer
+MenuItem
+
+LATER: Add keyboard controls to GUIMenuBar (left/right arrows should move between entries if user is not browsing a sub-menu)
+ - esc should cancel out of the menu bar
+ - alt should focus the menu bar
+
+----------------------------------------------------------------------
+VisualStudio integration
+
+VS integration will likely not work with VSExpress or Community edition
+ - VSExpress doesn't support EnvDTE so the only option is to open it using a shell command which doesn't seem to offer precise parameters
+ - Community edition should work similarily to Pro, but might have a different executable and/or registry paths
+
+For later:
+ - Make sure that 3rd party assemblies can be imported in the project, and that they are properly referenced in VS project generation and compilation
+
+----------------------------------------------------------------------
+Script compilation
 
-Retrieve a list of selected objects from SelectionManager
-Find ones with Renderable components
-Retrieve Meshes, and world transforms from them
-Draw that same mesh with either a wireframe or a grayed out shader with a slight depth bias
+For later:
+ - I need to hook up script compilation with assembly refresh, and the build system.
+   - e.g. when recompiling inside the editor it should automatically start compiling when changes are detected,
+     show some kind of visual indicator and refresh assemblies when its done. When publishing it should recompile
+	 assemblies for release. Also hook up console to compiler output?