From f2266b843959413277767a990bb9a9c5593f3489 Mon Sep 17 00:00:00 2001 From: LaG1924 Date: Sun, 13 Jun 2021 13:47:33 +0500 Subject: Implemented basic RmlUi integration --- src/AssetManager.cpp | 12 ++-- src/Render.cpp | 40 +++++++++++++ src/Render.hpp | 11 ++++ src/Rml.cpp | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/Rml.hpp | 56 +++++++++++++++++++ src/Shader.hpp | 8 +++ 6 files changed, 277 insertions(+), 4 deletions(-) create mode 100644 src/Rml.cpp create mode 100644 src/Rml.hpp (limited to 'src') diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index 514d008..0db495a 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -402,22 +402,26 @@ void ParseAssetShader(AssetTreeNode &node) { std::string vertPath = j["vert"].get(); std::string fragPath = j["frag"].get(); - AssetTreeNode *vertAsset = AssetManager::GetAssetByAssetName(vertPath); - AssetTreeNode *fragAsset = AssetManager::GetAssetByAssetName(fragPath); + AssetTreeNode* vertAsset = AssetManager::GetAssetByAssetName(vertPath); + AssetTreeNode* fragAsset = AssetManager::GetAssetByAssetName(fragPath); std::string vertSource((char*)vertAsset->data.data(), (char*)vertAsset->data.data() + vertAsset->data.size()); std::string fragSource((char*)fragAsset->data.data(), (char*)fragAsset->data.data() + fragAsset->data.size()); std::vector uniforms; - for (auto &it : j["uniforms"]) { + for (auto& it : j["uniforms"]) { uniforms.push_back(it.get()); } node.asset = std::make_unique(); - AssetShader *asset = dynamic_cast(node.asset.get()); + AssetShader* asset = dynamic_cast(node.asset.get()); asset->shader = std::make_unique(vertSource, fragSource, uniforms); + } catch (std::exception &e) { + glCheckError(); + LOG(ERROR) << "Shader asset parsing failed: " << e.what(); } catch (...) { glCheckError(); + LOG(ERROR) << "Shader asset parsing failed with unknown reason"; return; } } diff --git a/src/Render.cpp b/src/Render.cpp index d583205..7835b98 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "imgui_impl_sdl_gl3.h" #include "Shader.hpp" @@ -16,6 +17,7 @@ #include "Settings.hpp" #include "Framebuffer.hpp" #include "Plugin.hpp" +#include "Rml.hpp" Render::Render(unsigned int windowWidth, unsigned int windowHeight, std::string windowTitle) { @@ -30,6 +32,8 @@ Render::Render(unsigned int windowWidth, unsigned int windowHeight, AssetManager::InitAssetManager(); glCheckError(); PrepareToRendering(); + glCheckError(); + InitRml(); glCheckError(); //Read settings @@ -73,6 +77,10 @@ Render::~Render() { Settings::WriteDouble("resolutionScale", fieldResolutionScale); Settings::Save(); + Rml::RemoveContext("default"); + rmlRender.reset(); + rmlSystem.reset(); + PluginSystem::Init(); framebuffer.reset(); @@ -125,6 +133,7 @@ void Render::InitGlew() { glViewport(0, 0, width, height); glClearColor(0.8,0.8,0.8, 1.0f); glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); @@ -220,6 +229,8 @@ void Render::HandleEvents() { SDL_GL_GetDrawableSize(window, &width, &height); renderState.WindowWidth = width; renderState.WindowHeight = height; + rmlRender->Update(width, height); + rmlContext->SetDimensions(Rml::Vector2i(width, height)); framebuffer->Resize(width * fieldResolutionScale, height * fieldResolutionScale); Framebuffer::GetDefault().Resize(width, height); break; @@ -331,6 +342,7 @@ void Render::HandleEvents() { break; } } + rmlContext->Update(); } void Render::HandleMouseCapture() { @@ -366,6 +378,9 @@ void Render::Update() { void Render::RenderGui() { OPTICK_EVENT(); + + rmlContext->Render(); + ImGui_ImplSdlGL3_NewFrame(window); if (isMouseCaptured) { @@ -750,3 +765,28 @@ void Render::InitEvents() { } }); } + +void Render::InitRml() { + LOG(INFO) << "Initializing Rml"; + + rmlSystem = std::make_unique(); + Rml::SetSystemInterface(rmlSystem.get()); + + rmlRender = std::make_unique(renderState); + Rml::SetRenderInterface(rmlRender.get()); + rmlRender->Update(renderState.WindowWidth, renderState.WindowHeight); + + if (!Rml::Initialise()) + LOG(WARNING) << "Rml not initialized"; + + rmlContext = Rml::CreateContext("default", Rml::Vector2i(renderState.WindowWidth, renderState.WindowHeight)); + + if (!Rml::LoadFontFace("OpenSans-Regular.ttf")) + LOG(WARNING) << "Rml font not loaded"; + + Rml::ElementDocument* document = rmlContext->LoadDocument("test.rml"); + if (document) + document->Show(); + else + LOG(WARNING) << "Rml document not loaded"; +} diff --git a/src/Render.hpp b/src/Render.hpp index 8e2e233..a8c437c 100644 --- a/src/Render.hpp +++ b/src/Render.hpp @@ -13,6 +13,12 @@ class RendererWorld; class Framebuffer; +class RmlRenderInterface; +class RmlSystemInterface; +namespace Rml +{ + class Context; +} class Render { SDL_Window *window; @@ -43,6 +49,9 @@ class Render { bool fieldFlight; float fieldBrightness; float fieldResolutionScale; + std::unique_ptr rmlRender; + std::unique_ptr rmlSystem; + Rml::Context* rmlContext; void SetMouseCapture(bool IsCaptured); @@ -64,6 +73,8 @@ class Render { void InitEvents(); + void InitRml(); + public: Render(unsigned int windowWidth, unsigned int windowHeight, std::string windowTitle); ~Render(); diff --git a/src/Rml.cpp b/src/Rml.cpp new file mode 100644 index 0000000..7987121 --- /dev/null +++ b/src/Rml.cpp @@ -0,0 +1,154 @@ +#include "Rml.hpp" + +#include + +#include "AssetManager.hpp" +#include "Shader.hpp" +#include "Utility.hpp" + +double RmlSystemInterface::GetElapsedTime() { + return totalTime; +} + +bool RmlSystemInterface::LogMessage(Rml::Log::Type type, const Rml::String& message) { + switch (type) { + case Rml::Log::Type::LT_ALWAYS: + LOG(ERROR) << message; + break; + case Rml::Log::Type::LT_ERROR: + LOG(ERROR) << message; + break; + case Rml::Log::Type::LT_ASSERT: + LOG(ERROR) << message; + break; + case Rml::Log::Type::LT_WARNING: + LOG(WARNING) << message; + break; + case Rml::Log::Type::LT_INFO: + LOG(INFO) << message; + break; + case Rml::Log::Type::LT_DEBUG: + LOG(DEBUG) << message; + break; + case Rml::Log::Type::LT_MAX: + LOG(DEBUG) << message; + break; + } + return true; +} + +RmlRenderInterface::RmlRenderInterface(RenderState& renderState) : State(&renderState) { + glGenVertexArrays(1, &Vao); + glBindVertexArray(Vao); + glCheckError(); + + glGenBuffers(1, &Ebo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, 0, nullptr, GL_STREAM_DRAW); + glCheckError(); + + glGenBuffers(1, &Vbo); + glBindBuffer(GL_ARRAY_BUFFER, Vbo); + glBufferData(GL_ARRAY_BUFFER, 0, nullptr, GL_STREAM_DRAW); + glCheckError(); + + { + //Vertex position (2 float) + GLuint PosAttribPos = 0; + glVertexAttribPointer(PosAttribPos, 2, GL_FLOAT, GL_FALSE, 20, (void*)0); + glEnableVertexAttribArray(PosAttribPos); + + //Vertex colour (4 uint8 RGBA) + GLuint ColAttribPos = 1; + glVertexAttribIPointer(ColAttribPos, 4, GL_UNSIGNED_BYTE, 20, (void*)8); + glEnableVertexAttribArray(ColAttribPos); + + //Vertex tex_coord (2 float) + GLuint TexAttribPos = 2; + glVertexAttribPointer(TexAttribPos, 2, GL_FLOAT, GL_FALSE, 20, (void*)12); + glEnableVertexAttribArray(TexAttribPos); + } + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glCheckError(); +} + +RmlRenderInterface::~RmlRenderInterface() { + glDeleteVertexArrays(1, &Vao); + glDeleteBuffers(1, &Vbo); + glDeleteBuffers(1, &Ebo); + glCheckError(); +} + +void RmlRenderInterface::RenderGeometry(Rml::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rml::TextureHandle texture, const Rml::Vector2f& translation) { + if (texture) { + AssetManager::GetAsset("/altcraft/shaders/rmltex")->shader->Activate(); + glBindTexture(GL_TEXTURE_2D, texture); + } + else + AssetManager::GetAsset("/altcraft/shaders/rml")->shader->Activate(); + glCheckError(); + + glBindVertexArray(Vao); + glCheckError(); + + glBindBuffer(GL_ARRAY_BUFFER, Vbo); + glBufferData(GL_ARRAY_BUFFER, num_vertices * sizeof(Rml::Vertex), vertices, GL_STREAM_DRAW); + glCheckError(); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, num_indices * sizeof(int), indices, GL_STREAM_DRAW); + glCheckError(); + + glDrawElements(GL_TRIANGLES, num_indices, GL_UNSIGNED_INT, 0); + glCheckError(); + glBindVertexArray(0); +} + +void RmlRenderInterface::EnableScissorRegion(bool enable) { + +} + +void RmlRenderInterface::SetScissorRegion(int x, int y, int width, int height) { + +} + +bool RmlRenderInterface::LoadTexture(Rml::TextureHandle& texture_handle, Rml::Vector2i& texture_dimensions, const Rml::String& source) { + return false; +} + +bool RmlRenderInterface::GenerateTexture(Rml::TextureHandle& texture_handle, const Rml::byte* source, const Rml::Vector2i& source_dimensions) { + int mipLevelCount = 1; + glActiveTexture(GL_TEXTURE0); + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glCheckError(); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, source_dimensions.x, source_dimensions.y, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, source); + glCheckError(); + + texture_handle = texture; + return true; +} + +void RmlRenderInterface::ReleaseTexture(Rml::TextureHandle texture) { + GLuint textures = texture; + glDeleteTextures(1, &textures); + glCheckError(); +} + +void RmlRenderInterface::Update(unsigned int windowWidth, unsigned int windowHeight) { + AssetManager::GetAsset("/altcraft/shaders/rml")->shader->Activate(); + AssetManager::GetAsset("/altcraft/shaders/rml")->shader->SetUniform("viewportSize", windowWidth, windowHeight); + glCheckError(); + AssetManager::GetAsset("/altcraft/shaders/rmltex")->shader->Activate(); + AssetManager::GetAsset("/altcraft/shaders/rmltex")->shader->SetUniform("viewportSize", windowWidth, windowHeight); + AssetManager::GetAsset("/altcraft/shaders/rmltex")->shader->SetUniform("fontTexture", 0); + glCheckError(); +} diff --git a/src/Rml.hpp b/src/Rml.hpp new file mode 100644 index 0000000..5815c3e --- /dev/null +++ b/src/Rml.hpp @@ -0,0 +1,56 @@ +#pragma once + +#include +#include + +#include "Renderer.hpp" + +class RmlSystemInterface : public Rml::SystemInterface { + double totalTime; + +public: + + virtual double GetElapsedTime() override; + + virtual bool LogMessage(Rml::Log::Type type, const Rml::String& message) override; + + inline void Update(double timeToUpdate) { + totalTime += timeToUpdate; + } + +}; + +class RmlRenderInterface : public Rml::RenderInterface { + RenderState* State; + + GLuint Vao, Vbo, Ebo; + +public: + + RmlRenderInterface(RenderState &renderState); + + RmlRenderInterface(const RmlRenderInterface&) = delete; + + RmlRenderInterface(RmlRenderInterface&&) = delete; + + RmlRenderInterface& operator=(const RmlRenderInterface&) = delete; + + RmlRenderInterface& operator=(RmlRenderInterface&&) = delete; + + ~RmlRenderInterface(); + + virtual void RenderGeometry(Rml::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rml::TextureHandle texture, const Rml::Vector2f& translation) override; + + virtual void EnableScissorRegion(bool enable) override; + + virtual void SetScissorRegion(int x, int y, int width, int height) override; + + virtual bool LoadTexture(Rml::TextureHandle& texture_handle, Rml::Vector2i& texture_dimensions, const Rml::String& source) override; + + virtual bool GenerateTexture(Rml::TextureHandle& texture_handle, const Rml::byte* source, const Rml::Vector2i& source_dimensions) override; + + virtual void ReleaseTexture(Rml::TextureHandle texture) override; + + void Update(unsigned int windowWidth, unsigned int windowHeight); + +}; diff --git a/src/Shader.hpp b/src/Shader.hpp index 8e1ce9e..6b3220d 100644 --- a/src/Shader.hpp +++ b/src/Shader.hpp @@ -26,10 +26,18 @@ public: void Activate(); + inline void SetUniform(const std::string& name, unsigned int val, unsigned int val2) { + glUniform2ui(GetUniformLocation(name), val, val2); + } + inline void SetUniform(const std::string &name, int val) { glUniform1i(GetUniformLocation(name), val); } + inline void SetUniform(const std::string& name, int val, int val2) { + glUniform2i(GetUniformLocation(name), val, val2); + } + inline void SetUniform(const std::string &name, float val) { glUniform1f(GetUniformLocation(name), val); } -- cgit v1.2.3