From 3ce136741d31e545ff703d2b172d82ee4c601d90 Mon Sep 17 00:00:00 2001 From: Riyyi Date: Sun, 31 Jan 2021 14:54:06 +0100 Subject: [PATCH] Improve API regarding server-side GL capabilities, fix font transparency --- inferno/src/inferno/application.cpp | 5 ++- inferno/src/inferno/render/context.cpp | 46 +++++----------------- inferno/src/inferno/render/context.h | 10 +---- inferno/src/inferno/render/renderer.cpp | 36 +++++++++++++++++ inferno/src/inferno/render/renderer.h | 10 ++++- inferno/src/inferno/window.cpp | 52 +++++++++++++++---------- inferno/src/inferno/window.h | 8 ++-- 7 files changed, 95 insertions(+), 72 deletions(-) diff --git a/inferno/src/inferno/application.cpp b/inferno/src/inferno/application.cpp index 286279f..9ddc948 100644 --- a/inferno/src/inferno/application.cpp +++ b/inferno/src/inferno/application.cpp @@ -46,6 +46,8 @@ namespace Inferno { m_scene = std::make_shared(); m_scene->initialize(); + RenderCommand::initialize(); + Renderer2D* renderer2D = new Renderer2D(); renderer2D->initialize(); @@ -65,6 +67,7 @@ namespace Inferno { FontManager::the().destroy(); RendererCharacter::the().destroy(); Renderer2D::the().destroy(); + RenderCommand::destroy(); m_scene->destroy(); TextureManager::the().destroy(); ShaderManager::the().destroy(); @@ -186,7 +189,7 @@ namespace Inferno { infoln("WindowResizeEvent {}x{} triggered", e.getWidth(), e.getHeight()); - m_window->getContext()->setViewport(0, 0, e.getWidth(), e.getHeight()); + RenderCommand::setViewport(0, 0, e.getWidth(), e.getHeight()); return true; } diff --git a/inferno/src/inferno/render/context.cpp b/inferno/src/inferno/render/context.cpp index f3f3358..b52956f 100644 --- a/inferno/src/inferno/render/context.cpp +++ b/inferno/src/inferno/render/context.cpp @@ -12,14 +12,14 @@ namespace Inferno { Context::Context(GLFWwindow* window) : m_window(window) { + ASSERT(window, "Context window is nullptr!"); } -// ----------------------------------------- - void Context::initialize() { + Context::setCurrent(); + // Initialize glad - glfwMakeContextCurrent(m_window); int glad = gladLoadGLLoader((GLADloadproc)glfwGetProcAddress); ASSERT(glad, "Failed to initialize glad!"); @@ -29,34 +29,12 @@ namespace Inferno { comment() << " Renderer: " << glGetString(GL_RENDERER); comment() << " Version: " << glGetString(GL_VERSION); -#ifdef NF_ENABLE_ASSERTS - int versionMajor; - int versionMinor; - glGetIntegerv(GL_MAJOR_VERSION, &versionMajor); - glGetIntegerv(GL_MINOR_VERSION, &versionMinor); - ASSERT(versionMajor > 4 || (versionMajor == 4 && versionMinor >= 5), - "Inferno requires at least OpenGL version 4.5!"); -#endif - - Window& w = *(Window*)glfwGetWindowUserPointer(m_window); - - // Disable vsync - if (!w.isVSync()) { - glfwSwapInterval(0); - } - - // Set viewport - this->setViewport(0, 0, w.getWidth(), w.getHeight()); - - // Enable z-buffer / depth buffer - glEnable(GL_DEPTH_TEST); - - // Enable transparency - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); + // Check OpenGL version + ASSERT(GLVersion.major > 4 || (GLVersion.major == 4 && GLVersion.minor >= 5), + "Inferno requires at least OpenGL version 4.5!"); } - void Context::update() + void Context::destroy() { } @@ -65,14 +43,10 @@ namespace Inferno { glfwSwapBuffers(m_window); } - void Context::destroy() + void Context::setCurrent() { + // Set current OpenGL context to this window + glfwMakeContextCurrent(m_window); } -// ----------------------------------------- - - void Context::setViewport(int x, int y, int width, int height) const - { - glViewport(x, y, width, height); - } } diff --git a/inferno/src/inferno/render/context.h b/inferno/src/inferno/render/context.h index e03a474..b3f12f7 100644 --- a/inferno/src/inferno/render/context.h +++ b/inferno/src/inferno/render/context.h @@ -8,18 +8,12 @@ namespace Inferno { class Context { public: Context(GLFWwindow* window); - // virtual ~Context(); - -// ----------------------------------------- void initialize(); - void update(); - void render(); void destroy(); + void render(); -// ----------------------------------------- - - void setViewport(int x, int y, int width, int height) const; + void setCurrent(); private: GLFWwindow* m_window; diff --git a/inferno/src/inferno/render/renderer.cpp b/inferno/src/inferno/render/renderer.cpp index edabc17..1507106 100644 --- a/inferno/src/inferno/render/renderer.cpp +++ b/inferno/src/inferno/render/renderer.cpp @@ -11,6 +11,21 @@ namespace Inferno { + void RenderCommand::initialize() + { + setDepthTest(true); + + // Enable transparency + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + info() << "RenderCommand initialized"; + } + + void RenderCommand::destroy() + { + } + void RenderCommand::clear() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -27,6 +42,24 @@ namespace Inferno { glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, nullptr); } + void RenderCommand::setViewport(int32_t x, int32_t y, uint32_t width, uint32_t height) + { + glViewport(x, y, width, height); + } + + void RenderCommand::setDepthTest(bool enabled) + { + // Set z-buffer / depth buffer + enabled ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST); + } + + bool RenderCommand::depthTest() + { + unsigned char depthTest = GL_FALSE; + glGetBooleanv(GL_DEPTH_TEST, &depthTest); + return depthTest == GL_TRUE; + } + int32_t RenderCommand::textureUnitAmount() { int32_t amount = 0; @@ -397,7 +430,10 @@ namespace Inferno { bind(); // Render + bool depthTest = RenderCommand::depthTest(); + RenderCommand::setDepthTest(false); RenderCommand::drawIndexed(m_vertexArray, m_quadIndex * indexPerQuad); + RenderCommand::setDepthTest(depthTest); unbind(); } diff --git a/inferno/src/inferno/render/renderer.h b/inferno/src/inferno/render/renderer.h index 7077683..10f36a4 100644 --- a/inferno/src/inferno/render/renderer.h +++ b/inferno/src/inferno/render/renderer.h @@ -1,7 +1,7 @@ #ifndef RENDERER_H #define RENDERER_H -#include // std::uint32_t +#include // std::int32_t, std::uint32_t #include // std::shared_ptr, std::unique_ptr, std::make_shared, std::make_unique #include "glm/ext/matrix_float4x4.hpp" // glm::mat4 @@ -42,11 +42,17 @@ namespace Inferno { class RenderCommand { public: + static void initialize(); + static void destroy(); + static void clear(); static void clearColor(const glm::vec4& color); - static void drawIndexed(const std::shared_ptr& vertexArray, uint32_t indexCount = 0); + static void setViewport(int32_t x, int32_t y, uint32_t width, uint32_t height); + static void setDepthTest(bool enabled); + + static bool depthTest(); static int32_t textureUnitAmount(); }; diff --git a/inferno/src/inferno/window.cpp b/inferno/src/inferno/window.cpp index e98fd3f..5a61a29 100644 --- a/inferno/src/inferno/window.cpp +++ b/inferno/src/inferno/window.cpp @@ -5,10 +5,11 @@ #include "inferno/event/applicationevent.h" #include "inferno/event/keyevent.h" #include "inferno/event/mouseevent.h" -#include "inferno/keycodes.h" #include "inferno/io/input.h" #include "inferno/io/log.h" +#include "inferno/keycodes.h" #include "inferno/render/context.h" +#include "inferno/render/renderer.h" #include "inferno/settings.h" #include "inferno/window.h" @@ -41,6 +42,7 @@ namespace Inferno { std::string title = m_properties.title; unsigned int width = m_properties.width; unsigned int height = m_properties.height; + bool vsync = m_properties.vsync; // Only init once if (s_windowCount == 0) { @@ -68,8 +70,9 @@ namespace Inferno { m_context = std::make_shared(m_window); m_context->initialize(); - // Capture cursor and hide it - // glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + // Set vsync, viewport + setVSync(vsync); + RenderCommand::setViewport(0, 0, width, height); // Error callback glfwSetErrorCallback([](int error, const char* description) { @@ -160,18 +163,29 @@ namespace Inferno { }); } + void Window::destroy() + { + m_context->destroy(); + + glfwDestroyWindow(m_window); + s_windowCount--; + + if (s_windowCount == 0) { + glfwTerminate(); + } + } + void Window::update() { glfwPollEvents(); - // Lock mouse in window - if (Input::isKeyPressed(keyCode("GLFW_KEY_LEFT_SUPER"))) { - glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + // Capture cursor in window and hide it + if (!Input::isKeyPressed(keyCode("GLFW_KEY_LEFT_SUPER"))) { + glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); } else { - glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); } - } void Window::render() @@ -179,19 +193,9 @@ namespace Inferno { m_context->render(); } - void Window::destroy() - { - glfwDestroyWindow(m_window); - s_windowCount--; - - if (s_windowCount == 0) { - glfwTerminate(); - } - } - // ----------------------------------------- - void Window::setWindowMonitor() + void Window::setWindowMonitor() const { GLFWmonitor* monitor = glfwGetPrimaryMonitor(); int xPos = 0; @@ -222,8 +226,10 @@ namespace Inferno { glfwSetWindowMonitor(m_window, monitor, xPos, yPos, width, height, refresh); } - bool Window::shouldClose() const { - return glfwWindowShouldClose(m_window); + void Window::setVSync(bool enabled) + { + enabled ? glfwSwapInterval(GL_TRUE) : glfwSwapInterval(GL_FALSE); + m_properties.vsync = enabled; } void Window::setShouldClose(bool close) const @@ -231,4 +237,8 @@ namespace Inferno { glfwSetWindowShouldClose(m_window, close ? GL_TRUE : GL_FALSE); } + bool Window::shouldClose() const { + return glfwWindowShouldClose(m_window); + } + } diff --git a/inferno/src/inferno/window.h b/inferno/src/inferno/window.h index 3108bc7..4e4758a 100644 --- a/inferno/src/inferno/window.h +++ b/inferno/src/inferno/window.h @@ -28,20 +28,20 @@ namespace Inferno { // ----------------------------------------- void initialize(); + void destroy(); void update(); void render(); - void destroy(); // ----------------------------------------- - void setWindowMonitor(); - bool shouldClose() const; + void setWindowMonitor() const; + void setVSync(bool enabled); void setShouldClose(bool close) const; + bool shouldClose() const; inline float getAspect() const { return static_cast(m_properties.width) / static_cast(m_properties.height); } inline int getWidth() const { return m_properties.width; } inline int getHeight() const { return m_properties.height; } - inline bool isVSync() const { return m_properties.vsync; } inline GLFWwindow* getWindow() const { return m_window; } inline const std::shared_ptr& getContext() const { return m_context; }