You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

98 lines
3.0 KiB

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* render.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/05/31 09:33:02 by narnaud #+# #+# */
/* Updated: 2022/11/21 23:17:22 by narnaud ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/cub3d.h"
void get_wall(int *startY, int *endY, int height)
{
*startY = -height / 2 + WIN_Y_SZ / 2;
if (*startY < 0)
*startY = 0;
*endY = height / 2 + WIN_Y_SZ / 2;
if (*endY >= WIN_Y_SZ)
*endY = WIN_Y_SZ - 1;
}
void draw_wall(t_env *env, t_rc *rc, int wallHeight, int *wall_lim)
{
int tex_height;
t_vec tex;
double step;
double y_out;
tex_height = env->tex[rc->tex].height;
tex.x = (int)(rc->wall_x * (double)env->tex[rc->tex].width);
if ((!rc->side && rc->vec.x > 0) || (rc->side && rc->vec.y < 0))
tex.x = env->tex[rc->tex].width - tex.x - 1;
step = 1.0 * tex_height / wallHeight;
y_out = (wall_lim[0] - WIN_Y_SZ / 2.0 + wallHeight / 2.0) * step;
while (wall_lim[0] < wall_lim[1])
{
tex.y = (int)y_out & (tex_height - 1);
y_out += step;
env->buffer[env->line_bytes * wall_lim[0] + rc->x] \
= env->tex[rc->tex].buffer[tex_height * tex.y + tex.x];
wall_lim[0]++;
}
}
void draw_vert(t_env *env, t_rc *rc, int side)
{
int wall_height;
int wall_lim[2];
wall_height = (int)(WIN_Y_SZ / rc->s_dist[side]);
if (wall_height < 0)
wall_height = 0;
get_wall(wall_lim, wall_lim + 1, wall_height);
draw_rectangle(env, (t_rect){(t_vec){rc->x, 0},
(t_vec){1, wall_lim[0]}, env->ceil_color}, 0);
draw_wall(env, rc, wall_height, wall_lim);
draw_rectangle(env, (t_rect){(t_vec){rc->x, wall_lim[1]},
(t_vec){1, WIN_Y_SZ - wall_lim[1]}, env->floor_color}, 0);
}
void render_view(t_env *env)
{
t_rc rc;
int x;
double cam_x;
x = 0;
while (x < WIN_X_SZ)
{
ft_bzero(&rc, sizeof(rc));
cam_x = 2 * x / (double)WIN_X_SZ - 1;
dvec_set(&rc.vec, env->player_dir.x + env->cam_plan.x * cam_x,
env->player_dir.y + env->cam_plan.y * cam_x);
rc.cell = (int [2]){env->player_pos.x, env->player_pos.y};
rc.step = (int [2]){0, 0};
rc.x = x;
init_ray(env, &rc);
while (!ray_hit(env, &rc))
rc.s_dist[rc.side] += rc.d_dist[rc.side];
check_side(&rc);
draw_vert(env, &rc, rc.side);
x++;
}
}
void render(t_env *env)
{
ft_bzero(env->buffer, WIN_Y_SZ * WIN_X_SZ * sizeof(int));
render_view(env);
if (env->minimap)
{
render_minimap(env);
}
mlx_put_image_to_window(env->mlx, env->win, env->img, 0, 0);
}