summary refs log tree commit diff
path: root/src/GFX
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2024-02-12 12:55:11 +0100
committerMel <einebeere@gmail.com>2024-02-12 12:55:11 +0100
commitd2b5fc5b3bc648afffa42375706429685ac63794 (patch)
treea2dfbb241e1d46e5616c5884e5f3d685de2a2cb6 /src/GFX
parent588c7e87b7cab270698d43ca5c22d67793ae5fc4 (diff)
downloadmeowcraft-d2b5fc5b3bc648afffa42375706429685ac63794.tar.zst
meowcraft-d2b5fc5b3bc648afffa42375706429685ac63794.zip
Split rendering into own thread and sync through render action lists
Diffstat (limited to 'src/GFX')
-rw-r--r--src/GFX/Actions.hpp39
-rw-r--r--src/GFX/Resources.cpp26
-rw-r--r--src/GFX/Resources.hpp38
-rw-r--r--src/GFX/Shading/Program.cpp9
-rw-r--r--src/GFX/Shading/Program.hpp4
-rw-r--r--src/GFX/Shading/Shader.hpp8
-rw-r--r--src/GFX/Window.cpp18
-rw-r--r--src/GFX/Window.hpp6
8 files changed, 134 insertions, 14 deletions
diff --git a/src/GFX/Actions.hpp b/src/GFX/Actions.hpp
new file mode 100644
index 0000000..cc19169
--- /dev/null
+++ b/src/GFX/Actions.hpp
@@ -0,0 +1,39 @@
+#pragma once
+#include "Mesh.hpp"
+#include "Resources.hpp"
+#include "../Transform.hpp"
+
+namespace MC::GFX {
+
+enum class DrawMode {
+    Triangles = GL_TRIANGLES,
+    Lines = GL_LINES,
+};
+
+struct Action {
+    Mesh* mesh;
+    Resources::Program program;
+    Transform transform;
+
+    F32 alpha = 1.0f;
+    DrawMode draw_mode = DrawMode::Triangles;
+};
+
+class Actions {
+public:
+    void add(Action const& action) {
+        m_actions.push_back(action);
+    }
+
+    void clear() {
+        m_actions.clear();
+    }
+
+    const std::vector<Action>& actions() const {
+        return m_actions;
+    }
+private:
+    std::vector<Action> m_actions;
+};
+
+}
diff --git a/src/GFX/Resources.cpp b/src/GFX/Resources.cpp
new file mode 100644
index 0000000..34ce32e
--- /dev/null
+++ b/src/GFX/Resources.cpp
@@ -0,0 +1,26 @@
+#include "Resources.hpp"
+
+#include "../Common/Assert.hpp"
+
+namespace MC::GFX {
+
+void Resources::initialize() {
+    ASSERT(!m_initialized, "Resources already initialized");
+    for (auto& metadata: m_program_metadata) {
+        m_programs[static_cast<USize>(metadata.id)] = create_program(metadata);
+    }
+    m_initialized = true;
+}
+
+Shading::Program const& Resources::program(Program id) const {
+    ASSERT(m_initialized, "Resources not initialized");
+    return m_programs[static_cast<USize>(id)];
+}
+
+Shading::Program Resources::create_program(ProgramMetadata const& metadata) {
+    Shading::Shader vertex(Shading::Shader::Type::Vertex, metadata.vertex);
+    Shading::Shader fragment(Shading::Shader::Type::Fragment, metadata.fragment);
+    return {vertex, fragment};
+}
+
+}
diff --git a/src/GFX/Resources.hpp b/src/GFX/Resources.hpp
new file mode 100644
index 0000000..4206e33
--- /dev/null
+++ b/src/GFX/Resources.hpp
@@ -0,0 +1,38 @@
+#pragma once
+
+#include <array>
+#include "Shading/Program.hpp"
+
+namespace MC::GFX {
+class Resources {
+public:
+    enum class Program: USize {
+        Terrain,
+        Clouds,
+        ImageViewer,
+        BlockOutline,
+    };
+    constexpr static USize ProgramCount = 4;
+
+    void initialize();
+    Shading::Program const& program(Program id) const;
+private:
+    struct ProgramMetadata {
+        Program id;
+        Char const* vertex;
+        Char const* fragment;
+    };
+
+    static inline std::array<ProgramMetadata, ProgramCount> const m_program_metadata = {{
+        {Program::Terrain, Assets::Shaders::terrain::vertex, Assets::Shaders::terrain::fragment},
+        {Program::Clouds, Assets::Shaders::clouds::vertex, Assets::Shaders::clouds::fragment},
+        {Program::ImageViewer, Assets::Shaders::image_viewer::vertex, Assets::Shaders::image_viewer::fragment},
+        {Program::BlockOutline, Assets::Shaders::block_outline::vertex, Assets::Shaders::block_outline::fragment},
+    }};
+
+    Bool m_initialized = false;
+    std::array<Shading::Program, ProgramCount> m_programs = {};
+
+    static Shading::Program create_program(ProgramMetadata const& metadata);
+};
+}
diff --git a/src/GFX/Shading/Program.cpp b/src/GFX/Shading/Program.cpp
index ff10012..fe5d576 100644
--- a/src/GFX/Shading/Program.cpp
+++ b/src/GFX/Shading/Program.cpp
@@ -2,6 +2,8 @@
 #include <stdexcept>
 #include "Program.hpp"
 
