diff --git a/include/Engine/Rendering/Font.h b/include/Engine/Rendering/Font.h new file mode 100644 index 00000000..89a21eb0 --- /dev/null +++ b/include/Engine/Rendering/Font.h @@ -0,0 +1,36 @@ +#ifndef Font_h__ +#define Font_h__ + +#include +#include FT_FREETYPE_H +#include FT_GLYPH_H +#include +#include + +#include "../OpenGL.h" +#include "../GLM.h" +#include "../Core/ResourceManager.h" + +class Font : public Resource +{ + friend class ResourceManager; +private: + Font(std::string path); + +public: + struct Character { + GLuint TextureID; // ID handle of the glyph texture + glm::ivec2 Size; // Size of glyph + glm::ivec2 Bearing; // Offset from baseline to left/top of glyph + GLuint Advance; // Offset to advance to next glyph + }; + + + + int FontSize = 16; + + ~Font(); + + std::map m_Characters; +}; +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/RenderQueue.h b/include/Engine/Rendering/RenderQueue.h index e42cc8dc..b533f992 100644 --- a/include/Engine/Rendering/RenderQueue.h +++ b/include/Engine/Rendering/RenderQueue.h @@ -11,49 +11,16 @@ #include "Camera.h" #include "RenderJob.h" #include "ModelJob.h" +#include "TextJob.h" #include "PointLightJob.h" #include "DirectionalLightJob.h" - -/* -struct SpriteJob : RenderJob -{ - unsigned int ShaderID = 0; - unsigned int TextureID = 0; - - glm::mat4 ModelMatrix; - const Texture* DiffuseTexture = nullptr; - const Texture* NormalTexture = nullptr; - const Texture* SpecularTexture = nullptr; - glm::vec4 Color; - - void CalculateHash() override - { - Hash = TextureID; - } -}; - -struct PointLightJob : RenderJob -{ - glm::vec4 Position; - glm::vec4 Color; - float Radius; - float Intensity; - float Falloff; - float padding = 123; - - void CalculateHash() override - { - Hash = 0; - } -}; -*/ - struct RenderScene { ::Camera* Camera = nullptr; std::list> ForwardJobs; std::list> PointLightJobs; + std::list> TextJobs; std::list> DirectionalLightJobs; Rectangle Viewport; bool ClearDepth = false; @@ -62,6 +29,7 @@ struct RenderScene { ForwardJobs.clear(); PointLightJobs.clear(); + TextJobs.clear(); DirectionalLightJobs.clear(); } }; @@ -98,5 +66,4 @@ public: private: int m_Size = 0; }; - #endif \ No newline at end of file diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index 04c394a9..ef824ea5 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -32,6 +32,7 @@ private: EventRelay m_ESetCamera; bool OnSetCamera(Events::SetCamera &event); + void fillText(std::list>& jobs, World* world); void fillPointLights(std::list>& jobs, World* world); void fillDirectionalLights(std::list>& jobs, World* world); EventRelay m_EInputCommand; diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index cc9599d3..34f442e9 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -18,6 +18,8 @@ #include "Camera.h" #include "../Core/Transform.h" +#include "TextRenderer.h" + class Renderer : public IRenderer { public: @@ -34,6 +36,7 @@ public: private: //----------------------Variables----------------------// EventBroker* m_EventBroker; + TextRenderer* m_TextRenderer; Texture* m_ErrorTexture; Texture* m_WhiteTexture; diff --git a/include/Engine/Rendering/TextJob.h b/include/Engine/Rendering/TextJob.h new file mode 100644 index 00000000..a11761d2 --- /dev/null +++ b/include/Engine/Rendering/TextJob.h @@ -0,0 +1,58 @@ +#ifndef TextJob_h__ +#define TextJob_h__ + +#include + +#include "../Common.h" +#include "../GLM.h" +#include "../Core/ComponentWrapper.h" +#include "Texture.h" +#include "RenderJob.h" +#include "../Core/ResourceManager.h" +#include "Font.h" + +struct TextJob : RenderJob +{ + TextJob(glm::mat4 matrix, Font* font, ComponentWrapper textComponent) + : RenderJob() + { + Matrix = matrix; + Color = (glm::vec4)textComponent["Color"]; + Content = (std::string)textComponent["Content"]; + Resource = font; + + if ((int)textComponent["Alignment"] == textComponent["Alignment"].Enum("Left")) { + Alignment = AlignmentEnum::Left; + } else if ((int)textComponent["Alignment"] == textComponent["Alignment"].Enum("Right")) { + Alignment = AlignmentEnum::Right; + } else if ((int)textComponent["Alignment"] == textComponent["Alignment"].Enum("Center")) { + Alignment = AlignmentEnum::Center; + } else { + LOG_ERROR("Text alignment invalid"); + Alignment = AlignmentEnum::Left; + } + + }; + + enum class AlignmentEnum + { + Left, + Right, + Center + }; + + glm::mat4 Matrix; + glm::vec4 Color; + std::string Content; + Font* Resource; + AlignmentEnum Alignment; + + + + void CalculateHash() override + { + Hash = 0; + } +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/TextRenderer.h b/include/Engine/Rendering/TextRenderer.h new file mode 100644 index 00000000..cdc1d8c7 --- /dev/null +++ b/include/Engine/Rendering/TextRenderer.h @@ -0,0 +1,31 @@ +#ifndef TextRenderer_h__ +#define TextRenderer_h__ + +#include +#include FT_FREETYPE_H + +#include "../OpenGL.h" +#include "../GLM.h" +#include "ShaderProgram.h" +#include "Font.h" +#include "../Core/ResourceManager.h" +#include "RenderQueue.h" + +class TextRenderer +{ +public: + TextRenderer(); + void Initialize(); + void Update(); + void Draw(RenderScene& scene); + +private: + void renderText(std::string text, Font* font, TextJob::AlignmentEnum alignment, glm::vec4 color, glm::mat4 modelMatrix, glm::mat4 projectionMatrix, glm::mat4 viewMatrix); + + Font* font; + GLuint VAO, VBO; + ShaderProgram* m_TextProgram; +}; + + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/Texture.h b/include/Engine/Rendering/Texture.h index 16892afc..0fe650b3 100644 --- a/include/Engine/Rendering/Texture.h +++ b/include/Engine/Rendering/Texture.h @@ -18,6 +18,7 @@ public: void Bind(GLenum textureUnit = GL_TEXTURE0); GLuint m_Texture = 0; + }; #endif diff --git a/include/Game/Game.h b/include/Game/Game.h index 6dd5e2cd..fab10a49 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -19,6 +19,7 @@ #include "Rendering/RenderSystem.h" #include "Core/EntityFileParser.h" #include "Core/Octree.h" +#include "Rendering/Font.h" #include "Systems/InterpolationSystem.h" // Network #include diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 0b5ba629..12d94611 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -6,6 +6,7 @@ + diff --git a/resources/Schema/Components/Text.xml b/resources/Schema/Components/Text.xml new file mode 100644 index 00000000..9ca629d1 --- /dev/null +++ b/resources/Schema/Components/Text.xml @@ -0,0 +1,8 @@ + + + Text + + + true +
+ \ No newline at end of file diff --git a/resources/Schema/Components/Text.xsd b/resources/Schema/Components/Text.xsd new file mode 100644 index 00000000..14e91a35 --- /dev/null +++ b/resources/Schema/Components/Text.xsd @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + A visible font loaded from disk + + + + + the content of the string printed + + + The asset file, font resolution, example: Fonts/font.ttf,16 + + + Color + + + Wether the text is visible or not + + + Text alignment + + + + + \ No newline at end of file diff --git a/resources/Schema/Entities/RenderingWorld.xml b/resources/Schema/Entities/RenderingWorld.xml index 86a3090a..69b18982 100644 --- a/resources/Schema/Entities/RenderingWorld.xml +++ b/resources/Schema/Entities/RenderingWorld.xml @@ -1,58 +1,262 @@ - + + - - - - - - - - - - - - - Models/Camera.obj - - - MainCamera - - - - - - - - - - Models/Camera.obj - - - ActionCamera - - - - - - - - - - - Models/Core/UnitPlane.obj - - - - - - - - - - An error - - - - - \ No newline at end of file + + + + + + + + ActionCamera + + + Models/Camera.obj + + + + + + + + + + + Camera #2 + Fonts/DroidSans.ttf,64 + 0 + + + + + + + + + + + + + + Models/Core/UnitPlane.obj + + + + + + + + + + + + Models/Assault.obj + + + + + + + + + + + Welcome! + Fonts/DroidSans.ttf,1280 + + + + + + + + + + + 2 + + + + + + + + + + + + + 6 + 0.5 + + + + + + + + + + + 8 + + + + + + + + + + + + + + 6 + 0.5 + + + + + + + + + + + 8 + + + + + + + + + + + + + + 6 + 0.5 + + + + + + + + + + + 8 + + + + + + + + + + + + + 6 + 0.5 + + + + + + + + + + 8 + + + + + + + + + + + + + + + Models/Assault.obj + + + + + + + + + + + MainCamera + + + + Models/Camera.obj + false + + + + + + + + + + + Taiwan #1 + Fonts/DroidSans.ttf,64 + 0 + + + + + + + + + + + + + + + 0.80000001192092896 + + + Models/DirectionalLightWidget.obj + + + + + + + + + + + + Models/Core/UnitCube.obj + + + + + + + + + + diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index 2f9e5184..5583b8b8 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -16,6 +16,7 @@ + diff --git a/resources/Shaders/Text.frag.glsl b/resources/Shaders/Text.frag.glsl new file mode 100644 index 00000000..2726b5d1 --- /dev/null +++ b/resources/Shaders/Text.frag.glsl @@ -0,0 +1,12 @@ +#version 430 +in vec2 TexCoords; +out vec4 color; + +uniform sampler2D text; +uniform vec3 textColor; + +void main() +{ + vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r); + color = vec4(textColor, 1.0) * sampled; +} \ No newline at end of file diff --git a/resources/Shaders/Text.vert.glsl b/resources/Shaders/Text.vert.glsl new file mode 100644 index 00000000..43c86795 --- /dev/null +++ b/resources/Shaders/Text.vert.glsl @@ -0,0 +1,13 @@ +#version 430 +layout (location = 0) in vec4 vertex; // +out vec2 TexCoords; + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; + +void main() +{ + gl_Position = P * V * M * vec4(vertex.xy, 0.0, 1.0); + TexCoords = vertex.zw; +} \ No newline at end of file diff --git a/src/Engine/CMakeLists.txt b/src/Engine/CMakeLists.txt index 277cb617..1ed39177 100644 --- a/src/Engine/CMakeLists.txt +++ b/src/Engine/CMakeLists.txt @@ -8,6 +8,7 @@ find_package(assimp REQUIRED) find_package(ZLIB REQUIRED) find_package(PNG REQUIRED) find_package(Xerces REQUIRED) +find_package(Freetype REQUIRED) # Because FindOpenAL is retarded set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/deps/include/OpenAL") find_package(OpenAL REQUIRED) @@ -25,6 +26,7 @@ include_directories( ${assimp_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS} ${Xerces_INCLUDE_DIRS} + ${FREETYPE_INCLUDE_DIRS} ${OPENAL_INCLUDE_DIR} ${X11_INCLUDE_DIRS} ) @@ -126,6 +128,7 @@ set(LIBRARIES ${assimp_LIBRARIES} ${PNG_LIBRARIES} ${Xerces_LIBRARIES} + ${FREETYPE_LIBRARIES} ${OPENAL_LIBRARY} ${X11_LIBRARIES} ) diff --git a/src/Engine/Rendering/Font.cpp b/src/Engine/Rendering/Font.cpp new file mode 100644 index 00000000..940694ea --- /dev/null +++ b/src/Engine/Rendering/Font.cpp @@ -0,0 +1,108 @@ +#include "Rendering/Font.h" + + +Font::Font(std::string path) +{ + typedef boost::tokenizer> tokenizer; + boost::char_separator sep(","); + tokenizer tok(path, sep); + + + tokenizer::iterator it = tok.begin(); + std::string filePath = ""; + + if (it != tok.end()) { + filePath = (*it).c_str(); + it++; + if (it != tok.end()) { + if((*it).c_str() == "") { + throw std::runtime_error(""); + } + + try { + FontSize = boost::lexical_cast((*it).c_str()); + } catch (boost::bad_lexical_cast const&) { + LOG_ERROR("input string did not have a valid font resolution"); + throw std::runtime_error(""); + } + } + } else { + throw std::runtime_error("");; + } + + + FT_Library library; + FT_Face face; + + if (FT_Init_FreeType(&library)) { + LOG_ERROR("FreeType error: init failed"); + throw std::runtime_error("");; + } + + if (FT_New_Face(library, filePath.c_str(), 0, &face)) { + LOG_ERROR("FreeType error: loading font"); + throw std::runtime_error("");; + } + + FT_Set_Char_Size(face, 0, FontSize*64, 300, 300); // temp + FT_Set_Pixel_Sizes(face, 0, FontSize); // + + if (FT_Load_Char(face, 'X', FT_LOAD_RENDER)) { + LOG_ERROR("FreeType error: loading char"); + throw std::runtime_error("");; + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + for (GLubyte c = 0; c < 128; c++) { + + + //Load character glyph + if (FT_Load_Char(face, c, FT_LOAD_RENDER)) { + continue; + } + + //Generate texture + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RED, + face->glyph->bitmap.width, + face->glyph->bitmap.rows, + 0, + GL_RED, + GL_UNSIGNED_BYTE, + face->glyph->bitmap.buffer + ); + // Set texture options + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + // Now store character for later use + Character character = { + texture, + glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows), + glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top), + face->glyph->advance.x + }; + + m_Characters.insert(std::pair(c, character)); + } + + + FT_Done_Face(face); + FT_Done_FreeType(library); + GLERROR("Font Load"); +} + +Font::~Font() +{ + for (auto c : m_Characters) { + glDeleteTextures(1, &c.second.TextureID); + } +} diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index 3b5ade59..6f448896 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -46,10 +46,8 @@ void PickingPass::InitializeShaderPrograms() void PickingPass::Draw(RenderScene& scene) { PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle()); - //TODO: Render: Add code for more jobs than modeljobs. - GLuint ShaderHandle = m_PickingProgram->GetHandle(); m_PickingProgram->Bind(); @@ -78,9 +76,9 @@ void PickingPass::Draw(RenderScene& scene) m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); if (m_ColorCounter[0] > 255) { m_ColorCounter[0] = 0; - m_ColorCounter[1]++;; + m_ColorCounter[1]++; } else { - m_ColorCounter[0]++;; + m_ColorCounter[0]++; } } diff --git a/src/Engine/Rendering/PickingPassState.cpp b/src/Engine/Rendering/PickingPassState.cpp index 2b4f30c4..0c4f4aca 100644 --- a/src/Engine/Rendering/PickingPassState.cpp +++ b/src/Engine/Rendering/PickingPassState.cpp @@ -8,6 +8,7 @@ PickingPassState::PickingPassState(GLuint frameBuffer) GLERROR("---3"); Enable(GL_DEPTH_TEST); Enable(GL_CULL_FACE); + Disable(GL_BLEND); glm::vec4 clearColor = glm::vec4(0.f); //ClearColor(clearColor); diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 6eedc34c..5aa0108e 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -110,6 +110,42 @@ void RenderSystem::fillDirectionalLights(std::list>& } } + +void RenderSystem::fillText(std::list>& jobs, World* world) +{ + auto texts = world->GetComponents("Text"); + if (texts == nullptr) { + return; + } + + for (auto& textComponent : *texts) { + bool visible = textComponent["Visible"]; + if (!visible) { + continue; + } + std::string resource = textComponent["Resource"]; + if (resource.empty()) { + continue; + } + + Font* font; + try { + font = ResourceManager::Load(resource); + } catch (const std::exception&) { + try { + font = ResourceManager::Load("Fonts/DroidSans.ttf,16"); + } catch (const std::exception&) { + continue; + } + } + + glm::mat4 modelMatrix = Transform::ModelMatrix(textComponent.EntityID, world); + std::shared_ptr modelJob = std::shared_ptr(new TextJob(modelMatrix, font, textComponent)); + jobs.push_back(modelJob); + + } +} + bool RenderSystem::OnInputCommand(const Events::InputCommand& e) { return false; @@ -133,6 +169,7 @@ void RenderSystem::Update(double dt) fillModels(scene.ForwardJobs); fillPointLights(scene.PointLightJobs, m_World); fillDirectionalLights(scene.DirectionalLightJobs, m_World); + fillText(scene.TextJobs, world); m_RenderFrame->Add(scene); } \ No newline at end of file diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index c0347612..d788fd8e 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -9,6 +9,9 @@ void Renderer::Initialize() glfwSwapInterval(m_VSYNC); InitializeShaders(); InitializeTextures(); + m_TextRenderer = new TextRenderer(); + m_TextRenderer->Initialize(); + m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.obj"); m_UnitQuad = ResourceManager::Load("Models/Core/UnitQuad.obj"); @@ -77,6 +80,7 @@ void Renderer::Update(double dt) { m_EventBroker->Process(); InputUpdate(dt); + m_TextRenderer->Update(); m_ImGuiRenderPass->Update(dt); } @@ -97,7 +101,11 @@ void Renderer::Draw(RenderFrame& frame) //m_DrawScenePass->Draw(rq); GLERROR("Renderer::Draw m_DrawScenePass->Draw"); + + m_TextRenderer->Draw(*scene); + } + m_ImGuiRenderPass->Draw(); glfwSwapBuffers(m_Window); diff --git a/src/Engine/Rendering/TextRenderer.cpp b/src/Engine/Rendering/TextRenderer.cpp new file mode 100644 index 00000000..a8dfc083 --- /dev/null +++ b/src/Engine/Rendering/TextRenderer.cpp @@ -0,0 +1,110 @@ +#include "Rendering/TextRenderer.h" + +TextRenderer::TextRenderer() +{ + +} + +void TextRenderer::Initialize() +{ + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &VBO); + glBindVertexArray(VAO); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, NULL, GL_DYNAMIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + + m_TextProgram = ResourceManager::Load("#TextProgram"); + m_TextProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/Text.vert.glsl"))); + m_TextProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/Text.frag.glsl"))); + m_TextProgram->Compile(); + m_TextProgram->Link(); +} + +void TextRenderer::Update() +{ + +} + +void TextRenderer::Draw(RenderScene& scene) +{ + for (auto &job : scene.TextJobs) { + auto textJob = std::dynamic_pointer_cast(job); + if (textJob) { + + renderText(textJob->Content, textJob->Resource, textJob->Alignment, textJob->Color, textJob->Matrix, scene.Camera->ProjectionMatrix(), scene.Camera->ViewMatrix()); + } + } +} + +void TextRenderer::renderText(std::string text, Font* font, TextJob::AlignmentEnum alignment, glm::vec4 color, glm::mat4 modelMatrix, glm::mat4 projectionMatrix, glm::mat4 viewMatrix) +{ + GLfloat penX = 0; + GLfloat penY = 0; + float scale = 1.0/font->FontSize; + + GLfloat stringWidth = 0.f; + + for (std::string::const_iterator c = text.begin(); c != text.end(); c++) { + Font::Character ch = font->m_Characters[*c]; + stringWidth += (ch.Advance >> 6) * scale; + } + + if(alignment == TextJob::AlignmentEnum::Center) { + penX = -stringWidth/2.f; + } else if (alignment == TextJob::AlignmentEnum::Right) { + penX = -stringWidth; + } else { + penX = 0; + } + + glEnable(GL_BLEND); + glDisable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + m_TextProgram->Bind(); + glUniform3f(glGetUniformLocation(m_TextProgram->GetHandle(), "textColor"), color.x, color.y, color.z); + glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "M"), 1, GL_FALSE, glm::value_ptr(modelMatrix)); + glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "V"), 1, GL_FALSE, glm::value_ptr(viewMatrix)); + glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "P"), 1, GL_FALSE, glm::value_ptr(projectionMatrix)); + glActiveTexture(GL_TEXTURE0); + glBindVertexArray(VAO); + + + for (std::string::const_iterator c = text.begin(); c != text.end(); c++) { + Font::Character ch = font->m_Characters[*c]; + + GLfloat xpos = penX + ch.Bearing.x * scale; + GLfloat ypos = penY - (ch.Size.y - ch.Bearing.y) * scale; + + GLfloat w = ch.Size.x * scale; + GLfloat h = ch.Size.y * scale; + + GLfloat vertices[6][4] = { + { xpos, ypos + h, 0.0, 0.0 }, + { xpos, ypos, 0.0, 1.0 }, + { xpos + w, ypos, 1.0, 1.0 }, + + { xpos, ypos + h, 0.0, 0.0 }, + { xpos + w, ypos, 1.0, 1.0 }, + { xpos + w, ypos + h, 1.0, 0.0 } + }; + + glBindTexture(GL_TEXTURE_2D, ch.TextureID); + + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glDrawArrays(GL_TRIANGLES, 0, 6); + penX += (ch.Advance >> 6) * scale; // Bitshift by 6 to get value in pixels (2^6 = 64) + } + glBindVertexArray(0); + glBindTexture(GL_TEXTURE_2D, 0); + + GLERROR("Text rendering Error"); +} + diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 7b2f114e..384c4a5b 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -20,6 +20,7 @@ Game::Game(int argc, char* argv[]) ResourceManager::RegisterType("Texture"); ResourceManager::RegisterType("ShaderProgram"); ResourceManager::RegisterType("EntityFile"); + ResourceManager::RegisterType("FontFile"); m_Config = ResourceManager::Load("Config.ini"); ResourceManager::UseThreading = m_Config->Get("Multithreading.ResourceLoading", true);