Box implementation, improved window API
This commit is contained in:
parent
1ae16b306f
commit
988b0bdbcd
12 changed files with 224 additions and 27 deletions
|
|
@ -1,13 +1,16 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "window.hpp"
|
||||||
|
|
||||||
namespace uui
|
namespace uui
|
||||||
{
|
{
|
||||||
class Application
|
class Application
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void run() = 0;
|
virtual void run() = 0;
|
||||||
virtual void 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;
|
||||||
};
|
};
|
||||||
} // namespace uui
|
} // namespace uui
|
||||||
|
|
|
||||||
12
include/uui/component.hpp
Normal file
12
include/uui/component.hpp
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace uui
|
||||||
|
{
|
||||||
|
|
||||||
|
class Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void render() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -16,14 +16,18 @@ class GlApplication: public Application
|
||||||
friend class GlWindow;
|
friend class GlWindow;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
#ifdef DEBUG
|
||||||
|
constexpr static bool debug_mode = true;
|
||||||
|
#else
|
||||||
|
constexpr static bool debug_mode = false;
|
||||||
|
#endif
|
||||||
|
std::vector<std::shared_ptr<GlWindow>> windows;
|
||||||
|
|
||||||
GlApplication();
|
GlApplication();
|
||||||
~GlApplication();
|
~GlApplication();
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
void add_window(int width, int height, const std::string& title);
|
std::weak_ptr<Window> add_window(int width, int height, const std::string& title);
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<std::unique_ptr<GlWindow>> windows;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class GlWindow: public Window
|
class GlWindow: public Window
|
||||||
|
|
@ -34,6 +38,8 @@ public:
|
||||||
GlWindow(const GlApplication& app, int width, int height, const std::string& title);
|
GlWindow(const GlApplication& app, int width, int height, const std::string& title);
|
||||||
~GlWindow();
|
~GlWindow();
|
||||||
|
|
||||||
|
void add_box();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const GlApplication& app;
|
const GlApplication& app;
|
||||||
|
|
||||||
|
|
|
||||||
22
include/uui/opengl/box.hpp
Normal file
22
include/uui/opengl/box.hpp
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#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_program;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace uui
|
||||||
|
|
@ -1,22 +1,25 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
|
||||||
#include <optional>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "graphic_context.hpp"
|
#include "graphic_context.hpp"
|
||||||
|
#include "uui/component.hpp"
|
||||||
|
|
||||||
|
namespace uui
|
||||||
|
{
|
||||||
class Window
|
class Window
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string title;
|
std::string title;
|
||||||
|
std::vector<std::unique_ptr<Component>> components;
|
||||||
|
|
||||||
virtual void draw() = 0;
|
virtual void add_box() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GLFWwindow* glfw_window;
|
GLFWwindow* glfw_window;
|
||||||
|
|
||||||
|
virtual void draw() = 0;
|
||||||
};
|
};
|
||||||
|
} // namespace uui
|
||||||
|
|
|
||||||
15
make.py
15
make.py
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import shutil
|
||||||
|
|
||||||
from umake import make
|
from umake import make
|
||||||
|
|
||||||
|
|
@ -30,14 +31,16 @@ class Config:
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
def pre_compile():
|
def pre_compile():
|
||||||
# Compiling fragment shaders
|
# Copying OpenGL shaders
|
||||||
for frag_path in Config.SOURCE_DIR.rglob('*.frag'):
|
src_opengl_shader_path = Config.SOURCE_DIR / 'uui' / 'opengl' / 'shaders'
|
||||||
out_path = (Config.BIN_DIR / frag_path.relative_to(Config.SOURCE_DIR))
|
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 not out_path.parent.exists():
|
if not out_path.parent.exists():
|
||||||
out_path.parent.mkdir(parents=True)
|
out_path.parent.mkdir(parents=True)
|
||||||
if subprocess.run(['glslc', str(frag_path), '-o', str(out_path) + '.spv']).returncode != 0:
|
shutil.copy(shader_path, out_path)
|
||||||
print(f'Error while compiling fragment shader {frag_path}')
|
|
||||||
return
|
|
||||||
Config.PRE_COMPILE_FUNCTION = pre_compile
|
Config.PRE_COMPILE_FUNCTION = pre_compile
|
||||||
make(Config)
|
make(Config)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,10 @@ int main()
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
uui::GlApplication app;
|
uui::GlApplication app;
|
||||||
app.add_window(800, 600, "Vulkan!");
|
auto window_1 = app.add_window(800, 600, "OpenGl!");
|
||||||
app.add_window(600, 600, "Vulkan 2!");
|
window_1.lock()->add_box();
|
||||||
|
auto window_2 = app.add_window(600, 600, "OpenGL 2!");
|
||||||
|
window_2.lock()->add_box();
|
||||||
app.run();
|
app.run();
|
||||||
}
|
}
|
||||||
catch(const std::exception& error)
|
catch(const std::exception& error)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
#include "uui/opengl/application.hpp"
|
#include "uui/opengl/application.hpp"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
uui::GlApplication::GlApplication()
|
uui::GlApplication::GlApplication()
|
||||||
{
|
{
|
||||||
|
std::cout << "Creating the GlApplication" << std::endl;
|
||||||
// Init GLFW
|
// Init GLFW
|
||||||
glfwInit();
|
glfwInit();
|
||||||
// Set all the required options for GLFW
|
// Set all the required options for GLFW
|
||||||
|
|
@ -13,12 +16,14 @@ uui::GlApplication::GlApplication()
|
||||||
|
|
||||||
uui::GlApplication::~GlApplication()
|
uui::GlApplication::~GlApplication()
|
||||||
{
|
{
|
||||||
|
std::cout << "Destroying the GlApplication" << std::endl;
|
||||||
|
windows.clear();
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void uui::GlApplication::run()
|
void uui::GlApplication::run()
|
||||||
{
|
{
|
||||||
std::cout << "Starting the Application" << std::endl;
|
std::cout << "Starting the GlApplication" << std::endl;
|
||||||
|
|
||||||
auto start_time = std::chrono::high_resolution_clock::now();
|
auto start_time = std::chrono::high_resolution_clock::now();
|
||||||
auto end_time = start_time;
|
auto end_time = start_time;
|
||||||
|
|
@ -57,10 +62,10 @@ void uui::GlApplication::run()
|
||||||
}
|
}
|
||||||
frame_count += 1;
|
frame_count += 1;
|
||||||
}
|
}
|
||||||
std::cout << "Ending the Application" << std::endl;
|
std::cout << "Ending the GlApplication" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uui::GlApplication::add_window(int width, int height, const std::string& title)
|
std::weak_ptr<uui::Window> uui::GlApplication::add_window(int width, int height, const std::string& title)
|
||||||
{
|
{
|
||||||
windows.push_back(std::make_unique<GlWindow>(*this, width, height, title));
|
windows.push_back(std::make_unique<GlWindow>(*this, width, height, title));
|
||||||
glfwSwapInterval(1);
|
glfwSwapInterval(1);
|
||||||
|
|
@ -69,4 +74,5 @@ void uui::GlApplication::add_window(int width, int height, const std::string& ti
|
||||||
glfwMakeContextCurrent((*(windows.end() - 2))->glfw_window);
|
glfwMakeContextCurrent((*(windows.end() - 2))->glfw_window);
|
||||||
glfwSwapInterval(0);
|
glfwSwapInterval(0);
|
||||||
}
|
}
|
||||||
|
return windows.back();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
114
src/uui/opengl/box.cpp
Normal file
114
src/uui/opengl/box.cpp
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
#include "uui/opengl/box.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "uui/opengl/application.hpp"
|
||||||
|
#include "uui/shader.hpp"
|
||||||
|
|
||||||
|
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_code = vertex_src.data();
|
||||||
|
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 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_code = fragment_src.data();
|
||||||
|
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 error : " << info << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creating shader program
|
||||||
|
gl_program = glCreateProgram();
|
||||||
|
glAttachShader(gl_program, vertex_shader);
|
||||||
|
glAttachShader(gl_program, fragment_shader);
|
||||||
|
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);
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
float vertices[] = {
|
||||||
|
-0.5f, -0.5f, 0.0f,
|
||||||
|
0.5f, -0.5f, 0.0f,
|
||||||
|
0.0f, 0.5f, 0.0f
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
glGenVertexArrays(1, &gl_vao);
|
||||||
|
glGenBuffers(1, &gl_vbo);
|
||||||
|
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
|
||||||
|
glBindVertexArray(gl_vao);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, gl_vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glVertexAttribPointer(
|
||||||
|
0, // index
|
||||||
|
3, // size
|
||||||
|
GL_FLOAT, // type
|
||||||
|
GL_FALSE, // enable normalization,
|
||||||
|
3 * sizeof(float), // stride
|
||||||
|
nullptr // offset
|
||||||
|
);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
|
// unbinding VBO/VAO
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uui::GlBox::~GlBox()
|
||||||
|
{
|
||||||
|
std::cout << "Closing a GlBox" << std::endl;
|
||||||
|
glDeleteVertexArrays(1, &gl_vao);
|
||||||
|
glDeleteProgram(gl_program);
|
||||||
|
glDeleteBuffers(1, &gl_vbo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uui::GlBox::render()
|
||||||
|
{
|
||||||
|
glBindVertexArray(gl_vao);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
glUseProgram(gl_program);
|
||||||
|
}
|
||||||
7
src/uui/opengl/shaders/main.frag
Normal file
7
src/uui/opengl/shaders/main.frag
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
#version 460 core
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
|
||||||
|
}
|
||||||
8
src/uui/opengl/shaders/main.vert
Normal file
8
src/uui/opengl/shaders/main.vert
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#version 460 core
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 aPos;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
|
||||||
|
}
|
||||||
|
|
@ -2,32 +2,43 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "uui/opengl/box.hpp"
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
std::cout << "Creating a Window" << std::endl;
|
std::cout << "Creating a GlWindow" << std::endl;
|
||||||
this->title = title;
|
this->title = title;
|
||||||
|
|
||||||
glfw_window = glfwCreateWindow(width, height, title.c_str(), NULL, NULL);
|
glfw_window = glfwCreateWindow(width, height, title.c_str(), NULL, NULL);
|
||||||
if(glfw_window == NULL)
|
if(glfw_window == NULL)
|
||||||
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);
|
||||||
|
|
||||||
if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
||||||
throw std::runtime_error("GLWindow : Failed to initialize OpenGL context");
|
throw std::runtime_error("GLWindow : Failed to initialize OpenGL context");
|
||||||
glViewport(0, 0, width, height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uui::GlWindow::~GlWindow()
|
uui::GlWindow::~GlWindow()
|
||||||
{
|
{
|
||||||
std::cout << "Closing a Window" << std::endl;
|
std::cout << "Closing a GlWindow" << std::endl;
|
||||||
glfwMakeContextCurrent(glfw_window);
|
glfwMakeContextCurrent(glfw_window);
|
||||||
|
components.clear();
|
||||||
glfwDestroyWindow(glfw_window);
|
glfwDestroyWindow(glfw_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uui::GlWindow::draw()
|
void uui::GlWindow::draw()
|
||||||
{
|
{
|
||||||
glfwMakeContextCurrent(glfw_window);
|
glfwMakeContextCurrent(glfw_window);
|
||||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
for(auto& component: components) component->render();
|
||||||
|
|
||||||
glfwSwapBuffers(glfw_window);
|
glfwSwapBuffers(glfw_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uui::GlWindow::add_box()
|
||||||
|
{
|
||||||
|
glfwMakeContextCurrent(glfw_window);
|
||||||
|
components.push_back(std::make_unique<GlBox>());
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue