From 3d18ccf04e605511c84b7d6e2249cbcce7d0f7e9 Mon Sep 17 00:00:00 2001 From: Jay Robson Date: Wed, 10 Jul 2024 23:11:00 +1000 Subject: [PATCH] working particle system --- assets/image/blue_brick_floor.png | Bin 0 -> 804 bytes assets/image/blue_brick_wall.png | Bin 0 -> 6918 bytes assets/image/cross.png | Bin 0 -> 775 bytes assets/image/white_brick_floor.png | Bin 0 -> 780 bytes assets/image/white_brick_wall.png | Bin 0 -> 6727 bytes assets/image/yellow_brick_floor.png | Bin 0 -> 808 bytes assets/shader/header.glsl | 3 +- assets/shader/model.vert | 8 +-- assets/shader/particles.comp | 71 ++++++++++++------- assets/shader/random.glsl | 12 ++++ src/graphics/context.cpp | 13 ++-- src/graphics/context.hpp | 11 +-- src/graphics/particles.cpp | 86 +++++++++++++++--------- src/graphics/particles.hpp | 45 ++++++++----- src/graphics/pipeline.cpp | 7 +- src/graphics/pipeline.hpp | 11 +-- src/graphics/shader.hpp | 3 +- src/graphics/texture.hpp | 8 +++ src/graphics/texture/generate_atlas.cpp | 7 +- src/graphics/vertex.cpp | 7 +- src/graphics/vertex.hpp | 5 +- src/graphics/window.cpp | 1 + src/main.cpp | 8 +-- src/world/builder.cpp | 27 ++++++-- src/world/builder.hpp | 4 +- src/world/chunk.cpp | 2 +- src/world/chunk.hpp | 4 +- src/world/map.hpp | 1 + src/world/player.cpp | 7 +- src/world/player.hpp | 5 +- src/world/state.cpp | 6 +- src/world/state.hpp | 10 ++- 32 files changed, 246 insertions(+), 126 deletions(-) create mode 100644 assets/image/blue_brick_floor.png create mode 100644 assets/image/blue_brick_wall.png create mode 100644 assets/image/cross.png create mode 100644 assets/image/white_brick_floor.png create mode 100644 assets/image/white_brick_wall.png create mode 100644 assets/image/yellow_brick_floor.png diff --git a/assets/image/blue_brick_floor.png b/assets/image/blue_brick_floor.png new file mode 100644 index 0000000000000000000000000000000000000000..5aa2bc41587d92b8d36fcb2e11318061d22f7585 GIT binary patch literal 804 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 KMNUMnLSTYj&QKfx literal 0 HcmV?d00001 diff --git a/assets/image/white_brick_wall.png b/assets/image/white_brick_wall.png new file mode 100644 index 0000000000000000000000000000000000000000..b8cba1adb7153782c80d01a4ebf964ae4a35a9c9 GIT binary patch literal 6727 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 literal 0 HcmV?d00001 diff --git a/assets/image/yellow_brick_floor.png b/assets/image/yellow_brick_floor.png new file mode 100644 index 0000000000000000000000000000000000000000..99ec7ab03ac93d192851c34b7c5cbac63362dff1 GIT binary patch literal 808 zcmV+@1K0eCP)EX>4Tx04R}tkv&MmKpe$iQ?*hm4i*t{$WV2$i;6hbDionYs1;guFuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|?BJy6A|?JWDYS_7;J6>}?mh0_0YbgZG^;BHXu55t z5^*t;T@?eb2q1_a3}RenmN6$uNpu`v_we!cF3PhypZjz4sX2=QK9M-a4AUmwAfDN@ z4bJ<-VOEq?;&b8&lP*a7$aTfzH_io@1)do;)2VslFtJ!@W2KE*(bR~ii6g3}Q@)V# zSmnIMSu0mr^Pc>Lp`5<5%ypV0NMI35kRU=q6(y8mBTB1IiiH&I$2<6kUB5&wg=bb;{@U#SDLpQP7X zTI2}m-v%zOTbi;5TgF%rLEHm00O;TgphKaVlG6zsw+;EP&P4n(Jfw0{W9`_!1ZCGC z8XMO 0 ? 1 : 0); + + mat2 uv = mat2(rand_vec2(n), rand_vec2(n)); + uv = mat2(min(uv[0], uv[1]), max(uv[0], uv[1])); + uint v_id = (gl_GlobalInvocationID.x * gl_WorkGroupSize.y * p_size + gl_GlobalInvocationID.y) * 4; + + for(int i = 0; i < 4; i++) { + vertices_out[v_id+i].pos = pos; + vertices_out[v_id+i].colour = colour; + vertices_out[v_id+i].screen_offset = (QUADS[i]*2-1) * p.size; + vertices_out[v_id+i].uv = QUADS[i] * (uv[1] - uv[0]) + uv[0]; + vertices_out[v_id+i].texid = p.texid; + } } diff --git a/assets/shader/random.glsl b/assets/shader/random.glsl index bdf0a44..3537a8d 100644 --- a/assets/shader/random.glsl +++ b/assets/shader/random.glsl @@ -9,6 +9,18 @@ float rand_float(inout int n) { return float(n) / float(0x7fffffff); } +vec2 rand_vec2(inout int n) { + return vec2(rand_float(n), rand_float(n)); +} + +vec3 rand_vec3(inout int n) { + return vec3(rand_float(n), rand_float(n), rand_float(n)); +} + +vec4 rand_vec4(inout int n) { + return vec4(rand_float(n), rand_float(n), rand_float(n), rand_float(n)); +} + void rand_mix(inout int n, int v) { n = rand_gen(n ^ v); } diff --git a/src/graphics/context.cpp b/src/graphics/context.cpp index 87891b2..437480d 100644 --- a/src/graphics/context.cpp +++ b/src/graphics/context.cpp @@ -1,7 +1,7 @@ #include "context.hpp" +#include "../world/state.hpp" #include "gl/uniform.hpp" -#include "window.hpp" #include #include #include @@ -9,15 +9,13 @@ using Graphics::Context; -Context::Context(GLFWwindow* window, unsigned int program) { - assert(window); +Context::Context(unsigned int program) { glUseProgram(program); m_u_model = glGetUniformLocation(program, "u_model"); m_u_view = glGetUniformLocation(program, "u_view"); m_u_projection = glGetUniformLocation(program, "u_projection"); m_u_colour = glGetUniformLocation(program, "u_colour"); m_program = program; - m_window = window; } void Context::set_model_matrix(glm::mat4 mat) const { @@ -38,9 +36,10 @@ void Context::set_projection_matrix(glm::mat4 mat) { m_projection = mat; } -void Context::set_player(const World::Player& player) { - set_projection_matrix(glm::perspective(glm::radians(90.0f), Graphics::Window::get_aspect(), 0.01f, 10.f)); - set_view_matrix(player.get_view_matrix()); +void Context::set_from_state(const World::State& state) { + const World::Player& player = state.m_player; + set_projection_matrix(player.m_projection); + set_view_matrix(player.m_view); m_transform = player.m_pos; } diff --git a/src/graphics/context.hpp b/src/graphics/context.hpp index 2541976..2c5c850 100644 --- a/src/graphics/context.hpp +++ b/src/graphics/context.hpp @@ -3,12 +3,13 @@ #include #include -#include "../world/player.hpp" -#include "window.hpp" + +namespace World { + struct State; +}; namespace Graphics { struct Context { - GLFWwindow* m_window; unsigned int m_program; unsigned int m_u_model; unsigned int m_u_view; @@ -18,13 +19,13 @@ namespace Graphics { glm::mat4 m_view; glm::mat4 m_projection; - Context(GLFWwindow* window, unsigned int program); + Context(unsigned int program); void set_model_matrix(glm::mat4 mat) const; void set_view_matrix(glm::mat4 mat); void set_projection_matrix(glm::mat4 mat); void set_colour_matrix(glm::mat4 mat) const; - void set_player(const World::Player& player); + void set_from_state(const World::State& state); glm::mat4 get_vp() const; }; diff --git a/src/graphics/particles.cpp b/src/graphics/particles.cpp index ec26138..b66913c 100644 --- a/src/graphics/particles.cpp +++ b/src/graphics/particles.cpp @@ -1,15 +1,15 @@ #include "particles.hpp" -#include "context.hpp" #include "pipeline.hpp" #include "shader.hpp" #include "vertex.hpp" #include #include +#include +#include using Graphics::Particles; - struct InfoType { float m_time; int m_size; @@ -18,60 +18,86 @@ struct InfoType { Particles::Particles() { m_time_started = glfwGetTime(); - glNamedBufferStorage(m_ssbo_particles, sizeof(Type) * MAX_PARTICLES, nullptr, GL_MAP_PERSISTENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT); - glNamedBufferData(m_ssbo_vertices, sizeof(Vertex) * MAX_PARTICLES, nullptr, GL_DYNAMIC_COPY); - glNamedBufferData(m_ubo_info, sizeof(InfoType), nullptr, GL_DYNAMIC_DRAW); - m_particles_mapping = (Type*)glMapNamedBuffer(m_ssbo_particles, GL_READ_WRITE); + std::vector indices(MAX_PARTICLES*6); + std::vector lookup(MAX_PARTICLE_GROUPS); - glBindVertexArray(m_vao); - glBindBuffer(GL_ARRAY_BUFFER, m_ssbo_vertices); - glBindVertexArray(0); + for(int i = 0; i < MAX_PARTICLES; i++) { + int i4 = i*4; + int i6 = i*6; + indices[i6+0] = i4+0; + indices[i6+1] = i4+1; + indices[i6+2] = i4+3; + indices[i6+3] = i4+0; + indices[i6+4] = i4+3; + indices[i6+5] = i4+2; + } + + for(int i = 0; i < MAX_PARTICLE_GROUPS; i++) { + lookup[i] = i; + } + + glNamedBufferStorage(m_buff_particles, sizeof(Type) * MAX_PARTICLE_GROUPS, nullptr, GL_MAP_PERSISTENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT); + glNamedBufferStorage(m_buff_lookup, sizeof(int) * MAX_PARTICLE_GROUPS, lookup.data(), GL_MAP_PERSISTENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT); + glNamedBufferData(m_buff_vertices, sizeof(Vertex) * MAX_PARTICLES * 4, nullptr, GL_DYNAMIC_COPY); + glNamedBufferData(m_buff_indices, sizeof(int) * MAX_PARTICLES * 6, indices.data(), GL_STATIC_COPY); + glNamedBufferData(m_buff_info, sizeof(InfoType), nullptr, GL_DYNAMIC_DRAW); + m_particles_mapping = (Type*)glMapNamedBuffer(m_buff_particles, GL_READ_WRITE); + m_lookup_mapping = (int*)glMapNamedBuffer(m_buff_lookup, GL_READ_WRITE); + + Vertex::set_vertex_attribs(m_vao, m_buff_vertices); + glVertexArrayElementBuffer(m_vao, m_buff_indices); } -void Particles::update(const Pipeline& pipeline) { +void Particles::update() { double now = get_time_diff(); int j = 0; - for(int i = 0; i < m_particles_mapping_size; i++) { - Type& p = m_particles_mapping[i]; - if(p.m_time_start + p.m_duration < now) { + for(int i = 0; i < m_mapping_size; i++) { + Type& p = m_particles_mapping[m_lookup_mapping[i]]; + if(p.m_time_start + p.m_duration > now) { if(i > j) { - m_particles_mapping[j] = m_particles_mapping[i]; + std::swap(m_lookup_mapping[j], m_lookup_mapping[i]); } j++; } } - m_particles_mapping_size = j; + m_mapping_size = j; InfoType info { .m_time = (float)now, - .m_size = m_particles_mapping_size, + .m_size = 1, }; - glNamedBufferSubData(m_ubo_info, 0, sizeof(InfoType), &info); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, Shader::SSBO_PARTICLES_IN, m_ssbo_particles); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, Shader::SSBO_PARTICLES_OUT, m_ssbo_vertices); - glBindBufferBase(GL_UNIFORM_BUFFER, Shader::UBO_PARTICLES_INFO, m_ubo_info); - glUseProgram(pipeline.m_program_particles); - glDispatchCompute(m_particles_mapping_size, 1, 1); + glNamedBufferSubData(m_buff_info, 0, sizeof(InfoType), &info); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, Shader::SSBO_PARTICLES_IN, m_buff_particles); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, Shader::SSBO_PARTICLES_OUT, m_buff_vertices); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, Shader::SSBO_PARTICLES_LOOKUP, m_buff_lookup); + glBindBufferBase(GL_UNIFORM_BUFFER, Shader::UBO_PARTICLES_INFO, m_buff_info); + glUseProgram(Graphics::Pipeline::CURRENT->m_program_particles); + glDispatchCompute(m_mapping_size, info.m_size, 1); } void Particles::render(const Context& ctx) const { + if(m_mapping_size == 0) { + return; + } + glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); - ctx.set_colour_matrix(glm::mat4(1)); ctx.set_model_matrix(glm::mat4(1)); + ctx.set_colour_matrix(glm::mat4(1)); glBindVertexArray(m_vao); - glDrawArrays(GL_POINTS, 0, m_particles_mapping_size); - glBindVertexArray(0); + glDrawElements(GL_TRIANGLES, m_mapping_size * PARTICLES_PER_GROUP * 6, GL_UNSIGNED_INT, 0); } -void Particles::add(const Type& type) { - if(m_particles_mapping_size < MAX_PARTICLES) { - m_particles_mapping[m_particles_mapping_size++] = type; +void Particles::add(Type type) { + if(m_mapping_size < MAX_PARTICLE_GROUPS) { + type.m_time_start = (float)get_time_diff(); + type.m_seed = random(); + m_particles_mapping[m_lookup_mapping[m_mapping_size++]] = type; } } -double Particles::get_time_diff() { - return m_time_started - glfwGetTime(); +double Particles::get_time_diff() const { + return glfwGetTime() - m_time_started; } diff --git a/src/graphics/particles.hpp b/src/graphics/particles.hpp index ca8b4e9..e23e28d 100644 --- a/src/graphics/particles.hpp +++ b/src/graphics/particles.hpp @@ -7,36 +7,51 @@ #include namespace Graphics { - struct Pipeline; struct Particles { struct Type { glm::vec3 m_pos; - float m_random_velocity_scale; - glm::vec3 m_velocity; - float m_random_colour_scale; - glm::vec4 m_colour; + int _padding_1; + + glm::vec3 m_vel; + int _padding_2; + + glm::vec3 m_acc; + int _padding_3; + + glm::vec4 m_colour = {1, 1, 1, 1}; + + float m_random_pos; + float m_random_vel; + float m_random_time; float m_time_start; + float m_duration; float m_size; - int m_seed; + unsigned int m_texid; + unsigned int m_seed; }; - static_assert(sizeof(Type) == 64); + static_assert(sizeof(Type) == 96); - static constexpr int MAX_PARTICLES = 1024; + static constexpr int MAX_PARTICLE_GROUPS = 1024; + static constexpr int PARTICLES_PER_GROUP = 64; + static constexpr int MAX_PARTICLES = MAX_PARTICLE_GROUPS * PARTICLES_PER_GROUP; GL::VertexArray m_vao; - GL::ArrayBuffer m_ssbo_particles; - GL::ArrayBuffer m_ssbo_vertices; - GL::ArrayBuffer m_ubo_info; + GL::ArrayBuffer m_buff_particles; + GL::ArrayBuffer m_buff_lookup; + GL::ArrayBuffer m_buff_vertices; + GL::ArrayBuffer m_buff_indices; + GL::ArrayBuffer m_buff_info; Type* m_particles_mapping; - int m_particles_mapping_size = 0; + int* m_lookup_mapping; + int m_mapping_size = 0; double m_time_started; Particles(); - void add(const Type& type); - double get_time_diff(); - void update(const Pipeline& pipeline); + void update(); + void add(Type type); + double get_time_diff() const; void render(const Context& ctx) const; }; }; diff --git a/src/graphics/pipeline.cpp b/src/graphics/pipeline.cpp index 39a5a8c..3095d0e 100644 --- a/src/graphics/pipeline.cpp +++ b/src/graphics/pipeline.cpp @@ -7,6 +7,8 @@ #include "shader/compile.hpp" #include "shader/link.hpp" #include "texture/generate_atlas.hpp" +#include "../world/state.hpp" +#include "../util/debug.hpp" using Graphics::Pipeline; @@ -19,6 +21,9 @@ Pipeline::Pipeline() { Graphics::Shader::link(m_program_model, {model_vert, model_frag}); Graphics::Shader::link(m_program_particles, {particles_comp}); + + CHECK_DEBUG(CURRENT == nullptr); + CURRENT = this; } bool Pipeline::should_close() const { @@ -27,7 +32,6 @@ bool Pipeline::should_close() const { void Pipeline::update() { m_window.update(); - m_particles.update(*this); } void Pipeline::render(const World::State& state, const Context& ctx) const { @@ -36,7 +40,6 @@ void Pipeline::render(const World::State& state, const Context& ctx) const { glClearColor(0.1, 0.1, 0.12, 1); state.render(ctx); - m_particles.render(ctx); m_window.swap_buffers(); } diff --git a/src/graphics/pipeline.hpp b/src/graphics/pipeline.hpp index e1106b7..a356dff 100644 --- a/src/graphics/pipeline.hpp +++ b/src/graphics/pipeline.hpp @@ -1,18 +1,21 @@ #pragma once -#include "context.hpp" #include "gl/program.hpp" -#include "particles.hpp" #include "texture/generate_atlas.hpp" +#include "context.hpp" #include "window.hpp" -#include "../world/state.hpp" + +namespace World { + struct State; +}; namespace Graphics { struct Pipeline { + static inline Pipeline* CURRENT = nullptr; + Window m_window; Texture::GeneratedAtlas m_generated_atlas; - Particles m_particles; GL::Program m_program_model; GL::Program m_program_particles; diff --git a/src/graphics/shader.hpp b/src/graphics/shader.hpp index 1fdc1fe..e3d728f 100644 --- a/src/graphics/shader.hpp +++ b/src/graphics/shader.hpp @@ -5,7 +5,8 @@ namespace Graphics::Shader { constexpr int SSBO_ATLAS_BUFFER = 1; constexpr int SSBO_PARTICLES_IN = 2; constexpr int SSBO_PARTICLES_OUT = 3; - constexpr int UBO_PARTICLES_INFO = 4; + constexpr int SSBO_PARTICLES_LOOKUP = 4; + constexpr int UBO_PARTICLES_INFO = 5; constexpr int TEX_ATLAS = 1; }; diff --git a/src/graphics/texture.hpp b/src/graphics/texture.hpp index 252755d..bfdbb38 100644 --- a/src/graphics/texture.hpp +++ b/src/graphics/texture.hpp @@ -6,12 +6,20 @@ namespace Graphics::Texture { inline Image MISSING {"missing.png", Image::Edge::REPEATING}; inline Image WHITE {"white.png", Image::Edge::REPEATING}; + inline Image CROSS {"cross.png", Image::Edge::CLAMP}; inline Image YELLOW_BRICK_WALL {"yellow_brick_wall.png", Image::Edge::REPEATING}; + inline Image YELLOW_BRICK_FLOOR {"yellow_brick_floor.png", Image::Edge::REPEATING}; + inline Image WHITE_BRICK_WALL {"white_brick_wall.png", Image::Edge::REPEATING}; + inline Image WHITE_BRICK_FLOOR {"white_brick_floor.png", Image::Edge::REPEATING}; inline Image* const IMAGES[] { &MISSING, &WHITE, + &CROSS, &YELLOW_BRICK_WALL, + &YELLOW_BRICK_FLOOR, + &WHITE_BRICK_WALL, + &WHITE_BRICK_FLOOR, }; }; diff --git a/src/graphics/texture/generate_atlas.cpp b/src/graphics/texture/generate_atlas.cpp index b169afe..1a8a057 100644 --- a/src/graphics/texture/generate_atlas.cpp +++ b/src/graphics/texture/generate_atlas.cpp @@ -5,6 +5,7 @@ #include "atlas.hpp" #include "image.hpp" #include "uv.hpp" +#include #include #include #include @@ -60,8 +61,8 @@ void Graphics::Texture::generate_atlas(GeneratedAtlas& ga) { src->clear_host(); uvs[it->id] = { - .uv0={(it->x + offset + 0.5f) / size, (it->y + offset + 0.5f) / size}, - .uv1={(it->x + offset + src->m_size.x - 0.5f) / size, (it->y + offset + src->m_size.y - 0.5f) / size}, + .uv0={float(it->x + offset) / size, float(it->y + offset) / size}, + .uv1={float(it->x + offset + src->m_size.x) / size, float(it->y + offset + src->m_size.y) / size}, .zpos=zpos, .edges=src->m_edges, }; @@ -70,6 +71,8 @@ void Graphics::Texture::generate_atlas(GeneratedAtlas& ga) { } } + std::cout << "Finished stitching " << size << "x" << size << "x" << atlas.m_size.z << " atlas" << std::endl; + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, Graphics::Shader::SSBO_ATLAS_BUFFER, ga.m_ssbo_id); glNamedBufferData(ga.m_ssbo_id, sizeof(UV) * uvs.size(), uvs.data(), GL_STATIC_DRAW); diff --git a/src/graphics/vertex.cpp b/src/graphics/vertex.cpp index c951881..166b60e 100644 --- a/src/graphics/vertex.cpp +++ b/src/graphics/vertex.cpp @@ -11,10 +11,11 @@ void Vertex::set_vertex_attribs(unsigned int vao, unsigned int vbo) { glVertexArrayVertexBuffer(vao, 0, vbo, 0, sizeof(v)); glVertexArrayAttribFormat(vao, 0, 4, GL_FLOAT, false, Util::pointer_diff(&v, &v.m_pos)); glVertexArrayAttribFormat(vao, 1, 4, GL_FLOAT, false, Util::pointer_diff(&v, &v.m_colour)); - glVertexArrayAttribFormat(vao, 2, 2, GL_FLOAT, false, Util::pointer_diff(&v, &v.m_uv)); - glVertexArrayAttribIFormat(vao, 3, 1, GL_UNSIGNED_INT, Util::pointer_diff(&v, &v.m_texid)); + glVertexArrayAttribFormat(vao, 2, 2, GL_FLOAT, false, Util::pointer_diff(&v, &v.m_screen_offset)); + glVertexArrayAttribFormat(vao, 3, 2, GL_FLOAT, false, Util::pointer_diff(&v, &v.m_uv)); + glVertexArrayAttribIFormat(vao, 4, 1, GL_UNSIGNED_INT, Util::pointer_diff(&v, &v.m_texid)); - for(int i = 0; i < 4; i++) { + for(int i = 0; i < 5; i++) { glEnableVertexArrayAttrib(vao, i); glVertexArrayAttribBinding(vao, i, 0); } diff --git a/src/graphics/vertex.hpp b/src/graphics/vertex.hpp index 2c51820..5cb4360 100644 --- a/src/graphics/vertex.hpp +++ b/src/graphics/vertex.hpp @@ -7,13 +7,14 @@ namespace Graphics { struct Vertex { glm::vec4 m_pos; glm::vec4 m_colour = {1, 1, 1, 1}; + glm::vec2 m_screen_offset = {0, 0}; glm::vec2 m_uv; unsigned int m_texid = 0; - int _padding_1 = 0; + int _padding_1[3] = {0}; static void set_vertex_attribs(unsigned int vao, unsigned int vbo); }; - static_assert(sizeof(Vertex) == 48); + static_assert(sizeof(Vertex) == 64); }; diff --git a/src/graphics/window.cpp b/src/graphics/window.cpp index 8291f1f..086d464 100644 --- a/src/graphics/window.cpp +++ b/src/graphics/window.cpp @@ -76,6 +76,7 @@ Window::Window() { glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } Window::Window(Window&& o) { diff --git a/src/main.cpp b/src/main.cpp index 012402b..5f031bd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,11 +9,11 @@ int main() { World::State state; while(!pipeline.should_close()) { - Graphics::Context ctx(pipeline.m_window, pipeline.m_program_model); - ctx.set_player(state.m_player); - pipeline.update(); - state.update(ctx); + state.update(); + + Graphics::Context ctx(pipeline.m_program_model); + ctx.set_from_state(state); pipeline.render(state, ctx); } } diff --git a/src/world/builder.cpp b/src/world/builder.cpp index e9c6056..d786a15 100644 --- a/src/world/builder.cpp +++ b/src/world/builder.cpp @@ -4,6 +4,8 @@ #include "../graphics/texture.hpp" #include "chunk.hpp" #include "map.hpp" +#include "player.hpp" +#include "state.hpp" #include "tile/empty.hpp" #include "tile/tile_base.hpp" #include @@ -18,7 +20,7 @@ using World::Builder; Builder::Builder() { Graphics::Mesh mesh; auto prim = Chunk::PRIMITIVE_B; - prim.m_texid = Graphics::Texture::YELLOW_BRICK_WALL; + prim.m_texid = Graphics::Texture::YELLOW_BRICK_FLOOR; mesh.add_primitive(prim); for(int i = 0; i < 4; i++) { @@ -30,17 +32,20 @@ Builder::Builder() { m_model.set(mesh, GL_STATIC_DRAW); } -void Builder::update(Map& map, const Graphics::Context& ctx) { +void Builder::update(State& state) { m_has_intersect = false; if(Graphics::Window::mouse_locked) { return; } + Player& player = state.m_player; + Map& map = state.m_map; + glm::vec<2, double> mpos; - glfwGetCursorPos(ctx.m_window, &mpos.x, &mpos.y); + glfwGetCursorPos(glfwGetCurrentContext(), &mpos.x, &mpos.y); mpos.y = Graphics::Window::size.y - mpos.y; - glm::vec<3, double> near = glm::unProject(glm::vec3(mpos, -1), ctx.m_view, ctx.m_projection, glm::vec4(0, 0, Graphics::Window::size)); - glm::vec<3, double> far = glm::unProject(glm::vec3(mpos, 1), ctx.m_view, ctx.m_projection, glm::vec4(0, 0, Graphics::Window::size)); + glm::vec<3, double> near = glm::unProject(glm::vec3(mpos, -1), player.m_view, player.m_projection, glm::vec4(0, 0, Graphics::Window::size)); + glm::vec<3, double> far = glm::unProject(glm::vec3(mpos, 1), player.m_view, player.m_projection, glm::vec4(0, 0, Graphics::Window::size)); glm::vec<3, double> direction = far - near; const glm::vec<2, double> CHECK_TILES[] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; bool found = false; @@ -49,7 +54,7 @@ void Builder::update(Map& map, const Graphics::Context& ctx) { return; } - m_intersect = glm::round(glm::vec<2, double>(near - direction / direction.z * near.z) + ctx.m_transform); + m_intersect = glm::round(glm::vec<2, double>(near - direction / direction.z * near.z) + player.m_pos); m_has_intersect = true; if(map.get_tile(m_intersect)) { @@ -71,6 +76,16 @@ void Builder::update(Map& map, const Graphics::Context& ctx) { tile = nullptr; } map.set_tile(m_intersect, std::move(tile)); + + state.m_particles.add({ + .m_pos = {m_intersect, 0.75/2}, + .m_acc = {0, 0, -0.98}, + .m_random_pos = 0.5, + .m_random_vel = 0.05, + .m_duration = 1, + .m_size = 0.025, + .m_texid = Graphics::Texture::YELLOW_BRICK_WALL, + }); } void Builder::render(const Graphics::Context& ctx) const { diff --git a/src/world/builder.hpp b/src/world/builder.hpp index 6612a0b..5c58a83 100644 --- a/src/world/builder.hpp +++ b/src/world/builder.hpp @@ -3,9 +3,9 @@ #include "../graphics/context.hpp" #include "../graphics/gl/model.hpp" -#include "map.hpp" namespace World { + struct State; struct Builder { enum Mode { SET, @@ -19,7 +19,7 @@ namespace World { Builder(); - void update(Map& map, const Graphics::Context& ctx); + void update(State& state); void render(const Graphics::Context& ctx) const; }; }; diff --git a/src/world/chunk.cpp b/src/world/chunk.cpp index 7e8a49a..a2d2021 100644 --- a/src/world/chunk.cpp +++ b/src/world/chunk.cpp @@ -79,7 +79,7 @@ void Chunk::update(Map& map) { auto prim = PRIMITIVE_B; prim.m_offset = {t_off, 0, 0}; - prim.m_texid = Graphics::Texture::MISSING; + prim.m_texid = Graphics::Texture::YELLOW_BRICK_FLOOR; mesh.add_primitive(prim); for(int i = 0; i < std::size(neighbours); i++) { diff --git a/src/world/chunk.hpp b/src/world/chunk.hpp index dbd7bcf..e4af606 100644 --- a/src/world/chunk.hpp +++ b/src/world/chunk.hpp @@ -32,9 +32,9 @@ namespace World { static const inline Graphics::Primitive<4, 6> PRIMITIVE_0 = { .m_vertices={ {.m_pos={-0.5, -0.5, 0.75, 1}, .m_uv={0, 0}}, - {.m_pos={-0.5, -0.5, 0, 1}, .m_uv={0, 2}}, + {.m_pos={-0.5, -0.5, 0, 1}, .m_uv={0, 1.5}}, {.m_pos={+0.5, -0.5, 0.75, 1}, .m_uv={2, 0}}, - {.m_pos={+0.5, -0.5, 0, 1}, .m_uv={2, 2}}, + {.m_pos={+0.5, -0.5, 0, 1}, .m_uv={2, 1.5}}, }, .m_indices={ 0, 2, 3, diff --git a/src/world/map.hpp b/src/world/map.hpp index 5064515..4cc08de 100644 --- a/src/world/map.hpp +++ b/src/world/map.hpp @@ -14,6 +14,7 @@ namespace World { #include namespace World { + struct State; struct Map { static constexpr int N = 16; std::map m_chunks; diff --git a/src/world/player.cpp b/src/world/player.cpp index c76c9a7..36b0a89 100644 --- a/src/world/player.cpp +++ b/src/world/player.cpp @@ -1,7 +1,6 @@ #include "player.hpp" #include "../graphics/window.hpp" -#include "../util/math/mod.hpp" #include #include #include @@ -64,13 +63,13 @@ void Player::update() { m_vel += m_accel; m_pos += m_vel; m_accel = -m_vel * 0.125; -} -glm::mat4 Player::get_view_matrix() const { glm::mat4 mat(1); mat = glm::translate(mat, {0, 0, -m_distance}); mat = glm::rotate(mat, (float)m_yaw, {-1, 0, 0}); mat = glm::rotate(mat, (float)m_pitch, {0, 0, 1}); - return mat; + + m_view = mat; + m_projection = glm::perspective(glm::radians(90.0f), Graphics::Window::get_aspect(), 0.01f, 10.f); } diff --git a/src/world/player.hpp b/src/world/player.hpp index 72400e6..39496fd 100644 --- a/src/world/player.hpp +++ b/src/world/player.hpp @@ -11,13 +11,16 @@ namespace World { glm::vec<2, double> m_vel = {0.01, 0}; glm::vec<2, double> m_accel = {0, 0}; glm::vec<2, double> m_cursor_last; + + glm::mat4 m_view; + glm::mat4 m_projection; + double m_distance = 2; double m_pitch = 0; double m_yaw = glm::pi() * 5.0 / 16.0; Player(); void update(); - glm::mat4 get_view_matrix() const; }; }; diff --git a/src/world/state.cpp b/src/world/state.cpp index 5d2d145..940a9cc 100644 --- a/src/world/state.cpp +++ b/src/world/state.cpp @@ -9,14 +9,16 @@ State::State() { m_map.set_tile({0, 0}, std::make_unique()); } -void State::update(const Graphics::Context& ctx) { - m_builder.update(m_map, ctx); +void State::update() { m_player.update(); + m_builder.update(*this); m_map.update(); + m_particles.update(); } void State::render(const Graphics::Context& ctx) const { m_map.render(ctx); m_builder.render(ctx); + m_particles.render(ctx); } diff --git a/src/world/state.hpp b/src/world/state.hpp index a46c79e..abc3549 100644 --- a/src/world/state.hpp +++ b/src/world/state.hpp @@ -1,20 +1,26 @@ #pragma once -#include "../graphics/context.hpp" +namespace World { + struct State; +}; + +#include +#include "../graphics/particles.hpp" #include "builder.hpp" #include "player.hpp" #include "map.hpp" namespace World { struct State { + Graphics::Particles m_particles; Builder m_builder; Player m_player; Map m_map; State(); - void update(const Graphics::Context& ctx); + void update(); void render(const Graphics::Context& ctx) const; }; };