From 75692c09a649a9390069369a7811c19bff1ac3f5 Mon Sep 17 00:00:00 2001 From: hugogogo Date: Mon, 2 May 2022 23:19:27 +0200 Subject: [PATCH] wip calcul texture image x position, and add protection when creating texture --- headers/cube3d_proto.h | 4 +-- headers/cube3d_struct.h | 14 +++++++++- srcs/draw/draw_column.c | 55 +++++++++++++++++++++++++++++++-------- srcs/draw/ray_intersect.c | 2 +- srcs/draw/raycast.c | 46 ++++++++++++++++++++++---------- srcs/init/init_textures.c | 29 +++++++++++++++++---- 6 files changed, 116 insertions(+), 34 deletions(-) diff --git a/headers/cube3d_proto.h b/headers/cube3d_proto.h index b5bdf6e..7ce4f9f 100644 --- a/headers/cube3d_proto.h +++ b/headers/cube3d_proto.h @@ -87,8 +87,8 @@ void draw(t_game *game); // raycast.c void raycast(t_game *game, t_rcast *rcast); // ray_intersect.c -void ray_intersect(t_game *game, t_rcast *rcast, t_vec *ray); +void ray_intersect_wall(t_game *game, t_rcast *rcast, t_vec *ray); // draw_column.c -void draw_column(t_game *game, t_rcast *rcast); +void draw_column(t_game *game, t_rcast *rcast, t_wall *wall, t_txt *txt); #endif diff --git a/headers/cube3d_struct.h b/headers/cube3d_struct.h index b2074ec..195f661 100644 --- a/headers/cube3d_struct.h +++ b/headers/cube3d_struct.h @@ -26,6 +26,18 @@ typedef struct s_vec t_coord end; } t_vec; +/* + * struct with all elements for raycasting + */ + +typedef struct s_wall +{ + t_vec vec; + int height; + int delta; + int posx; +} t_wall; + /* * struct with all elements for raycasting */ @@ -34,7 +46,7 @@ typedef struct s_rcast { t_vec screen_size; t_vec ray; - t_vec wall; + t_wall wall; int screen_width; int screen_height; int screen_dist; diff --git a/srcs/draw/draw_column.c b/srcs/draw/draw_column.c index 0594d9c..81bb9e8 100644 --- a/srcs/draw/draw_column.c +++ b/srcs/draw/draw_column.c @@ -1,43 +1,76 @@ #include "cube3d.h" -void draw_floor_ceiling(t_game *game, t_rcast *rcast, t_txt *txt) +static void draw_floor_ceiling(t_game *game, t_rcast *rcast, t_txt *txt) { t_vec plan; plan.start.x = rcast->ray_nb; plan.end.x = rcast->ray_nb; - if (rcast->wall.start.y > 0) + if (rcast->wall.vec.start.y > 0) { plan.start.y = rcast->screen_height; - plan.end.y = rcast->wall.start.y; + plan.end.y = rcast->wall.vec.start.y; draw_line(&game->img, &plan, txt->rgb_floor); } - if (rcast->wall.start.y < rcast->screen_height) + if (rcast->wall.vec.start.y < rcast->screen_height) { - plan.start.y = rcast->wall.end.y; + plan.start.y = rcast->wall.vec.end.y; plan.end.y = 0; draw_line(&game->img, &plan, txt->rgb_ceiling); } } -void draw_column(t_game *game, t_rcast *rcast) +static void draw_txt_line(t_img *img, t_rcast *rcast, t_wall *wall, t_img *txt_img, int color) +{ + (void)img; + (void)wall; + (void)txt_img; + (void)color; + +// draw_line(img, &wall->vec, color); + + int img_x; + + img_x = (wall->posx * txt_img->width) / rcast->cell; +printf("img_x:%i\n", img_x); + +// t_coord dist; +// int i; +// int j; +// +// dist.x = (*vec).end.x - (*vec).start.x; +// dist.y = (*vec).end.y - (*vec).start.y; +// i = 0; +// j = 0; +// while (ft_abs(i) <= ft_abs(dist.x) && ft_abs(j) <= ft_abs(dist.y)) +// { +// draw_pixel(img, (*vec).start.x + i, (*vec).start.y + j, color); +// if (!ft_abs(dist.x) || ft_abs(j) < ft_abs(i * dist.y / dist.x)) +// j += ft_sign(dist.y); +// else +// i += ft_sign(dist.x); +// } +} + +void draw_column(t_game *game, t_rcast *rcast, t_wall *wall, t_txt *txt) { int color_n; int color_s; int color_e; int color_o; + (void)wall; color_n = 0x00FF00FF; color_s = 0x0000EEEE; color_e = 0x00DDDD00; color_o = 0x00CCCCCC; - draw_floor_ceiling(game, rcast, &game->txt); + draw_floor_ceiling(game, rcast, txt); if (!rcast->is_x && rcast->slope_y > 0) - draw_line(&game->img, &rcast->wall, color_n); + draw_txt_line(&game->img, rcast, wall, &txt->img_n, color_n); if (!rcast->is_x && rcast->slope_y < 0) - draw_line(&game->img, &rcast->wall, color_s); + draw_line(&game->img, &rcast->wall.vec, color_s); if (rcast->is_x && rcast->slope_x > 0) - draw_line(&game->img, &rcast->wall, color_e); + draw_line(&game->img, &rcast->wall.vec, color_e); if (rcast->is_x && rcast->slope_x < 0) - draw_line(&game->img, &rcast->wall, color_o); + draw_line(&game->img, &rcast->wall.vec, color_o); } diff --git a/srcs/draw/ray_intersect.c b/srcs/draw/ray_intersect.c index bae693e..cd8c786 100644 --- a/srcs/draw/ray_intersect.c +++ b/srcs/draw/ray_intersect.c @@ -70,7 +70,7 @@ static void next_cell(t_rcast *rcast) } } -void ray_intersect(t_game *game, t_rcast *rcast, t_vec *ray) +void ray_intersect_wall(t_game *game, t_rcast *rcast, t_vec *ray) { ray->start.x = rcast->ray.start.x + game->plr.pos.x; ray->start.y = rcast->ray.start.y + game->plr.pos.y; diff --git a/srcs/draw/raycast.c b/srcs/draw/raycast.c index 3ba9287..caea111 100644 --- a/srcs/draw/raycast.c +++ b/srcs/draw/raycast.c @@ -1,35 +1,52 @@ #include "cube3d.h" +static void calcul_img_column(t_game *game, t_rcast *rcast, t_wall *wall) +{ + int tmp; + + if (rcast->is_x == 1) + { + tmp = (rcast->slope_y + wall->delta) / ft_abs(rcast->slope_x); + tmp += game->plr.pos.y; + wall->posx = tmp % rcast->cell; + } + else + { + tmp = (rcast->slope_x + wall->delta) / ft_abs(rcast->slope_y); + tmp += game->plr.pos.x; + wall->posx = tmp % rcast->cell; + } +} + static void fill_wall_vector(t_rcast *rcast, int height) { if (height < 0) height = 0; if (height > rcast->screen_height) height = rcast->screen_height; - rcast->wall.start.y = rcast->screen_height / 2 + height / 2; - rcast->wall.end.y = rcast->screen_height / 2 - height / 2; + rcast->wall.vec.start.y = rcast->screen_height / 2 + height / 2; + rcast->wall.vec.end.y = rcast->screen_height / 2 - height / 2; } static void calcul_wall(t_rcast *rcast) { long int height; - int delta; - rcast->wall.start.x = rcast->ray_nb; - rcast->wall.end.x = rcast->ray_nb; + rcast->wall.vec.start.x = rcast->ray_nb; + rcast->wall.vec.end.x = rcast->ray_nb; if (rcast->is_x == 1) - delta = rcast->next_x - rcast->ray_step_x; - else if (rcast->is_x == 0) - delta = rcast->next_y - rcast->ray_step_y; + rcast->wall.delta = rcast->next_x - rcast->ray_step_x; + else + rcast->wall.delta = rcast->next_y - rcast->ray_step_y; height = rcast->screen_height * rcast->cell; if (rcast->slope_x) height *= rcast->slope_x; if (rcast->slope_y) height *= rcast->slope_y; - if (delta && rcast->screen_dist) - height /= (delta * rcast->screen_dist); - height = ft_abs(height); - fill_wall_vector(rcast, height); + if (rcast->wall.delta && rcast->screen_dist) + height /= (rcast->wall.delta * rcast->screen_dist); + rcast->wall.height = ft_abs(height); + fill_wall_vector(rcast, rcast->wall.height); } void raycast(t_game *game, t_rcast *rcast) @@ -39,9 +56,10 @@ void raycast(t_game *game, t_rcast *rcast) rcast->ray_nb = 0; while (rcast->ray_nb <= rcast->screen_width) { - ray_intersect(game, rcast, &ray); + ray_intersect_wall(game, rcast, &ray); calcul_wall(rcast); - draw_column(game, rcast); + calcul_img_column(game, rcast, &rcast->wall); + draw_column(game, rcast, &rcast->wall, &game->txt); (rcast->ray_nb)++; } } diff --git a/srcs/init/init_textures.c b/srcs/init/init_textures.c index e14f906..15e226e 100644 --- a/srcs/init/init_textures.c +++ b/srcs/init/init_textures.c @@ -1,15 +1,34 @@ #include "cube3d.h" -static void init_txtr_img(t_img *img, void *mlx_ptr, char *path) +static int init_txtr_img(t_img *img, void *mlx_ptr, char *path) { img->ptr = mlx_xpm_file_to_image(mlx_ptr, path, &img->width, &img->height); + if (img->ptr == NULL) + return (1); img->data = mlx_get_data_addr(img->ptr, &img->bpp, &img->szl, &img->ndn); + return (0); } void init_txtr(t_txt *txt, void *mlx_ptr) { - init_txtr_img(&txt->img_n, mlx_ptr, txt->txt_north); - init_txtr_img(&txt->img_n, mlx_ptr, txt->txt_south); - init_txtr_img(&txt->img_n, mlx_ptr, txt->txt_east); - init_txtr_img(&txt->img_n, mlx_ptr, txt->txt_west); + if (init_txtr_img(&txt->img_n, mlx_ptr, txt->txt_north) == 1) + mb_exit("failed to read image for texture nord", EXIT_FAILURE); + if (init_txtr_img(&txt->img_s, mlx_ptr, txt->txt_south) == 1) + { + mlx_destroy_image(mlx_ptr, txt->img_n.ptr); + mb_exit("failed to read image for texture south", EXIT_FAILURE); + } + if (init_txtr_img(&txt->img_e, mlx_ptr, txt->txt_east) == 1) + { + mlx_destroy_image(mlx_ptr, txt->img_n.ptr); + mlx_destroy_image(mlx_ptr, txt->img_s.ptr); + mb_exit("failed to read image for texture east", EXIT_FAILURE); + } + if (init_txtr_img(&txt->img_w, mlx_ptr, txt->txt_west) == 1) + { + mlx_destroy_image(mlx_ptr, txt->img_n.ptr); + mlx_destroy_image(mlx_ptr, txt->img_s.ptr); + mlx_destroy_image(mlx_ptr, txt->img_e.ptr); + mb_exit("failed to read image for texture west", EXIT_FAILURE); + } }