diff --git a/include/graphics/fbo.hpp b/include/graphics/fbo.hpp index b35be62..caa6a47 100644 --- a/include/graphics/fbo.hpp +++ b/include/graphics/fbo.hpp @@ -48,6 +48,7 @@ namespace gfx{ bool attach(const texture& tex, GLenum point); bool attach(const rbo& r, GLenum point); + bool bind()const; bool bind(gl_frame_buffer& b)const; bool bind_lock(gl_frame_buffer& b)const; void bind_unlock(gl_frame_buffer& b)const; diff --git a/include/graphics/texture.hpp b/include/graphics/texture.hpp index 8a92113..e1a5b16 100644 --- a/include/graphics/texture.hpp +++ b/include/graphics/texture.hpp @@ -58,6 +58,7 @@ namespace gfx{ public: //create the texture with no image data texture(); + texture(GLenum format, GLsizei w, GLsizei h, GLenum type); //create the texture with image data from 'i' texture(const image& i); //TODO image data from raw unsigned char array @@ -72,6 +73,7 @@ namespace gfx{ //overwrite the current image data with 'i' bool set_image(const image& i); + void resize(GLenum format, GLsizei w, GLsizei h, GLenum type); //set the size of the texture, will wrap the image according to the chosen wrap mode void set_width(int w); diff --git a/src/graphics/fbo.cpp b/src/graphics/fbo.cpp index 8d16d52..0c81734 100644 --- a/src/graphics/fbo.cpp +++ b/src/graphics/fbo.cpp @@ -49,16 +49,21 @@ namespace gfx{ bool fbo::attach(const texture& tex, GLenum point){ if(!bind(framebuffer::draw)) return false; + tex.bind(); glFramebufferTexture2D(m_draw.get_bound_id(), point, GL_TEXTURE_2D, tex.raw(), 0); return true; } bool fbo::attach(const rbo& r, GLenum point){ if(!bind(framebuffer::draw)) return false; + r.bind(); glFramebufferRenderbuffer(m_draw.get_bound_id(), point, GL_RENDERBUFFER, r.raw()); return true; } + bool fbo::bind()const{ + return (bind(framebuffer::draw) && bind(framebuffer::read)); + } bool fbo::bind(gl_frame_buffer& b)const{ if(GL_DRAW_FRAMEBUFFER == b.get_buffer_id()){ if(!m_draw.bind(b)) diff --git a/src/graphics/shader_program.cpp b/src/graphics/shader_program.cpp index 76f6b35..efff514 100644 --- a/src/graphics/shader_program.cpp +++ b/src/graphics/shader_program.cpp @@ -503,6 +503,7 @@ namespace gfx{ set_uniform(get_uniform_loc(name), t, tex_unit); } void shader_program::set_uniform(GLuint loc, const texture& t, GLuint tex_unit){ + use(); t.use(tex_unit, loc); } diff --git a/src/graphics/texture.cpp b/src/graphics/texture.cpp index 482f518..dbb1439 100644 --- a/src/graphics/texture.cpp +++ b/src/graphics/texture.cpp @@ -25,6 +25,12 @@ namespace gfx{ texture::texture(){ glGenTextures(1, &m_tex_id); } + texture::texture(GLenum format, GLsizei w, GLsizei h, GLenum type): + m_width(w), m_height(h) + { + glGenTextures(1, &m_tex_id); + resize(format, w, h, type); + } texture::texture(const image& i): texture() { @@ -72,6 +78,11 @@ namespace gfx{ glGenerateMipmap(GL_TEXTURE_2D); return true; } + void texture::resize(GLenum format, GLsizei w, GLsizei h, GLenum type){ + bind(); + glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, type, NULL); + glGenerateMipmap(GL_TEXTURE_2D); + } void texture::set_width(int w){ m_width = w; diff --git a/src/main.cpp b/src/main.cpp index 5bf82a5..1ac7326 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,6 +20,7 @@ #include "graphics/vbo.hpp" #include "graphics/shader.hpp" #include "graphics/shader_program.hpp" +#include "graphics/fbo.hpp" #include "engine/camera.hpp" @@ -136,14 +137,6 @@ std::string select_audio_file(){ return {}; } -void gay_thread(sfx::mixer& m, std::atomic_bool& should_gay_thread_stop){ - while(!should_gay_thread_stop){ - sfx::mixchunk ch = read_audio_file(select_audio_file().c_str()); - m.get_channel(0).play(ch); - std::this_thread::sleep_for(std::chrono::seconds(3)); - } -} - gfx::shader_program create_example_shader(){ static constexpr const char vertex_source[] = "#version 330 core\n" "layout (location = 0) in vec3 position;" @@ -199,6 +192,48 @@ gfx::shader_program create_example_shader(){ } return prog; } +gfx::shader_program create_screen_shader(){ + static constexpr const char vertex_source[] = "#version 330 core\n" + "layout (location = 0) in vec2 position;" + "layout (location = 1) in vec2 tex_coords;" + + "out vec2 frag_tex_coords;" + + "void main(){" + "gl_Position = vec4(position, -1.0, 1.0);" + "frag_tex_coords = tex_coords;" + "}"; + static constexpr const char fragment_source[] = "#version 330 core\n" + "out vec4 FragColor;" + + "in vec2 frag_tex_coords;" + + "uniform sampler2D fbtexture;" + "void main(){" + "FragColor = mix(vec4(1,0,0,1),texture(fbtexture, frag_tex_coords), 0.8);" + "}"; + gfx::shader_program prog; + gfx::shader vert(vertex_source, gfx::shader::type::VERTEX); + gfx::shader frag(fragment_source, gfx::shader::type::FRAGMENT); + bool error = false; + if(vert.has_compile_error()){ + debug_print_error("%s\n", vert.get_error().c_str()); + error = true; + } + if(frag.has_compile_error()){ + debug_print_error("%s\n", frag.get_error().c_str()); + error = true; + } + if(error) + return prog; + prog.attach_shaders(vert, frag); + prog.link(); + if(prog.has_link_error()){ + debug_print_error("%s\n", prog.get_error().c_str()); + } + return prog; +} + class grid { @@ -233,7 +268,7 @@ public: int main(){ const grid g; - egn::ortho_camera cam(10, 10, 1, 100); + egn::ortho_camera cam(5, 5, 1, 100); srand(time(NULL)); game_state gs = {}; @@ -243,46 +278,79 @@ int main(){ manager.handle_window_close_event(handle_window_close); manager.handle_keypress_event(handle_input_events); - //audio testing thread setup - sfx::mixer mix(sfx::mixer::mode::STEREO, 1, 44100); - std::atomic_bool should_gay_thread_stop = false; - std::thread t(gay_thread, std::ref(mix), std::ref(should_gay_thread_stop)); + //fbo setup + gfx::fbo fbo; + gfx::rbo rbo(640, 480, GL_DEPTH24_STENCIL8); + gfx::texture tex(GL_RGB, 640, 480, GL_UNSIGNED_BYTE); + fbo.attach(rbo, GL_DEPTH_STENCIL_ATTACHMENT); + fbo.attach(tex, GL_COLOR_ATTACHMENT0); + glClearColor(0, 0, 0, 1); + fbo.unbind(); - //create our gl objects - gfx::vbo vbo(sizeof(GLfloat) * sizeof(27), gfx::vbo::usage::STATIC_DRAW); - gfx::shader_program prog = create_example_shader(); - gfx::vao vao; + //create our gl objects for rendering to the fbo + gfx::vbo normal_vbo(sizeof(GLfloat) * 27, gfx::vbo::usage::STATIC_DRAW); + gfx::shader_program normal_shader = create_example_shader(); + gfx::vao normal_vao; //add our view-projection matrix in the glsl uniform variable - prog.set_uniform("vp_mat", cam.get_projection_matrix()*cam.get_view_matrix()); - auto mat = prog.get_uniform_mat4("vp_mat"); - math::dump_matrix(mat); + normal_shader.set_uniform("vp_mat", cam.get_projection_matrix()*cam.get_view_matrix()); //put the grid square positions for(size_t i = 0;i < 3;++i){ for(size_t j = 0;j < 3;++j){ - vbo.buffer(g[i][j], sizeof(GLfloat) * 3); + normal_vbo.buffer(g[i][j], sizeof(GLfloat) * 3); } } //tell gl how to interpret the data in the vbo - vao.bind(); - vbo.bind(gfx::buffer::array); - auto attrib = vao.get_attribute(0); + normal_vao.bind(); + normal_vbo.bind(gfx::buffer::array); + auto attrib = normal_vao.get_attribute(0); attrib.set_float_pointer(3, 3, 0); attrib.enable_array_mode(); + constexpr GLfloat square_coords[] = { + -1, 1, 0, 1, + -1, -1, 0, 0, + 1, -1, 1, 0, + 1, -1, 1, 0, + 1, 1, 1, 1, + -1, 1, 0, 1 + }; + + gfx::vbo screen_vbo(sizeof(square_coords), gfx::vbo::usage::STATIC_DRAW); + gfx::shader_program screen_shader = create_screen_shader(); + gfx::vao screen_vao; + + + screen_vbo.buffer(square_coords, sizeof(square_coords)); + screen_vao.bind(); + screen_vbo.bind(gfx::buffer::array); + attrib = screen_vao.get_attribute(0); + attrib.set_float_pointer(2, 4, 0); + attrib.enable_array_mode(); + attrib = screen_vao.get_attribute(1); + attrib.set_float_pointer(2, 4, 2); + attrib.enable_array_mode(); + while(!manager.should_close()){ //render using program 'prog' with data from 'vao' - prog.use(); - vao.bind(); + fbo.bind(); + glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + normal_shader.use(); + normal_vao.bind(); glDrawArrays(GL_POINTS, 0, 9); + fbo.unbind(); + glDisable(GL_DEPTH_TEST); + screen_shader.use(); + screen_shader.set_uniform("fbtexture", tex, 0); + screen_vao.bind(); + glDrawArrays(GL_TRIANGLES, 0, 6); manager.update(); } - should_gay_thread_stop = true; while(exists_empty_tile(gs) && gs.turn != -1){ game_turn(gs, get_player_input()); } - t.join(); }