Explorar o código

Labels render properly using GUI system

Marko Pintera %!s(int64=13) %!d(string=hai) anos
pai
achega
dd1bf27377

+ 15 - 85
CamelotClient/CamelotClient.cpp

@@ -32,78 +32,6 @@
 
 using namespace CamelotEngine;
 
-MaterialHandle createTextMaterial()
-{
-	#if defined DX9
-	// TODO
-	#elif defined DX11
-	String textShader_dx11psLoc = "C:\\Projects\\CamelotEngine\\Data\\textShader_hlsl11_ps.gpuprog";
-	String textShader_dx11vsLoc = "C:\\Projects\\CamelotEngine\\Data\\textShader_hlsl11_vs.gpuprog";
-
-	ImportOptionsPtr gpuProgImportOptions = Importer::instance().createImportOptions(textShader_dx11psLoc);
-	if(rtti_is_of_type<GpuProgramImportOptions>(gpuProgImportOptions))
-	{
-		GpuProgramImportOptions* importOptions = static_cast<GpuProgramImportOptions*>(gpuProgImportOptions.get());
-
-		importOptions->setEntryPoint("ps_main");
-		importOptions->setLanguage("hlsl");
-		importOptions->setProfile(GPP_PS_4_0);
-		importOptions->setType(GPT_FRAGMENT_PROGRAM);
-	}
-
-	HighLevelGpuProgramHandle textShaderFragProgRef = Importer::instance().import(textShader_dx11psLoc, gpuProgImportOptions);
-
-	gpuProgImportOptions = Importer::instance().createImportOptions(textShader_dx11vsLoc);
-	if(rtti_is_of_type<GpuProgramImportOptions>(gpuProgImportOptions))
-	{
-		GpuProgramImportOptions* importOptions = static_cast<GpuProgramImportOptions*>(gpuProgImportOptions.get());
-
-		importOptions->setEntryPoint("vs_main");
-		importOptions->setLanguage("hlsl");
-		importOptions->setProfile(GPP_VS_4_0);
-		importOptions->setType(GPT_VERTEX_PROGRAM);
-	}
-
-	HighLevelGpuProgramHandle textShaderVertProgRef = Importer::instance().import(textShader_dx11vsLoc, gpuProgImportOptions);
-
-	#else
-	// TODO
-#endif
-
-	ShaderPtr textShader = Shader::create("TextShader");
-
-	textShader->addParameter("samp", "samp", GPOT_SAMPLER2D);
-	textShader->addParameter("tex", "tex", GPOT_TEXTURE2D);
-	//TechniquePtr newTechniqueGL = textShader->addTechnique("GLRenderSystem", "ForwardRenderer");
-	//PassPtr newPassGL = newTechniqueGL->addPass();
-	//newPassGL->setVertexProgram(textShaderVertProgRef);
-	//newPassGL->setFragmentProgram(textShaderFragProgRef);
-
-	//TechniquePtr newTechniqueDX = textShader->addTechnique("D3D9RenderSystem", "ForwardRenderer");
-	//PassPtr newPassDX = newTechniqueDX->addPass();
-	//newPassDX->setVertexProgram(textShaderVertProgRef);
-	//newPassDX->setFragmentProgram(textShaderFragProgRef);
-
-	TechniquePtr newTechniqueDX11 = textShader->addTechnique("D3D11RenderSystem", "ForwardRenderer");
-	PassPtr newPassDX11 = newTechniqueDX11->addPass();
-	newPassDX11->setVertexProgram(textShaderVertProgRef);
-	newPassDX11->setFragmentProgram(textShaderFragProgRef);
-
-	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;
-
-	BlendStateHandle blendState = BlendState::create(desc);
-	newPassDX11->setBlendState(blendState);
-
-	MaterialHandle textMaterial = Material::create();
-	textMaterial->setShader(textShader);
-
-	return textMaterial;
-}
-
 int CALLBACK WinMain(
 	_In_  HINSTANCE hInstance,
 	_In_  HINSTANCE hPrevInstance,
@@ -141,22 +69,23 @@ int CALLBACK WinMain(
 	GameObjectPtr testTextGO = GameObject::create("TestText");
 	std::shared_ptr<TestTextSprite> textSprite = testTextGO->addComponent<TestTextSprite>();
 
-	// Debug test fonts
-	ImportOptionsPtr fontImportOptions = Importer::instance().createImportOptions("C:\\arial.ttf");
-	if(rtti_is_of_type<FontImportOptions>(fontImportOptions))
+	FontHandle font;
+	
 	{
-		FontImportOptions* importOptions = static_cast<FontImportOptions*>(fontImportOptions.get());
+		ImportOptionsPtr fontImportOptions = Importer::instance().createImportOptions("C:\\arial.ttf");
+		if(rtti_is_of_type<FontImportOptions>(fontImportOptions))
+		{
+			FontImportOptions* importOptions = static_cast<FontImportOptions*>(fontImportOptions.get());
 
-		vector<CamelotEngine::UINT32>::type fontSizes;
-		fontSizes.push_back(12);
-		importOptions->setFontSizes(fontSizes);
-	}
-
-	FontHandle font = Importer::instance().import("C:\\arial.ttf", fontImportOptions);
+			vector<CamelotEngine::UINT32>::type fontSizes;
+			fontSizes.push_back(12);
+			importOptions->setFontSizes(fontSizes);
+		}
 
-	MaterialHandle textMaterial = createTextMaterial();
+		font = Importer::instance().import("C:\\arial.ttf", fontImportOptions);
+	}
 
-	textSprite->setText("TESTfAV", font, 12, textMaterial);
+	//textSprite->setText(camera, "TESTfAV", font, 12);
 
 #if defined DX9
 	///////////////// HLSL 9 SHADERS //////////////////////////
@@ -361,6 +290,7 @@ int CALLBACK WinMain(
 	gResources().unload(vertProgRef);
 	gResources().unload(testMaterial);
 
+	font.reset();
 	testMaterial.reset();
 	testTexRef.reset();
 	dbgMeshRef.reset();
@@ -388,7 +318,7 @@ int CALLBACK WinMain(
 	testShader = nullptr;
 	
 	renderWindow = nullptr;
-
+	
 	gApplication().shutDown();
 
 	return 0;

+ 15 - 40
CamelotClient/CmTestTextSprite.cpp

@@ -6,62 +6,37 @@
 #include "CmTextSprite.h"
 #include "CmFont.h"
 #include "CmMaterial.h"
+#include "CmGUILabel.h"
+#include "CmGUISkin.h"
+#include "CmOverlayManager.h"
 
 namespace CamelotEngine
 {
 	TestTextSprite::TestTextSprite(GameObjectPtr parent)
-		:Component(parent), mTextSprite(nullptr)
+		:GUIWidget(parent), mSkin(nullptr)
 	{
-		mTextRenderable = gameObject()->addComponent<Renderable>();
-		mTextMesh = Mesh::create();
-
-		mTextSprite = new TextSprite();
 	}
 
 	TestTextSprite::~TestTextSprite()
 	{
-		if(mTextSprite != nullptr)
-			delete mTextSprite;
+		if(mSkin != nullptr)
+			delete mSkin;
 	}
 
-	void TestTextSprite::setText(const String& text, FontHandle font, UINT32 fontSize, MaterialHandle textMaterial)
+	void TestTextSprite::setText(const CameraPtr& camera, const String& text, FontHandle font, UINT32 fontSize)
 	{
-		mTextSprite->setText(text);
-		mTextSprite->setFont(font.getInternalPtr(), fontSize);
-
-		UINT32 numTextFaces = mTextSprite->getNumQuads(0);
-		UINT32 numVertices = numTextFaces * 4;
-		UINT32 numIndices = numTextFaces * 6;
-
-		std::shared_ptr<MeshData> textData(new MeshData());
-
-		auto indices = new UINT32[numIndices];
-		auto vertices = new Vector3[numVertices];
-		auto uvs = new Vector2[numVertices];
-
-		auto vec2Buffer = new Vector2[numVertices];
-
-		mTextSprite->fillBuffer(vec2Buffer, uvs, indices, 0, numTextFaces, 0);
-
-		for(UINT32 i = 0; i < numVertices; i++)
-			vertices[i] = Vector3(vec2Buffer[i].x, vec2Buffer[i].y, 0.0f);
-
-		delete[] vec2Buffer;
-
-		textData->setPositions(vertices, numVertices);
-		textData->setUV0(uvs, numVertices);
-		textData->setIndices(indices, numIndices);
+		mSkin = new GUISkin();
 
-		mTextMesh->setMeshData(textData);
+		OverlayManager::instance().attachOverlay(camera, this);		
 
-		mTextRenderable->setMesh(mTextMesh);
+		GUIElementStyle labelStyle;
+		labelStyle.font = font;
+		labelStyle.fontSize = fontSize;
 
-		UINT32 nearestSize = font->getClosestAvailableSize(12);
-		const FontData* fontData = font->getFontDataForSize(nearestSize);
+		mSkin->setStyle(GUILabel::getGUITypeName(), labelStyle);
 
-		TextureHandle texturePage = fontData->texturePages[0]; // TODO - This won't work if font uses multiple pages
-		textMaterial->setTexture("tex", texturePage);
-		mTextRenderable->setMaterial(textMaterial);
+		setSkin(mSkin);
+		addLabel(text);
 	}
 
 	void TestTextSprite::update()

+ 4 - 7
CamelotClient/CmTestTextSprite.h

@@ -1,24 +1,21 @@
 #include "CmPrerequisites.h"
-#include "CmComponent.h"
+#include "CmGUIWidget.h"
 
 namespace CamelotEngine
 {
-	class TestTextSprite : public Component
+	class TestTextSprite : public GUIWidget
 	{
 	private:
 		friend class GameObject;
 
 		TestTextSprite(GameObjectPtr parent);
 
-		RenderablePtr mTextRenderable;
-		MeshHandle mTextMesh;
-		TextSprite* mTextSprite;
-
+		GUISkin* mSkin;
 	public:
 		~TestTextSprite();
 
 		virtual void update();
 
-		void setText(const String& text, FontHandle font, UINT32 fontSize, MaterialHandle textMaterial);
+		void setText(const CameraPtr& camera, const String& text, FontHandle font, UINT32 fontSize);
 	};
 }

+ 0 - 2
CamelotCore/Include/CmGUIElement.h

@@ -68,7 +68,5 @@ namespace CamelotEngine
 	protected:
 		GUIWidget* mParent;
 		const GUIElementStyle* mStyle;
-
-		virtual const String& getGUITypeName() = 0;
 	};
 }

+ 1 - 1
CamelotCore/Include/CmGUIElementStyle.h

@@ -12,7 +12,7 @@ namespace CamelotEngine
 
 		}
 
-		FontPtr font;
+		FontHandle font;
 		UINT32 fontSize;
 	};
 }

