This commit is contained in:
Willem Haffmans 2025-05-14 21:25:45 +02:00
parent f9272b27c7
commit 74633b0a97
4 changed files with 159 additions and 106 deletions

View File

@ -6,7 +6,7 @@
/* By: whaffman <whaffman@student.codam.nl> +#+ */ /* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */ /* +#+ */
/* Created: 2025/04/15 16:28:16 by qmennen #+# #+# */ /* Created: 2025/04/15 16:28:16 by qmennen #+# #+# */
/* Updated: 2025/05/14 19:23:07 by whaffman ######## odam.nl */ /* Updated: 2025/05/14 21:24:48 by whaffman ######## odam.nl */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -32,4 +32,12 @@ void draw_line(t_game *game, t_render render, int x);
unsigned int get_texture_color(mlx_texture_t *texture, unsigned int get_texture_color(mlx_texture_t *texture,
t_render render, t_vec2_int tex); t_render render, t_vec2_int tex);
void sort_sprites(t_game *game);
void calculate_sprite_dist(t_game *game);
void cam_fraction(t_game *game, t_sprite *sprite);
unsigned int calculate_alpha(int x, int y, double dist);
unsigned int sample_texture_color(mlx_texture_t *texture,
t_vec2_int tex, int alpha);
#endif #endif

View File

