From 9c87c4399f5324ee01ea0c55b693b75d501ff400 Mon Sep 17 00:00:00 2001 From: rexy712 Date: Thu, 1 Oct 2020 07:51:32 -0700 Subject: [PATCH] Figure out how to resize a framebuffer (just fucking delete all attachments and rebuild them lol). Remove render_manager from main.cpp. Move game logic out of main to make it less cluttered. Remove unused audio functions from main.cpp. --- include/game_state.hpp | 11 ++- include/graphics/fbo.hpp | 10 ++ include/graphics/rbo.hpp | 2 + include/graphics/window.hpp | 6 ++ include/math/mat.hpp | 2 +- include/render.hpp | 2 +- include/util/init_constants.hpp | 29 ++++++ src/graphics/fbo.cpp | 29 ++++++ src/graphics/rbo.cpp | 4 + src/graphics/window.cpp | 12 +++ src/logic.cpp | 98 +++++++++++++++++++ src/main.cpp | 164 +++++++------------------------- src/render.cpp | 6 +- 13 files changed, 240 insertions(+), 135 deletions(-) create mode 100644 include/util/init_constants.hpp create mode 100644 src/logic.cpp diff --git a/include/game_state.hpp b/include/game_state.hpp index 3b09ae3..2676afd 100644 --- a/include/game_state.hpp +++ b/include/game_state.hpp @@ -1,6 +1,6 @@ /** This file is a part of our_dick - Copyright (C) 2020 r0nk + Copyright (C) 2020 r0nk, 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 @@ -26,4 +26,13 @@ struct game_state { char board[TILE_COUNT]; }; + +int get_player_input(); +int check_win_condition(const game_state& gs, char player); +void display_game_state(const game_state& gs); +void player_turn(game_state& gs, char player, int input); +void game_turn(game_state& gs,int player_input); +int exists_empty_tile(const game_state& gs); + + #endif diff --git a/include/graphics/fbo.hpp b/include/graphics/fbo.hpp index 38c3606..fec2ca3 100644 --- a/include/graphics/fbo.hpp +++ b/include/graphics/fbo.hpp @@ -23,6 +23,8 @@ #include "gl_buffers.hpp" #include "texture.hpp" #include "rbo.hpp" +#include "math/vec.hpp" +#include "util/init_constants.hpp" namespace gfx{ @@ -33,6 +35,7 @@ namespace gfx{ public: fbo(); + fbo(util::no_initialize_t); fbo(const fbo&) = delete; fbo(fbo&& f); ~fbo(); @@ -46,6 +49,13 @@ namespace gfx{ bool attach(const texture& tex, GLenum point); bool attach(const rbo& r, GLenum point); + void clear_color_buffer(const math::vec4& color = {0.0f, 0.0f, 0.0f, 1.0f}); + void clear_depth_buffer(GLfloat value = 1.0f); + void clear_stencil_buffer(GLint value = 0); + void clear(GLbitfield mask); + + void set_viewport(GLfloat x, GLfloat y, GLfloat w, GLfloat h); + bool bind()const; bool bind(gl_frame_buffer_manager& b)const; }; diff --git a/include/graphics/rbo.hpp b/include/graphics/rbo.hpp index c5205c0..6ac5008 100644 --- a/include/graphics/rbo.hpp +++ b/include/graphics/rbo.hpp @@ -48,6 +48,8 @@ namespace gfx{ void resize(GLsizei w, GLsizei h); void reformat(GLenum format); + GLuint release(); + GLsizei get_width()const; GLsizei get_height()const; }; diff --git a/include/graphics/window.hpp b/include/graphics/window.hpp index 5ad8e67..4f0c8bf 100644 --- a/include/graphics/window.hpp +++ b/include/graphics/window.hpp @@ -21,6 +21,8 @@ #include "gl_include.hpp" #include "math/math.hpp" +#include "util/init_constants.hpp" +#include "fbo.hpp" namespace gfx{ @@ -42,6 +44,7 @@ namespace gfx{ private: GLFWwindow* m_window = nullptr; + fbo m_root_fbo{util::no_initialize}; char* m_title = nullptr; int m_antialias_level = 0; int m_refresh_rate = GLFW_DONT_CARE; @@ -68,6 +71,9 @@ namespace gfx{ void destroy(); + fbo& framebuffer(); + const fbo& framebuffer()const; + void set_size(const vec2&); void set_size(int w, int h); void set_width(int w); diff --git a/include/math/mat.hpp b/include/math/mat.hpp index 635604c..934b794 100644 --- a/include/math/mat.hpp +++ b/include/math/mat.hpp @@ -62,7 +62,7 @@ namespace math{ //Value initializing constructors constexpr explicit matrix_base(value_type v); template - constexpr explicit matrix_base(Args&&... args); + constexpr matrix_base(Args&&... args); //Copying constructors constexpr matrix_base(const matrix_base&) = default; diff --git a/include/render.hpp b/include/render.hpp index 60872db..c4e361a 100644 --- a/include/render.hpp +++ b/include/render.hpp @@ -32,7 +32,7 @@ class render_manager { private: static inline bool s_initialized = false; -private: +public: using close_callback = void(*)(void); using input_callback = void(*)(GLFWwindow*, int, int, int, int); close_callback m_window_close_callback; diff --git a/include/util/init_constants.hpp b/include/util/init_constants.hpp new file mode 100644 index 0000000..3300afc --- /dev/null +++ b/include/util/init_constants.hpp @@ -0,0 +1,29 @@ +/** + 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 . +*/ + +#ifndef OUR_DICK_UTIL_INIT_CONSTANTS_HPP +#define OUR_DICK_UTIL_INIT_CONSTANTS_HPP + +namespace util{ + + struct no_initialize_t{}; + static constexpr no_initialize_t no_initialize; + +} + +#endif diff --git a/src/graphics/fbo.cpp b/src/graphics/fbo.cpp index 54525c0..56afc8f 100644 --- a/src/graphics/fbo.cpp +++ b/src/graphics/fbo.cpp @@ -19,12 +19,15 @@ #include "graphics/fbo.hpp" #include //swap, exchange #include "graphics/scoped_buffer_bind.hpp" +#include "config.hpp" namespace gfx{ fbo::fbo(){ glCreateFramebuffers(1, &m_buffer); } + fbo::fbo(util::no_initialize_t): + m_buffer(0){} fbo::fbo(fbo&& f): m_buffer(std::exchange(f.m_buffer, 0)){} fbo::~fbo(){ @@ -54,6 +57,32 @@ namespace gfx{ return true; } + void fbo::clear_color_buffer(const math::vec4& color){ + glClearNamedFramebufferfv(m_buffer, GL_COLOR, 0, &color[0]); + } + void fbo::clear_depth_buffer(GLfloat value){ + glClearNamedFramebufferfv(m_buffer, GL_DEPTH, 0, &value); + } + void fbo::clear_stencil_buffer(GLint value){ + glClearNamedFramebufferiv(m_buffer, GL_STENCIL, 0, &value); + } + void fbo::clear(GLbitfield bits){ + static constexpr GLfloat zeros[4] = {0, 0, 0, 1}; + static constexpr GLint zero = 0; + if(bits & GL_COLOR_BUFFER_BIT){ + glClearNamedFramebufferfv(m_buffer, GL_COLOR, 0, zeros); + } + if(bits & GL_DEPTH_BUFFER_BIT){ + glClearNamedFramebufferfv(m_buffer, GL_DEPTH, 0, zeros); + } + if(bits & GL_STENCIL_BUFFER_BIT){ + glClearNamedFramebufferiv(m_buffer, GL_STENCIL, 0, &zero); + } + } + + void fbo::set_viewport(GLfloat x, GLfloat y, GLfloat w, GLfloat h){ + glViewportIndexedf(m_buffer, x, y, w, h); + } bool fbo::bind()const{ glBindFramebuffer(GL_FRAMEBUFFER, m_buffer); return true; diff --git a/src/graphics/rbo.cpp b/src/graphics/rbo.cpp index 04ee284..dd57a2d 100644 --- a/src/graphics/rbo.cpp +++ b/src/graphics/rbo.cpp @@ -67,6 +67,10 @@ namespace gfx{ *this = rbo(m_width, m_height, format); } + GLuint rbo::release(){ + return std::exchange(m_buffer, 0); + } + GLsizei rbo::get_width()const{ return m_width; } diff --git a/src/graphics/window.cpp b/src/graphics/window.cpp index 1dc5344..c71e7c6 100644 --- a/src/graphics/window.cpp +++ b/src/graphics/window.cpp @@ -189,6 +189,9 @@ static void enable_opengl_debug_context(){ #ifdef OUR_DICK_ENABLE_DEBUG_OUTPUT enable_opengl_debug_context(); #endif + glfwMakeContextCurrent(m_window); + m_root_fbo.set_viewport(0, 0, width, height); + set_swap_interval(m_swap_interval); glfwMakeContextCurrent(current_context); @@ -238,6 +241,9 @@ static void enable_opengl_debug_context(){ enable_opengl_debug_context(); #endif + glfwMakeContextCurrent(m_window); + m_root_fbo.set_viewport(0, 0, size.x(), size.y()); + set_swap_interval(w.m_swap_interval); set_pos(w.get_pos()); set_visible(w.is_visible()); @@ -294,6 +300,12 @@ static void enable_opengl_debug_context(){ delete[] m_title; m_title = nullptr; } + fbo& window::framebuffer(){ + return m_root_fbo; + } + const fbo& window::framebuffer()const{ + return m_root_fbo; + } void window::set_size(const vec2& v){ set_size(v.x(), v.y()); diff --git a/src/logic.cpp b/src/logic.cpp new file mode 100644 index 0000000..7e9436e --- /dev/null +++ b/src/logic.cpp @@ -0,0 +1,98 @@ +/** + This file is a part of our_dick + Copyright (C) 2020 r0nk + + 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 . +*/ + +// 0 | 1 | 2 +// --------- +// 3 | 4 | 5 +// --------- +// 6 | 7 | 8 + +#include "game_state.hpp" + +#include //rand +#include //printf, fprintf + + +#define TILE_COUNT 9 + +int get_player_input(){ + //TODO get player input + return rand() % 9; +} + +int check_win_condition(const game_state& gs, char player){ + int i; + for(i = 0 ; i < 3; i++){ + //rows + if(gs.board[(i*3)] == player && gs.board[(i*3)+1] == player && gs.board[(i*3)+2] == player) + return 1; + //column + if(gs.board[i] == player && gs.board[i+3] == player && gs.board[i+6] == player) + return 1; + } + if(gs.board[0] == player && gs.board[4] == player && gs.board[8] == player) + return 1; + if(gs.board[2] == player && gs.board[4] == player && gs.board[6] == player) + return 1; + + return 0; +} + +void display_game_state(const game_state& gs){ + printf("turn %i:\n", gs.turn); + for(int i = 0; i < 3; i++){ + for(int j = 0; j < 3; j++){ + if(gs.board[(i*3)+j]) + printf("%c", gs.board[(i*3)+j]); + else + printf("_"); + } + printf("\n"); + } +} + +void player_turn(game_state& gs, char player, int input){ + if(input > TILE_COUNT && input < 0) + fprintf(stderr,"ERR: player input not in range."); + if(!gs.board[input]) + gs.board[input] = player; + if(check_win_condition(gs, player)){ + printf("player %c wins!\n", player); + gs.turn = -1; + } +} + +void game_turn(game_state& gs,int player_input){ + gs.turn++; + player_turn(gs, 'O', player_input); + display_game_state(gs); + if(gs.turn == -1) + return; + player_turn(gs, 'X', rand() % TILE_COUNT); + display_game_state(gs); +} + +int exists_empty_tile(const game_state& gs){ + int i; + for(i = 0; i < TILE_COUNT; i++) + if(!gs.board[i]) + return 1; + return 0; +} + + diff --git a/src/main.cpp b/src/main.cpp index 5fe95fa..9ec7d28 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,144 +16,30 @@ along with this program. If not, see . */ -#include #include #include -#include -#include -#include -#include -#include -#include "render.hpp" #include "game_state.hpp" -#include "math/math.hpp" -#include "math/debug.hpp" #include "config.hpp" -#include "audio/sndrd.hpp" -#include "audio/mixdata.hpp" -#include "audio/mixer.hpp" #include "graphics/vao.hpp" #include "graphics/vbo.hpp" -#include "graphics/shader.hpp" #include "graphics/shader_program.hpp" #include "graphics/fbo.hpp" +#include "graphics/window.hpp" #include "engine/camera.hpp" -// 0 | 1 | 2 -// --------- -// 3 | 4 | 5 -// --------- -// 6 | 7 | 8 - -#define TILE_COUNT 9 - -int get_player_input(){ - //TODO get player input - return rand() % 9; -} - -int check_win_condition(const game_state& gs, char player){ - int i; - for(i = 0 ; i < 3; i++){ - //rows - if(gs.board[(i*3)] == player && gs.board[(i*3)+1] == player && gs.board[(i*3)+2] == player) - return 1; - //column - if(gs.board[i] == player && gs.board[i+3] == player && gs.board[i+6] == player) - return 1; - } - if(gs.board[0] == player && gs.board[4] == player && gs.board[8] == player) - return 1; - if(gs.board[2] == player && gs.board[4] == player && gs.board[6] == player) - return 1; - - return 0; -} - -void display_game_state(const game_state& gs){ - printf("turn %i:\n", gs.turn); - for(int i = 0; i < 3; i++){ - for(int j = 0; j < 3; j++){ - if(gs.board[(i*3)+j]) - printf("%c", gs.board[(i*3)+j]); - else - printf("_"); - } - printf("\n"); - } -} - -void player_turn(game_state& gs, char player, int input){ - if(input > TILE_COUNT && input < 0) - fprintf(stderr,"ERR: player input not in range."); - if(!gs.board[input]) - gs.board[input] = player; - if(check_win_condition(gs, player)){ - printf("player %c wins!\n", player); - gs.turn = -1; - } -} - -void game_turn(game_state& gs,int player_input){ - gs.turn++; - player_turn(gs, 'O', player_input); - display_game_state(gs); - if(gs.turn == -1) - return; - player_turn(gs, 'X', rand() % TILE_COUNT); - display_game_state(gs); -} - -int exists_empty_tile(const game_state& gs){ - int i; - for(i = 0; i < TILE_COUNT; i++) - if(!gs.board[i]) - return 1; - return 0; -} - -void handle_window_close(){ - debug_print("[II] Window close event triggered\n"); -} - void handle_input_events(GLFWwindow* window, int key, int, int, int){ debug_print("[II] Recieved keycode %d\n", key); if(key == 256) glfwSetWindowShouldClose(window, GLFW_TRUE); } - -sfx::mixchunk read_audio_file(const char* filename){ - debug_print("Reading in %s\n", filename); - sfx::sndrd f(filename, sfx::sndrd::mode::r); - if(!f.valid()){ - return {}; - } - return f.read_all(); +void handle_resize_event(GLFWwindow*, int width, int height){ + debug_print("Window resized to %dx%d\n", width, height); + glViewportIndexedf(0, 0, 0, width, height); } -std::string select_audio_file(){ - namespace fs = std::filesystem; - size_t filecnt = 0; - for(fs::directory_iterator i("assets/moans"); i != fs::directory_iterator(); ++i){ - fs::directory_entry e = *i; - if(!e.is_directory()) - ++filecnt; - } - - size_t selection = rand() % filecnt; - for(fs::directory_iterator i("assets/moans");i != fs::directory_iterator();++i){ - fs::directory_entry e = *i; - if(selection == 0){ - return e.path().native(); - } - if(!e.is_directory()) - --selection; - } - return {}; -} gfx::shader_program create_example_shader(){ static constexpr const char vertex_source[] = "#version 330 core\n" @@ -228,7 +114,7 @@ gfx::shader_program create_screen_shader(){ "uniform sampler2D fbtexture;" "void main(){" - "FragColor = mix(vec4(1,0,0,1),texture(fbtexture, frag_tex_coords), 0.8);" + "FragColor = mix(vec4(1,0,0,1),texture(fbtexture, frag_tex_coords), 0.9);" "}"; gfx::shader_program prog; gfx::shader vert(vertex_source, gfx::shader::type::VERTEX); @@ -292,17 +178,18 @@ int main(){ game_state gs = {}; //window testing setup - render_manager manager(640, 480, "Tic-Tac-Gugh"); - manager.handle_window_close_event(handle_window_close); - manager.handle_keypress_event(handle_input_events); + gfx::window window(4, 5, 640, 480, "Tic-Tac-Gugh"); + glfwSetKeyCallback(window.raw(), handle_input_events); //TODO + glfwSetFramebufferSizeCallback(window.raw(), handle_resize_event); + window.make_current(); + window.set_visible(true); //fbo setup gfx::fbo fbo; gfx::rbo rbo(640, 480, GL_DEPTH24_STENCIL8); - gfx::texture tex(GL_RGB, 640, 480, GL_UNSIGNED_BYTE); + gfx::texture tex(GL_RGBA, 640, 480, GL_UNSIGNED_BYTE); fbo.attach(rbo, GL_DEPTH_STENCIL_ATTACHMENT); fbo.attach(tex, GL_COLOR_ATTACHMENT0); - glClearColor(0, 0, 0, 1); //create our gl objects for rendering to the fbo gfx::vbo normal_vbo(sizeof(GLfloat) * 27, gfx::vbo::usage::STATIC_DRAW); @@ -352,22 +239,41 @@ int main(){ attrib.associate_with(0); attrib.enable(); - while(!manager.should_close()){ - //render using program 'prog' with data from 'vao' + int stored_width = window.get_width(), stored_height = window.get_height(); + while(!window.should_close()){ + + //Workaround for resize callback just to see if this worked + if(stored_width != window.get_width() || + stored_height != window.get_height()) + { + stored_width = window.get_width(); + stored_height = window.get_height(); + fbo.detach(GL_DEPTH_STENCIL_ATTACHMENT); + fbo.detach(GL_COLOR_ATTACHMENT0); + fbo = gfx::fbo(); + rbo = gfx::rbo(stored_width, stored_height, GL_DEPTH24_STENCIL8); + tex = gfx::texture(GL_RGBA, stored_width, stored_height, GL_UNSIGNED_BYTE); + fbo.attach(rbo, GL_DEPTH_STENCIL_ATTACHMENT); + fbo.attach(tex, GL_COLOR_ATTACHMENT0); + debug_print("%dx%d\n", window.get_width(), window.get_height()); + } fbo.bind(); glEnable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + fbo.clear_color_buffer(); + fbo.clear_depth_buffer(); normal_shader.use(); normal_vao.bind(); glDrawArrays(GL_POINTS, 0, 9); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + window.framebuffer().bind(); glDisable(GL_DEPTH_TEST); screen_shader.use(); screen_shader.set_uniform("fbtexture", tex, 0); screen_vao.bind(); glDrawArrays(GL_TRIANGLES, 0, 6); - manager.update(); + + window.swap_buffers(); + glfwPollEvents(); } while(exists_empty_tile(gs) && gs.turn != -1){ diff --git a/src/render.cpp b/src/render.cpp index cdd6ba3..ee0a4f7 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -25,7 +25,7 @@ namespace{ void handle_resize_event(GLFWwindow*, int width, int height){ debug_print("Window resized\n"); - glViewport(0, 0, width, height); + glViewportIndexedf(0, 0, 0, width, height); } } @@ -36,7 +36,7 @@ render_manager::render_manager(int width, int height, const char* title): m_main_window(width, height, title) { m_main_window.make_current(); - glViewport(0, 0, width, height); + glViewportIndexedf(0, 0, 0, width, height); glClearColor(0, 0, 0, 1); glfwSetFramebufferSizeCallback(m_main_window, handle_resize_event); m_main_window.set_visible(true); @@ -48,7 +48,7 @@ bool render_manager::should_close()const{ void render_manager::update(){ m_main_window.swap_buffers(); - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glfwPollEvents(); }