Correct resize and safer pointers

This commit is contained in:
Corentin 2021-07-07 15:57:26 +09:00
commit 3b2be83590
9 changed files with 193 additions and 81 deletions

View file

@ -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();
}
}

View file

@ -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];
}

View file

@ -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
}
}

View file

@ -2,7 +2,9 @@
out vec4 FragColor;
in vec4 backgroundColor;
void main()
{
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
FragColor = backgroundColor;
}

View file

@ -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;
}

View file

@ -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;