@ -6,7 +6,7 @@
/* By: whaffman <whaffman@student.codam.nl> +#+ */ /* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */ /* +#+ */
/* Created: 2025/04/15 15:52:44 by qmennen #+# #+# */ /* Created: 2025/04/15 15:52:44 by qmennen #+# #+# */
/* Updated: 2025/05/14 18:42:39 by whaffman ######## odam.nl */ /* Updated: 2025/05/14 21:18:39 by whaffman ######## odam.nl */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -118,6 +118,13 @@ typedef struct s_render
double wall_x; double wall_x;
} t_render; } t_render;
typedef struct s_sprite_column
{
t_vec2_int start;
t_vec2_int end;
int x;
} t_sprite_column;
typedef struct s_game typedef struct s_game
{ {
t_map *map; t_map *map;

View File

@ -6,93 +6,12 @@
/* By: whaffman <whaffman@student.codam.nl> +#+ */ /* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */ /* +#+ */
/* Created: 2025/05/08 12:23:17 by qmennen #+# #+# */ /* Created: 2025/05/08 12:23:17 by qmennen #+# #+# */
/* Updated: 2025/05/14 20:06:28 by whaffman ######## odam.nl */ /* Updated: 2025/05/14 21:21:55 by whaffman ######## odam.nl */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "render.h" #include "render.h"
static void sort_sprites(t_game *game)
{
int i;
int j;
t_sprite key;
i = 1;
while (i < game->map->n_sprites)
{
key = game->map->sprites[i];
j = i - 1;
while (j >= 0 && game->map->sprites[j].dist < key.dist)
{
game->map->sprites[j + 1] = game->map->sprites[j];
j--;
}
game->map->sprites[j + 1] = key;
i++;
}
}
static void calculate_sprite_dist(t_game *game)
{
t_vec2 player_pos;
int i;
i = 0;
player_pos = game->player->pos;
while (i < game->map->n_sprites)
{
game->map->sprites[i].dist = dist_point_line(game->map->sprites[i].pos,
(t_vec2_line){player_pos, game->player->camera});
i++;
}
}
static void cam_fraction(t_game *game, t_sprite *sprite)
{
t_vec2 ps;
t_vec2 cam;
double frac_cam;
double frac_sprite;
double denominator;
cam = game->player->camera;
ps = sub(sprite->pos, game->player->pos);
frac_cam = (ps.y * game->player->dir.x - ps.x * game->player->dir.y);
denominator = (ps.x * cam.y - ps.y * cam.x);
frac_sprite = (cam.y * game->player->dir.x - cam.x * game->player->dir.y);
sprite->cam_frac = NAN;
if (denominator == 0 || (frac_sprite / denominator) < 0)
return ;
sprite->cam_frac = frac_cam / denominator;
if (sprite->cam_frac < -1 || sprite->cam_frac > 1)
sprite->cam_frac = NAN;
return ;
}
unsigned int calculate_alpha(int x, int y, double dist)
{
int alpha;
dist = (dist > 1) * dist + (dist <= 1) * 1;
alpha = (255.0 / dist);
return (alpha);
}
unsigned int sample_texture_color(
mlx_texture_t *texture,
int x, int y, int alpha
)
{
int index;
index = (x + y * texture->width) * texture->bytes_per_pixel;
return (texture->pixels[index] << 24
| texture->pixels[index + 1] << 16
| texture->pixels[index + 2] << 8
| (texture->pixels[index + 3] != 0) * alpha);
}
static void get_start_end(t_game *game, static void get_start_end(t_game *game,
t_sprite *sprite, t_vec2_int *start, t_vec2_int *end) t_sprite *sprite, t_vec2_int *start, t_vec2_int *end)
{ {
@ -107,39 +26,64 @@ static void get_start_end(t_game *game,
end->y = start->y + (sprite->texture->height * sprite_scale); end->y = start->y + (sprite->texture->height * sprite_scale);
} }
static int sprite_visible(t_game *game,
t_sprite *sprite, t_render *render, int x)
{
return (!isnan(sprite->cam_frac)
&& sprite->dist > 0.5
&& x > 0
&& x < game->screen->width
&& sprite->dist <= render[x].perp_dist);
}
static void draw_sprite_column(
t_game *game, t_sprite *sprite, t_render *render,
t_sprite_column column)
{
t_vec2_int tex;
t_vec2 inv_range;
int alpha;
int y;
unsigned int color;
inv_range.y = 1.0 / (column.end.y - column.start.y);
inv_range.x = 1.0 / (column.end.x - column.start.x);
alpha = calculate_alpha(column.start.x, column.start.y, sprite->dist);
tex.x = (column.x - column.start.x) * sprite->texture->width;
tex.x *= inv_range.x;
y = column.start.y;
while (y < column.end.y)
{
tex.y = (y - column.start.y) * sprite->texture->height;
tex.y *= inv_range.y;
color = sample_texture_color(sprite->texture, tex, alpha);
if (y > 0 && y < game->screen->height && (color & 0xFF) != 0)
mlx_put_pixel(game->screen->img, column.x, y, color);
y++;
}
}
void draw_sprite(t_game *game, t_sprite *sprite, t_render *render) void draw_sprite(t_game *game, t_sprite *sprite, t_render *render)
{ {
t_vec2 invrange;
t_vec2_int start; t_vec2_int start;
t_vec2_int end; t_vec2_int end;
t_vec2_int tex; t_sprite_column column;
t_vec2_int disp; int x;
int alpha;
unsigned int color;
if (isnan(sprite->cam_frac) || sprite->dist <= 0.5) if (isnan(sprite->cam_frac) || sprite->dist <= 0.5)
return ; return ;
get_start_end(game, sprite, &start, &end); get_start_end(game, sprite, &start, &end);
invrange.y = 1.0 / (end.y - start.y); x = start.x;
invrange.x = 1.0 / (end.x - start.x); while (x < end.x)
alpha = calculate_alpha(start.x, start.y, sprite->dist);
disp.x = start.x;
while (disp.x < end.x)
{ {
if (disp.x > 0 && disp.x < game->screen->width && sprite->dist <= render[disp.x].perp_dist) if (sprite_visible(game, sprite, render, x))
{ {
tex.x = (disp.x - start.x) * invrange.x * sprite->texture->width; column.start = start;
disp.y = start.y; column.end = end;
while (disp.y < end.y) column.x = x;
{ draw_sprite_column(game, sprite, render, column);
tex.y = (disp.y - start.y) * invrange.y * sprite->texture->height;
color = sample_texture_color(sprite->texture, tex.x, tex.y, alpha);
if (disp.y > 0 && disp.y < game->screen->height && (color & 0xFF) != 0)
mlx_put_pixel(game->screen->img, disp.x, disp.y, color);
disp.y++;
} }
} x++;
disp.x++;
} }
} }

View File

@ -0,0 +1,94 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* render_sprite_utils.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/05/14 21:21:57 by whaffman #+# #+# */
/* Updated: 2025/05/14 21:25:24 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "cub3d.h"
void sort_sprites(t_game *game)
{
int i;
int j;
t_sprite key;
i = 1;
while (i < game->map->n_sprites)
{
key = game->map->sprites[i];
j = i - 1;
while (j >= 0 && game->map->sprites[j].dist < key.dist)
{
game->map->sprites[j + 1] = game->map->sprites[j];
j--;
}
game->map->sprites[j + 1] = key;
i++;
}
}
void calculate_sprite_dist(t_game *game)
{
t_vec2 player_pos;
int i;
i = 0;
player_pos = game->player->pos;
while (i < game->map->n_sprites)
{
game->map->sprites[i].dist = dist_point_line(game->map->sprites[i].pos,
(t_vec2_line){player_pos, game->player->camera});
i++;
}
}
void cam_fraction(t_game *game, t_sprite *sprite)
{
t_vec2 ps;
t_vec2 cam;
double frac_cam;
double frac_sprite;
double denominator;
cam = game->player->camera;
ps = sub(sprite->pos, game->player->pos);
frac_cam = (ps.y * game->player->dir.x - ps.x * game->player->dir.y);
denominator = (ps.x * cam.y - ps.y * cam.x);
frac_sprite = (cam.y * game->player->dir.x - cam.x * game->player->dir.y);
sprite->cam_frac = NAN;
if (denominator == 0 || (frac_sprite / denominator) < 0)
return ;
sprite->cam_frac = frac_cam / denominator;
if (sprite->cam_frac < -1 || sprite->cam_frac > 1)
sprite->cam_frac = NAN;
return ;
}
unsigned int calculate_alpha(int x, int y, double dist)
{
int alpha;
dist = (dist > 1) * dist + (dist <= 1) * 1;
alpha = (255.0 / dist);
return (alpha);
}
unsigned int sample_texture_color(
mlx_texture_t *texture,
t_vec2_int tex, int alpha
)
{
int index;
index = (tex.x + tex.y * texture->width) * texture->bytes_per_pixel;
return (texture->pixels[index] << 24
| texture->pixels[index + 1] << 16
| texture->pixels[index + 2] << 8
| (texture->pixels[index + 3] != 0) * alpha);
}