117 lines
3.5 KiB
C
117 lines
3.5 KiB
C
/* ************************************************************************** */
|
|
/* */
|
|
/* :::::::: */
|
|
/* render_walls.c :+: :+: */
|
|
/* +:+ */
|
|
/* By: whaffman <whaffman@student.codam.nl> +#+ */
|
|
/* +#+ */
|
|
/* Created: 2025/05/14 13:05:28 by whaffman #+# #+# */
|
|
/* Updated: 2025/05/18 12:05:07 by whaffman ######## odam.nl */
|
|
/* */
|
|
/* ************************************************************************** */
|
|
|
|
#include "cub3d.h"
|
|
|
|
t_side get_side(t_vec2 ray_dir, double perp_dist)
|
|
{
|
|
if (perp_dist > 0)
|
|
{
|
|
if (ray_dir.x > 0)
|
|
return (SIDE_WEST);
|
|
else
|
|
return (SIDE_EAST);
|
|
}
|
|
else
|
|
{
|
|
if (ray_dir.y > 0)
|
|
return (SIDE_NORTH);
|
|
else
|
|
return (SIDE_SOUTH);
|
|
}
|
|
}
|
|
|
|
t_render cast_ray(t_game *game, int x)
|
|
{
|
|
t_vec2 ray_dir;
|
|
t_vec2 pos;
|
|
t_render render;
|
|
double perp_dist;
|
|
|
|
ray_dir = add(game->player->dir,
|
|
mul(game->player->camera,
|
|
(2.0f * x / (double)game->screen->width - 1)));
|
|
pos = game->player->pos;
|
|
perp_dist = dda(ray_dir, pos, game->map);
|
|
render.perp_dist = fabs(perp_dist);
|
|
render.side = get_side(ray_dir, perp_dist);
|
|
if (perp_dist < 0)
|
|
render.wall_x = pos.x + ray_dir.x * render.perp_dist;
|
|
else
|
|
render.wall_x = pos.y + ray_dir.y * render.perp_dist;
|
|
render.wall_x -= floor(render.wall_x);
|
|
return (render);
|
|
}
|
|
|
|
unsigned int get_texture_color(mlx_texture_t *texture,
|
|
t_render render, t_vec2_int tex)
|
|
{
|
|
int index;
|
|
double dist;
|
|
|
|
if (tex.x < 0)
|
|
tex.x = 0;
|
|
if (tex.y < 0)
|
|
tex.y = 0;
|
|
index = (tex.x + tex.y * texture->height) * texture->bytes_per_pixel;
|
|
dist = (render.perp_dist == 0) * 1e30
|
|
+ (render.perp_dist > 1) * render.perp_dist
|
|
+ (render.perp_dist <= 1) * 1;
|
|
return ((unsigned int)texture->pixels[index] << 24
|
|
| (unsigned int)texture->pixels[index + 1] << 16
|
|
| (unsigned int)texture->pixels[index + 2] << 8
|
|
| (int)(1.0 / dist * 255));
|
|
}
|
|
|
|
static int set_range(t_game *game, t_render render, t_range *range, int height)
|
|
{
|
|
int tex_start;
|
|
|
|
height = game->screen->height / render.perp_dist;
|
|
range->start = game->screen->height / 2 - height / 2;
|
|
tex_start = range->start;
|
|
range->start = (range->start > 0) * range->start;
|
|
range->end = height / 2 + game->screen->height / 2;
|
|
if (range->end >= game->screen->height)
|
|
range->end = game->screen->height - 1;
|
|
return (tex_start);
|
|
}
|
|
|
|
void draw_line(t_game *game, t_render render, int x)
|
|
{
|
|
int color;
|
|
int height;
|
|
int tex_start;
|
|
t_vec2_int tex;
|
|
t_range range;
|
|
|
|
height = game->screen->height / render.perp_dist;
|
|
tex_start = set_range(game, render, &range, height);
|
|
tex.x = render.wall_x * game->map->textures[render.side]->width;
|
|
if (render.side == SIDE_NORTH || render.side == SIDE_EAST)
|
|
tex.x = game->map->textures[render.side]->width - tex.x - 1;
|
|
while (range.start < range.end)
|
|
{
|
|
tex.y = (range.start - tex_start);
|
|
tex.y *= ((double)game->map->textures[render.side]->height / height);
|
|
color = get_texture_color(game->map->textures[render.side],
|
|
render, tex);
|
|
if (x < 0
|
|
|| x >= game->screen->width
|
|
|| range.start < 0
|
|
|| range.start >= game->screen->height)
|
|
break ;
|
|
mlx_put_pixel(game->screen->img, x, range.start, color);
|
|
range.start++;
|
|
}
|
|
}
|