+#include "../../Common/Assert.hpp"
+
 namespace MC::GFX::Shading {
 
 Program::Program(Shader vertex, Shader fragment) {
@@ -26,6 +28,7 @@ Program::Program(Shader vertex, Shader fragment) {
 }
 
 void Program::bind() const {
+    ASSERT(m_program != 0, "Program is not initialized");
     glUseProgram(m_program);
 }
 
@@ -33,10 +36,12 @@ void Program::unbind() const {
     glUseProgram(0);
 }
 
-Uniform Program::uniform(const std::string& name) const {
+std::optional<Uniform> Program::uniform(const std::string& name) const {
+    ASSERT(m_program != 0, "Program is not initialized");
     auto index = glGetUniformLocation(m_program, name.c_str());
 
-    return {name, static_cast<U32>(index)};
+    if (index == -1) return {};
+    return {{name, static_cast<U32>(index)}};
 }
 
 U32 Program::get() const {
diff --git a/src/GFX/Shading/Program.hpp b/src/GFX/Shading/Program.hpp
index 2f48698..67838dc 100644
--- a/src/GFX/Shading/Program.hpp
+++ b/src/GFX/Shading/Program.hpp
@@ -1,5 +1,6 @@
 #pragma once
 
+#include <optional>
 #include <string>
 #include "Shader.hpp"
 #include "Uniform.hpp"
@@ -8,11 +9,12 @@ namespace MC::GFX::Shading {
 
 class Program {
 public:
+    Program() : m_program(0) {}
     Program(Shader vertex, Shader fragment);
 
     U32 get() const;
 
-    Uniform uniform(const std::string& name) const;
+    std::optional<Uniform> uniform(std::string const& name) const;
 
     void bind() const;
     void unbind() const;
diff --git a/src/GFX/Shading/Shader.hpp b/src/GFX/Shading/Shader.hpp
index 21fd899..8c6c5c8 100644
--- a/src/GFX/Shading/Shader.hpp
+++ b/src/GFX/Shading/Shader.hpp
@@ -19,14 +19,6 @@ public:
         return m_shader;
     }
 
-    static Shader create_vertex() {
-        return {Type::Vertex, Assets::Shaders::vertex};
-    }
-
-    static Shader create_fragment() {
-        return {Type::Fragment, Assets::Shaders::fragment};
-    }
-
 private:
     U32 m_shader;
 };
diff --git a/src/GFX/Window.cpp b/src/GFX/Window.cpp
index bbe2ba7..c0c5b03 100644
--- a/src/GFX/Window.cpp
+++ b/src/GFX/Window.cpp
@@ -2,6 +2,8 @@
 #include "../Common/Sizes.hpp"
 #include "Window.hpp"
 
+#include "../Common/Assert.hpp"
+
 namespace MC::GFX {
 
 Window::Window(const Char* title, U32 width, U32 height) {
@@ -48,8 +50,11 @@ Bool Window::mouse(I32 key, I32 type) const {
     return glfwGetMouseButton(m_window, key) == type;
 }
 
-void Window::start_frame() {
+void Window::start_render() {
     glfwSwapBuffers(m_window);
+}
+
+void Window::poll_events() {
     glfwPollEvents();
 }
 
@@ -57,4 +62,13 @@ void Window::on_size_change(void (callback)(GLFWwindow*, I32, I32)) {
     glfwSetFramebufferSizeCallback(m_window, callback);
 }
 
-}
\ No newline at end of file
+void Window::attach() const {
+    glfwMakeContextCurrent(m_window);
+}
+
+void Window::detach() const {
+    ASSERT(glfwGetCurrentContext() == m_window, "Cannot detach window that is not current");
+    glfwMakeContextCurrent(nullptr);
+}
+
+}
diff --git a/src/GFX/Window.hpp b/src/GFX/Window.hpp
index ac0efd2..c26b0fd 100644
--- a/src/GFX/Window.hpp
+++ b/src/GFX/Window.hpp
@@ -16,8 +16,12 @@ public:
 
     void on_size_change(void (* callback)(GLFWwindow*, I32, I32));
 
+    void attach() const;
+    void detach() const;
+
     void close();
-    void start_frame();
+    void start_render();
+    void poll_events();
     Vector<2> mouse_delta();
 
     Bool key(I32 key, I32 type) const;