From 3864910ac0af4bef91863b7102f9f6ef35ae9bae Mon Sep 17 00:00:00 2001 From: Gregory Date: Sat, 11 Mar 2017 20:17:03 +0200 Subject: [PATCH] semiworking color gradient --- CMakeLists.txt | 2 +- inc/fdf.h | 56 ++++++++++--- src/FDF_init.c | 39 +++++++++ src/color.c | 63 +++++++++++++++ src/help_func.c | 10 ++- src/hooks.c | 15 ++++ src/image_routine.c | 26 ++++++ src/line.c | 56 ++++++++----- src/main.c | 193 ++++++++++++++++++++++++++++++-------------- src/map_init.c | 5 +- src/mat4.c | 4 +- src/pnt_init.c | 10 +++ src/render.c | 47 ++++++----- 13 files changed, 414 insertions(+), 112 deletions(-) create mode 100644 src/FDF_init.c create mode 100644 src/color.c create mode 100644 src/hooks.c create mode 100644 src/image_routine.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 7745294..99c2e72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ set(SOURCE_FILES src/pnt_init.c src/help_func.c src/render.c - src/mat4.c) # sources + src/mat4.c src/color.c src/FDF_init.c src/hooks.c src/image_routine.c) # sources add_executable(fdf ${SOURCE_FILES}) # compilation diff --git a/inc/fdf.h b/inc/fdf.h index b41f164..b9bb942 100644 --- a/inc/fdf.h +++ b/inc/fdf.h @@ -15,25 +15,41 @@ #include #include -# define HEIGHT 500 -# define WIDTH 500 +# define HEIGHT 700 +# define WIDTH 700 +# define BPP 32 +# define ENDIAN 1 +# define COLOR1 2604805 +# define COLOR2 12518661 + +typedef struct s_color +{ + int red; + int green; + int blue; +} t_color; typedef struct s_vec { - double x; - double y; - double z; - int color; + float x; + float y; + float z; } t_vec; typedef struct s_pnt { int x; int y; - int z; - int color; + float z; + t_color color; } t_pnt; +typedef struct s_line +{ + t_pnt p1; + t_pnt p2; +} t_line; + typedef struct s_mw { void *mlx; @@ -67,18 +83,24 @@ typedef struct s_FDF { t_map *map; t_mw *mw; - int w_heigth; + int w_height; int w_width; + int bpp; + int line_size; + void *image; + char *image_data; + int endian; } t_FDF; typedef struct s_swap { int swap_x; + int swap_z; int swap_coord; } t_swap; -void line(t_pnt p1, t_pnt p2, t_mw *mw); +void line(t_pnt p1, t_pnt p2, t_FDF *FDF); t_map *map_init(char *path); void pnt_init(t_map *map); @@ -99,5 +121,19 @@ void render(t_FDF *FDF); void free_tab(char **tab); void quit(t_FDF *FDF); +void swap_init(t_swap *s); + +t_color color_init(int red, int green, int blue); +t_color color_lerp(t_color c1, t_color c2, float step); +t_color int_to_color(int c); +int color_to_int(t_color c); +t_color choose_color(t_line *line, t_swap *s, t_FDF *FDF); + +t_mw *mlx_and_win_ptr_init(int x, int y); +t_FDF *FDF_init(char *path); + +int key_hook(int keycode, void *m); + +void put_pixel_to_image(t_line *line, t_swap *s, t_FDF *FDF); #endif diff --git a/src/FDF_init.c b/src/FDF_init.c new file mode 100644 index 0000000..089db41 --- /dev/null +++ b/src/FDF_init.c @@ -0,0 +1,39 @@ +#include "fdf.h" + +t_mw *mlx_and_win_ptr_init(int x, int y) +{ + t_mw *mw; + + mw = NULL; + if ((mw = malloc(sizeof(t_mw)))) + { + mw->mlx = mlx_init(); + mw->win = mlx_new_window(mw->mlx, x, y, "FDF"); + } + return (mw); +} + +t_FDF *FDF_init(char *path) +{ + t_FDF *FDF; + + FDF = NULL; + if ((FDF = malloc(sizeof(t_FDF)))) + { + FDF->map = map_init(path); + pnt_init(FDF->map); + FDF->w_height = HEIGHT; + FDF->w_width = WIDTH; + FDF->bpp = BPP; + FDF->line_size = WIDTH; + FDF->endian = ENDIAN; + FDF->mw = mlx_and_win_ptr_init(WIDTH, HEIGHT); + FDF->image = mlx_new_image(FDF->mw->mlx, FDF->w_height, FDF->w_height); + FDF->image_data = mlx_get_data_addr( + FDF->image, + &FDF->bpp, + &FDF->line_size, + &FDF->endian); + } + return (FDF); +} diff --git a/src/color.c b/src/color.c new file mode 100644 index 0000000..a6de92b --- /dev/null +++ b/src/color.c @@ -0,0 +1,63 @@ +#include "fdf.h" + +t_color color_init(int red, int green, int blue) +{ + t_color c; + + c.red = red; + c.blue = blue; + c.green = green; + return (c); +} + +t_color color_lerp(t_color c1, t_color c2, float step) +{ + t_color new; + new.red = (float)(c2.red - c1.red) * step + c1.red; + new.green = (float)(c2.green - c1.green) * step + c1.green; + new.blue = (float)(c2.blue - c1.blue) * step + c1.blue; + return (new); +} + +int color_to_int(t_color c) +{ + return ((c.red << 16) | (c.green << 8) | c.blue); +} + +t_color int_to_color(int c) +{ + t_color new; + + new.blue = c & 0x0000FF; + new.green = (c >> 8) & 0x0000FF; + new.red = (c >> 16 ) & 0x0000FF; + c = 0; + return (new); +} + +t_color choose_color(t_line *line, t_swap *s, t_FDF *FDF) +{ + t_color c; + float z1; + float z2; + + FDF = FDF; + z1 = line->p1.z; + z2 = line->p2.z; + if (z2 == 0 && z1 == 0) + c = int_to_color(COLOR1); + else if (z1 == z2) + c = int_to_color(COLOR2); + else if (z2 == 0) + c = int_to_color(COLOR1); + else if (z1 == 0) + c = int_to_color(COLOR2); + else + { + if (s->swap_z) + c = color_lerp(int_to_color(COLOR2), int_to_color(COLOR1), z1 / z2); + else + c = color_lerp(int_to_color(COLOR1), int_to_color(COLOR2), z1 / z2); + } + return (c); +} diff --git a/src/help_func.c b/src/help_func.c index c9ec840..b2ae163 100644 --- a/src/help_func.c +++ b/src/help_func.c @@ -9,6 +9,14 @@ void free_tab(char **tab) void quit(t_FDF *FDF) { - mlx_destroy_window(FDF->mw->mlx, FDF->mw->win); + if (FDF && FDF->mw->mlx && FDF->mw->win) + mlx_destroy_window(FDF->mw->mlx, FDF->mw->win); exit(0); +} + +void swap_init(t_swap *s) +{ + s->swap_coord = 0; + s->swap_x = 1; + s->swap_z = 0; } \ No newline at end of file diff --git a/src/hooks.c b/src/hooks.c new file mode 100644 index 0000000..59e0972 --- /dev/null +++ b/src/hooks.c @@ -0,0 +1,15 @@ +#include "fdf.h" + +int key_hook(int keycode, void *m) +{ + printf("%d\n", keycode); + if (keycode == 53 || keycode == 65307) + quit(m); +// if (keycode == 123) +// left(mlx); +// if (keycode == 126) +// up(mlx); +// if (keycode == 125) +// down(mlx); + return (0); +} \ No newline at end of file diff --git a/src/image_routine.c b/src/image_routine.c new file mode 100644 index 0000000..a8dabf6 --- /dev/null +++ b/src/image_routine.c @@ -0,0 +1,26 @@ +#include "fdf.h" + +void put_pixel_to_image(t_line *line, t_swap *s, t_FDF *FDF) +{ + int x; + int y; + + x = line->p1.x; + y = line->p1.y; + if (s->swap_coord) + { + y = line->p1.x; + x = line->p1.y; + } + if (x < 0) + x = 0; + if (x > FDF->w_width) + x = FDF->w_width; + if (y < 0) + y = 0; + if (y > FDF->w_height) + y = FDF->w_height; + *((int *)FDF->image_data + x + y * FDF->w_width) = color_to_int( + choose_color(line, s, FDF)); +} + diff --git a/src/line.c b/src/line.c index 007cd07..c9109da 100644 --- a/src/line.c +++ b/src/line.c @@ -1,6 +1,15 @@ #include "fdf.h" +static void swap_z(t_pnt *p1, t_pnt *p2) +{ + float tmp; + + tmp = p1->z; + p1->z = p2->z; + p2->z = tmp; +} + static void swap_x_y(t_pnt *p1, t_pnt *p2) { int temp; @@ -23,37 +32,41 @@ static void swap_points(t_pnt *p1, t_pnt *p2) } -static void draw_line(t_pnt *p1, t_pnt *p2, t_mw *mw, t_swap *s) +static void draw_line(t_line *line, t_swap *s, t_FDF *FDF) { - int dx = abs(p2->x - p1->x); - int dy = abs(p2->y - p1->y); - int derr = 2 * dy - dx; - while (p1->x < p2->x) + int dx; + int dy; + int derr; + float dz; + + dx = abs(line->p2.x - line->p1.x); + dy = abs(line->p2.y - line->p1.y); + dz = fabs(line->p2.z - line->p1.z); + derr = 2 * dy - dx; + while (line->p1.x < line->p2.x) { - if (s->swap_coord) - mlx_pixel_put(mw->mlx, mw->win, p1->y, p1->x, 0xFFFFFF); - else - mlx_pixel_put(mw->mlx, mw->win, p1->x, p1->y, 0xFFFFFF); + put_pixel_to_image(line, s, FDF); if (derr > 0) { - p1->y += s->swap_x; + line->p1.y += s->swap_x; derr -= dx; } - (p1->x)++; + (line->p1.x)++; + (line->p1.z) += dz / dx; derr += dy; } } -void line(t_pnt p1, t_pnt p2, t_mw *mw) +void line(t_pnt p1, t_pnt p2, t_FDF *FDF) { - int dx; - int dy; - t_swap swap; + int dx; + int dy; + t_swap swap; + t_line line; dx = abs(p2.x - p1.x); dy = abs(p2.y - p1.y); - swap.swap_coord = 0; - swap.swap_x = 1; + swap_init(&swap); if (dy > dx) { swap_x_y(&p1, &p2); @@ -63,6 +76,13 @@ void line(t_pnt p1, t_pnt p2, t_mw *mw) swap_points(&p1, &p2); if (p1.y > p2.y) swap.swap_x = -1; - draw_line(&p1, &p2, mw, &swap); + if (p1.z > p2.z) + { + swap_z(&p1, &p2); + swap.swap_z = 1; + } + line.p1 = p1; + line.p2 = p2; + draw_line(&line, &swap, FDF); } diff --git a/src/main.c b/src/main.c index 38a649c..f28067e 100644 --- a/src/main.c +++ b/src/main.c @@ -6,84 +6,157 @@ // MODIFIED: 2017-03-09 20:51:10 #include "fdf.h" -#include - -int key_hook(int keycode, void *m) +void circle(t_FDF *FDF) { - printf("%d\n", keycode); - if (keycode == 53 || keycode == 65307) - quit(m); -// if (keycode == 123) -// left(mlx); -// if (keycode == 126) -// up(mlx); -// if (keycode == 125) -// down(mlx); - return (0); + t_pnt p1; + t_pnt p2; + double angle; + + + for (int i = 0; i < 360; i += 1) + { + p1.x = 250; + p1.y = 250; + angle = i * M_PI / 180; + p2.x = p1.x + 250 * sin(angle); + p2.y = p1.y + 250 * cos(angle); + line(p1, p2, FDF); + } } -t_mw *mlx_and_win_ptr_init(int x, int y) +void test_line(t_FDF *FDF) { - t_mw *mw; + t_pnt p1; + t_pnt p2; - mw = NULL; - if ((mw = malloc(sizeof(t_mw)))) + p1.x = 0; + p1.y = 0; + p2.x = 500; + for (p2.y = 0; p2.y <= 500; p2.y += 4) { - mw->mlx = mlx_init(); - mw->win = mlx_new_window(mw->mlx, x, y, "FDF"); + line(p1, p2, FDF); + mlx_put_image_to_window(FDF->mw->mlx, FDF->mw->win, FDF->image, 0, 0); } - return (mw); -} - -t_FDF *FDF_init(char *path) -{ - t_FDF *FDF; - - FDF = NULL; - if ((FDF = malloc(sizeof(t_FDF)))) + for (p2.x = 500; p2.x >= 0; p2.x -= 4) { - FDF->w_heigth = HEIGHT; - FDF->w_width = WIDTH; - FDF->mw = mlx_and_win_ptr_init(WIDTH, HEIGHT); - FDF->map = map_init(path); - pnt_init(FDF->map); + line(p1, p2, FDF); + mlx_put_image_to_window(FDF->mw->mlx, FDF->mw->win, FDF->image, 0, 0); + } + p1.x = 500; + p1.y = 0; + p2.x = 0; + for (p2.y = 0; p2.y <= 500; p2.y += 4) + { + line(p1, p2, FDF); + mlx_put_image_to_window(FDF->mw->mlx, FDF->mw->win, FDF->image, 0, 0); + } + for (p2.x = 0; p2.x <= 500; p2.x += 4) + { + line(p1, p2, FDF); + mlx_put_image_to_window(FDF->mw->mlx, FDF->mw->win, FDF->image, 0, 0); + } + p1.x = 500; + p1.y = 500; + p2.x = 500; + p2.y = 0; + for (p2.x = 500; p2.x >= 0; p2.x -= 4) + { + line(p1, p2, FDF); + mlx_put_image_to_window(FDF->mw->mlx, FDF->mw->win, FDF->image, 0, 0); + } + for (p2.y = 0; p2.y <= 500; p2.y += 4) + { + line(p1, p2, FDF); + mlx_put_image_to_window(FDF->mw->mlx, FDF->mw->win, FDF->image, 0, 0); + } + p1.x = 0; + p1.y = 500; + p2.x = 500; + p2.y = 500; + for (p2.y = 500; p2.y >= 0; p2.y -= 4) + { + line(p1, p2, FDF); + mlx_put_image_to_window(FDF->mw->mlx, FDF->mw->win, FDF->image, 0, 0); + } + for (p2.x = 500; p2.x >= 0; p2.x -= 4) + { + line(p1, p2, FDF); + mlx_put_image_to_window(FDF->mw->mlx, FDF->mw->win, FDF->image, 0, 0); + } + mlx_clear_window(FDF->mw->mlx, FDF->mw->win); + p1.x = 0; + p1.y = 0; + p2.y = 500; + for (p2.x = 0; p2.x <= 500; p2.x += 1) + { + line(p1, p2, FDF); + mlx_put_image_to_window(FDF->mw->mlx, FDF->mw->win, FDF->image, 0, 0); + p1.x += 1; + } + mlx_clear_window(FDF->mw->mlx, FDF->mw->win); + p1.x = 0; + p1.y = 0; + p2.x = 500; + for (p2.y = 0; p2.y <= 500; p2.y += 1) + { + line(p1, p2, FDF); + mlx_put_image_to_window(FDF->mw->mlx, FDF->mw->win, FDF->image, 0, 0); + p1.y += 1; + } + mlx_clear_window(FDF->mw->mlx, FDF->mw->win); + p1.x = 500; + p1.y = 0; + p2.x = 500; + for (; p2.x >= 0; p2.x -= 1) + { + line(p1, p2, FDF); + mlx_put_image_to_window(FDF->mw->mlx, FDF->mw->win, FDF->image, 0, 0); + p1.x -= 1; + } + mlx_clear_window(FDF->mw->mlx, FDF->mw->win); + p1.x = 0; + p1.y = 500; + p2.x = 500; + for (p2.y = 500; p2.y >= 0; p2.y -= 1) + { + line(p1, p2, FDF); + mlx_put_image_to_window(FDF->mw->mlx, FDF->mw->win, FDF->image, 0, 0); + p1.y -= 1; } - return (FDF); } int main(int argc, char **argv) { t_FDF *FDF; - void *image; - char *data; - int i; - int bpp; - int endian; - int j; - int line; - +// int i; +// int j; +// int rgb; +// t_color c1; +// t_color c2; +// t_color c3; if (argc != 2) return (0); FDF = FDF_init(argv[1]); - i = 0; - bpp = 4; - endian = 1; - image = mlx_new_image(FDF->mw->mlx, FDF->w_heigth, FDF->w_heigth); - data = mlx_get_data_addr(image, &bpp, &line, &endian); - while (i < FDF->w_heigth) - { - j = 0; - while (j < FDF->w_width) - { - *((int *)data + j + i * FDF->w_width) = mlx_get_color_value(FDF->mw->mlx, 0x4286f4); - j++; - } - i++; - } - mlx_put_image_to_window(FDF->mw->mlx, FDF->mw->win, image, 0, 0); - //render(FDF); - mlx_key_hook(FDF->mw->win, key_hook, FDF); +// i = 0; +// c1 = color_init(225, 13, 14); +// c2 = color_init(20, 177, 4); +// c3 = c1; +// while (i < FDF->w_height) +// { +// j = 0; +// rgb = color_to_int(c3); +// while (j < FDF->w_width) +// { +// *((int *)FDF->image_data + j + i * FDF->w_width) = rgb; +// j++; +// } +// c3 = color_lerp(c1, c2, (float)i / FDF->w_height); +// i++; +// } +// mlx_put_image_to_window(FDF->mw->mlx, FDF->mw->win, FDF->image, 0, 0); + render(FDF); + mlx_key_hook(FDF->mw->win, key_hook, FDF); mlx_loop(FDF->mw->mlx); return (0); } diff --git a/src/map_init.c b/src/map_init.c index e45e765..e890752 100644 --- a/src/map_init.c +++ b/src/map_init.c @@ -77,7 +77,10 @@ t_map *map_init(char *path) t_map *map; map = malloc(sizeof(t_map)); - str_map = to_str_map(path); + if (!(str_map = to_str_map(path))) + { + quit(0); + } tab_map = ft_strsplit(str_map, '\n'); map->lst_map = to_lst_map(tab_map); map_dimensions(map); diff --git a/src/mat4.c b/src/mat4.c index 3012fcb..fe5111d 100644 --- a/src/mat4.c +++ b/src/mat4.c @@ -161,7 +161,7 @@ void vec_mat_mult(t_mat4 *m, t_vec *v, t_pnt *result) { // double vec4; double x; - double y; + double y; // double z; x = v->x * m->mx[0][0] + v->y * m->mx[1][0] + v->z * m->mx[2][0] + @@ -180,5 +180,5 @@ void vec_mat_mult(t_mat4 *m, t_vec *v, t_pnt *result) // } result->x = x; result->y = y; -// result->z = z; +// result->z = v->z; } \ No newline at end of file diff --git a/src/pnt_init.c b/src/pnt_init.c index 8edc3b3..2fcc35f 100644 --- a/src/pnt_init.c +++ b/src/pnt_init.c @@ -3,13 +3,23 @@ void pnt_init(t_map *map) { t_pnt **arr_pnt; + t_list *lst_map; int i; + int j; + lst_map = map->lst_map; arr_pnt = malloc(sizeof(t_pnt *) * (map->y_max + 1)); i = 0; while (i <= map->y_max) { + j = 0; arr_pnt[i] = malloc(sizeof(t_pnt) * (map->x_max + 1)); + while (j <= map->x_max) + { + arr_pnt[i][j].z = ((t_vec *)(lst_map->content))->z; + lst_map = lst_map->next; + j++; + } i++; } map->arr_pnt = arr_pnt; diff --git a/src/render.c b/src/render.c index 23b305e..4d373ff 100644 --- a/src/render.c +++ b/src/render.c @@ -89,11 +89,13 @@ t_mat4 *orth_mat_init(int l, int r, int b, int t, int n, int f) return (orth); } -void draw(t_map *map, t_mw *mw) +void draw(t_FDF *FDF) { int i; int j; + t_map *map; + map = FDF->map; i = 0; while (i <= map->y_max) { @@ -101,33 +103,38 @@ void draw(t_map *map, t_mw *mw) while (j <= map->x_max) { if (i == map->y_max && j < map->x_max) - line(map->arr_pnt[i][j], map->arr_pnt[i][j + 1], mw); + line(map->arr_pnt[i][j], map->arr_pnt[i][j + 1], FDF); else if (i < map->y_max && j == map->x_max) - line(map->arr_pnt[i][j], map->arr_pnt[i + 1][j], mw); + line(map->arr_pnt[i][j], map->arr_pnt[i + 1][j], FDF); else if (i < map->y_max && j < map->x_max) { - line(map->arr_pnt[i][j], map->arr_pnt[i + 1][j], mw); - line(map->arr_pnt[i][j], map->arr_pnt[i][j + 1], mw); + line(map->arr_pnt[i][j], map->arr_pnt[i + 1][j], FDF); + line(map->arr_pnt[i][j], map->arr_pnt[i][j + 1], FDF); } j++; } i++; } + mlx_put_image_to_window(FDF->mw->mlx, FDF->mw->win, FDF->image, 0, 0); } void center(t_map *map) { t_list *l; - double d_width; - double d_height; + double d_x; + double d_y; + double d_z; - d_width = map->x_max / 2.0f; - d_height = map->y_max / 2.0f; + + d_x = map->x_max / 2.0f; + d_y = map->y_max / 2.0f; + d_z = map->z_max / 2.0f; l = map->lst_map; while (l) { - ((t_vec *)(l->content))->x = ((t_vec *)(l->content))->x - d_width; - ((t_vec *)(l->content))->y = ((t_vec *)(l->content))->y - d_height; + ((t_vec *)(l->content))->x = ((t_vec *)(l->content))->x - d_x; + ((t_vec *)(l->content))->y = ((t_vec *)(l->content))->y - d_y; + ((t_vec *)(l->content))->z = ((t_vec *)(l->content))->z - d_z; l = l->next; } } @@ -148,7 +155,8 @@ void render(t_FDF *FDF) rot_z = mat4_init(); translate = mat4_init(); scale = mat4_init(); - vp = viewport_mat_init(FDF->w_width, FDF->w_heigth); + final = mat4_init(); + vp = viewport_mat_init(FDF->w_width, FDF->w_height); orth = orth_mat_init( 0, FDF->map->x_max + 2, @@ -156,23 +164,24 @@ void render(t_FDF *FDF) FDF->map->x_max + 2, 0, FDF->map->z_max + 2); - mat4_x_rot(rot_x, 45); - mat4_z_rot(rot_z, 45); - mat4_y_rot(rot_y, 45); - mat4_scale(scale, 1, 1, 1); + mat4_x_rot(rot_x, 30); + mat4_z_rot(rot_z, -45); + mat4_y_rot(rot_y, -20); + mat4_scale(scale, 0.9, 0.9, 0.1); mat4_translate( translate, (((double)FDF->map->x_max) / 2.0f), (((double)FDF->map->x_max) / 2.0f), (((double)FDF->map->z_max) / 2.0f)); final = mat4_mult(vp, orth); + final = mat4_mult(translate, final); + final = mat4_mult(rot_z ,final); final = mat4_mult(rot_x, final); final = mat4_mult(rot_y ,final); - final = mat4_mult(translate, final); -// final = mat4_mult(scale, final); + final = mat4_mult(scale, final); center(FDF->map); transform(final, FDF->map); - draw(FDF->map, FDF->mw); + draw(FDF); }