+ 3 - 2
CamelotCore/Include/CmGUILabel.h

@@ -7,6 +7,9 @@ namespace CamelotEngine
 {
 	class CM_EXPORT GUILabel : public GUIElement
 	{
+	public:
+		static const String& getGUITypeName();
+
 	protected:
 		~GUILabel();
 
@@ -35,7 +38,5 @@ namespace CamelotEngine
 
 		friend class GUIWidget;
 		GUILabel(GUIWidget* parent, const String& text, const GUISkin* skin);
-
-		virtual const String& getGUITypeName();
 	};
 }

+ 5 - 4
CamelotCore/Include/CmGUIWidget.h

@@ -12,14 +12,15 @@ namespace CamelotEngine
 
 		virtual void render(const CameraPtr& camera, DeferredRenderContextPtr& renderContext) const;
 	protected:
+		friend class GameObject;
+
+		GUIWidget(GameObjectPtr parent);
+
 		GUILabel* addLabel(const String& text);
 
+		void setSkin(const GUISkin* skin);
 		const GUISkin* getGUISkin() const;
-
 	private:
-		friend class GameObject;
-
-		GUIWidget(GameObjectPtr parent);
 
 		void updateMeshes() const;
 

+ 4 - 4
CamelotCore/Include/CmTextSprite.h

