colors and projections

This commit is contained in:
whaffman 2024-12-16 17:54:39 +01:00
parent 256adb4ff3
commit fc19ce7624
13 changed files with 200 additions and 94 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"cmake.ignoreCMakeListsMissing": true
}

View File

@ -46,3 +46,11 @@
... ...
fun:_dl_open fun:_dl_open
} }
{
<MLX42>
Memcheck:Addr8
...
fun:dl_open_worker
}

View File

@ -40,6 +40,20 @@
# define WIDTH 500 # define WIDTH 500
# define HEIGHT 500 # define HEIGHT 500
typedef enum e_colormode
{
COLOR_MODE_DEFAULT,
COLOR_MODE_Z,
COLOR_MODE_GRADIENT
} t_colormode;
typedef enum e_projection
{
PROJECTION_ISOMETRIC,
PROJECTION_PARALLEL,
PROJECTION_TRIMETRIC
} t_projection;
typedef struct s_point_3d typedef struct s_point_3d
{ {
double x; double x;
@ -52,6 +66,7 @@ typedef struct s_point_2d
{ {
int x; int x;
int y; int y;
int orig_z;
int color; int color;
} t_point_2d; } t_point_2d;
@ -82,15 +97,17 @@ typedef struct s_fdf
int last_width; int last_width;
int last_height; int last_height;
double z_scale; double z_scale;
t_colormode colormode;
t_projection projection;
} t_fdf; } t_fdf;
int interpolate_color(t_point_2d start, t_point_2d end, t_point_2d current); int interpolate_color(t_point_2d start,
t_point_2d end, t_point_2d current);
int get_color(char *str); int get_color(char *str);
int get_map_sizes(char *filename, t_map *map); int get_map_sizes(char *filename, t_map *map);
void free_line_and_split(char **line, char ***split); void free_line_and_split(char **line, char ***split);
int read_map(char *filename, t_fdf *fdf); int load_map_from_file(char *filename, t_fdf *fdf);
int parse_map(char *filename, t_fdf *fdf); int parse_map(char *filename, t_fdf *fdf);
void print_map(t_map *map);
void copy_map(t_fdf *fdf); void copy_map(t_fdf *fdf);
void fdf_apply_rotation(t_fdf *fdf); void fdf_apply_rotation(t_fdf *fdf);
void handle_error(t_fdf *fdf, char *error); void handle_error(t_fdf *fdf, char *error);
@ -98,8 +115,8 @@ void handle_error(t_fdf *fdf, char *error);
void rotate_x(t_point_3d **points, double angle, int size); void rotate_x(t_point_3d **points, double angle, int size);
void rotate_y(t_point_3d **points, double angle, int size); void rotate_y(t_point_3d **points, double angle, int size);
void rotate_z(t_point_3d **points, double angle, int size); void rotate_z(t_point_3d **points, double angle, int size);
bool fdf_put_pixel(mlx_image_t *img, t_point_2d point); bool fdf_put_pixel(t_fdf *fdf, t_point_2d point);
void fdf_draw_line(mlx_image_t *img, t_point_2d start, void fdf_draw_line(t_fdf *fdf, t_point_2d start,
t_point_2d end); t_point_2d end);
int fdf_hooks(t_fdf *fdf); int fdf_hooks(t_fdf *fdf);
void resize_hook(int width, int height, void *param); void resize_hook(int width, int height, void *param);
@ -116,6 +133,11 @@ int init_mlx(t_fdf *fdf);
void set_map_point(t_fdf *fdf, int x, int y, char **str); void set_map_point(t_fdf *fdf, int x, int y, char **str);
mlx_image_t *draw_menu(t_fdf *fdf); mlx_image_t *draw_menu(t_fdf *fdf);
int get_z_color(double z, int z_max); int get_z_color(double z, int z_max);
void close_hook(void *param);
int get_gradient_color(double z, int z_max);
void project_parallel(t_fdf *fdf);
void project(t_fdf *fdf);
#endif #endif

View File

