From a841fa7c92003809718e0a3eb1b64d922f28458f Mon Sep 17 00:00:00 2001 From: Sara <sara@saragerretsen.nl> Date: Sun, 1 Oct 2023 21:58:48 +0200 Subject: [PATCH] reworked rendering to transform sprites to pixel coordinates correctly --- src/assets.c | 1 + src/camera.c | 32 ++++++++++++++++++-------------- src/camera.h | 7 ++++--- src/fencer.c | 18 +++++++++--------- src/level.c | 8 ++++---- src/sprite.c | 9 ++++----- src/tilemap.c | 4 ++-- src/tilemap.h | 2 +- src/transform.h | 4 ++-- 9 files changed, 45 insertions(+), 40 deletions(-) diff --git a/src/assets.c b/src/assets.c index 4169b2b..5eabd3e 100644 --- a/src/assets.c +++ b/src/assets.c @@ -64,6 +64,7 @@ static void _empty_assets() { AssetData* start = _assets; AssetData* end = _assets + _assets_len; + for(AssetData* asset = start; asset < end; ++asset) { asset->destructor(asset->asset); } diff --git a/src/camera.c b/src/camera.c index 1cb3a71..7502dfe 100644 --- a/src/camera.c +++ b/src/camera.c @@ -6,26 +6,30 @@ Camera g_camera; void camera_init() { LOG_INFO("camera_init"); - g_camera.centre = ZeroVector; - g_camera.width = 10; + g_camera.transform = IdentityTransform; + g_camera.fov = 10; } static inline float _camera_height(Camera* self) { - return self->width * ((float)g_render_resolution.y / (float)g_render_resolution.x); + return self->fov * ((float)g_render_resolution.y / (float)g_render_resolution.x); } -static inline -float _cam_to_world_conversion() { - return g_render_resolution.x / g_camera.width; -} +SDL_FRect camera_world_to_pixel_rect(Camera* self, SDL_FRect* world_space) { + Transform t = self->transform; + t.rotation = 0; + t.scale = OneVector; + t = transform_invert(t); -SDL_FRect camera_world_to_screen_space(Camera* self, SDL_FRect* world_space) { - float unit = _cam_to_world_conversion(); - return (SDL_FRect) { - .x = (g_camera.centre.x - world_space->x + g_camera.width/2.0) * unit, - .y = (g_camera.centre.y - world_space->y + _camera_height(&g_camera)/2.0) * unit, - .w = world_space->w * unit, - .h = world_space->h * unit + Vector tl = {world_space->x + (self->fov / 2.0), world_space->y + (_camera_height(self) / 2.0)}; + Vector size = {world_space->w, world_space->h}; + + tl = vmulff(transform_point(&t, tl), g_render_resolution.x / self->fov); + size = vmulff(vmulf(t.scale, size), g_render_resolution.x / self->fov); + + + return (SDL_FRect){ + tl.x, tl.y, + size.x, size.y }; } diff --git a/src/camera.h b/src/camera.h index 9098e0b..c2ab7fa 100644 --- a/src/camera.h +++ b/src/camera.h @@ -2,11 +2,12 @@ #define _fencer_camera_h #include "vmath.h" +#include "transform.h" #include <SDL2/SDL_rect.h> struct Camera { - Vector centre; - float width; + float fov; + Transform transform; }; typedef struct Camera Camera; @@ -16,6 +17,6 @@ extern Camera g_camera; extern void camera_init(); extern SDL_FRect camera_screen_to_world_space(Camera* self, SDL_FRect* camera_space); -extern SDL_FRect camera_world_to_screen_space(Camera* self, SDL_FRect* world_space); +extern SDL_FRect camera_world_to_pixel_rect(Camera* self, SDL_FRect* world_space); #endif // !_fencer_camera_h diff --git a/src/fencer.c b/src/fencer.c index c2a0bf8..12cba63 100644 --- a/src/fencer.c +++ b/src/fencer.c @@ -16,32 +16,32 @@ static Vector cam_speed = ZeroVector; static void cam_move_h(int val) { - cam_speed.x = -val * 0.01f; + cam_speed.x = val * 0.1f; } static void cam_move_v(int val) { - cam_speed.y = val * 0.01f; + cam_speed.y = -val * 0.1f; } static void play() { + g_camera.fov = 40; spr_player_standing = spritesheet_load("assets/sprites/player.png", (IVector){128, 128}); player = sprite_from_spritesheet(spr_player_standing, 0); - sprite_set_origin(player, (Vector){0.5f, 1.0f}); - player_trans.scale = OneVector; - assert(player != NULL && "Player failed to load"); + player_trans.scale = (Vector){4.f, 4.f}; + sprite_set_origin(player, (Vector){0.25f, 1.f}); level = level_load("level_0"); - assert(level != NULL && "Level failed to load"); input_add_axis_action(SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, &cam_move_h); input_add_axis_action(SDL_SCANCODE_DOWN, SDL_SCANCODE_UP, &cam_move_v); - g_camera.width = 20; + } static void tick() { - g_camera.centre = vaddf(g_camera.centre, cam_speed); + g_camera.transform.position = vaddf(g_camera.transform.position, cam_speed); + player_trans.position = g_camera.transform.position; } static @@ -52,7 +52,7 @@ void draw() { int main(int argc, char* argv[]) { struct ProgramSettings config = { - .target_fps = 0, // unbounded speed + .target_fps = 120, .title = "fencer", .view_resolution = {1920, 1080}, .on_play = &play, diff --git a/src/level.c b/src/level.c index b39023a..3e0b0bf 100644 --- a/src/level.c +++ b/src/level.c @@ -13,10 +13,9 @@ struct Level { asset_id asset_id; size_t level_iid; + Transform transform; Tilemap** tilemaps; - size_t tilemaps_len; - Vector player_start; }; @@ -62,7 +61,8 @@ Level* level_from_json(cJSON* json) { return NULL; } *self = (Level) { - .asset_id = store_asset(self, &_deallocate_level) + .asset_id = store_asset(self, &_deallocate_level), + .transform = IdentityTransform }; // fetch the instance id @@ -125,6 +125,6 @@ void level_destroy(Level* self) { void level_draw(Level* self) { Tilemap** end = self->tilemaps + self->tilemaps_len; for(Tilemap** map = self->tilemaps; map != end; ++map) { - tilemap_draw(*map); + tilemap_draw(*map, self->transform); } } diff --git a/src/sprite.c b/src/sprite.c index d74df8a..76e2370 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -44,19 +44,18 @@ void sprite_draw(Sprite* self, Transform transform) { SDL_Texture* texture = spritesheet_get_texture(self->spritesheet); SDL_Rect source = spritesheet_get_frame_rect(self->spritesheet, self->current_frame); - Vector left_top = vinvf(transform_point(&transform, self->origin)); + Vector left_top = transform_point(&transform, vinvf(self->origin)); SDL_FRect destination = (SDL_FRect) { left_top.x, left_top.y, transform.scale.x, transform.scale.y }; - - destination = camera_world_to_screen_space(&g_camera, &destination); - - Vector origin = vmulff(vmulf(self->origin, transform.scale), 0.5f); + destination = camera_world_to_pixel_rect(&g_camera, &destination); + Vector origin = vmulf(self->origin, transform.scale); SDL_RenderCopyExF(g_renderer, texture, &source, &destination, transform.rotation * 57.2958, &origin, SDL_FLIP_NONE); + SDL_SetRenderDrawColor(g_renderer, 255, 255, 255, 255); } Vector sprite_get_origin(Sprite* self) { diff --git a/src/tilemap.c b/src/tilemap.c index db5bba3..d5fc6a8 100644 --- a/src/tilemap.c +++ b/src/tilemap.c @@ -95,8 +95,8 @@ Tilemap* tilemap_from_autolayer(cJSON* json) { return self; } -void tilemap_draw(Tilemap* self) { - Transform tiletrans = self->transform; +void tilemap_draw(Tilemap* self, Transform transform) { + Transform tiletrans = transform_apply(transform, self->transform); TileInstance* tile; for(int i = 0; i < self->map_num; ++i) { diff --git a/src/tilemap.h b/src/tilemap.h index 8be86ef..1956f33 100644 --- a/src/tilemap.h +++ b/src/tilemap.h @@ -14,6 +14,6 @@ extern void tilemap_destroy(Tilemap* self); extern void tilemap_set_tileset(Tilemap* self, Tileset* set); -extern void tilemap_draw(Tilemap* tilemap); +extern void tilemap_draw(Tilemap* tilemap, Transform transform); #endif // !_fencer_tilemap_h diff --git a/src/transform.h b/src/transform.h index 9687f28..9627601 100644 --- a/src/transform.h +++ b/src/transform.h @@ -37,12 +37,12 @@ Transform transform_invert(Transform a) { static inline Vector transform_direction(Transform* self, Vector direction) { - return vmulf(vrotatef(direction, self->rotation), self->scale); + return vrotatef(direction, self->rotation); } static inline Vector transform_point(Transform* self, Vector position) { - return vaddf(transform_direction(self, position), self->position); + return vaddf(vmulf(transform_direction(self, position), self->scale), self->position); } #endif // !_fencer_transform_h