Remove inheritances, component implementation
This commit is contained in:
parent
748644b220
commit
20835586ab
15 changed files with 375 additions and 229 deletions
|
|
@ -11,7 +11,7 @@ class Application
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void run() = 0;
|
virtual void run() = 0;
|
||||||
virtual std::weak_ptr<Window> add_window(int width, int height, const std::string& title) = 0;
|
// virtual std::weak_ptr<Window> add_window(int width, int height, const std::string& title) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static bool application_created;
|
static bool application_created;
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,31 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
namespace uui
|
namespace uui
|
||||||
{
|
{
|
||||||
|
|
||||||
class Component
|
class Component
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Component(
|
||||||
|
const std::variant<int, float> x, const std::variant<int, float> y, const std::variant<int, float> width,
|
||||||
|
const std::variant<int, float> 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;
|
virtual void render() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::variant<int, float> position_x;
|
||||||
|
std::variant<int, float> position_y;
|
||||||
|
std::variant<int, float> size_width;
|
||||||
|
std::variant<int, float> size_height;
|
||||||
|
|
||||||
|
std::array<float, 4> background_color;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace uui
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,16 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "graphic_context.hpp"
|
#include "graphic_context.hpp"
|
||||||
#include "uui/application.hpp"
|
|
||||||
#include "uui/window.hpp"
|
|
||||||
|
|
||||||
namespace uui
|
namespace uui
|
||||||
{
|
{
|
||||||
|
|
||||||
class GlWindow;
|
class GlWindow;
|
||||||
class GlApplication: public Application
|
class GlApplication
|
||||||
{
|
{
|
||||||
friend class GlWindow;
|
friend class GlWindow;
|
||||||
|
|
||||||
|
|
@ -27,23 +26,45 @@ public:
|
||||||
~GlApplication();
|
~GlApplication();
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
std::weak_ptr<Window> add_window(int width, int height, const std::string& title);
|
std::weak_ptr<GlWindow> 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 GlApplication;
|
||||||
|
friend class GlComponent;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GlWindow(const GlApplication& app, int width, int height, const std::string& title);
|
std::string title;
|
||||||
|
std::vector<std::shared_ptr<GlComponent>> components;
|
||||||
|
|
||||||
|
GlWindow(const GlWindow&) = delete;
|
||||||
|
GlWindow(GlWindow&&) = delete;
|
||||||
~GlWindow();
|
~GlWindow();
|
||||||
|
|
||||||
void add_box();
|
std::weak_ptr<GlComponent> create_component(
|
||||||
|
const std::variant<int, float> x, const std::variant<int, float> y, const std::variant<int, float> width,
|
||||||
|
const std::variant<int, float> height);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const GlApplication& app;
|
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();
|
void draw();
|
||||||
|
|
||||||
|
static void glfw_resize_callback(GLFWwindow* window, int width, int height);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace uui
|
} // namespace uui
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
48
include/uui/opengl/component.hpp
Normal file
48
include/uui/opengl/component.hpp
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
// #include <memory>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
|
#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<GlWindow> window;
|
||||||
|
GlWindow* window;
|
||||||
|
|
||||||
|
std::variant<int, float> position_x;
|
||||||
|
std::variant<int, float> position_y;
|
||||||
|
std::variant<int, float> size_width;
|
||||||
|
std::variant<int, float> size_height;
|
||||||
|
|
||||||
|
std::array<float, 4> background_color;
|
||||||
|
|
||||||
|
bool initialized;
|
||||||
|
|
||||||
|
GLuint gl_vbo;
|
||||||
|
GLuint gl_vao;
|
||||||
|
GLuint gl_ebo;
|
||||||
|
|
||||||
|
GlComponent(
|
||||||
|
GlWindow* window, const std::variant<int, float> x, const std::variant<int, float> y,
|
||||||
|
const std::variant<int, float> width, const std::variant<int, float> height);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void deinit();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace uui
|
||||||
13
include/uui/opengl/gl_utils.hpp
Normal file
13
include/uui/opengl/gl_utils.hpp
Normal file
|
|
@ -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__)
|
||||||
|
|
@ -13,9 +13,8 @@ class Window
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string title;
|
std::string title;
|
||||||
std::vector<std::unique_ptr<Component>> components;
|
|
||||||
|
|
||||||
virtual void add_box() = 0;
|
virtual void add_component(const Component& box) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GLFWwindow* glfw_window;
|
GLFWwindow* glfw_window;
|
||||||
|
|
|
||||||
2
make.py
2
make.py
|
|
@ -36,7 +36,7 @@ def main():
|
||||||
for shader_path in (
|
for shader_path in (
|
||||||
list(src_opengl_shader_path.rglob('*.vert'))
|
list(src_opengl_shader_path.rglob('*.vert'))
|
||||||
+ list(src_opengl_shader_path.rglob('*.frag'))):
|
+ 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():
|
if not out_path.parent.exists():
|
||||||
out_path.parent.mkdir(parents=True)
|
out_path.parent.mkdir(parents=True)
|
||||||
shutil.copy(shader_path, out_path)
|
shutil.copy(shader_path, out_path)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "uui/opengl/application.hpp"
|
#include "uui/opengl/application.hpp"
|
||||||
|
#include "uui/opengl/component.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
@ -13,16 +14,17 @@ int main()
|
||||||
{
|
{
|
||||||
uui::GlApplication app;
|
uui::GlApplication app;
|
||||||
// uui::GlApplication app2; // exception : application already created
|
// uui::GlApplication app2; // exception : application already created
|
||||||
auto window_1 = app.add_window(800, 600, "OpenGl!");
|
auto window_1 = app.create_window(800, 600, "OpenGl!");
|
||||||
window_1.lock()->add_box();
|
window_1.lock()->create_component(0, 1, 0.5f, 50);
|
||||||
app.run();
|
app.run();
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
uui::GlApplication app;
|
uui::GlApplication app;
|
||||||
auto window_1 = app.add_window(800, 600, "OpenGl!");
|
auto window_1 = app.create_window(800, 600, "OpenGl!");
|
||||||
window_1.lock()->add_box();
|
window_1.lock()->create_component(0.25f, 0.25f, 0.5f, 0.5f);
|
||||||
auto window_2 = app.add_window(600, 600, "OpenGL 2!");
|
window_1.lock()->create_component(0.75f, 0.75f, 0.25f, 0.25f);
|
||||||
window_2.lock()->add_box();
|
auto window_2 = app.create_window(600, 600, "OpenGL 2!");
|
||||||
|
window_2.lock()->create_component(0, 0.5f, 100, 0.5f);
|
||||||
app.run();
|
app.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
bool uui::GlApplication::application_created = false;
|
||||||
|
|
||||||
uui::GlApplication::GlApplication()
|
uui::GlApplication::GlApplication()
|
||||||
{
|
{
|
||||||
if(application_created)
|
if(application_created)
|
||||||
|
|
@ -76,14 +78,15 @@ void uui::GlApplication::run()
|
||||||
std::cout << "Ending the GlApplication" << std::endl;
|
std::cout << "Ending the GlApplication" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::weak_ptr<uui::Window> uui::GlApplication::add_window(int width, int height, const std::string& title)
|
std::weak_ptr<uui::GlWindow> uui::GlApplication::create_window(int width, int height, const std::string& title)
|
||||||
{
|
{
|
||||||
windows.push_back(std::make_unique<GlWindow>(*this, width, height, title));
|
std::shared_ptr<uui::GlWindow> window(new uui::GlWindow(*this, width, height, title));
|
||||||
|
windows.push_back(window);
|
||||||
glfwSwapInterval(1);
|
glfwSwapInterval(1);
|
||||||
if(windows.size() > 1)
|
if(windows.size() > 1)
|
||||||
{
|
{
|
||||||
glfwMakeContextCurrent((*(windows.end() - 2))->glfw_window);
|
glfwMakeContextCurrent((*(windows.end() - 2))->glfw_window);
|
||||||
glfwSwapInterval(0);
|
glfwSwapInterval(0);
|
||||||
}
|
}
|
||||||
return windows.back();
|
return window;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,178 +0,0 @@
|
||||||
#include "uui/opengl/box.hpp"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#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();
|
|
||||||
}
|
|
||||||
122
src/uui/opengl/component.cpp
Normal file
122
src/uui/opengl/component.cpp
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
#include "uui/opengl/component.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "uui/opengl/application.hpp"
|
||||||
|
#include "uui/opengl/gl_utils.hpp"
|
||||||
|
|
||||||
|
uui::GlComponent::GlComponent(
|
||||||
|
GlWindow* window, const std::variant<int, float> x, const std::variant<int, float> y,
|
||||||
|
const std::variant<int, float> width, const std::variant<int, float> 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<int, float>& 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<float>(std::get<0>(position_x)) / static_cast<float>(window->width);
|
||||||
|
float vert_y = position_y.index() == 1 ? std::get<1>(position_y)
|
||||||
|
: static_cast<float>(std::get<0>(position_y)) / static_cast<float>(window->height);
|
||||||
|
float vert_w = size_width.index() == 1 ? std::get<1>(size_width)
|
||||||
|
: static_cast<float>(std::get<0>(size_width)) / static_cast<float>(window->width);
|
||||||
|
float vert_h = size_height.index() == 1 ? std::get<1>(size_height)
|
||||||
|
: static_cast<float>(std::get<0>(size_height)) / static_cast<float>(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();
|
||||||
|
}
|
||||||
39
src/uui/opengl/gl_utils.cpp
Normal file
39
src/uui/opengl/gl_utils.cpp
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
#include "uui/opengl/gl_utils.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#version 460 core
|
#version 460 core
|
||||||
|
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "uui/opengl/box.hpp"
|
#include "uui/opengl/component.hpp"
|
||||||
|
#include "uui/opengl/gl_utils.hpp"
|
||||||
|
#include "uui/shader.hpp"
|
||||||
|
|
||||||
static void APIENTRY
|
static void APIENTRY
|
||||||
glDebugOutput(GLenum source, GLenum type, unsigned int id, GLenum severity, GLsizei length, const char* message, const void* userParam)
|
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;
|
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);
|
glfwMakeContextCurrent(window);
|
||||||
|
auto gl_window = reinterpret_cast<uui::GlWindow*>(glfwGetWindowUserPointer(window));
|
||||||
|
gl_window->width = width;
|
||||||
|
gl_window->height = height;
|
||||||
glViewport(0, 0, width, 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);
|
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;
|
std::cout << "Creating a GlWindow" << std::endl;
|
||||||
this->title = title;
|
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");
|
throw std::runtime_error("GLWindow : failed to create GLFW window");
|
||||||
glfwMakeContextCurrent(glfw_window);
|
glfwMakeContextCurrent(glfw_window);
|
||||||
|
|
||||||
|
glfwSetWindowUserPointer(glfw_window, this);
|
||||||
glfwSetFramebufferSizeCallback(glfw_window, glfw_resize_callback);
|
glfwSetFramebufferSizeCallback(glfw_window, glfw_resize_callback);
|
||||||
glfwSetKeyCallback(glfw_window, glfw_key_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);
|
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()
|
uui::GlWindow::~GlWindow()
|
||||||
{
|
{
|
||||||
std::cout << "Closing a GlWindow" << std::endl;
|
std::cout << "Closing a GlWindow" << std::endl;
|
||||||
glfwMakeContextCurrent(glfw_window);
|
glfwMakeContextCurrent(glfw_window);
|
||||||
|
glDeleteProgram(gl_program);
|
||||||
components.clear();
|
components.clear();
|
||||||
glfwDestroyWindow(glfw_window);
|
glfwDestroyWindow(glfw_window);
|
||||||
}
|
}
|
||||||
|
|
@ -105,13 +178,20 @@ void uui::GlWindow::draw()
|
||||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
glUseProgram(gl_program);
|
||||||
for(auto& component: components) component->render();
|
for(auto& component: components) component->render();
|
||||||
|
|
||||||
glfwSwapBuffers(glfw_window);
|
glfwSwapBuffers(glfw_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uui::GlWindow::add_box()
|
std::weak_ptr<uui::GlComponent> uui::GlWindow::create_component(
|
||||||
|
const std::variant<int, float> x, const std::variant<int, float> y, const std::variant<int, float> width,
|
||||||
|
const std::variant<int, float> height)
|
||||||
{
|
{
|
||||||
glfwMakeContextCurrent(glfw_window);
|
glfwMakeContextCurrent(glfw_window);
|
||||||
components.push_back(std::make_unique<GlBox>());
|
// std::shared_ptr<uui::GlWindow> self_ptr(this);
|
||||||
|
std::shared_ptr<uui::GlComponent> component(new uui::GlComponent(this, x, y, width, height));
|
||||||
|
component->init();
|
||||||
|
components.push_back(component);
|
||||||
|
return component;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue