From c36db1ef4ba655e07c526bc569cde1d663adff30 Mon Sep 17 00:00:00 2001 From: whaffman Date: Mon, 12 May 2025 12:56:12 +0200 Subject: [PATCH] norm WIP --- inc/cub3d.h | 3 +- inc/vec_math.h | 44 ++++++---- src/math/get_fraction.c | 22 +++++ src/render/DDAscratch.c | 9 +-- src/render/render_minimap.c | 93 +++++++++++++--------- src/render/render_sprite.c | 155 +++++++++++++++--------------------- src/util/initialize.c | 4 +- 7 files changed, 176 insertions(+), 154 deletions(-) create mode 100644 src/math/get_fraction.c diff --git a/inc/cub3d.h b/inc/cub3d.h index ab5e595..c541d3d 100644 --- a/inc/cub3d.h +++ b/inc/cub3d.h @@ -6,7 +6,7 @@ /* By: qmennen +#+ */ /* +#+ */ /* Created: 2025/04/15 12:22:29 by qmennen #+# #+# */ -/* Updated: 2025/05/09 15:05:36 by whaffman ######## odam.nl */ +/* Updated: 2025/05/12 11:31:51 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -32,6 +32,7 @@ # define NUM_KEYS 256 # define TILE_SIZE 8 +#define MINIMAP_SIZE 300 # include "MLX42.h" # include "allowed.h" diff --git a/inc/vec_math.h b/inc/vec_math.h index 7d15302..b21e3d8 100644 --- a/inc/vec_math.h +++ b/inc/vec_math.h @@ -6,13 +6,13 @@ /* By: qmennen +#+ */ /* +#+ */ /* Created: 2025/04/25 10:11:44 by whaffman #+# #+# */ -/* Updated: 2025/05/12 11:04:28 by whaffman ######## odam.nl */ +/* Updated: 2025/05/12 12:11:59 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ #ifndef VEC_MATH_H -#define VEC_MATH_H -#include "types.h" +# define VEC_MATH_H +# include "types.h" /** * @brief Calculates the distance between two 2D vectors. @@ -21,7 +21,7 @@ * @param b The second 2D vector. * @return The distance between vector a and vector b as a double. */ -double dist(t_vec2 a, t_vec2 b); +double dist(t_vec2 a, t_vec2 b); /** * @brief Calculates the norm (length) of a 2D vector. @@ -29,7 +29,7 @@ double dist(t_vec2 a, t_vec2 b); * @param a The 2D vector. * @return The norm of vector a as a double. */ -double norm(t_vec2 a); +double norm(t_vec2 a); /** * @brief Calculates the dot product of two 2D vectors. @@ -38,7 +38,7 @@ double norm(t_vec2 a); * @param b The second 2D vector. * @return The dot product of vector a and vector b as a double. */ -double dot(t_vec2 a, t_vec2 b); +double dot(t_vec2 a, t_vec2 b); /** * @brief Calculates the distance from a point to a line. @@ -47,7 +47,7 @@ double dot(t_vec2 a, t_vec2 b); * @param line The line defined by a (support)point and a direction. * @return The distance from the point to the line as a double. */ -double dist_point_line(t_vec2 point, t_vec2_line line); +double dist_point_line(t_vec2 point, t_vec2_line line); /** * @brief Adds two 2D vectors. @@ -56,7 +56,7 @@ double dist_point_line(t_vec2 point, t_vec2_line line); * @param b The second 2D vector. * @return The sum of vector a and vector b as a new 2D vector. */ -t_vec2 add(t_vec2 a, t_vec2 b); +t_vec2 add(t_vec2 a, t_vec2 b); /** * @brief Subtracts one 2D vector from another. @@ -65,7 +65,7 @@ t_vec2 add(t_vec2 a, t_vec2 b); * @param b The second 2D vector to subtract from the first. * @return The result of subtracting vector b from vector a as a new 2D vector. */ -t_vec2 sub(t_vec2 a, t_vec2 b); +t_vec2 sub(t_vec2 a, t_vec2 b); /** * @brief Multiplies a 2D vector by a scalar. @@ -74,7 +74,7 @@ t_vec2 sub(t_vec2 a, t_vec2 b); * @param b The scalar to multiply the vector by. * @return The result of multiplying vector a by scalar b as a new 2D vector. */ -t_vec2 mul(t_vec2 a, double b); +t_vec2 mul(t_vec2 a, double b); /** * @brief Rotates a 2D vector by a given angle. @@ -83,7 +83,7 @@ t_vec2 mul(t_vec2 a, double b); * @param angle The angle in radians to rotate the vector by. * @return The rotated vector as a new 2D vector. */ -t_vec2 rot(t_vec2 a, double angle); +t_vec2 rot(t_vec2 a, double angle); /** * @brief Calculates the perpendicular vector of a 2D vector. @@ -91,7 +91,7 @@ t_vec2 rot(t_vec2 a, double angle); * @param a The 2D vector to calculate the perpendicular of. * @return The perpendicular vector as a new 2D vector. */ -t_vec2 perp(t_vec2 a); +t_vec2 perp(t_vec2 a); /** * @brief Rotates a 2D vector by a given direction vector. @@ -100,7 +100,7 @@ t_vec2 perp(t_vec2 a); * @param dir The direction vector to rotate by. * @return The rotated vector as a new 2D vector. */ -t_vec2 rot_by_dir(t_vec2 vec, t_vec2 dir, t_vec2 axis); +t_vec2 rot_by_dir(t_vec2 vec, t_vec2 dir, t_vec2 axis); /** * @brief Converts a 2D vector to a 2D integer vector. @@ -108,7 +108,7 @@ t_vec2 rot_by_dir(t_vec2 vec, t_vec2 dir, t_vec2 axis); * @param vec The 2D vector to convert. * @return The converted 2D integer vector. */ -t_vec2_int vec2_to_int(t_vec2 vec); +t_vec2_int vec2_to_int(t_vec2 vec); /** * @brief Converts a 2D integer vector to a 2D vector. @@ -116,6 +116,20 @@ t_vec2_int vec2_to_int(t_vec2 vec); * @param vec The 2D integer vector to convert. * @return The converted 2D vector. */ -t_vec2 vec2_from_int(t_vec2_int vec); +t_vec2 vec2_from_int(t_vec2_int vec); + + +/** + * @brief Calculates the fractional part of each component of a 2D vector. + * + * This function takes a 2D vector as input and returns a new vector where + * each component is the fractional part of the corresponding component + * in the input vector. The fractional part of a number is the part + * after the decimal point. + * + * @param vec The input 2D vector. + * @return A 2D vector containing the fractional parts. + */ +t_vec2 get_fraction(t_vec2 vec); #endif // VEC_MATH_H \ No newline at end of file diff --git a/src/math/get_fraction.c b/src/math/get_fraction.c new file mode 100644 index 0000000..e22a08a --- /dev/null +++ b/src/math/get_fraction.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* get_fraction.c :+: :+: */ +/* +:+ */ +/* By: whaffman +#+ */ +/* +#+ */ +/* Created: 2025/05/12 12:09:27 by whaffman #+# #+# */ +/* Updated: 2025/05/12 12:10:01 by whaffman ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +t_vec2 get_fraction(t_vec2 vec) +{ + t_vec2 result; + + result.x = vec.x - (int)vec.x; + result.y = vec.y - (int)vec.y; + return (result); +} \ No newline at end of file diff --git a/src/render/DDAscratch.c b/src/render/DDAscratch.c index 7b4f599..f56b11a 100644 --- a/src/render/DDAscratch.c +++ b/src/render/DDAscratch.c @@ -6,7 +6,7 @@ /* By: qmennen +#+ */ /* +#+ */ /* Created: 2025/05/02 11:58:09 by whaffman #+# #+# */ -/* Updated: 2025/05/09 15:20:04 by whaffman ######## odam.nl */ +/* Updated: 2025/05/12 12:55:30 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -193,7 +193,6 @@ void draw_floor(t_game *game) double row_dist; t_vec2 floor_step; t_vec2 floor_pos; - t_vec2_int floor_cell; t_vec2_int tex_coords; const t_vec2 left_ray = sub(game->player->dir, game->player->camera); const t_vec2 right_ray = add(game->player->dir, game->player->camera); @@ -207,14 +206,12 @@ void draw_floor(t_game *game) x = 0; while (x < game->screen->width) { - floor_cell = (t_vec2_int){(int)floor_pos.x, (int)floor_pos.y}; - tex_coords = (t_vec2_int){(int)(64 * (floor_pos.x - floor_cell.x)) & 63, - (int)(64 * (floor_pos.y - floor_cell.y)) & 63}; - floor_pos = add(floor_pos, floor_step); + tex_coords = vec2_to_int(mul(get_fraction(floor_pos), 64)); // & 63 is gone heap buffer overflow with asan i dont get it color = get_texture_color(game->map->texture_floor, (t_render){row_dist, 0, 0}, tex_coords.x, tex_coords.y); mlx_put_pixel(game->screen->img, x, y, color); color = get_texture_color(game->map->texture_ceiling, (t_render){row_dist, 0, 0}, tex_coords.x, tex_coords.y); mlx_put_pixel(game->screen->img, x, game->screen->height - y - 1, color); + floor_pos = add(floor_pos, floor_step); x++; } y++; diff --git a/src/render/render_minimap.c b/src/render/render_minimap.c index a4137b9..01d28f2 100644 --- a/src/render/render_minimap.c +++ b/src/render/render_minimap.c @@ -1,51 +1,66 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* render_minimap.c :+: :+: */ +/* +:+ */ +/* By: whaffman +#+ */ +/* +#+ */ +/* Created: 2025/05/12 11:31:34 by whaffman #+# #+# */ +/* Updated: 2025/05/12 11:31:43 by whaffman ######## odam.nl */ +/* */ +/* ************************************************************************** */ + #include "cub3d.h" +static int inside_circle(t_vec2_int point) +{ + const int radius_squared = 0.25 * MINIMAP_SIZE * MINIMAP_SIZE; + int dx; + int dy; + + dx = point.x - 0.5 * MINIMAP_SIZE; + dy = point.y - 0.5 * MINIMAP_SIZE; + return (dx * dx + dy * dy <= radius_squared); +} + +static void draw_minimap_pixel(t_game *game, t_vec2_int disp, t_vec2 map) +{ + mlx_image_t *img; + + img = game->screen->minimap; + if (map.x < 0 || map.x >= game->map->width + || map.y < 0 || map.y >= game->map->height) + mlx_put_pixel(img, disp.x, disp.y, 0x00ff0044); + else if (game->map->grid[(int)map.y][(int)map.x] == TILE_WALL) + mlx_put_pixel(img, disp.x, disp.y, 0x00ff00ff); + else if (game->map->grid[(int)map.y][(int)map.x] == TILE_EMPTY + || game->map->grid[(int)map.y][(int)map.x] == TILE_PLAYER) + mlx_put_pixel(img, disp.x, disp.y, 0x00ff0077); + else + mlx_put_pixel(img, disp.x, disp.y, 0x00ff0044); +} -#define MINIMAP_SIZE 300 void render_map(t_game *game) { + int i; t_vec2_int disp; - t_vec2 map; + t_vec2 map; + double map_center; - disp.x = 0; - while (disp.x < MINIMAP_SIZE) + i = 0; + map_center = 0.5 * MINIMAP_SIZE / TILE_SIZE; + while (i < MINIMAP_SIZE * MINIMAP_SIZE) { - disp.y = 0; - while (disp.y < MINIMAP_SIZE) + disp.x = i % MINIMAP_SIZE; + disp.y = i / MINIMAP_SIZE; + if (inside_circle(disp)) { - if (disp.x == 0.5 * MINIMAP_SIZE || disp.y == 0.5 * MINIMAP_SIZE) - { - mlx_put_pixel(game->screen->minimap, disp.x, disp.y, 0x00ff00dd); - disp.y++; - continue ; - } - if ((disp.x - 0.5 * MINIMAP_SIZE) *(disp.x - 0.5 * MINIMAP_SIZE) + (disp.y - 0.5 * MINIMAP_SIZE) * (disp.y - 0.5 * MINIMAP_SIZE) > 0.25* MINIMAP_SIZE * MINIMAP_SIZE) - { - disp.y++; - continue ; - } - map.x = ((double)disp.x/TILE_SIZE) + game->player->pos.x - (0.5 * MINIMAP_SIZE/TILE_SIZE); - map.y = ((double)disp.y/TILE_SIZE) + game->player->pos.y - (0.5 * MINIMAP_SIZE/TILE_SIZE); + map = mul(vec2_from_int(disp), 1.0 / TILE_SIZE); + map = add(map, game->player->pos); + map = sub(map, (t_vec2){map_center, map_center}); map = rot_by_dir(map, game->player->dir, game->player->pos); - - if (map.x < 0 || map.x >= game->map->width - || map.y < 0 || map.y >= game->map->height) - { - mlx_put_pixel(game->screen->minimap, disp.x, disp.y, 0x00ff0044); - - disp.y++; - continue ; - } - if (game->map->grid[(int)map.y][(int)map.x] == TILE_WALL) - mlx_put_pixel(game->screen->minimap, disp.x, disp.y, 0x00ff00ff); - else if (game->map->grid[(int)map.y][(int)map.x] == TILE_EMPTY - || game->map->grid[(int)map.y][(int)map.x] == TILE_PLAYER) - mlx_put_pixel(game->screen->minimap, disp.x, disp.y, 0x00ff0077); - else - mlx_put_pixel(game->screen->minimap, disp.x, disp.y, 0x00ff0044); - disp.y++; + draw_minimap_pixel(game, disp, map); } - disp.x++; - + i++; } -} \ No newline at end of file +} diff --git a/src/render/render_sprite.c b/src/render/render_sprite.c index 0f40710..7f2c559 100644 --- a/src/render/render_sprite.c +++ b/src/render/render_sprite.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ */ /* +#+ */ /* Created: 2025/05/08 12:23:17 by qmennen #+# #+# */ -/* Updated: 2025/05/11 13:26:18 by whaffman ######## odam.nl */ +/* Updated: 2025/05/12 12:46:26 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -33,84 +33,56 @@ static void sort_sprites(t_game *game) } } -// static void sort_sprites(t_game *game) -// { -// t_sprite sprite_temp; -// int n; -// int i; -// int new_n; - -// n = game->map->n_sprites; -// while (n > 1) -// { -// i = 1; -// new_n = 0; -// while (i <= n - 1) -// { -// if (game->map->sprites[i - 1].dist < game->map->sprites[i].dist) -// { -// sprite_temp = game->map->sprites[i - 1]; -// game->map->sprites[i - 1] = game->map->sprites[i]; -// game->map->sprites[i] = sprite_temp; -// new_n = i; -// } -// i++; -// } -// n = new_n; -// } -// } - -static void calculate_sprite_dist(t_game *game) +static void calculate_sprite_dist(t_game *game) { - int i; - t_vec2 player_pos; + 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}); + (t_vec2_line){player_pos, game->player->camera}); i++; } } -static void cam_fraction(t_game *game, t_sprite *sprite) +static void cam_fraction(t_game *game, t_sprite *sprite) { - t_vec2 ps; - double frac_cam; - double frac_sprite; - double denominator; + 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 * game->player->camera.y - ps.y * game->player->camera.x); - frac_sprite = (game->player->camera.y * game->player->dir.x - game->player->camera.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) - { - sprite->cam_frac = NAN; - return; - } + return ; sprite->cam_frac = frac_cam / denominator; if (sprite->cam_frac < -1 || sprite->cam_frac > 1) - { sprite->cam_frac = NAN; - return; - } - return; + return ; } -unsigned int calculate_alpha(mlx_texture_t *texture, int x, int y, double dist) + +unsigned int calculate_alpha(int x, int y, double dist) { - // int index; int alpha; - // index = (x + y * texture->width) * texture->bytes_per_pixel; 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) +unsigned int sample_texture_color( + mlx_texture_t *texture, + int x, int y, int alpha + ) { int index; @@ -121,58 +93,59 @@ unsigned int sample_texture_color(mlx_texture_t *texture, int x, int y, int alph | (texture->pixels[index + 3] != 0) * alpha); } -void draw_sprite(t_game *game, t_sprite *sprite, t_render *render) +static void get_start_end(t_game *game, + t_sprite *sprite, t_vec2_int *start, t_vec2_int *end) { - double sprite_scale; - double x_invrange; - double y_invrange; - int x_start; - int y_start; - int x_end; - int y_end; + double sprite_scale; - int x; - int y; - int alpha; - double tex_x; - double tex_y; - unsigned int color; + sprite_scale = 16.0 / sprite->dist; + start->x = 0.5 * (game->screen->width * (1.0 + sprite->cam_frac) + - sprite->texture->width * sprite_scale); + start->y = 0.5 * (game->screen->height + - sprite->texture->height * sprite_scale); + end->x = start->x + (sprite->texture->width * sprite_scale); + end->y = start->y + (sprite->texture->height * sprite_scale); +} + +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; if (isnan(sprite->cam_frac) || sprite->dist <= 0) - return; - sprite_scale = 16.0 / sprite->dist; - x_start = game->screen->width * 0.5 * (1.0 + sprite->cam_frac) - (sprite->texture->width * sprite_scale * 0.5); - y_start = (game->screen->height - sprite->texture->height * sprite_scale )* 0.5; - x_end = x_start + (sprite->texture->width * sprite_scale); - y_end = y_start + (sprite->texture->height * sprite_scale); - y_invrange = 1.0 / (y_end - y_start); - x_invrange = 1.0 / (x_end - x_start); - x = x_start; - alpha = calculate_alpha(sprite->texture, x_start, y_start, sprite->dist); - while (x < x_end) + 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) { - if (x > 0 && x < game->screen->width && sprite->dist <= render[x].perp_dist) + if (disp.x > 0 && disp.x < game->screen->width && sprite->dist <= render[disp.x].perp_dist) { - y = y_start; - tex_x = (x - x_start) * x_invrange * sprite->texture->width; - while (y < y_end) + tex.x = (disp.x - start.x) * invrange.x * sprite->texture->width; + disp.y = start.y; + while (disp.y < end.y) { - tex_y = (y- y_start) * y_invrange * sprite->texture->height; - color = sample_texture_color(sprite->texture, (int)(tex_x), (int)(tex_y), alpha); - if (y > 0 && y < game->screen->height && (color & 0xFF) != 0) - { - mlx_put_pixel(game->screen->img, x, y, color); - } - 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++; } } - x++; + disp.x++; } } -void render_sprites(t_render *render, t_game *game) +void render_sprites(t_render *render, t_game *game) { - int i; + int i; calculate_sprite_dist(game); sort_sprites(game); @@ -183,4 +156,4 @@ void render_sprites(t_render *render, t_game *game) draw_sprite(game, &game->map->sprites[i], render); i++; } -} \ No newline at end of file +} diff --git a/src/util/initialize.c b/src/util/initialize.c index 1e32ffc..324ca05 100644 --- a/src/util/initialize.c +++ b/src/util/initialize.c @@ -6,7 +6,7 @@ /* By: qmennen +#+ */ /* +#+ */ /* Created: 2025/04/22 17:08:26 by qmennen #+# #+# */ -/* Updated: 2025/05/11 14:03:16 by whaffman ######## odam.nl */ +/* Updated: 2025/05/12 12:51:27 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -14,7 +14,7 @@ static int init_temp(t_game **game) { - (*game)->map->sprites = malloc(sizeof(t_sprite) * 5); + (*game)->map->sprites = malloc(sizeof(t_sprite) * 10); if (!(*game)->map->sprites) return (FAILURE); (*game)->map->sprites[0].n_frames = 1;