From 20835586ab394af5745905cd9688831b404943a9 Mon Sep 17 00:00:00 2001 From: Corentin Date: Wed, 7 Jul 2021 03:59:23 +0900 Subject: [PATCH] Remove inheritances, component implementation --- include/uui/application.hpp | 2 +- include/uui/component.hpp | 23 +++- include/uui/opengl/application.hpp | 37 ++++-- include/uui/opengl/box.hpp | 23 ---- include/uui/opengl/component.hpp | 48 ++++++++ include/uui/opengl/gl_utils.hpp | 13 +++ include/uui/window.hpp | 3 +- make.py | 2 +- src/test/example_gl.cpp | 14 ++- src/uui/opengl/application.cpp | 9 +- src/uui/opengl/box.cpp | 178 ----------------------------- src/uui/opengl/component.cpp | 122 ++++++++++++++++++++ src/uui/opengl/gl_utils.cpp | 39 +++++++ src/uui/opengl/shaders/main.frag | 1 + src/uui/opengl/window.cpp | 90 ++++++++++++++- 15 files changed, 375 insertions(+), 229 deletions(-) delete mode 100644 include/uui/opengl/box.hpp create mode 100644 include/uui/opengl/component.hpp create mode 100644 include/uui/opengl/gl_utils.hpp delete mode 100644 src/uui/opengl/box.cpp create mode 100644 src/uui/opengl/component.cpp create mode 100644 src/uui/opengl/gl_utils.cpp diff --git a/include/uui/application.hpp b/include/uui/application.hpp index 1a237dc..151ca36 100644 --- a/include/uui/application.hpp +++ b/include/uui/application.hpp @@ -11,7 +11,7 @@ class Application { public: virtual void run() = 0; - virtual std::weak_ptr add_window(int width, int height, const std::string& title) = 0; + // virtual std::weak_ptr add_window(int width, int height, const std::string& title) = 0; protected: static bool application_created; diff --git a/include/uui/component.hpp b/include/uui/component.hpp index 6f67f5f..7e41fc9 100644 --- a/include/uui/component.hpp +++ b/include/uui/component.hpp @@ -1,12 +1,31 @@ #pragma once +#include +#include + namespace uui { - class Component { public: + Component( + const std::variant x, const std::variant y, const std::variant width, + const std::variant height): + position_x(x), + position_y(y), size_width(width), size_height(height) + { + background_color = {0.0f, 0.0f, 0.0f, 0.0f}; + } + virtual void render() = 0; + +protected: + std::variant position_x; + std::variant position_y; + std::variant size_width; + std::variant size_height; + + std::array background_color; }; -} +} // namespace uui diff --git a/include/uui/opengl/application.hpp b/include/uui/opengl/application.hpp index b436b18..9601f56 100644 --- a/include/uui/opengl/application.hpp +++ b/include/uui/opengl/application.hpp @@ -1,17 +1,16 @@ #pragma once #include +#include +#include #include #include "graphic_context.hpp" -#include "uui/application.hpp" -#include "uui/window.hpp" namespace uui { - class GlWindow; -class GlApplication: public Application +class GlApplication { friend class GlWindow; @@ -27,23 +26,45 @@ public: ~GlApplication(); void run(); - std::weak_ptr add_window(int width, int height, const std::string& title); + std::weak_ptr create_window(int width, int height, const std::string& title); + +private: + static bool application_created; }; -class GlWindow: public Window +class GlComponent; +class GlWindow { friend class GlApplication; + friend class GlComponent; public: - GlWindow(const GlApplication& app, int width, int height, const std::string& title); + std::string title; + std::vector> components; + + GlWindow(const GlWindow&) = delete; + GlWindow(GlWindow&&) = delete; ~GlWindow(); - void add_box(); + std::weak_ptr create_component( + const std::variant x, const std::variant y, const std::variant width, + const std::variant height); private: const GlApplication& app; + int width; + int height; + + GLFWwindow* glfw_window; + + GLuint gl_program; + + GlWindow(const GlApplication& app, int width, int height, const std::string& title); + void draw(); + + static void glfw_resize_callback(GLFWwindow* window, int width, int height); }; } // namespace uui diff --git a/include/uui/opengl/box.hpp b/include/uui/opengl/box.hpp deleted file mode 100644 index 1fe09b1..0000000 --- a/include/uui/opengl/box.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "graphic_context.hpp" -#include "uui/component.hpp" - -namespace uui -{ -class GlBox: public Component -{ -public: - GlBox(); - ~GlBox(); - - void render(); - -private: - GLuint gl_vbo; - GLuint gl_vao; - GLuint gl_ebo; - GLuint gl_program; -}; - -} // namespace uui diff --git a/include/uui/opengl/component.hpp b/include/uui/opengl/component.hpp new file mode 100644 index 0000000..1385ecb --- /dev/null +++ b/include/uui/opengl/component.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include +// #include +#include + +#include "graphic_context.hpp" +#include "window.hpp" + +namespace uui +{ +class GlComponent +{ + friend class GlWindow; + +public: + GlComponent(const GlComponent&) = delete; + GlComponent(GlComponent&&) = delete; + ~GlComponent(); + + void render(); + +private: + // std::weak_ptr window; + GlWindow* window; + + std::variant position_x; + std::variant position_y; + std::variant size_width; + std::variant size_height; + + std::array background_color; + + bool initialized; + + GLuint gl_vbo; + GLuint gl_vao; + GLuint gl_ebo; + + GlComponent( + GlWindow* window, const std::variant x, const std::variant y, + const std::variant width, const std::variant height); + + void init(); + void deinit(); +}; + +} // namespace uui diff --git a/include/uui/opengl/gl_utils.hpp b/include/uui/opengl/gl_utils.hpp new file mode 100644 index 0000000..fd29dc2 --- /dev/null +++ b/include/uui/opengl/gl_utils.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include "graphic_context.hpp" + +namespace uui +{ +namespace gl +{ +GLenum glCheckError(const char* file, int line); +} +} // namespace uui + +#define _glCheckError() uui::gl::glCheckError(__FILE__, __LINE__) diff --git a/include/uui/window.hpp b/include/uui/window.hpp index 378af08..b5d6c49 100644 --- a/include/uui/window.hpp +++ b/include/uui/window.hpp @@ -13,9 +13,8 @@ class Window { public: std::string title; - std::vector> components; - virtual void add_box() = 0; + virtual void add_component(const Component& box) = 0; protected: GLFWwindow* glfw_window; diff --git a/make.py b/make.py index f16bda7..8cabbf7 100644 --- a/make.py +++ b/make.py @@ -36,7 +36,7 @@ def main(): for shader_path in ( list(src_opengl_shader_path.rglob('*.vert')) + list(src_opengl_shader_path.rglob('*.frag'))): - out_path = (Config.BIN_DIR / shader_path.relative_to(Config.SOURCE_DIR)) + out_path = Config.BIN_DIR / shader_path.relative_to(Config.SOURCE_DIR) if not out_path.parent.exists(): out_path.parent.mkdir(parents=True) shutil.copy(shader_path, out_path) diff --git a/src/test/example_gl.cpp b/src/test/example_gl.cpp index 1b8ab33..043d374 100644 --- a/src/test/example_gl.cpp +++ b/src/test/example_gl.cpp @@ -1,6 +1,7 @@ #include #include "uui/opengl/application.hpp" +#include "uui/opengl/component.hpp" using namespace std; @@ -13,16 +14,17 @@ int main() { uui::GlApplication app; // uui::GlApplication app2; // exception : application already created - auto window_1 = app.add_window(800, 600, "OpenGl!"); - window_1.lock()->add_box(); + auto window_1 = app.create_window(800, 600, "OpenGl!"); + window_1.lock()->create_component(0, 1, 0.5f, 50); app.run(); } { uui::GlApplication app; - auto window_1 = app.add_window(800, 600, "OpenGl!"); - window_1.lock()->add_box(); - auto window_2 = app.add_window(600, 600, "OpenGL 2!"); - window_2.lock()->add_box(); + auto window_1 = app.create_window(800, 600, "OpenGl!"); + window_1.lock()->create_component(0.25f, 0.25f, 0.5f, 0.5f); + window_1.lock()->create_component(0.75f, 0.75f, 0.25f, 0.25f); + auto window_2 = app.create_window(600, 600, "OpenGL 2!"); + window_2.lock()->create_component(0, 0.5f, 100, 0.5f); app.run(); } } diff --git a/src/uui/opengl/application.cpp b/src/uui/opengl/application.cpp index 5295457..9d4857b 100644 --- a/src/uui/opengl/application.cpp +++ b/src/uui/opengl/application.cpp @@ -3,6 +3,8 @@ #include #include +bool uui::GlApplication::application_created = false; + uui::GlApplication::GlApplication() { if(application_created) @@ -76,14 +78,15 @@ void uui::GlApplication::run() std::cout << "Ending the GlApplication" << std::endl; } -std::weak_ptr uui::GlApplication::add_window(int width, int height, const std::string& title) +std::weak_ptr uui::GlApplication::create_window(int width, int height, const std::string& title) { - windows.push_back(std::make_unique(*this, width, height, title)); + std::shared_ptr window(new uui::GlWindow(*this, width, height, title)); + windows.push_back(window); glfwSwapInterval(1); if(windows.size() > 1) { glfwMakeContextCurrent((*(windows.end() - 2))->glfw_window); glfwSwapInterval(0); } - return windows.back(); + return window; } diff --git a/src/uui/opengl/box.cpp b/src/uui/opengl/box.cpp deleted file mode 100644 index 37ff9d4..0000000 --- a/src/uui/opengl/box.cpp +++ /dev/null @@ -1,178 +0,0 @@ -#include "uui/opengl/box.hpp" - -#include - -#include "uui/opengl/application.hpp" -#include "uui/shader.hpp" - -GLenum glCheckError_(const char* file, int line) -{ - GLenum errorCode; - while((errorCode = glGetError()) != GL_NO_ERROR) - { - std::string error; - switch(errorCode) - { - case GL_INVALID_ENUM: - error = "INVALID_ENUM"; - break; - case GL_INVALID_VALUE: - error = "INVALID_VALUE"; - break; - case GL_INVALID_OPERATION: - error = "INVALID_OPERATION"; - break; - case GL_STACK_OVERFLOW: - error = "STACK_OVERFLOW"; - break; - case GL_STACK_UNDERFLOW: - error = "STACK_UNDERFLOW"; - break; - case GL_OUT_OF_MEMORY: - error = "OUT_OF_MEMORY"; - break; - case GL_INVALID_FRAMEBUFFER_OPERATION: - error = "INVALID_FRAMEBUFFER_OPERATION"; - break; - } - std::cout << error << " | " << file << " (" << line << ")" << std::endl; - } - return errorCode; -} -#define glCheckError() glCheckError_(__FILE__, __LINE__) - -uui::GlBox::GlBox() -{ - std::cout << "Creating a GlBox" << std::endl; - - // Vertex shader compilation - GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); - { - auto vertex_src = readFile("bin/uui/opengl/shaders/main.vert"); - auto vertex_str = std::string(vertex_src.begin(), vertex_src.end()); - auto vertex_code = vertex_str.c_str(); - glShaderSource(vertex_shader, 1, &vertex_code, NULL); - glCompileShader(vertex_shader); - if constexpr(uui::GlApplication::debug_mode) - { - int success; - char info[512]; - glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success); - if(!success) - { - glGetShaderInfoLog(vertex_shader, 512, NULL, info); - std::cout << "GlBox vertex shader creation error : " << info << std::endl; - } - } - } - - // Fragment shader compilation - GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); - { - auto fragment_src = readFile("bin/uui/opengl/shaders/main.frag"); - auto fragment_str = std::string(fragment_src.begin(), fragment_src.end()); - auto fragment_code = fragment_str.c_str(); - glShaderSource(fragment_shader, 1, &fragment_code, NULL); - glCompileShader(fragment_shader); - if constexpr(uui::GlApplication::debug_mode) - { - int success; - char info[512]; - glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success); - if(!success) - { - glGetShaderInfoLog(fragment_shader, 512, NULL, info); - std::cout << "GlBox fragment shader creation error : " << info << std::endl; - } - } - } - - // Creating shader program - gl_program = glCreateProgram(); - glAttachShader(gl_program, vertex_shader); - if constexpr(uui::GlApplication::debug_mode) - glCheckError(); - glAttachShader(gl_program, fragment_shader); - if constexpr(uui::GlApplication::debug_mode) - glCheckError(); - glLinkProgram(gl_program); - if constexpr(uui::GlApplication::debug_mode) - { - int success; - char info[512]; - glGetProgramiv(gl_program, GL_LINK_STATUS, &success); - if(!success) - { - glGetProgramInfoLog(gl_program, 512, NULL, info); - std::cout << "GlBox error : " << info << std::endl; - } - } - glDeleteShader(vertex_shader); - glDeleteShader(fragment_shader); - - glGenVertexArrays(1, &gl_vao); - glGenBuffers(1, &gl_vbo); - glGenBuffers(1, &gl_ebo); - // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). - glBindVertexArray(gl_vao); - if constexpr(uui::GlApplication::debug_mode) - glCheckError(); - - // clang-format off - float vertices[] = { - 0.5f, 0.5f, 0.0f, // top right - 0.5f, -0.5f, 0.0f, // bottom right - -0.5f, -0.5f, 0.0f, // bottom left - -0.5f, 0.5f, 0.0f // top left - }; - // clang-format on - glBindBuffer(GL_ARRAY_BUFFER, gl_vbo); - if constexpr(uui::GlApplication::debug_mode) - glCheckError(); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - if constexpr(uui::GlApplication::debug_mode) - glCheckError(); - - glVertexAttribPointer( - 0, // index - 3, // size - GL_FLOAT, // type - GL_FALSE, // enable normalization, - 3 * sizeof(float), // stride - (void*)0 // offset - ); - glEnableVertexAttribArray(0); - - unsigned int indices[] = { - 0, 1, 3, // first triangle - 1, 2, 3 // second triangle - }; - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl_ebo); - if constexpr(uui::GlApplication::debug_mode) - glCheckError(); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); - if constexpr(uui::GlApplication::debug_mode) - glCheckError(); - - // unbinding VBO/VAO - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); -} - -uui::GlBox::~GlBox() -{ - std::cout << "Closing a GlBox" << std::endl; - glDeleteVertexArrays(1, &gl_vao); - glDeleteBuffers(1, &gl_vbo); - glDeleteBuffers(1, &gl_ebo); - glDeleteProgram(gl_program); -} - -void uui::GlBox::render() -{ - glUseProgram(gl_program); - glBindVertexArray(gl_vao); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0); - if constexpr(uui::GlApplication::debug_mode) - glCheckError(); -} diff --git a/src/uui/opengl/component.cpp b/src/uui/opengl/component.cpp new file mode 100644 index 0000000..f8267fc --- /dev/null +++ b/src/uui/opengl/component.cpp @@ -0,0 +1,122 @@ +#include "uui/opengl/component.hpp" + +#include + +#include "uui/opengl/application.hpp" +#include "uui/opengl/gl_utils.hpp" + +uui::GlComponent::GlComponent( + GlWindow* window, const std::variant x, const std::variant y, + const std::variant width, const std::variant height): + window(window), + position_x(x), position_y(y), size_width(width), size_height(height), initialized(false) +{ + std::cout << "Creating a GlBox" << std::endl; + + auto zero_to_float = [](std::variant& value) { + if(value.index() == 0 && std::get<0>(value) == 0) + value = 0.0f; + }; + zero_to_float(position_x); + zero_to_float(position_y); + zero_to_float(size_width); + zero_to_float(size_height); + + background_color = {0.0f, 0.0f, 0.0f, 0.0f}; +} + +uui::GlComponent::~GlComponent() +{ + std::cout << "Closing a GlBox" << std::endl; + if(initialized) + deinit(); +} + +void uui::GlComponent::init() +{ + if(initialized) + throw std::runtime_error("GlBox error : calling init while already initialized"); + + glGenVertexArrays(1, &gl_vao); + glGenBuffers(1, &gl_vbo); + glGenBuffers(1, &gl_ebo); + // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). + glBindVertexArray(gl_vao); + if constexpr(uui::GlApplication::debug_mode) + _glCheckError(); + + { + float vert_x = position_x.index() == 1 ? std::get<1>(position_x) + : static_cast(std::get<0>(position_x)) / static_cast(window->width); + float vert_y = position_y.index() == 1 ? std::get<1>(position_y) + : static_cast(std::get<0>(position_y)) / static_cast(window->height); + float vert_w = size_width.index() == 1 ? std::get<1>(size_width) + : static_cast(std::get<0>(size_width)) / static_cast(window->width); + float vert_h = size_height.index() == 1 ? std::get<1>(size_height) + : static_cast(std::get<0>(size_height)) / static_cast(window->height); + float x_min = (2.0f * vert_x) - 1.0f; + float x_max = x_min + (2.0f * vert_w); + float y_min = (-2.0f * vert_y) + 1.0f; + float y_max = y_min - (2.0f * vert_h); + // clang-format off + float vertices[] = { + x_max, y_min, 0.0f, // top right + x_max, y_max, 0.0f, // bottom right + x_min, y_max, 0.0f, // bottom left + x_min, y_min, 0.0f // top left + }; + // clang-format on + glBindBuffer(GL_ARRAY_BUFFER, gl_vbo); + if constexpr(uui::GlApplication::debug_mode) + _glCheckError(); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + if constexpr(uui::GlApplication::debug_mode) + _glCheckError(); + } + + glVertexAttribPointer( + 0, // index + 3, // size + GL_FLOAT, // type + GL_FALSE, // enable normalization, + 3 * sizeof(float), // stride + (void*)0 // offset + ); + glEnableVertexAttribArray(0); + + unsigned int indices[] = { + 0, 1, 3, // first triangle + 1, 2, 3 // second triangle + }; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl_ebo); + if constexpr(uui::GlApplication::debug_mode) + _glCheckError(); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + if constexpr(uui::GlApplication::debug_mode) + _glCheckError(); + + // unbinding VBO/VAO + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + + initialized = true; +} + +void uui::GlComponent::deinit() +{ + if(!initialized) + throw std::runtime_error("GlBox error : calling deinit while not initialized"); + + glDeleteVertexArrays(1, &gl_vao); + glDeleteBuffers(1, &gl_vbo); + glDeleteBuffers(1, &gl_ebo); + initialized = false; +} + +void uui::GlComponent::render() +{ + glBindVertexArray(gl_vao); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0); + if constexpr(uui::GlApplication::debug_mode) + _glCheckError(); +} diff --git a/src/uui/opengl/gl_utils.cpp b/src/uui/opengl/gl_utils.cpp new file mode 100644 index 0000000..19c4326 --- /dev/null +++ b/src/uui/opengl/gl_utils.cpp @@ -0,0 +1,39 @@ +#include "uui/opengl/gl_utils.hpp" + +#include +#include + +GLenum uui::gl::glCheckError(const char* file, int line) +{ + GLenum errorCode; + while((errorCode = glGetError()) != GL_NO_ERROR) + { + std::string error; + switch(errorCode) + { + case GL_INVALID_ENUM: + error = "INVALID_ENUM"; + break; + case GL_INVALID_VALUE: + error = "INVALID_VALUE"; + break; + case GL_INVALID_OPERATION: + error = "INVALID_OPERATION"; + break; + case GL_STACK_OVERFLOW: + error = "STACK_OVERFLOW"; + break; + case GL_STACK_UNDERFLOW: + error = "STACK_UNDERFLOW"; + break; + case GL_OUT_OF_MEMORY: + error = "OUT_OF_MEMORY"; + break; + case GL_INVALID_FRAMEBUFFER_OPERATION: + error = "INVALID_FRAMEBUFFER_OPERATION"; + break; + } + std::cout << error << " | " << file << " (" << line << ")" << std::endl; + } + return errorCode; +} diff --git a/src/uui/opengl/shaders/main.frag b/src/uui/opengl/shaders/main.frag index f1f1dfe..78f4aca 100644 --- a/src/uui/opengl/shaders/main.frag +++ b/src/uui/opengl/shaders/main.frag @@ -1,4 +1,5 @@ #version 460 core + out vec4 FragColor; void main() diff --git a/src/uui/opengl/window.cpp b/src/uui/opengl/window.cpp index 4692147..85b8512 100644 --- a/src/uui/opengl/window.cpp +++ b/src/uui/opengl/window.cpp @@ -2,7 +2,9 @@ #include -#include "uui/opengl/box.hpp" +#include "uui/opengl/component.hpp" +#include "uui/opengl/gl_utils.hpp" +#include "uui/shader.hpp" static void APIENTRY glDebugOutput(GLenum source, GLenum type, unsigned int id, GLenum severity, GLsizei length, const char* message, const void* userParam) @@ -49,9 +51,12 @@ glDebugOutput(GLenum source, GLenum type, unsigned int id, GLenum severity, GLsi std::cout << std::endl; } -static void glfw_resize_callback(GLFWwindow* window, int width, int height) +void uui::GlWindow::glfw_resize_callback(GLFWwindow* window, int width, int height) { glfwMakeContextCurrent(window); + auto gl_window = reinterpret_cast(glfwGetWindowUserPointer(window)); + gl_window->width = width; + gl_window->height = height; glViewport(0, 0, width, height); } @@ -61,7 +66,8 @@ static void glfw_key_callback(GLFWwindow* window, int key, int scancode, int act glfwSetWindowShouldClose(window, true); } -uui::GlWindow::GlWindow(const uui::GlApplication& app, int width, int height, const std::string& title): app(app) +uui::GlWindow::GlWindow(const uui::GlApplication& app, int width, int height, const std::string& title): + app(app), width(width), height(height) { std::cout << "Creating a GlWindow" << std::endl; this->title = title; @@ -71,6 +77,7 @@ uui::GlWindow::GlWindow(const uui::GlApplication& app, int width, int height, co throw std::runtime_error("GLWindow : failed to create GLFW window"); glfwMakeContextCurrent(glfw_window); + glfwSetWindowUserPointer(glfw_window, this); glfwSetFramebufferSizeCallback(glfw_window, glfw_resize_callback); glfwSetKeyCallback(glfw_window, glfw_key_callback); @@ -89,12 +96,78 @@ uui::GlWindow::GlWindow(const uui::GlApplication& app, int width, int height, co glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE); } } + + // Vertex shader compilation + GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); + { + auto vertex_src = readFile("bin/uui/opengl/shaders/main.vert"); + auto vertex_str = std::string(vertex_src.begin(), vertex_src.end()); + auto vertex_code = vertex_str.c_str(); + glShaderSource(vertex_shader, 1, &vertex_code, NULL); + glCompileShader(vertex_shader); + if constexpr(uui::GlApplication::debug_mode) + { + int success; + char info[512]; + glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success); + if(!success) + { + glGetShaderInfoLog(vertex_shader, 512, NULL, info); + std::cout << "GlBox vertex shader creation error : " << info << std::endl; + } + } + } + + // Fragment shader compilation + GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + { + auto fragment_src = readFile("bin/uui/opengl/shaders/main.frag"); + auto fragment_str = std::string(fragment_src.begin(), fragment_src.end()); + auto fragment_code = fragment_str.c_str(); + glShaderSource(fragment_shader, 1, &fragment_code, NULL); + glCompileShader(fragment_shader); + if constexpr(uui::GlApplication::debug_mode) + { + int success; + char info[512]; + glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success); + if(!success) + { + glGetShaderInfoLog(fragment_shader, 512, NULL, info); + std::cout << "GlBox fragment shader creation error : " << info << std::endl; + } + } + } + + // Creating shader program + gl_program = glCreateProgram(); + glAttachShader(gl_program, vertex_shader); + if constexpr(uui::GlApplication::debug_mode) + _glCheckError(); + glAttachShader(gl_program, fragment_shader); + if constexpr(uui::GlApplication::debug_mode) + _glCheckError(); + glLinkProgram(gl_program); + if constexpr(uui::GlApplication::debug_mode) + { + int success; + char info[512]; + glGetProgramiv(gl_program, GL_LINK_STATUS, &success); + if(!success) + { + glGetProgramInfoLog(gl_program, 512, NULL, info); + std::cout << "GlBox error : " << info << std::endl; + } + } + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); } uui::GlWindow::~GlWindow() { std::cout << "Closing a GlWindow" << std::endl; glfwMakeContextCurrent(glfw_window); + glDeleteProgram(gl_program); components.clear(); glfwDestroyWindow(glfw_window); } @@ -105,13 +178,20 @@ void uui::GlWindow::draw() glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); + glUseProgram(gl_program); for(auto& component: components) component->render(); glfwSwapBuffers(glfw_window); } -void uui::GlWindow::add_box() +std::weak_ptr uui::GlWindow::create_component( + const std::variant x, const std::variant y, const std::variant width, + const std::variant height) { glfwMakeContextCurrent(glfw_window); - components.push_back(std::make_unique()); + // std::shared_ptr self_ptr(this); + std::shared_ptr component(new uui::GlComponent(this, x, y, width, height)); + component->init(); + components.push_back(component); + return component; }