Add RAII window class
This commit is contained in:
parent
d0fc25d3c2
commit
fb692b80b4
127
include/graphics/window.hpp
Normal file
127
include/graphics/window.hpp
Normal file
@ -0,0 +1,127 @@
|
||||
/**
|
||||
This file is a part of our_dick
|
||||
Copyright (C) 2020 rexy712
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OUR_DICK_GRAPHICS_WINDOW_HPP
|
||||
#define OUR_DICK_GRAPHICS_WINDOW_HPP
|
||||
|
||||
#include "gl_include.hpp"
|
||||
#include "math/math.hpp"
|
||||
|
||||
namespace graphics{
|
||||
|
||||
using namespace math;
|
||||
|
||||
class window
|
||||
{
|
||||
public:
|
||||
enum class mousemode : int{
|
||||
DISABLED,
|
||||
HIDDEN,
|
||||
NORMAL,
|
||||
};
|
||||
private:
|
||||
static constexpr int s_default_cver_maj = 3;
|
||||
static constexpr int s_default_cver_min = 3;
|
||||
|
||||
private:
|
||||
GLFWwindow* m_window = nullptr;
|
||||
char* m_title = nullptr;
|
||||
int m_antialias_level = 0;
|
||||
int m_refresh_rate = GLFW_DONT_CARE;
|
||||
int m_swap_interval = 1;
|
||||
|
||||
public:
|
||||
window(int width, int height, const char* title);
|
||||
window(int context_vmaj, int context_vmin, int width, int height, const char* title, int antialias = 0, int refresh = GLFW_DONT_CARE);
|
||||
window(const window&);
|
||||
window(window&&);
|
||||
~window();
|
||||
|
||||
window& operator=(const window&);
|
||||
window& operator=(window&&);
|
||||
|
||||
GLFWwindow* raw();
|
||||
const GLFWwindow* raw()const;
|
||||
|
||||
operator GLFWwindow*();
|
||||
operator const GLFWwindow*()const;
|
||||
|
||||
void make_current();
|
||||
void swap_buffers();
|
||||
|
||||
void destroy();
|
||||
|
||||
void set_size(const vec2<int>&);
|
||||
void set_size(int w, int h);
|
||||
void set_width(int w);
|
||||
void set_height(int h);
|
||||
void set_title(const char* t);
|
||||
void set_pos(const vec2<int>&);
|
||||
void set_pos(int x, int y);
|
||||
void set_x(int x);
|
||||
void set_y(int y);
|
||||
|
||||
void set_visible(bool b = true);
|
||||
void toggle_visible();
|
||||
void set_resizable(bool b = true);
|
||||
void set_decorated(bool b = true);
|
||||
void set_always_on_top(bool b = true);
|
||||
void set_antialias(int level);
|
||||
void set_refresh_rate(int rate);
|
||||
void set_swap_interval(int i);
|
||||
void set_should_close(bool b = true);
|
||||
void set_mousemode(mousemode m);
|
||||
|
||||
void set_key_callback();
|
||||
//TODO callbacks
|
||||
void set_active();
|
||||
|
||||
|
||||
vec2<int> get_size()const;
|
||||
int get_width()const;
|
||||
int get_height()const;
|
||||
|
||||
vec2<int> get_pos()const;
|
||||
int get_posx()const;
|
||||
int get_posy()const;
|
||||
|
||||
vec2<int> get_context_version()const;
|
||||
int get_context_vmaj()const;
|
||||
int get_context_vmin()const;
|
||||
int get_swap_interval()const;
|
||||
|
||||
vec2<double> get_cursor_pos()const;
|
||||
double get_cursor_posx()const;
|
||||
double get_cursor_posy()const;
|
||||
bool get_key(int key, int action)const;
|
||||
|
||||
bool is_visible()const;
|
||||
bool is_resizable()const;
|
||||
bool is_decorated()const;
|
||||
bool is_always_on_top()const;
|
||||
bool is_fullscreen()const;
|
||||
bool should_close()const;
|
||||
mousemode get_mousemode()const;
|
||||
|
||||
private:
|
||||
void copy_title(const char* title, size_t titlelen);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include "graphics/gl_include.hpp"
|
||||
#include "graphics/window.hpp"
|
||||
|
||||
#define OPENGL_VERSION 400
|
||||
#define GLSL_VERSION 400
|
||||
@ -11,12 +12,14 @@ class GLFWwindow;
|
||||
|
||||
class render_manager
|
||||
{
|
||||
private:
|
||||
static inline bool s_initialized = false;
|
||||
private:
|
||||
using close_callback = void(*)(void);
|
||||
using input_callback = void(*)(GLFWwindow*, int, int, int, int);
|
||||
close_callback m_window_close_callback;
|
||||
input_callback m_input_handler;
|
||||
GLFWwindow* m_main_window;
|
||||
graphics::window m_main_window;
|
||||
|
||||
public:
|
||||
enum renderer_error{
|
||||
@ -29,8 +32,9 @@ public:
|
||||
render_manager(const render_manager&) = delete;
|
||||
render_manager(render_manager&&) = delete;
|
||||
|
||||
render_manager();
|
||||
renderer_error init(int width, int height, const char* title); // Sets up the OpenGL environment
|
||||
bool should_close()const;
|
||||
|
||||
render_manager(int width, int height, const char* title);
|
||||
void update(); // Update the GL context and draw new frame
|
||||
void request_exit();
|
||||
|
||||
|
||||
279
src/graphics/window.cpp
Normal file
279
src/graphics/window.cpp
Normal file
@ -0,0 +1,279 @@
|
||||
/**
|
||||
This file is a part of our_dick
|
||||
Copyright (C) 2020 rexy712
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "graphics/window.hpp"
|
||||
|
||||
#include <utility> //exchange, swap, pair
|
||||
#include <cstring> //strlen, strncpy
|
||||
|
||||
namespace graphics{
|
||||
|
||||
window::window(int width, int height, const char* title):
|
||||
window(s_default_cver_maj, s_default_cver_min, width, height, title){}
|
||||
window::window(int cver_maj, int cver_min, int width, int height, const char* title, int antialias, int refresh):
|
||||
m_antialias_level(antialias),
|
||||
m_refresh_rate(refresh)
|
||||
{
|
||||
copy_title(title, strlen(title));
|
||||
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_DECORATED, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_FLOATING, GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_REFRESH_RATE, m_refresh_rate);
|
||||
glfwWindowHint(GLFW_SAMPLES, m_antialias_level);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, cver_maj);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, cver_min);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
m_window = glfwCreateWindow(width, height, title, nullptr, nullptr);
|
||||
}
|
||||
window::window(const window& w):
|
||||
m_antialias_level(w.m_antialias_level),
|
||||
m_refresh_rate(w.m_refresh_rate),
|
||||
m_swap_interval(w.m_swap_interval)
|
||||
{
|
||||
GLFWwindow* current_context = glfwGetCurrentContext();
|
||||
|
||||
copy_title(w.m_title, strlen(w.m_title));
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, w.get_context_vmaj());
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, w.get_context_vmin());
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_RESIZABLE, w.is_resizable());
|
||||
glfwWindowHint(GLFW_DECORATED, w.is_decorated());
|
||||
glfwWindowHint(GLFW_FLOATING, w.is_always_on_top());
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_REFRESH_RATE, w.m_refresh_rate);
|
||||
glfwWindowHint(GLFW_SAMPLES, w.m_antialias_level);
|
||||
|
||||
auto size = w.get_size();
|
||||
m_window = glfwCreateWindow(size.x(), size.y(), m_title, nullptr, nullptr);
|
||||
make_current();
|
||||
set_swap_interval(w.m_swap_interval);
|
||||
set_pos(w.get_pos());
|
||||
set_visible(w.is_visible());
|
||||
|
||||
glfwMakeContextCurrent(current_context);
|
||||
}
|
||||
window::window(window&& w):
|
||||
m_window(std::exchange(w.m_window, nullptr)),
|
||||
m_title(std::exchange(w.m_title, nullptr)),
|
||||
m_antialias_level(w.m_antialias_level),
|
||||
m_refresh_rate(w.m_refresh_rate),
|
||||
m_swap_interval(w.m_swap_interval){}
|
||||
window::~window(){
|
||||
destroy();
|
||||
}
|
||||
|
||||
window& window::operator=(const window& w){
|
||||
return (*this = window(w));
|
||||
}
|
||||
window& window::operator=(window&& w){
|
||||
std::swap(m_window, w.m_window);
|
||||
m_antialias_level = w.m_antialias_level;
|
||||
m_refresh_rate = w.m_refresh_rate;
|
||||
m_swap_interval = w.m_swap_interval;
|
||||
return *this;
|
||||
}
|
||||
GLFWwindow* window::raw(){
|
||||
return m_window;
|
||||
}
|
||||
const GLFWwindow* window::raw()const{
|
||||
return m_window;
|
||||
}
|
||||
|
||||
window::operator GLFWwindow*(){
|
||||
return m_window;
|
||||
}
|
||||
window::operator const GLFWwindow*()const{
|
||||
return m_window;
|
||||
}
|
||||
|
||||
|
||||
void window::make_current(){
|
||||
glfwMakeContextCurrent(m_window);
|
||||
}
|
||||
void window::swap_buffers(){
|
||||
glfwSwapBuffers(m_window);
|
||||
}
|
||||
|
||||
void window::destroy(){
|
||||
if(m_window)
|
||||
glfwDestroyWindow(m_window);
|
||||
m_window = nullptr;
|
||||
|
||||
delete[] m_title;
|
||||
m_title = nullptr;
|
||||
}
|
||||
|
||||
void window::set_size(const vec2<int>& v){
|
||||
set_size(v.x(), v.y());
|
||||
}
|
||||
void window::set_size(int w, int h){
|
||||
glfwSetWindowSize(m_window, w, h);
|
||||
}
|
||||
void window::set_width(int w){
|
||||
set_size(w, get_height());
|
||||
}
|
||||
void window::set_height(int h){
|
||||
set_size(get_width(), h);
|
||||
}
|
||||
void window::set_title(const char* t){
|
||||
glfwSetWindowTitle(m_window, t);
|
||||
}
|
||||
void window::set_pos(const vec2<int>& v){
|
||||
set_pos(v.x(), v.y());
|
||||
}
|
||||
void window::set_pos(int x, int y){
|
||||
glfwSetWindowPos(m_window, x, y);
|
||||
}
|
||||
void window::set_x(int x){
|
||||
set_pos(x, get_posy());
|
||||
}
|
||||
void window::set_y(int y){
|
||||
set_pos(get_posx(), y);
|
||||
}
|
||||
|
||||
void window::set_visible(bool b){
|
||||
if(b)
|
||||
glfwShowWindow(m_window);
|
||||
else
|
||||
glfwHideWindow(m_window);
|
||||
}
|
||||
void window::toggle_visible(){
|
||||
if(is_visible())
|
||||
glfwHideWindow(m_window);
|
||||
else
|
||||
glfwShowWindow(m_window);
|
||||
}
|
||||
void window::set_resizable(bool b){
|
||||
glfwSetWindowAttrib(m_window, GLFW_RESIZABLE, b);
|
||||
}
|
||||
void window::set_decorated(bool b){
|
||||
glfwSetWindowAttrib(m_window, GLFW_DECORATED, b);
|
||||
}
|
||||
void window::set_always_on_top(bool b){
|
||||
glfwSetWindowAttrib(m_window, GLFW_FLOATING, b);
|
||||
}
|
||||
void window::set_antialias(int level){
|
||||
m_antialias_level = level;
|
||||
}
|
||||
void window::set_refresh_rate(int rate){
|
||||
m_refresh_rate = rate;
|
||||
}
|
||||
void window::set_swap_interval(int i){
|
||||
GLFWwindow* current_context = glfwGetCurrentContext();
|
||||
glfwMakeContextCurrent(m_window);
|
||||
glfwSwapInterval(i);
|
||||
glfwMakeContextCurrent(current_context);
|
||||
}
|
||||
|
||||
void window::set_should_close(bool b){
|
||||
glfwSetWindowShouldClose(m_window, b);
|
||||
}
|
||||
/*
|
||||
void window::set_mousemode(mousemode m){
|
||||
//TODO
|
||||
}
|
||||
*/
|
||||
void window::set_active(){
|
||||
glfwMakeContextCurrent(m_window);
|
||||
}
|
||||
|
||||
|
||||
vec2<int> window::get_size()const{
|
||||
vec2<int> retval;
|
||||
glfwGetWindowSize(m_window, &retval.x(), &retval.y());
|
||||
return retval;
|
||||
}
|
||||
int window::get_width()const{
|
||||
return get_size().x();
|
||||
}
|
||||
int window::get_height()const{
|
||||
return get_size().y();
|
||||
}
|
||||
|
||||
vec2<int> window::get_pos()const{
|
||||
vec2<int> retval;
|
||||
glfwGetWindowPos(m_window, &retval.x(), &retval.y());
|
||||
return retval;
|
||||
}
|
||||
int window::get_posx()const{
|
||||
return get_pos().x();
|
||||
}
|
||||
int window::get_posy()const{
|
||||
return get_pos().x();
|
||||
}
|
||||
vec2<int> window::get_context_version()const{
|
||||
return vec2<int>{get_context_vmaj(), get_context_vmin()};
|
||||
}
|
||||
int window::get_context_vmaj()const{
|
||||
return glfwGetWindowAttrib(m_window, GLFW_CONTEXT_VERSION_MAJOR);
|
||||
}
|
||||
int window::get_context_vmin()const{
|
||||
return glfwGetWindowAttrib(m_window, GLFW_CONTEXT_VERSION_MINOR);
|
||||
}
|
||||
int window::get_swap_interval()const{
|
||||
return m_swap_interval;
|
||||
}
|
||||
|
||||
vec2<double> window::get_cursor_pos()const{
|
||||
vec2<double> retval;
|
||||
glfwGetCursorPos(m_window, &retval.x(), &retval.y());
|
||||
return retval;
|
||||
}
|
||||
double window::get_cursor_posx()const{
|
||||
return get_cursor_pos().x();
|
||||
}
|
||||
double window::get_cursor_posy()const{
|
||||
return get_cursor_pos().y();
|
||||
}
|
||||
bool window::get_key(int key, int action)const{
|
||||
return glfwGetKey(m_window, key) == action;
|
||||
}
|
||||
|
||||
bool window::is_visible()const{
|
||||
return glfwGetWindowAttrib(m_window, GLFW_VISIBLE);
|
||||
}
|
||||
bool window::is_resizable()const{
|
||||
return glfwGetWindowAttrib(m_window, GLFW_RESIZABLE);
|
||||
}
|
||||
bool window::is_decorated()const{
|
||||
return glfwGetWindowAttrib(m_window, GLFW_DECORATED);
|
||||
}
|
||||
bool window::is_always_on_top()const{
|
||||
return glfwGetWindowAttrib(m_window, GLFW_FLOATING);
|
||||
}
|
||||
bool window::should_close()const{
|
||||
return glfwWindowShouldClose(m_window);
|
||||
}
|
||||
/* bool window::is_fullscreen()const{
|
||||
//TODO
|
||||
}
|
||||
auto window::get_mousemode()const -> mousemode{
|
||||
//TODO
|
||||
}
|
||||
*/
|
||||
void window::copy_title(const char* title, size_t titlelen){
|
||||
m_title = new char[titlelen + 1];
|
||||
strncpy(m_title, title, titlelen);
|
||||
m_title[titlelen] = 0;
|
||||
}
|
||||
}
|
||||
11
src/main.cpp
11
src/main.cpp
@ -30,7 +30,6 @@
|
||||
|
||||
namespace{
|
||||
bool running = true;
|
||||
render_manager manager;
|
||||
}
|
||||
|
||||
int get_player_input(){
|
||||
@ -103,10 +102,10 @@ void handle_window_close(){
|
||||
running = false;
|
||||
}
|
||||
|
||||
void handle_input_events(GLFWwindow*, int key, int, int, int){
|
||||
void handle_input_events(GLFWwindow* window, int key, int, int, int){
|
||||
debug_print("[II] Recieved keycode %d\n", key);
|
||||
if(key == 256)
|
||||
manager.request_exit();
|
||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||
}
|
||||
|
||||
audio::mixchunk read_audio_file(const char* filename){
|
||||
@ -188,10 +187,11 @@ int main(){
|
||||
};
|
||||
|
||||
srand(time(NULL));
|
||||
glfwInit(); //TODO: handle in a similar way as PortAudio library initialization
|
||||
game_state gs = {};
|
||||
audio::mixer mix(audio::mixer::mode::STEREO, 1, 44100);
|
||||
|
||||
manager.init(640, 480, "Tic-Tac-Gugh");
|
||||
render_manager manager(640, 480, "Tic-Tac-Gugh");
|
||||
manager.handle_window_close_event(handle_window_close);
|
||||
manager.handle_keypress_event(handle_input_events);
|
||||
|
||||
@ -213,7 +213,7 @@ int main(){
|
||||
attrib.set_float_pointer(3, 3, 0);
|
||||
attrib.enable_array_mode();
|
||||
|
||||
while(running){
|
||||
while(!manager.should_close()){
|
||||
//render using program 'prog' with data from 'vao'
|
||||
prog.use();
|
||||
vao.bind();
|
||||
@ -226,4 +226,5 @@ int main(){
|
||||
game_turn(gs, get_player_input());
|
||||
}
|
||||
t.join();
|
||||
//TODO: cannot call glfwTerminate before the window is closed
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "graphics/gl_include.hpp"
|
||||
#include "render.hpp"
|
||||
#include "config.hpp"
|
||||
#include "graphics/window.hpp"
|
||||
#include <cstdio>
|
||||
|
||||
namespace{
|
||||
@ -11,45 +12,25 @@ namespace{
|
||||
}
|
||||
|
||||
|
||||
render_manager::render_manager() :
|
||||
render_manager::render_manager(int width, int height, const char* title):
|
||||
m_window_close_callback(nullptr),
|
||||
m_input_handler(nullptr),
|
||||
m_main_window(nullptr){}
|
||||
|
||||
render_manager::renderer_error render_manager::init (int width, int height, const char* title){
|
||||
if(!glfwInit()){
|
||||
fprintf(stderr, "[EE] failed to initialize GLFW.\n");
|
||||
return RENDERER_INIT_ERROR;
|
||||
}
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
m_main_window = glfwCreateWindow(width, height, title, nullptr, nullptr);
|
||||
if(!m_main_window){
|
||||
fprintf(stderr, "[EE] Could not create window\n");
|
||||
return RENDERER_WINDOW_ERROR;
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(m_main_window);
|
||||
if(gl3wInit()){
|
||||
fprintf(stderr, "[EE] failed to initialize OpenGL\n");
|
||||
return RENDERER_CONTEXT_ERROR;
|
||||
}
|
||||
|
||||
m_main_window(width, height, title)
|
||||
{
|
||||
m_main_window.make_current();
|
||||
gl3wInit();
|
||||
glViewport(0, 0, width, height);
|
||||
glClearColor(0, 0, 0, 1);
|
||||
|
||||
debug_print("[DD] OpenGL %s, GLSL %s\n", glGetString(GL_VERSION), glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
|
||||
glfwSetFramebufferSizeCallback(m_main_window, handle_resize_event);
|
||||
m_main_window.set_visible(true);
|
||||
}
|
||||
|
||||
return RENDERER_OK;
|
||||
bool render_manager::should_close()const{
|
||||
return m_main_window.should_close();
|
||||
}
|
||||
|
||||
void render_manager::update(){
|
||||
glfwSwapBuffers(m_main_window);
|
||||
m_main_window.swap_buffers();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glfwPollEvents();
|
||||
}
|
||||
@ -57,5 +38,5 @@ void render_manager::update(){
|
||||
void render_manager::request_exit(){
|
||||
if(m_window_close_callback)
|
||||
m_window_close_callback();
|
||||
glfwSetWindowShouldClose(m_main_window, GLFW_TRUE);
|
||||
m_main_window.set_should_close(true);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user