Correct resize and safer pointers
This commit is contained in:
parent
20835586ab
commit
3b2be83590
9 changed files with 193 additions and 81 deletions
|
|
@ -26,10 +26,11 @@ public:
|
|||
~GlApplication();
|
||||
|
||||
void run();
|
||||
std::weak_ptr<GlWindow> create_window(int width, int height, const std::string& title);
|
||||
std::shared_ptr<GlWindow> create_window(int width, int height, const std::string& title);
|
||||
std::shared_ptr<GlWindow> get_window(size_t index) const;
|
||||
|
||||
private:
|
||||
static bool application_created;
|
||||
static GlApplication* application_pointer;
|
||||
};
|
||||
|
||||
class GlComponent;
|
||||
|
|
@ -46,22 +47,28 @@ public:
|
|||
GlWindow(GlWindow&&) = delete;
|
||||
~GlWindow();
|
||||
|
||||
std::weak_ptr<GlComponent> create_component(
|
||||
std::shared_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:
|
||||
const GlApplication& app;
|
||||
GlApplication* app;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
bool need_resize_refresh;
|
||||
|
||||
size_t index;
|
||||
bool initialized;
|
||||
|
||||
GLFWwindow* glfw_window;
|
||||
|
||||
GLuint gl_program;
|
||||
|
||||
GlWindow(const GlApplication& app, int width, int height, const std::string& title);
|
||||
GlWindow(GlApplication* app, size_t index, int width, int height, const std::string& title);
|
||||
|
||||
void init();
|
||||
void deinit();
|
||||
void draw();
|
||||
|
||||
static void glfw_resize_callback(GLFWwindow* window, int width, int height);
|
||||
|
|
|
|||
|
|
@ -18,16 +18,16 @@ public:
|
|||
GlComponent(GlComponent&&) = delete;
|
||||
~GlComponent();
|
||||
|
||||
void render();
|
||||
void set_background_color(float r, float g, float b, float a = 0.0f);
|
||||
|
||||
private:
|
||||
// std::weak_ptr<GlWindow> window;
|
||||
GlWindow* window;
|
||||
std::shared_ptr<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;
|
||||
bool coord_all_relative;
|
||||
|
||||
std::array<float, 4> background_color;
|
||||
|
||||
|
|
@ -38,11 +38,14 @@ private:
|
|||
GLuint gl_ebo;
|
||||
|
||||
GlComponent(
|
||||
GlWindow* window, const std::variant<int, float> x, const std::variant<int, float> y,
|
||||
std::shared_ptr<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 set_vbo_data();
|
||||
void deinit();
|
||||
void render();
|
||||
void on_resize();
|
||||
};
|
||||
|
||||
} // namespace uui
|
||||
|
|
|
|||
19
make.py
19
make.py
|
|
@ -4,7 +4,7 @@ import os
|
|||
from pathlib import Path
|
||||
import shutil
|
||||
|
||||
from umake import make
|
||||
from umake import get_hash, make
|
||||
|
||||
|
||||
class Config:
|
||||
|
|
@ -31,17 +31,32 @@ class Config:
|
|||
|
||||
def main():
|
||||
def pre_compile():
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
# Compiling vulkan shaders
|
||||
# for shader_path in (
|
||||
# list((Config.SOURCE_DIR / 'uui' / 'vulkan').rglob('*.vert'))
|
||||
# + list((Config.SOURCE_DIR / 'uui' / 'vulkan').rglob('*.frag'))):
|
||||
# out_path = Config.BIN_DIR / shader_path.relative_to(Config.SOURCE_DIR)
|
||||
# if not out_path.parent.exists():
|
||||
# out_path.parent.mkdir(parents=True)
|
||||
# if subprocess.run(['glslc', str(shader_path), '-o', str(out_path) + '.spv']).returncode != 0:
|
||||
# print(f'Error while compiling shader {shader_path}')
|
||||
# return
|
||||
>>>>>>> 675cbbf (Correct resize and safer pointers)
|
||||
# Copying OpenGL shaders
|
||||
src_opengl_shader_path = Config.SOURCE_DIR / 'uui' / 'opengl' / 'shaders'
|
||||
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)
|
||||
if out_path.exists() and get_hash(shader_path) == get_hash(out_path):
|
||||
continue
|
||||
if not out_path.parent.exists():
|
||||
out_path.parent.mkdir(parents=True)
|
||||
shutil.copy(shader_path, out_path)
|
||||
|
||||
# Config.PRE_COMPILE_FUNCTION = pre_compile
|
||||
Config.PRE_COMPILE_FUNCTION = pre_compile
|
||||
make(Config)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,24 +7,28 @@ using namespace std;
|
|||
|
||||
int main()
|
||||
{
|
||||
cout << "Example Staring" << endl;
|
||||
|
||||
try
|
||||
{
|
||||
cout << "Starting example 1" << endl;
|
||||
{
|
||||
uui::GlApplication app;
|
||||
// uui::GlApplication app2; // exception : application already created
|
||||
auto window_1 = app.create_window(800, 600, "OpenGl!");
|
||||
window_1.lock()->create_component(0, 1, 0.5f, 50);
|
||||
auto window = app.create_window(800, 600, "OpenGl!");
|
||||
auto comp = window->create_component(0, 100, 0.5f, 50);
|
||||
comp->set_background_color(0.8f, 0.1f, 0.5f);
|
||||
app.run();
|
||||
}
|
||||
cout << "\nStarting example 2" << endl;
|
||||
{
|
||||
uui::GlApplication app;
|
||||
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 comp = window_1->create_component(0.25f, 0.25f, 0.5f, 0.5f);
|
||||
comp->set_background_color(0.8f, 0.1f, 0.5f);
|
||||
comp = window_1->create_component(0.75f, 0.75f, 0.25f, 0.25f);
|
||||
comp->set_background_color(0.2f, 0.1f, 0.5f);
|
||||
auto window_2 = app.create_window(600, 600, "OpenGL 2!");
|
||||
window_2.lock()->create_component(0, 0.5f, 100, 0.5f);
|
||||
comp = window_2->create_component(0, 0.5f, 100, 0.5f);
|
||||
comp->set_background_color(0.2f, 0.5f, 0.3f);
|
||||
app.run();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@
|
|||
#include <chrono>
|
||||
#include <iostream>
|
||||
|
||||
bool uui::GlApplication::application_created = false;
|
||||
uui::GlApplication* uui::GlApplication::application_pointer = nullptr;
|
||||
|
||||
uui::GlApplication::GlApplication()
|
||||
{
|
||||
if(application_created)
|
||||
if(application_pointer != nullptr)
|
||||
throw std::runtime_error("GlApplication error: the application already created");
|
||||
if constexpr(debug_mode)
|
||||
std::cout << "Creating the GlApplication in debug mode" << std::endl;
|
||||
|
|
@ -23,7 +23,7 @@ uui::GlApplication::GlApplication()
|
|||
if constexpr(uui::GlApplication::debug_mode)
|
||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
|
||||
|
||||
application_created = true;
|
||||
application_pointer = this;
|
||||
}
|
||||
|
||||
uui::GlApplication::~GlApplication()
|
||||
|
|
@ -31,7 +31,7 @@ uui::GlApplication::~GlApplication()
|
|||
std::cout << "Destroying the GlApplication" << std::endl;
|
||||
windows.clear();
|
||||
glfwTerminate();
|
||||
application_created = false;
|
||||
application_pointer = nullptr;
|
||||
}
|
||||
|
||||
void uui::GlApplication::run()
|
||||
|
|
@ -67,6 +67,7 @@ void uui::GlApplication::run()
|
|||
glfwMakeContextCurrent((*(windows.end() - 2))->glfw_window);
|
||||
glfwSwapInterval(1);
|
||||
}
|
||||
window->deinit();
|
||||
windows.erase(it);
|
||||
it -= 1;
|
||||
}
|
||||
|
|
@ -78,9 +79,10 @@ void uui::GlApplication::run()
|
|||
std::cout << "Ending the GlApplication" << std::endl;
|
||||
}
|
||||
|
||||
std::weak_ptr<uui::GlWindow> uui::GlApplication::create_window(int width, int height, const std::string& title)
|
||||
std::shared_ptr<uui::GlWindow> uui::GlApplication::create_window(int width, int height, const std::string& title)
|
||||
{
|
||||
std::shared_ptr<uui::GlWindow> window(new uui::GlWindow(*this, width, height, title));
|
||||
std::shared_ptr<uui::GlWindow> window(new uui::GlWindow(this, windows.size(), width, height, title));
|
||||
window->init();
|
||||
windows.push_back(window);
|
||||
glfwSwapInterval(1);
|
||||
if(windows.size() > 1)
|
||||
|
|
@ -90,3 +92,10 @@ std::weak_ptr<uui::GlWindow> uui::GlApplication::create_window(int width, int he
|
|||
}
|
||||
return window;
|
||||
}
|
||||
|
||||
std::shared_ptr<uui::GlWindow> uui::GlApplication::get_window(size_t index) const
|
||||
{
|
||||
if(index > windows.size())
|
||||
throw std::runtime_error("Application doesn't have window at given index");
|
||||
return windows[index];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,21 +6,27 @@
|
|||
#include "uui/opengl/gl_utils.hpp"
|
||||
|
||||
uui::GlComponent::GlComponent(
|
||||
GlWindow* window, const std::variant<int, float> x, const std::variant<int, float> y,
|
||||
std::shared_ptr<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;
|
||||
coord_all_relative = true;
|
||||
auto parse_coords = [&](std::variant<int, float>& value) {
|
||||
if(value.index() == 0)
|
||||
{
|
||||
if(std::get<0>(value) == 0)
|
||||
value = 0.0f;
|
||||
else
|
||||
coord_all_relative = false;
|
||||
}
|
||||
};
|
||||
zero_to_float(position_x);
|
||||
zero_to_float(position_y);
|
||||
zero_to_float(size_width);
|
||||
zero_to_float(size_height);
|
||||
parse_coords(position_x);
|
||||
parse_coords(position_y);
|
||||
parse_coords(size_width);
|
||||
parse_coords(size_height);
|
||||
|
||||
background_color = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
}
|
||||
|
|
@ -32,6 +38,14 @@ uui::GlComponent::~GlComponent()
|
|||
deinit();
|
||||
}
|
||||
|
||||
void uui::GlComponent::set_background_color(float r, float g, float b, float a)
|
||||
{
|
||||
background_color = {r, g, b, a};
|
||||
glBindVertexArray(gl_vao);
|
||||
set_vbo_data();
|
||||
glBindVertexArray(0); // Optional : for safety
|
||||
}
|
||||
|
||||
void uui::GlComponent::init()
|
||||
{
|
||||
if(initialized)
|
||||
|
|
@ -45,44 +59,7 @@ void uui::GlComponent::init()
|
|||
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);
|
||||
set_vbo_data();
|
||||
|
||||
unsigned int indices[] = {
|
||||
0, 1, 3, // first triangle
|
||||
|
|
@ -102,6 +79,55 @@ void uui::GlComponent::init()
|
|||
initialized = true;
|
||||
}
|
||||
|
||||
void uui::GlComponent::set_vbo_data()
|
||||
{
|
||||
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, background_color[0] , background_color[1], background_color[2], background_color[3], // top right
|
||||
x_max, y_max, 0.0f, background_color[0] , background_color[1], background_color[2], background_color[3], // bottom right
|
||||
x_min, y_max, 0.0f, background_color[0] , background_color[1], background_color[2], background_color[3], // bottom left
|
||||
x_min, y_min, 0.0f, background_color[0] , background_color[1], background_color[2], background_color[3] // 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,
|
||||
7 * sizeof(float), // stride
|
||||
(void*)0 // offset
|
||||
);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(
|
||||
1, // index
|
||||
3, // size
|
||||
GL_FLOAT, // type
|
||||
GL_FALSE, // enable normalization,
|
||||
7 * sizeof(float), // stride
|
||||
(void*)(3 * sizeof(float)) // offset
|
||||
);
|
||||
glEnableVertexAttribArray(1);
|
||||
}
|
||||
|
||||
void uui::GlComponent::deinit()
|
||||
{
|
||||
if(!initialized)
|
||||
|
|
@ -120,3 +146,13 @@ void uui::GlComponent::render()
|
|||
if constexpr(uui::GlApplication::debug_mode)
|
||||
_glCheckError();
|
||||
}
|
||||
|
||||
void uui::GlComponent::on_resize()
|
||||
{
|
||||
if(!coord_all_relative)
|
||||
{
|
||||
glBindVertexArray(gl_vao);
|
||||
set_vbo_data();
|
||||
glBindVertexArray(0); // Optional : for safety
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec4 backgroundColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
|
||||
FragColor = backgroundColor;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
#version 460 core
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 0) in vec3 vPos;
|
||||
layout (location = 1) in vec4 vBackgroundColor;
|
||||
|
||||
out vec4 backgroundColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
|
||||
gl_Position = vec4(vPos.x, vPos.y, vPos.z, 1.0);
|
||||
backgroundColor = vBackgroundColor;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,9 +55,10 @@ void uui::GlWindow::glfw_resize_callback(GLFWwindow* window, int width, int heig
|
|||
{
|
||||
glfwMakeContextCurrent(window);
|
||||
auto gl_window = reinterpret_cast<uui::GlWindow*>(glfwGetWindowUserPointer(window));
|
||||
glViewport(0, 0, width, height);
|
||||
gl_window->width = width;
|
||||
gl_window->height = height;
|
||||
glViewport(0, 0, width, height);
|
||||
gl_window->need_resize_refresh = true;
|
||||
}
|
||||
|
||||
static void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||
|
|
@ -66,11 +67,27 @@ 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), width(width), height(height)
|
||||
uui::GlWindow::GlWindow(uui::GlApplication* app, size_t index, int width, int height, const std::string& title):
|
||||
app(app), width(width), height(height), need_resize_refresh(false), index(index), initialized(false)
|
||||
{
|
||||
std::cout << "Creating a GlWindow" << std::endl;
|
||||
this->title = title;
|
||||
}
|
||||
|
||||
uui::GlWindow::~GlWindow()
|
||||
{
|
||||
std::cout << "Closing a GlWindow" << std::endl;
|
||||
if(initialized)
|
||||
{
|
||||
std::cout << "Destructor-deinit a GlWindow" << std::endl;
|
||||
deinit();
|
||||
}
|
||||
}
|
||||
|
||||
void uui::GlWindow::init()
|
||||
{
|
||||
if(initialized)
|
||||
throw std::runtime_error("GlWindow error : calling init while already initialized");
|
||||
|
||||
glfw_window = glfwCreateWindow(width, height, title.c_str(), NULL, NULL);
|
||||
if(glfw_window == NULL)
|
||||
|
|
@ -161,15 +178,23 @@ uui::GlWindow::GlWindow(const uui::GlApplication& app, int width, int height, co
|
|||
}
|
||||
glDeleteShader(vertex_shader);
|
||||
glDeleteShader(fragment_shader);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
uui::GlWindow::~GlWindow()
|
||||
void uui::GlWindow::deinit()
|
||||
{
|
||||
std::cout << "Closing a GlWindow" << std::endl;
|
||||
if(!initialized)
|
||||
throw std::runtime_error("GlWindow error : calling deinit while not initialized");
|
||||
|
||||
std::cout << "Deinit a GlWindow" << std::endl;
|
||||
|
||||
glfwMakeContextCurrent(glfw_window);
|
||||
glDeleteProgram(gl_program);
|
||||
for(auto& component: components) component->deinit();
|
||||
components.clear();
|
||||
glfwDestroyWindow(glfw_window);
|
||||
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
void uui::GlWindow::draw()
|
||||
|
|
@ -179,18 +204,25 @@ void uui::GlWindow::draw()
|
|||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glUseProgram(gl_program);
|
||||
if(need_resize_refresh)
|
||||
{
|
||||
for(auto& component: components) component->on_resize();
|
||||
need_resize_refresh = false;
|
||||
}
|
||||
for(auto& component: components) component->render();
|
||||
|
||||
glfwSwapBuffers(glfw_window);
|
||||
}
|
||||
|
||||
std::weak_ptr<uui::GlComponent> uui::GlWindow::create_component(
|
||||
std::shared_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)
|
||||
{
|
||||
if(!initialized)
|
||||
throw std::runtime_error("GlWindow error : cannot create component while not initialized");
|
||||
|
||||
glfwMakeContextCurrent(glfw_window);
|
||||
// std::shared_ptr<uui::GlWindow> self_ptr(this);
|
||||
std::shared_ptr<uui::GlComponent> component(new uui::GlComponent(this, x, y, width, height));
|
||||
std::shared_ptr<uui::GlComponent> component(new uui::GlComponent(app->get_window(index), x, y, width, height));
|
||||
component->init();
|
||||
components.push_back(component);
|
||||
return component;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue