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
}
{
<MLX42>
Memcheck:Addr8
...
fun:dl_open_worker
}

120
inc/fdf.h
View File

@ -31,16 +31,30 @@
# define FILE_ERROR "Error: could not open file %s\n"
# define USAGE_ERROR "Usage: %s <filename>\n"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
# ifndef M_PI
# define M_PI 3.14159265358979323846
# endif
# define SQRT2 1.41421356237309514547
# define SQRT6 2.44948974278317788134
# define WIDTH 500
# define HEIGHT 500
typedef struct s_point_3d
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
{
double x;
double y;
@ -52,11 +66,12 @@ typedef struct s_point_2d
{
int x;
int y;
int orig_z;
int color;
} t_point_2d;
typedef struct s_map
typedef struct s_map
{
t_point_3d *orig;
t_point_3d *rot;
@ -68,54 +83,61 @@ typedef struct s_map
typedef struct s_fdf
{
t_map *map;
mlx_t *mlx;
mlx_image_t *img;
mlx_image_t *menu;
double angle_x;
double angle_y;
double angle_z;
double animate_z;
double zoom;
int offset_x;
int offset_y;
int last_width;
int last_height;
double z_scale;
t_map *map;
mlx_t *mlx;
mlx_image_t *img;
mlx_image_t *menu;
double angle_x;
double angle_y;
double angle_z;
double animate_z;
double zoom;
int offset_x;
int offset_y;
int last_width;
int last_height;
double z_scale;
t_colormode colormode;
t_projection projection;
} t_fdf;
int interpolate_color(t_point_2d start, t_point_2d end, t_point_2d current);
int get_color(char *str);
int get_map_sizes(char *filename, t_map *map);
void free_line_and_split(char **line, char ***split);
int read_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 fdf_apply_rotation(t_fdf *fdf);
void handle_error(t_fdf *fdf, char *error);
int interpolate_color(t_point_2d start,
t_point_2d end, t_point_2d current);
int get_color(char *str);
int get_map_sizes(char *filename, t_map *map);
void free_line_and_split(char **line, char ***split);
int load_map_from_file(char *filename, t_fdf *fdf);
int parse_map(char *filename, t_fdf *fdf);
void copy_map(t_fdf *fdf);
void fdf_apply_rotation(t_fdf *fdf);
void handle_error(t_fdf *fdf, char *error);
void rotate_x(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);
bool fdf_put_pixel(mlx_image_t *img, t_point_2d point);
void fdf_draw_line(mlx_image_t *img, t_point_2d start,
t_point_2d end);
int fdf_hooks(t_fdf *fdf);
void resize_hook(int width, int height, void *param);
void rotate_x(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);
bool fdf_put_pixel(t_fdf *fdf, t_point_2d point);
void fdf_draw_line(t_fdf *fdf, t_point_2d start,
t_point_2d end);
int fdf_hooks(t_fdf *fdf);
void resize_hook(int width, int height, void *param);
void draw_hook(void *param);
void key_hook(mlx_key_data_t keydata, void *param);
void fdf_set_background(mlx_image_t *img, int color);
void project_isometric(t_fdf *fdf);
double deg2rad(double deg);
t_fdf *initialise_fdf(void);
bool clean_fdf(t_fdf *fdf);
void get_z_max(t_fdf *fdf);
int init_mlx(t_fdf *fdf);
void set_map_point(t_fdf *fdf, int x, int y, char **str);
void draw_hook(void *param);
void key_hook(mlx_key_data_t keydata, void *param);
void fdf_set_background(mlx_image_t *img, int color);
void project_isometric(t_fdf *fdf);
double deg2rad(double deg);
t_fdf *initialise_fdf(void);
bool clean_fdf(t_fdf *fdf);
void get_z_max(t_fdf *fdf);
int init_mlx(t_fdf *fdf);
void set_map_point(t_fdf *fdf, int x, int y, char **str);
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
@ -135,4 +157,4 @@ int get_z_color(double z, int z_max);
// [p] Change projection mode
// [ESC] Close window
// ============================
// ============================

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 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

View File

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

View File

@ -58,15 +58,23 @@ int interpolate_color(t_point_2d start, t_point_2d end, t_point_2d current)
return (red << 24 | green << 16 | blue << 8 | 0xFF);
}
int get_z_color(double z, int z_max)
int get_z_color(double z, int z_max)
{
int red;
int red;
int green;
int temp;
int temp;
temp = 255 * z / z_max;
red = temp;
green = 255 - temp;
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"
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
|| point.y < 0 || point.y >= (int) img->height)
int color;
color = 0xFFFFFFFF;
if (point.x < 0 || point.x >= (int) fdf->img->width
|| point.y < 0 || point.y >= (int) fdf->img->height)
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);
}
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 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)
{
current.color = interpolate_color(start, end, current);
fdf_put_pixel(img, current);
fdf_put_pixel(fdf, current);
if (delta > 0)
{
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 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)
{
current.color = interpolate_color(start, end, current);
fdf_put_pixel(img, current);
fdf_put_pixel(fdf, current);
if (delta > 0)
{
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
|| start.y < 0 || start.y >= (int) img->height)
&& (end.x < 0 || end.x >= (int) img->width
|| end.y < 0 || end.y >= (int) img->height))
if ((start.x < 0 || start.x >= (int) fdf->img->width
|| start.y < 0 || start.y >= (int) fdf->img->height)
&& (end.x < 0 || end.x >= (int) fdf->img->width
|| end.y < 0 || end.y >= (int) fdf->img->height))
return ;
if (abs(end.y - start.y) < abs(end.x - start.x))
{
if (start.x > end.x)
fdf_draw_line_low(img, end, start);
fdf_draw_line_low(fdf, end, start);
else
fdf_draw_line_low(img, start, end);
fdf_draw_line_low(fdf, start, end);
}
else
{
if (start.y > end.y)
fdf_draw_line_high(img, end, start);
fdf_draw_line_high(fdf, end, start);
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_key_hook(fdf->mlx, key_hook, fdf);
mlx_close_hook(fdf->mlx, close_hook, fdf);
mlx_resize_hook(fdf->mlx, resize_hook, fdf);
return (1);
}
@ -30,7 +31,7 @@ void resize_hook(int width, int height, void *param)
fdf = (t_fdf *)param;
mlx_delete_image(fdf->mlx, fdf->img);
fdf->img = mlx_new_image(fdf->mlx, fdf->mlx->width, fdf->mlx->height);
if (!fdf->img
if (!fdf->img
|| (mlx_image_to_window(fdf->mlx, fdf->img, 0, 0) < 0)
|| (mlx_image_to_window(fdf->mlx, fdf->menu, 10, 10) < 0))
exit(1);
@ -57,15 +58,15 @@ void draw_hook(void *param)
if (fdf->animate_z)
fdf->angle_z += deg2rad(fdf->animate_z);
fdf_apply_rotation(fdf);
project_isometric(fdf);
project(fdf);
i = 0;
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)
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)
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++;
}
// draw_menu(fdf);
@ -98,16 +99,21 @@ mlx_image_t *draw_menu(t_fdf *fdf)
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)
{
t_fdf *fdf;
fdf = (t_fdf *)param;
if (keydata.key == MLX_KEY_ESCAPE)
{
mlx_close_window(((t_fdf *)param)->mlx);
exit(0);
}
close_hook(fdf);
if (keydata.key == MLX_KEY_A && keydata.action != MLX_RELEASE)
fdf->angle_z -= deg2rad(5);
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;
if (keydata.key == MLX_KEY_SLASH && keydata.action == MLX_PRESS)
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;
printf("init_mlx\n");
mlx = mlx_init(WIDTH, HEIGHT, "FdF", true);
if (!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->last_width = WIDTH;
fdf->last_height = HEIGHT;
fdf->colormode = COLOR_MODE_DEFAULT;
fdf->projection = PROJECTION_ISOMETRIC;
fdf->map->orig = NULL;
fdf->map->rot = 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));
if (!fdf->map->orig || !fdf->map->rot || !fdf->map->proj)
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");
get_z_max(fdf);
ft_printf("%d\n", fdf->map->z_max);
return (SUCCESS);
}

View File

@ -12,6 +12,46 @@
#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)
{
int i;
@ -29,8 +69,18 @@ void project_isometric(t_fdf *fdf)
- 2 * fdf->map->rot[i].z) / SQRT6;
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].color = get_z_color(fdf->map->orig[i].z, fdf->map->z_max);
// fdf->map->proj[i].color = fdf->map->rot[i].color;
fdf->map->proj[i].orig_z = fdf->map->orig[i].z;
fdf->map->proj[i].color = fdf->map->rot[i].color;
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_ :::::: ::: */
/* read_map.c :+: / :+::+: :+: */
/* load_map_from_file.c :+: / :+::+: :+: */
/* +:+ > +:++:+ +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ +:+ +#++#++:++#++ */
/* +#+ +#+#+ +#++#+ +#+ \o/ */
@ -12,7 +12,7 @@
#include "fdf.h"
int read_map(char *filename, t_fdf *fdf)
int load_map_from_file(char *filename, t_fdf *fdf)
{
int fd;
char *line;