cub3d/src/render/render_walls.c
Willem Haffmans f2c6b09af8 minor changes
2025-05-18 13:10:21 +02:00

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++;
}
}