42_cub3d/render.c
2024-10-14 17:06:45 +02:00

138 lines
3.7 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* render.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: greg <greg@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/14 14:55:05 by greg #+# #+# */
/* Updated: 2024/10/14 16:53:21 by greg ### ########.fr */
/* */
/* ************************************************************************** */
#include "algo.h"
static int init_step(t_ray *ray)
{
if (ray->raydirX < 0)
{
ray->stepX = -1;
ray->sidedistX = (ray->posX - ray->mapX) * ray->deltadistX;
}
else
{
ray->stepX = 1;
ray->sidedistX = (ray->mapX + 1.0 - ray->posX) * ray->deltadistX;
}
if (ray->raydirY < 0)
{
ray->stepY = -1;
ray->sidedistY = (ray->posY - ray->mapY) * ray->deltadistY;
}
else
{
ray->stepY = 1;
ray->sidedistY = (ray->mapY + 1.0 - ray->posY) * ray->deltadistY;
}
return (0);
}
static int ray_pos(t_ray *ray, int x)
{
// position et direction du rayon
ray->cameraX = 2 * x / ray->width - 1;
ray->raydirX = ray->dirX + ray->planeX * ray->cameraX;
ray->raydirY = ray->dirY + ray->planeY * ray->cameraX;
ray->mapX = (int)ray->posX;
ray->mapY = (int)ray->posY;
ray->deltadistX = (ray->raydirX == 0) ? 1e30 : fabs(1 / ray->raydirX);
ray->deltadistY = (ray->raydirY == 0) ? 1e30 : fabs(1 / ray->raydirY);
return (0);
}
int draw_img(t_ray *ray, int drawStart, int *img_data, int drawEnd, int x)
{
// draw vertical line
int y = 0;
while (y <= drawStart)
{
img_data[y * (int)ray->width + x] = 0x29f8ff;;
y++;
}
y = drawStart;
while (y <= drawEnd)
{
img_data[y * (int)ray->width + x] = 0xFF0000;
y++;
}
y++;
while (y <= ray->height)
{
img_data[y * (int)ray->width + x] = 0xFF985C;
y++;
}
return (0);
}
void find_wall(t_ray *ray)
{
int side;
int hit;
hit = 0;
while(hit == 0)
{
if(ray->sidedistX < ray->sidedistY) //jump to next map square, either in x-direction, or in y-direction
{
ray->sidedistX += ray->deltadistX;
ray->mapX += ray->stepX;
side = 0;
}
else
{
ray->sidedistY += ray->deltadistY;
ray->mapY += ray->stepY;
side = 1;
}
if(worldMap[ray->mapX][ray->mapY] == 1) //Check if ray has hit a wall
hit = 1;
}
if(side == 0)
ray->perpwalldist = (ray->sidedistX - ray->deltadistX);
else
ray->perpwalldist = (ray->sidedistY - ray->deltadistY);
}
int render(t_ray *ray)
{
int x;
int lineHeight;
int *img_data;
int drawStart;
int drawEnd;
img_data = (int *)mlx_get_data_addr(ray->img_ptr, &(int){32}, &(int){ray->width * 4}, &(int){0});
ft_bzero(img_data, ray->width * ray->height * sizeof(int)); // clear image data
x = 0;
while (x++ < ray->width)
{
ray_pos(ray, x);
init_step(ray); //calculate step and initial sideDist
find_wall(ray);
lineHeight = (int)(ray->height / ray->perpwalldist); //Calculate height of line to draw on screen
drawStart = -lineHeight / 2 + ray->height / 2; //calculate lowest and highest pixel to fill in current stripe
if(drawStart < 0)
drawStart = 0;
drawEnd = lineHeight / 2 + ray->height / 2;
if(drawEnd >= ray->height)
drawEnd = ray->height - 1;
draw_img(ray, drawStart, img_data, drawEnd, x);
}
mlx_put_image_to_window(ray->mlx_ptr, ray->win_ptr, ray->img_ptr, 0, 0);
return (0);
}