@@ -19,16 +19,16 @@ namespace CamelotEngine
 	{
 	public:
 		TextSprite();
-		TextSprite(const String& text, FontPtr font, UINT32 fontSize);
+		TextSprite(const String& text, FontHandle font, UINT32 fontSize);
 
 		void setText(const String& text) { mText = text; setDirty(); }
-		void setFont(FontPtr font, UINT32 fontSize) { mFont = font; mFontSize = fontSize; setDirty(); }
+		void setFont(FontHandle font, UINT32 fontSize) { mFont = font; mFontSize = fontSize; setDirty(); }
 		void setWordWrap(bool wordWrap) { mWordWrap = wordWrap; setDirty(); }
 		void setAlignment(TextHorzAlign horzAlign, TextVertAlign vertAlign = TVA_Top) 
 			{ mHorzAlign = horzAlign; mVertAlign = vertAlign; setDirty(); }
 
 		String getText() const { return mText; }
-		FontPtr getFont() const { return mFont; }
+		FontHandle getFont() const { return mFont; }
 		UINT32 getFontSize() const { return mFontSize; }
 		bool getWordWrap() const { return mWordWrap; }
 		TextHorzAlign getTextHorzAlign() const { return mHorzAlign; }
@@ -36,7 +36,7 @@ namespace CamelotEngine
 
 	protected:
 		String mText;
-		FontPtr mFont;
+		FontHandle mFont;
 		UINT32 mFontSize;
 		bool mWordWrap;
 		TextHorzAlign mHorzAlign;

+ 6 - 0
CamelotCore/Source/CmGUIWidget.cpp

@@ -37,6 +37,11 @@ namespace CamelotEngine
 		return label;
 	}
 
