diff --git a/src/main.cpp b/src/main.cpp index 9ec7d28..ba4f871 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,6 +18,8 @@ #include #include +#include +#include #include "game_state.hpp" #include "config.hpp" @@ -29,6 +31,7 @@ #include "graphics/window.hpp" #include "engine/camera.hpp" +#include "math/debug.hpp" void handle_input_events(GLFWwindow* window, int key, int, int, int){ debug_print("[II] Recieved keycode %d\n", key); @@ -41,61 +44,6 @@ void handle_resize_event(GLFWwindow*, int width, int height){ } -gfx::shader_program create_example_shader(){ - static constexpr const char vertex_source[] = "#version 330 core\n" - "layout (location = 0) in vec3 position;" - "uniform mat4 vp_mat;" - - "void main(){" - "gl_Position = vec4(position, 1.0);" - "}"; - static constexpr const char geometry_source[] = "#version 330 core\n" - "layout (points) in;\n" - "layout (triangle_strip, max_vertices=4) out;\n" - "uniform mat4 vp_mat;\n" - - "void main(){\n" - "gl_Position = vp_mat * vec4((gl_in[0].gl_Position + vec4(-0.1, 0.1, 0, 0)).xyz, 1.0);\n" - "EmitVertex();\n" - "gl_Position = vp_mat * vec4((gl_in[0].gl_Position + vec4(-0.1, -0.1, 0, 0)).xyz, 1.0);\n" - "EmitVertex();\n" - "gl_Position = vp_mat * vec4((gl_in[0].gl_Position + vec4(0.1, 0.1, 0, 0)).xyz, 1.0);\n" - "EmitVertex();\n" - "gl_Position = vp_mat * vec4((gl_in[0].gl_Position + vec4(0.1, -0.1, 0, 0)).xyz, 1.0);\n" - "EmitVertex();\n" - "EndPrimitive();\n" - "}"; - static constexpr const char fragment_source[] = "#version 330 core\n" - "out vec4 FragColor;" - "void main(){" - "FragColor = vec4(0.0, 0.5, 0.6, 1.0);" - "}"; - gfx::shader_program prog; - gfx::shader vert(vertex_source, gfx::shader::type::VERTEX); - gfx::shader frag(fragment_source, gfx::shader::type::FRAGMENT); - gfx::shader geo(geometry_source, gfx::shader::type::GEOMETRY); - 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(geo.has_compile_error()){ - debug_print_error("%s\n", geo.get_error().c_str()); - error = true; - } - if(error) - return prog; - prog.attach_shaders(vert, frag, geo); - prog.link(); - if(prog.has_link_error()){ - debug_print_error("%s\n", prog.get_error().c_str()); - } - return prog; -} gfx::shader_program create_screen_shader(){ static constexpr const char vertex_source[] = "#version 330 core\n" "layout (location = 0) in vec2 position;" @@ -139,41 +87,148 @@ gfx::shader_program create_screen_shader(){ } -class grid +class sprite_shader : public gfx::shader_program { private: - math::mat3> m_mat{ - math::vec3{0.0f, 0.5f, -1.0f}, - math::vec3{0.5f, 0.5f, -1.0f}, - math::vec3{-0.5f, 0.5f, -1.0f}, + static constexpr char s_vertex_shader_text[] = "#version 330 core\n" + "layout (location = 0) in vec2 position;" + "layout (location = 1) in vec2 tex_coords;" + "layout (location = 2) in vec4 color;" - math::vec3{0.0f, 0.0f, -1.0f}, - math::vec3{0.5f, 0.0f, -1.0f}, - math::vec3{-0.5f, 0.0f, -1.0f}, + "out vec2 frag_tex_coords;" + "out vec4 frag_vertex_color;" - math::vec3{0.0f, -0.5f, -1.0f}, - math::vec3{0.5f, -0.5f, -1.0f}, - math::vec3{-0.5f, -0.5f, -1.0f} - }; + "uniform mat4 model_mat;" + "uniform mat4 vp_mat;" + "void main(){" + "gl_Position = vp_mat * model_mat * vec4(position, -1.0, 1.0);" + "frag_tex_coords = tex_coords;" + "frag_vertex_color = color;" + "}"; + static constexpr char s_fragment_shader_text[] = "#version 330 core\n" + "out vec4 FragColor;" + + "in vec2 frag_tex_coords;" + "in vec4 frag_vertex_color;" + + "uniform sampler2D texture1;" + + "void main(){" + "FragColor = texture(texture1, frag_tex_coords);" + "}"; public: - grid() = default; - grid(const grid&) = default; - grid(grid&&) = default; - ~grid() = default; + sprite_shader(): + shader_program(gfx::shader(s_fragment_shader_text, gfx::shader::type::FRAGMENT), + gfx::shader(s_vertex_shader_text, gfx::shader::type::VERTEX)) + { + link(); + } +}; +struct vertex { + math::vec2 pos; + math::vec2 tex_coords; + math::vec4 color; +}; - grid& operator=(const grid&) = default; - grid& operator=(grid&&) = default; +struct square : public egn::object{ + vertex vertices[6]; + gfx::texture& tex_handle; + gfx::vao vao; + gfx::vbo buffer; - auto operator[](size_t index)const{ - return m_mat[index]; + explicit square(gfx::texture& tex): + tex_handle(tex), + buffer(sizeof(GLfloat) * 48, gfx::vbo::usage::DYNAMIC_DRAW) + { + vertices[0].pos = {-1.0f, 1.0f}; + vertices[1].pos = {-1.0f, -1.0f}; + vertices[2].pos = {1.0f, -1.0f}; + vertices[3].pos = {1.0f, -1.0f}; + vertices[4].pos = {1.0f, 1.0f}; + vertices[5].pos = {-1.0f, 1.0f}; + + vertices[0].tex_coords = {0.0f, 1.0f}; + vertices[1].tex_coords = {0.0f, 0.0f}; + vertices[2].tex_coords = {1.0f, 0.0f}; + vertices[3].tex_coords = {1.0f, 0.0f}; + vertices[4].tex_coords = {1.0f, 1.0f}; + vertices[5].tex_coords = {0.0f, 1.0f}; + + vertices[0].color = {0.0f, 0.0f, 0.0f, 0.0f}; + vertices[1].color = {0.0f, 0.0f, 0.0f, 0.0f}; + vertices[2].color = {0.0f, 0.0f, 0.0f, 0.0f}; + vertices[3].color = {0.0f, 0.0f, 0.0f, 0.0f}; + vertices[4].color = {0.0f, 0.0f, 0.0f, 0.0f}; + vertices[5].color = {0.0f, 0.0f, 0.0f, 0.0f}; + + vao.bind_buffer(buffer, 0, 0, sizeof(GLfloat) * 8); + auto attrib = vao.get_attribute(0); + attrib.set_float_array(2, 0); + attrib.associate_with(0); + attrib.enable(); + attrib = vao.get_attribute(1); + attrib.set_float_array(2, 2); + attrib.associate_with(0); + attrib.enable(); + attrib = vao.get_attribute(2); + attrib.set_float_array(4, 4); + attrib.associate_with(0); + attrib.enable(); + } + + void render(gfx::shader_program& shader){ + { + auto mapping = buffer.map(gfx::vbo::maptype::WRITE); + char* data = reinterpret_cast(mapping.raw()); + for(size_t i = 0;i < sizeof(vertices) / sizeof(vertices[0]);++i){ + memcpy(data, vertices[i].pos, sizeof(GLfloat) * 2); + data += sizeof(GLfloat) * 2; + memcpy(data, vertices[i].tex_coords, sizeof(GLfloat) * 2); + data += sizeof(GLfloat) * 2; + memcpy(data, vertices[i].color, sizeof(GLfloat) * 4); + data += sizeof(GLfloat) * 4; + } + } + vao.bind(); + shader.set_uniform("texture1", tex_handle); + shader.set_uniform("model_mat", get_model_matrix()); + math::dump_matrix(get_model_matrix() * math::vec4(4, 3, 2, 1)); + glDrawArrays(GL_TRIANGLES, 0, 6); + buffer.clear(); } }; -int main(){ - const grid g; - egn::ortho_camera cam(5, 5, 1, 100); +struct scene { + std::vector squares; +}; +class renderer +{ +private: + gfx::fbo m_framebuffer; + gfx::texture m_fb_colorbuffer; + gfx::rbo m_fb_depthbuffer; + sprite_shader m_sprite_shader; + egn::ortho_camera m_cam; +public: + renderer(int width, int height): + m_fb_colorbuffer(GL_RGBA, width, height, GL_UNSIGNED_BYTE), + m_fb_depthbuffer(640, 480, GL_DEPTH24_STENCIL8), + m_cam(10, 10, 1, 50){} + + void render(scene& s){ + //m_framebuffer.bind(); + m_sprite_shader.use(); + m_sprite_shader.set_uniform("vp_mat", m_cam.get_projection_matrix()*m_cam.get_view_matrix()); + for(auto it = s.squares.begin();it != s.squares.end();++it){ + it->render(m_sprite_shader); + } + } + +}; + +int main(){ srand(time(NULL)); game_state gs = {}; @@ -184,94 +239,16 @@ int main(){ window.make_current(); window.set_visible(true); - //fbo setup - gfx::fbo fbo; - gfx::rbo rbo(640, 480, GL_DEPTH24_STENCIL8); - gfx::texture tex(GL_RGBA, 640, 480, GL_UNSIGNED_BYTE); - fbo.attach(rbo, GL_DEPTH_STENCIL_ATTACHMENT); - fbo.attach(tex, GL_COLOR_ATTACHMENT0); + gfx::texture tex2(gfx::image("assets/images/x.jpg")); + scene s; + s.squares.push_back(square{tex2}); + renderer test(window.get_width(), window.get_height()); - //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 - 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){ - normal_vbo.buffer(g[i][j], sizeof(GLfloat) * 3); - } - } - - //tell gl how to interpret the data in the vbo - normal_vao.bind_buffer(normal_vbo, 0, 0, sizeof(GLfloat) * 3); - auto attrib = normal_vao.get_attribute(0); - attrib.set_float_array(3, 0); - attrib.associate_with(0); - attrib.enable(); - - 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_buffer(screen_vbo, 0, 0, sizeof(GLfloat) * 4); - attrib = screen_vao.get_attribute(0); - attrib.set_float_array(2, 0); - attrib.associate_with(0); - attrib.enable(); - attrib = screen_vao.get_attribute(1); - attrib.set_float_array(2, 2); - attrib.associate_with(0); - attrib.enable(); - - 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); - fbo.clear_color_buffer(); - fbo.clear_depth_buffer(); - normal_shader.use(); - normal_vao.bind(); - glDrawArrays(GL_POINTS, 0, 9); - 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); - + window.framebuffer().clear_color_buffer(); + window.framebuffer().clear_depth_buffer(); + test.render(s); window.swap_buffers(); glfwPollEvents(); }