@ -1,4 +1,4 @@
5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 10 10 0 0 10 10 0 0 0 10 10 10 10 10 0 0 0 0 0 10 10 0 0 10 10 0 0 0 10 10 10 10 10 0 0 0
0 0 10 10 0 0 10 10 0 0 0 0 0 0 0 10 10 0 0 0 0 10 10 0 0 10 10 0 0 0 0 0 0 0 10 10 0 0

View File

@ -14,16 +14,12 @@
bool clean_fdf(t_fdf *fdf) bool clean_fdf(t_fdf *fdf)
{ {
mlx_delete_image(fdf->mlx, fdf->img);
mlx_delete_image(fdf->mlx, fdf->menu);
if (fdf->map) if (fdf->map)
{ {
free(fdf->map->orig); free(fdf->map->orig);
free(fdf->map->rot); free(fdf->map->rot);
free(fdf->map->proj); free(fdf->map->proj);
free(fdf->map); free(fdf->map);
} }
free(fdf); free(fdf);
return (true); return (true);

View File

@ -62,7 +62,6 @@ int get_z_color(double z, int z_max)
{ {
int red; int red;
int green; int green;
int temp; int temp;
temp = 255 * z / z_max; temp = 255 * z / z_max;
@ -70,3 +69,12 @@ int get_z_color(double z, int z_max)
green = 255 - temp; green = 255 - temp;
return (red << 24 | green << 16 | 0x00FF); return (red << 24 | green << 16 | 0x00FF);
} }
int get_gradient_color(double z, int z_max)
{
const int colors[] = {0x0058fbff, 0x007efeff, 0x008fd7ff, 0x0098a3f,
0x009c7aff, 0x1fa46bff, 0x5eb13dff, 0x83c052ff,
0xa5cf69ff, 0xc3de81ff, 0xeeffffff, 0xffffffff,0xffffffff};
return (colors[(int)(z * 12 / z_max)]);
}

View File

@ -11,16 +11,25 @@
/* ************************************************************************** */ /* ************************************************************************** */
#include "fdf.h" #include "fdf.h"
bool fdf_put_pixel(mlx_image_t *img, t_point_2d point) bool fdf_put_pixel(t_fdf *fdf, t_point_2d point)
{ {
if (point.x < 0 || point.x >= (int) img->width int color;
|| point.y < 0 || point.y >= (int) img->height)
color = 0xFFFFFFFF;
if (point.x < 0 || point.x >= (int) fdf->img->width
|| point.y < 0 || point.y >= (int) fdf->img->height)
return (false); return (false);
mlx_put_pixel(img, point.x, point.y, point.color); if (fdf->colormode == COLOR_MODE_DEFAULT)
color = point.color;
else if (fdf->colormode == COLOR_MODE_Z)
color = get_z_color(point.orig_z, fdf->map->z_max);
else if (fdf->colormode == COLOR_MODE_GRADIENT)
color = get_gradient_color(point.orig_z, fdf->map->z_max);
mlx_put_pixel(fdf->img, point.x, point.y, color);
return (true); return (true);
} }
void fdf_draw_line_low(mlx_image_t *img, t_point_2d start, t_point_2d end) void fdf_draw_line_low(t_fdf *fdf, t_point_2d start, t_point_2d end)
{ {
int delta; int delta;
int yi; int yi;
@ -37,7 +46,7 @@ void fdf_draw_line_low(mlx_image_t *img, t_point_2d start, t_point_2d end)
while (current.x <= end.x) while (current.x <= end.x)
{ {
current.color = interpolate_color(start, end, current); current.color = interpolate_color(start, end, current);
fdf_put_pixel(img, current); fdf_put_pixel(fdf, current);
if (delta > 0) if (delta > 0)
{ {
current.y += yi; current.y += yi;
@ -48,7 +57,7 @@ void fdf_draw_line_low(mlx_image_t *img, t_point_2d start, t_point_2d end)
} }
} }
void fdf_draw_line_high(mlx_image_t *img, t_point_2d start, t_point_2d end) void fdf_draw_line_high(t_fdf *fdf, t_point_2d start, t_point_2d end)
{ {
int delta; int delta;
int xi; int xi;
@ -65,7 +74,7 @@ void fdf_draw_line_high(mlx_image_t *img, t_point_2d start, t_point_2d end)
while (current.y <= end.y) while (current.y <= end.y)
{ {
current.color = interpolate_color(start, end, current); current.color = interpolate_color(start, end, current);
fdf_put_pixel(img, current); fdf_put_pixel(fdf, current);
if (delta > 0) if (delta > 0)
{ {
current.x += xi; current.x += xi;
@ -76,25 +85,25 @@ void fdf_draw_line_high(mlx_image_t *img, t_point_2d start, t_point_2d end)
} }
} }
void fdf_draw_line(mlx_image_t *img, t_point_2d start, t_point_2d end) void fdf_draw_line(t_fdf *fdf, t_point_2d start, t_point_2d end)
{ {
if ((start.x < 0 || start.x >= (int) img->width if ((start.x < 0 || start.x >= (int) fdf->img->width
|| start.y < 0 || start.y >= (int) img->height) || start.y < 0 || start.y >= (int) fdf->img->height)
&& (end.x < 0 || end.x >= (int) img->width && (end.x < 0 || end.x >= (int) fdf->img->width
|| end.y < 0 || end.y >= (int) img->height)) || end.y < 0 || end.y >= (int) fdf->img->height))
return ; return ;
if (abs(end.y - start.y) < abs(end.x - start.x)) if (abs(end.y - start.y) < abs(end.x - start.x))
{ {
if (start.x > end.x) if (start.x > end.x)
fdf_draw_line_low(img, end, start); fdf_draw_line_low(fdf, end, start);
else else
fdf_draw_line_low(img, start, end); fdf_draw_line_low(fdf, start, end);
} }
else else
{ {
if (start.y > end.y) if (start.y > end.y)
fdf_draw_line_high(img, end, start); fdf_draw_line_high(fdf, end, start);
else else
fdf_draw_line_high(img, start, end); fdf_draw_line_high(fdf, start, end);
} }
} }

View File

@ -17,6 +17,7 @@ int fdf_hooks(t_fdf *fdf)
{ {
mlx_loop_hook(fdf->mlx, draw_hook, fdf); mlx_loop_hook(fdf->mlx, draw_hook, fdf);
mlx_key_hook(fdf->mlx, key_hook, fdf); mlx_key_hook(fdf->mlx, key_hook, fdf);
mlx_close_hook(fdf->mlx, close_hook, fdf);
mlx_resize_hook(fdf->mlx, resize_hook, fdf); mlx_resize_hook(fdf->mlx, resize_hook, fdf);
return (1); return (1);
} }
@ -57,15 +58,15 @@ void draw_hook(void *param)
if (fdf->animate_z) if (fdf->animate_z)
fdf->angle_z += deg2rad(fdf->animate_z); fdf->angle_z += deg2rad(fdf->animate_z);
fdf_apply_rotation(fdf); fdf_apply_rotation(fdf);
project_isometric(fdf); project(fdf);
i = 0; i = 0;
while (i < fdf->map->width * fdf->map->height) while (i < fdf->map->width * fdf->map->height)
{ {
fdf_put_pixel(fdf->img, fdf->map->proj[i]); fdf_put_pixel(fdf, fdf->map->proj[i]);
if (i % fdf->map->width != fdf->map->width - 1) if (i % fdf->map->width != fdf->map->width - 1)
fdf_draw_line(fdf->img, fdf->map->proj[i], fdf->map->proj[i + 1]); fdf_draw_line(fdf, fdf->map->proj[i], fdf->map->proj[i + 1]);
if (i / fdf->map->width != fdf->map->height - 1) if (i / fdf->map->width != fdf->map->height - 1)
fdf_draw_line(fdf->img, fdf->map->proj[i], fdf->map->proj[i + fdf->map->width]); fdf_draw_line(fdf, fdf->map->proj[i], fdf->map->proj[i + fdf->map->width]);
i++; i++;
} }
// draw_menu(fdf); // draw_menu(fdf);
@ -98,16 +99,21 @@ mlx_image_t *draw_menu(t_fdf *fdf)
return (img); return (img);
} }
void close_hook(void *param)
{
mlx_close_window(((t_fdf *)param)->mlx);
mlx_terminate(((t_fdf *)param)->mlx);
clean_fdf((t_fdf *)param);
exit(0);
}
void key_hook(mlx_key_data_t keydata, void *param) void key_hook(mlx_key_data_t keydata, void *param)
{ {
t_fdf *fdf; t_fdf *fdf;
fdf = (t_fdf *)param; fdf = (t_fdf *)param;
if (keydata.key == MLX_KEY_ESCAPE) if (keydata.key == MLX_KEY_ESCAPE)
{ close_hook(fdf);
mlx_close_window(((t_fdf *)param)->mlx);
exit(0);
}
if (keydata.key == MLX_KEY_A && keydata.action != MLX_RELEASE) if (keydata.key == MLX_KEY_A && keydata.action != MLX_RELEASE)
fdf->angle_z -= deg2rad(5); fdf->angle_z -= deg2rad(5);
if (keydata.key == MLX_KEY_D && keydata.action != MLX_RELEASE) if (keydata.key == MLX_KEY_D && keydata.action != MLX_RELEASE)
@ -142,5 +148,9 @@ void key_hook(mlx_key_data_t keydata, void *param)
fdf->animate_z += 0.5; fdf->animate_z += 0.5;
if (keydata.key == MLX_KEY_SLASH && keydata.action == MLX_PRESS) if (keydata.key == MLX_KEY_SLASH && keydata.action == MLX_PRESS)
fdf->menu->enabled = !fdf->menu->enabled; fdf->menu->enabled = !fdf->menu->enabled;
if (keydata.key == MLX_KEY_C && keydata.action == MLX_PRESS)
fdf->colormode = (fdf->colormode + 1) % 3;
if (keydata.key == MLX_KEY_P && keydata.action == MLX_PRESS)
fdf->projection = (fdf->projection + 1) % 3;
} }

View File

@ -16,7 +16,6 @@ int init_mlx(t_fdf *fdf)
{ {
mlx_t *mlx; mlx_t *mlx;
printf("init_mlx\n");
mlx = mlx_init(WIDTH, HEIGHT, "FdF", true); mlx = mlx_init(WIDTH, HEIGHT, "FdF", true);
if (!mlx) if (!mlx)
handle_error(fdf, "Error: failed to initialise MLX"); handle_error(fdf, "Error: failed to initialise MLX");

View File

@ -36,6 +36,8 @@ t_fdf *initialise_fdf(void)
fdf->z_scale = 0.1; fdf->z_scale = 0.1;
fdf->last_width = WIDTH; fdf->last_width = WIDTH;
fdf->last_height = HEIGHT; fdf->last_height = HEIGHT;
fdf->colormode = COLOR_MODE_DEFAULT;
fdf->projection = PROJECTION_ISOMETRIC;
fdf->map->orig = NULL; fdf->map->orig = NULL;
fdf->map->rot = NULL; fdf->map->rot = NULL;
fdf->map->proj = NULL; fdf->map->proj = NULL;

View File

@ -24,9 +24,8 @@ int parse_map(char *filename, t_fdf *fdf)
fdf->map->proj = malloc(map_size * sizeof(t_point_2d)); fdf->map->proj = malloc(map_size * sizeof(t_point_2d));
if (!fdf->map->orig || !fdf->map->rot || !fdf->map->proj) if (!fdf->map->orig || !fdf->map->rot || !fdf->map->proj)
handle_error(fdf, MALLOC_ERROR); handle_error(fdf, MALLOC_ERROR);
if (!read_map(filename, fdf)) if (!load_map_from_file(filename, fdf))
handle_error(fdf, "Error: failed to read map"); handle_error(fdf, "Error: failed to read map");
get_z_max(fdf); get_z_max(fdf);
ft_printf("%d\n", fdf->map->z_max);
return (SUCCESS); return (SUCCESS);
} }

View File

@ -12,6 +12,46 @@
#include "fdf.h" #include "fdf.h"
void project_trimetric(t_fdf *fdf)
{
int i;
double x;
double y;
i = 0;
if (fdf->zoom == 0)
fdf->zoom = fmin(fdf->mlx->width / fdf->map->width,
fdf->mlx->height / fdf->map->height) / 2;
while (i < fdf->map->width * fdf->map->height)
{
x = fdf->map->rot[i].x - fdf->map->rot[i].y;
y = fdf->map->rot[i].x + fdf->map->rot[i].y - fdf->map->rot[i].z;
fdf->map->proj[i].x = x * fdf->zoom + fdf->offset_x;
fdf->map->proj[i].y = y * fdf->zoom + fdf->offset_y;
fdf->map->proj[i].orig_z = fdf->map->orig[i].z;
fdf->map->proj[i].color = fdf->map->rot[i].color;
i++;
}
}
void project_parallel(t_fdf *fdf)
{
int i;
i = 0;
if (fdf->zoom == 0)
fdf->zoom = fmin(fdf->mlx->width / fdf->map->width,
fdf->mlx->height / fdf->map->height) / 2;
while (i < fdf->map->width * fdf->map->height)
{
fdf->map->proj[i].x = fdf->map->rot[i].x * fdf->zoom + fdf->offset_x;
fdf->map->proj[i].y = fdf->map->rot[i].y * fdf->zoom + fdf->offset_y;
fdf->map->proj[i].orig_z = fdf->map->orig[i].z;
fdf->map->proj[i].color = fdf->map->orig[i].color;
i++;
}
}
void project_isometric(t_fdf *fdf) void project_isometric(t_fdf *fdf)
{ {
int i; int i;
@ -29,8 +69,18 @@ void project_isometric(t_fdf *fdf)
- 2 * fdf->map->rot[i].z) / SQRT6; - 2 * fdf->map->rot[i].z) / SQRT6;
fdf->map->proj[i].x = x * fdf->zoom + fdf->offset_x; fdf->map->proj[i].x = x * fdf->zoom + fdf->offset_x;
fdf->map->proj[i].y = y * fdf->zoom + fdf->offset_y; fdf->map->proj[i].y = y * fdf->zoom + fdf->offset_y;
fdf->map->proj[i].color = get_z_color(fdf->map->orig[i].z, fdf->map->z_max); fdf->map->proj[i].orig_z = fdf->map->orig[i].z;
// fdf->map->proj[i].color = fdf->map->rot[i].color; fdf->map->proj[i].color = fdf->map->rot[i].color;
i++; i++;
} }
} }
void project(t_fdf *fdf)
{
if (fdf->projection == PROJECTION_ISOMETRIC)
project_isometric(fdf);
else if (fdf->projection == PROJECTION_PARALLEL)
project_parallel(fdf);
else if (fdf->projection == PROJECTION_TRIMETRIC)
project_trimetric(fdf);
}

View File

@ -1,7 +1,7 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: o_ :::::: ::: */ /* ::: o_ :::::: ::: */
/* read_map.c :+: / :+::+: :+: */ /* load_map_from_file.c :+: / :+::+: :+: */
/* +:+ > +:++:+ +:+ */ /* +:+ > +:++:+ +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ +:+ +#++#++:++#++ */ /* By: whaffman <whaffman@student.codam.nl> +#+ +:+ +#++#++:++#++ */
/* +#+ +#+#+ +#++#+ +#+ \o/ */ /* +#+ +#+#+ +#++#+ +#+ \o/ */
@ -12,7 +12,7 @@
#include "fdf.h" #include "fdf.h"
int read_map(char *filename, t_fdf *fdf) int load_map_from_file(char *filename, t_fdf *fdf)
{ {
int fd; int fd;
char *line; char *line;