+	void GUIWidget::setSkin(const GUISkin* skin)
+	{
+		mSkin = skin;
+	}
+
 	const GUISkin* GUIWidget::getGUISkin() const
 	{
 		if(mSkin != nullptr)
@@ -121,6 +126,7 @@ namespace CamelotEngine
 		{
 			MeshHandle newMesh = Mesh::create();
 			mCachedMeshes.push_back(newMesh);
+			newMesh.waitUntilLoaded();
 		}
 
 		while((UINT32)mCachedMeshes.size() > numMeshes && (UINT32)mCachedMeshes.size() > 0)

+ 1 - 1
CamelotCore/Source/CmTextSprite.cpp

@@ -239,7 +239,7 @@ namespace CamelotEngine
 
 	}
 
-	TextSprite::TextSprite(const String& text, FontPtr font, UINT32 fontSize)
+	TextSprite::TextSprite(const String& text, FontHandle font, UINT32 fontSize)
 		:mText(text), mFont(font), mFontSize(fontSize), mWordWrap(false), mHorzAlign(THA_Left), mVertAlign(TVA_Top)
 	{
 

+ 2 - 2
CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp

@@ -126,8 +126,6 @@ namespace CamelotEngine
 		// Create render state manager
 		RenderStateManager::startUp(new D3D11RenderStateManager());
 
-		BuiltinMaterialManager::startUp(new D3D11BuiltinMaterialManager());
-
 		mCurrentCapabilities = createRenderSystemCapabilities();
 
 		mCurrentCapabilities->addShaderProfile("hlsl");
@@ -135,6 +133,8 @@ namespace CamelotEngine
 
 		mIAManager = new D3D11InputLayoutManager();
 
+		BuiltinMaterialManager::startUp(new D3D11BuiltinMaterialManager());
+
 		RenderSystem::initialize_internal();
 	}
 

+ 1 - 1
TODO.txt

@@ -28,7 +28,7 @@ Add TextUtil class
  When rendering GUIWidget its individual elements need to be sorted based on Z depth so the transparency works as expected
 
 Immediate TODO:
- IMPORTANT - GUIElement in its constructor calls a virtual method to detect actual type, which won't work
+ BuiltinMaterialManager creates a shader before shader factory is initialized
 
 Implement image shader for D3D11BuiltinMaterialManager
 Improve text shader so it doesn't have resolution values hardcoded in