From 74633b0a97c5d922406d9a52183c67d366c22edf Mon Sep 17 00:00:00 2001 From: Willem Haffmans Date: Wed, 14 May 2025 21:25:45 +0200 Subject: [PATCH] NORM --- inc/render.h | 10 +- inc/types.h | 9 +- src/render/render_sprite.c | 152 ++++++++++--------------------- src/render/render_sprite_utils.c | 94 +++++++++++++++++++ 4 files changed, 159 insertions(+), 106 deletions(-) create mode 100644 src/render/render_sprite_utils.c diff --git a/inc/render.h b/inc/render.h index dfe043c..17ad5e2 100644 --- a/inc/render.h +++ b/inc/render.h @@ -6,7 +6,7 @@ /* By: whaffman +#+ */ /* +#+ */ /* Created: 2025/04/15 16:28:16 by qmennen #+# #+# */ -/* Updated: 2025/05/14 19:23:07 by whaffman ######## odam.nl */ +/* Updated: 2025/05/14 21:24:48 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -32,4 +32,12 @@ void draw_line(t_game *game, t_render render, int x); unsigned int get_texture_color(mlx_texture_t *texture, t_render render, t_vec2_int tex); +void sort_sprites(t_game *game); +void calculate_sprite_dist(t_game *game); +void cam_fraction(t_game *game, t_sprite *sprite); +unsigned int calculate_alpha(int x, int y, double dist); +unsigned int sample_texture_color(mlx_texture_t *texture, + t_vec2_int tex, int alpha); + + #endif diff --git a/inc/types.h b/inc/types.h index 31238f6..745ec90 100644 --- a/inc/types.h +++ b/inc/types.h @@ -6,7 +6,7 @@ /* By: whaffman +#+ */ /* +#+ */ /* Created: 2025/04/15 15:52:44 by qmennen #+# #+# */ -/* Updated: 2025/05/14 18:42:39 by whaffman ######## odam.nl */ +/* Updated: 2025/05/14 21:18:39 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -118,6 +118,13 @@ typedef struct s_render double wall_x; } t_render; +typedef struct s_sprite_column +{ + t_vec2_int start; + t_vec2_int end; + int x; +} t_sprite_column; + typedef struct s_game { t_map *map; diff --git a/src/render/render_sprite.c b/src/render/render_sprite.c index 484f0d9..7f341d7 100644 --- a/src/render/render_sprite.c +++ b/src/render/render_sprite.c @@ -6,93 +6,12 @@ /* By: whaffman +#+ */ /* +#+ */ /* Created: 2025/05/08 12:23:17 by qmennen #+# #+# */ -/* Updated: 2025/05/14 20:06:28 by whaffman ######## odam.nl */ +/* Updated: 2025/05/14 21:21:55 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ #include "render.h" -static void sort_sprites(t_game *game) -{ - int i; - int j; - t_sprite key; - - i = 1; - while (i < game->map->n_sprites) - { - key = game->map->sprites[i]; - j = i - 1; - while (j >= 0 && game->map->sprites[j].dist < key.dist) - { - game->map->sprites[j + 1] = game->map->sprites[j]; - j--; - } - game->map->sprites[j + 1] = key; - i++; - } -} - -static void calculate_sprite_dist(t_game *game) -{ - t_vec2 player_pos; - int i; - - i = 0; - player_pos = game->player->pos; - while (i < game->map->n_sprites) - { - game->map->sprites[i].dist = dist_point_line(game->map->sprites[i].pos, - (t_vec2_line){player_pos, game->player->camera}); - i++; - } -} - -static void cam_fraction(t_game *game, t_sprite *sprite) -{ - t_vec2 ps; - t_vec2 cam; - double frac_cam; - double frac_sprite; - double denominator; - - cam = game->player->camera; - ps = sub(sprite->pos, game->player->pos); - frac_cam = (ps.y * game->player->dir.x - ps.x * game->player->dir.y); - denominator = (ps.x * cam.y - ps.y * cam.x); - frac_sprite = (cam.y * game->player->dir.x - cam.x * game->player->dir.y); - sprite->cam_frac = NAN; - if (denominator == 0 || (frac_sprite / denominator) < 0) - return ; - sprite->cam_frac = frac_cam / denominator; - if (sprite->cam_frac < -1 || sprite->cam_frac > 1) - sprite->cam_frac = NAN; - return ; -} - -unsigned int calculate_alpha(int x, int y, double dist) -{ - int alpha; - - dist = (dist > 1) * dist + (dist <= 1) * 1; - alpha = (255.0 / dist); - return (alpha); -} - -unsigned int sample_texture_color( - mlx_texture_t *texture, - int x, int y, int alpha - ) -{ - int index; - - index = (x + y * texture->width) * texture->bytes_per_pixel; - return (texture->pixels[index] << 24 - | texture->pixels[index + 1] << 16 - | texture->pixels[index + 2] << 8 - | (texture->pixels[index + 3] != 0) * alpha); -} - static void get_start_end(t_game *game, t_sprite *sprite, t_vec2_int *start, t_vec2_int *end) { @@ -107,39 +26,64 @@ static void get_start_end(t_game *game, end->y = start->y + (sprite->texture->height * sprite_scale); } +static int sprite_visible(t_game *game, + t_sprite *sprite, t_render *render, int x) +{ + return (!isnan(sprite->cam_frac) + && sprite->dist > 0.5 + && x > 0 + && x < game->screen->width + && sprite->dist <= render[x].perp_dist); +} + +static void draw_sprite_column( + t_game *game, t_sprite *sprite, t_render *render, + t_sprite_column column) +{ + t_vec2_int tex; + t_vec2 inv_range; + int alpha; + int y; + unsigned int color; + + inv_range.y = 1.0 / (column.end.y - column.start.y); + inv_range.x = 1.0 / (column.end.x - column.start.x); + alpha = calculate_alpha(column.start.x, column.start.y, sprite->dist); + tex.x = (column.x - column.start.x) * sprite->texture->width; + tex.x *= inv_range.x; + y = column.start.y; + while (y < column.end.y) + { + tex.y = (y - column.start.y) * sprite->texture->height; + tex.y *= inv_range.y; + color = sample_texture_color(sprite->texture, tex, alpha); + if (y > 0 && y < game->screen->height && (color & 0xFF) != 0) + mlx_put_pixel(game->screen->img, column.x, y, color); + y++; + } +} + void draw_sprite(t_game *game, t_sprite *sprite, t_render *render) { - t_vec2 invrange; t_vec2_int start; t_vec2_int end; - t_vec2_int tex; - t_vec2_int disp; - int alpha; - unsigned int color; + t_sprite_column column; + int x; if (isnan(sprite->cam_frac) || sprite->dist <= 0.5) return ; get_start_end(game, sprite, &start, &end); - invrange.y = 1.0 / (end.y - start.y); - invrange.x = 1.0 / (end.x - start.x); - alpha = calculate_alpha(start.x, start.y, sprite->dist); - disp.x = start.x; - while (disp.x < end.x) + x = start.x; + while (x < end.x) { - if (disp.x > 0 && disp.x < game->screen->width && sprite->dist <= render[disp.x].perp_dist) + if (sprite_visible(game, sprite, render, x)) { - tex.x = (disp.x - start.x) * invrange.x * sprite->texture->width; - disp.y = start.y; - while (disp.y < end.y) - { - tex.y = (disp.y - start.y) * invrange.y * sprite->texture->height; - color = sample_texture_color(sprite->texture, tex.x, tex.y, alpha); - if (disp.y > 0 && disp.y < game->screen->height && (color & 0xFF) != 0) - mlx_put_pixel(game->screen->img, disp.x, disp.y, color); - disp.y++; - } + column.start = start; + column.end = end; + column.x = x; + draw_sprite_column(game, sprite, render, column); } - disp.x++; + x++; } } diff --git a/src/render/render_sprite_utils.c b/src/render/render_sprite_utils.c new file mode 100644 index 0000000..bf76153 --- /dev/null +++ b/src/render/render_sprite_utils.c @@ -0,0 +1,94 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* render_sprite_utils.c :+: :+: */ +/* +:+ */ +/* By: whaffman +#+ */ +/* +#+ */ +/* Created: 2025/05/14 21:21:57 by whaffman #+# #+# */ +/* Updated: 2025/05/14 21:25:24 by whaffman ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +void sort_sprites(t_game *game) +{ + int i; + int j; + t_sprite key; + + i = 1; + while (i < game->map->n_sprites) + { + key = game->map->sprites[i]; + j = i - 1; + while (j >= 0 && game->map->sprites[j].dist < key.dist) + { + game->map->sprites[j + 1] = game->map->sprites[j]; + j--; + } + game->map->sprites[j + 1] = key; + i++; + } +} + +void calculate_sprite_dist(t_game *game) +{ + t_vec2 player_pos; + int i; + + i = 0; + player_pos = game->player->pos; + while (i < game->map->n_sprites) + { + game->map->sprites[i].dist = dist_point_line(game->map->sprites[i].pos, + (t_vec2_line){player_pos, game->player->camera}); + i++; + } +} + +void cam_fraction(t_game *game, t_sprite *sprite) +{ + t_vec2 ps; + t_vec2 cam; + double frac_cam; + double frac_sprite; + double denominator; + + cam = game->player->camera; + ps = sub(sprite->pos, game->player->pos); + frac_cam = (ps.y * game->player->dir.x - ps.x * game->player->dir.y); + denominator = (ps.x * cam.y - ps.y * cam.x); + frac_sprite = (cam.y * game->player->dir.x - cam.x * game->player->dir.y); + sprite->cam_frac = NAN; + if (denominator == 0 || (frac_sprite / denominator) < 0) + return ; + sprite->cam_frac = frac_cam / denominator; + if (sprite->cam_frac < -1 || sprite->cam_frac > 1) + sprite->cam_frac = NAN; + return ; +} + +unsigned int calculate_alpha(int x, int y, double dist) +{ + int alpha; + + dist = (dist > 1) * dist + (dist <= 1) * 1; + alpha = (255.0 / dist); + return (alpha); +} + +unsigned int sample_texture_color( + mlx_texture_t *texture, + t_vec2_int tex, int alpha + ) +{ + int index; + + index = (tex.x + tex.y * texture->width) * texture->bytes_per_pixel; + return (texture->pixels[index] << 24 + | texture->pixels[index + 1] << 16 + | texture->pixels[index + 2] << 8 + | (texture->pixels[index + 3] != 0) * alpha); +}