From 2103ce38edb160b2cc982b341535e1f147e66360 Mon Sep 17 00:00:00 2001 From: untodesu Date: Fri, 26 Dec 2025 22:11:55 +0500 Subject: Pixel scaling and collision jank fixes --- src/game/client/game.cc | 18 +++++++++++++----- src/game/shared/entity/collision.cc | 31 +++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 15 deletions(-) (limited to 'src/game') diff --git a/src/game/client/game.cc b/src/game/client/game.cc index 1681c01..9ade30f 100644 --- a/src/game/client/game.cc +++ b/src/game/client/game.cc @@ -86,6 +86,8 @@ #include "client/session.hh" #include "client/toggles.hh" +constexpr static int PIXEL_SIZE = 2; + config::Boolean client_game::streamer_mode(false); config::Boolean client_game::vertical_sync(true); config::Boolean client_game::world_curvature(true); @@ -96,6 +98,9 @@ bool client_game::hide_hud = false; static config::KeyBind hide_hud_toggle(GLFW_KEY_F1); +static int scaled_width; +static int scaled_height; + static ImFont* load_font(std::string_view path, float size, ImFontConfig& font_config, ImVector& ranges) { std::vector font; @@ -128,11 +133,14 @@ static void on_glfw_framebuffer_size(const GlfwFramebufferSizeEvent& event) glGenTextures(1, &globals::world_fbo_color); glGenRenderbuffers(1, &globals::world_fbo_depth); + scaled_width = event.size.x / PIXEL_SIZE; + scaled_height = event.size.y / PIXEL_SIZE; + glBindTexture(GL_TEXTURE_2D, globals::world_fbo_color); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, event.size.x, event.size.y, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, scaled_width, scaled_height, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr); glBindRenderbuffer(GL_RENDERBUFFER, globals::world_fbo_depth); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, event.size.x, event.size.y); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, scaled_width, scaled_height); glBindFramebuffer(GL_FRAMEBUFFER, globals::world_fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, globals::world_fbo_color, 0); @@ -590,7 +598,7 @@ void client_game::update_late(void) void client_game::render(void) { - glViewport(0, 0, globals::width, globals::height); + glViewport(0, 0, scaled_width, scaled_height); glBindFramebuffer(GL_FRAMEBUFFER, globals::world_fbo); glClearColor(skybox::fog_color.r, skybox::fog_color.g, skybox::fog_color.b, 1.000f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -611,7 +619,7 @@ void client_game::render(void) for(const auto [entity, collision, head, transform] : group.each()) { if(entity == globals::player) { // Don't render ourselves - continue; + // continue; } glm::fvec3 forward; @@ -636,7 +644,7 @@ void client_game::render(void) glBindFramebuffer(GL_READ_FRAMEBUFFER, globals::world_fbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - glBlitFramebuffer(0, 0, globals::width, globals::height, 0, 0, globals::width, globals::height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBlitFramebuffer(0, 0, scaled_width, scaled_height, 0, 0, globals::width, globals::height, GL_COLOR_BUFFER_BIT, GL_NEAREST); } void client_game::layout(void) diff --git a/src/game/shared/entity/collision.cc b/src/game/shared/entity/collision.cc index d9361b1..322bb91 100644 --- a/src/game/shared/entity/collision.cc +++ b/src/game/shared/entity/collision.cc @@ -15,6 +15,8 @@ #include "shared/coord.hh" #include "shared/globals.hh" +constexpr static float EPSILON = 0.5f; + static int vgrid_collide(const Dimension* dimension, int d, Collision& collision, Transform& transform, Velocity& velocity, VoxelMaterial& touch_surface, bool enable_snapping_to_grid) { @@ -87,7 +89,11 @@ static int vgrid_collide(const Dimension* dimension, int d, Collision& collision auto vbox = voxel->get_collision().push(lpos); auto vbox_center = 0.5f * vbox.min + 0.5f * vbox.max; - if(!csg_aabb.intersect(vbox)) { + math::AABBf clip_vbox(vbox); + clip_vbox.min -= EPSILON * globals::fixed_frametime; + clip_vbox.max += EPSILON * globals::fixed_frametime; + + if(!csg_aabb.intersect(clip_vbox)) { continue; // no intersection } @@ -140,10 +146,10 @@ static int vgrid_collide(const Dimension* dimension, int d, Collision& collision auto vbox_halfsize = 0.5f * closest_vbox.max[d] - 0.5f * closest_vbox.min[d]; if(movesign < 0) { - transform.local[d] = vbox_center + vbox_halfsize + ref_halfsize[d] - ref_center[d] + 0.01f * globals::fixed_frametime; + transform.local[d] = vbox_center + vbox_halfsize + ref_halfsize[d] - ref_center[d] + EPSILON * globals::fixed_frametime; } else { - transform.local[d] = vbox_center - vbox_halfsize - ref_halfsize[d] - ref_center[d] - 0.01f * globals::fixed_frametime; + transform.local[d] = vbox_center - vbox_halfsize - ref_halfsize[d] - ref_center[d] - EPSILON * globals::fixed_frametime; } } @@ -161,12 +167,20 @@ void Collision::fixed_update(Dimension* dimension) auto group = dimension->entities.group(entt::get); for(auto [entity, collision, transform, velocity] : group.each()) { - auto surface = VMAT_UNKNOWN; - auto vertical_move = vgrid_collide(dimension, 1, collision, transform, velocity, surface, true); + auto speedvec = velocity.value; + auto hspeed = glm::abs(0.5f * speedvec.x + 0.5f * speedvec.z); + auto vspeed = glm::abs(speedvec.y); + + glm::vec<3, VoxelMaterial> surface; + + glm::ivec3 movesign; + movesign.x = vgrid_collide(dimension, 0, collision, transform, velocity, surface.x, true); + movesign.z = vgrid_collide(dimension, 2, collision, transform, velocity, surface.z, true); + movesign.y = vgrid_collide(dimension, 1, collision, transform, velocity, surface.y, true); if(dimension->entities.any_of(entity)) { - if(vertical_move == math::sign(dimension->get_gravity())) { - dimension->entities.emplace_or_replace(entity, Grounded { surface }); + if(movesign.y == math::sign(dimension->get_gravity())) { + dimension->entities.emplace_or_replace(entity, Grounded { surface.y }); } else { dimension->entities.remove(entity); @@ -178,8 +192,5 @@ void Collision::fixed_update(Dimension* dimension) // concept of resting on the ground (it flies around) dimension->entities.remove(entity); } - - vgrid_collide(dimension, 0, collision, transform, velocity, surface, false); - vgrid_collide(dimension, 2, collision, transform, velocity, surface, false); } } -- cgit