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.

This commit is contained in:
rexy712 2020-10-01 07:51:32 -07:00
parent b2c8b0b3b5
commit 9c87c4399f
13 changed files with 240 additions and 135 deletions

View File

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

View File

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

View File

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

View File

@ -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<int>&);
void set_size(int w, int h);
void set_width(int w);

View File

@ -62,7 +62,7 @@ namespace math{
//Value initializing constructors
constexpr explicit matrix_base(value_type v);
template<typename... Args>
constexpr explicit matrix_base(Args&&... args);
constexpr matrix_base(Args&&... args);
//Copying constructors
constexpr matrix_base(const matrix_base&) = default;

View File

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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -19,12 +19,15 @@
#include "graphics/fbo.hpp"
#include <utility> //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<GLfloat>& 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;

View File

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

View File

@ -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<int>& v){
set_size(v.x(), v.y());

98
src/logic.cpp Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
// 0 | 1 | 2
// ---------
// 3 | 4 | 5
// ---------
// 6 | 7 | 8
#include "game_state.hpp"
#include <cstdlib> //rand
#include <cstdio> //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;
}

View File

@ -16,144 +16,30 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <filesystem>
#include <string>
#include <thread>
#include <chrono>
#include <atomic>
#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){

View File

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