From b733d9c6b98ec8cea58a04b75d69ac55cf911a3f Mon Sep 17 00:00:00 2001 From: narnaud Date: Tue, 31 May 2022 15:22:56 +0200 Subject: [PATCH] add: render view and player motion --- Makefile | 21 +++--- README.md | 68 +++++++---------- includes/cub3d.h | 13 +++- maps/scene.cub | 4 +- sources/main.c | 84 ++++++--------------- sources/parsing.c | 5 +- sources/render.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++ sources/utils.c | 9 ++- 8 files changed, 263 insertions(+), 122 deletions(-) create mode 100644 sources/render.c diff --git a/Makefile b/Makefile index d74e266..ba23661 100644 --- a/Makefile +++ b/Makefile @@ -1,20 +1,21 @@ -NAME = cub3d -LIBFT = libft.a +NAME = cub3d +LIBFT = libft.a -SRCS = sources/main.c sources/parsing.c sources/getline.c sources/utils.c -OBJS = ${SRCS:.c=.o} +SRCS = sources/main.c sources/parsing.c sources/getline.c sources/utils.c +SRCS += sources/render.c +OBJS = ${SRCS:.c=.o} -CC = gcc -RM = rm -rf +CC = gcc +RM = rm -rf -UNAME_S := $(shell uname -s) +UNAME_S := $(shell uname -s) ifeq ($(UNAME_S), Linux) - LFLAGS = -L ./mlx -lmlx_Linux -lXext -lX11 -lm -lz -L. -lft + LFLAGS = -L ./mlx -lmlx_Linux -lXext -lX11 -lm -lz -L. -lft endif ifeq ($(UNAME_S), Darwin) - LFLAGS = -lmlx -framework OpenGL -framework AppKit -L. -lft + LFLAGS = -lmlx -framework OpenGL -framework AppKit -L. -lft endif -CFLAGS = -Werror -Wall -Wextra -O3 -ffast-math -funsafe-math-optimizations +CFLAGS = -Werror -Wall -Wextra -O3 -ffast-math -funsafe-math-optimizations %.o:%.c ${CC} ${CFLAGS} -c $< -o ${<:.c=.o} diff --git a/README.md b/README.md index 2387b8b..436c79b 100644 --- a/README.md +++ b/README.md @@ -10,44 +10,30 @@ CUBE3D - [Tester & maps](https://github.com/MichelleJiam/cub3D_tester) ## Program life cycle : -- map parsing : - - [o] read file, - - [o] extract walls textures, - - [o] extract sky and ceil colors - - [o] import map into chained list, - - [-] comvert list to 2D array. - - [ ] save player pos, - - [ ] handle errors, -- initialize env -- generate window -- display view -- enable commands -- react to commands : - - calculate new pos, - - display new view, -- clean and exit - -## thoughts : - -## verify map validity : -The map must be closed with the player inside the walls. -- calloc a 2D array as X size is the size of the longer - line and y is the numbers of map lines. -- set the array cells to 1 for floor, 2 for walls -- outside cells will be zeros. -- read line by line until you encounter first wall then turn around -the map following the walls and never going on an already visited -wall until you come back to starting pos. - - -## initialize env : -- required datas : initial player pov angle, -- walls height -- eyes positions from screen ( -> field of view) -- calculate fov rays unit vectors, - - -## display view : -- calculate distance between player and intersection between rays and walls -- calculate viewed height of walls for each verticle -- draw walls, floor and sky +### Parsing +- [x] read file, +- [x] extract walls textures, +- [x] extract sky and ceil colors +- [x] import map into chained list, +- [x] comvert list to 2D array. +- [x] save player pos, +- [ ] handle errors, + - [-] not closed map + - [ ] texture files not exist, not permited or with wrong extension + - [ ] impossible color used + - [-] missing map +### Init +### Window +### Render +- [x] display ceil, walls and floor +- [ ] display wall's texture +### Control +- [x] enable commands + - [ ] wasd to move + - [x] arrows to move +- [ ] react to commands : + - [x] calculate new pos, + - [x] display new view, + - [-] avoid colisions +### Quit +- [ ] clean and exit diff --git a/includes/cub3d.h b/includes/cub3d.h index 94e82de..55ec492 100644 --- a/includes/cub3d.h +++ b/includes/cub3d.h @@ -6,7 +6,7 @@ /* By: narnaud +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/05/21 19:24:12 by narnaud #+# #+# */ -/* Updated: 2022/05/31 09:01:49 by narnaud ### ########.fr */ +/* Updated: 2022/05/31 13:36:06 by narnaud ### ########.fr */ /* */ /* ************************************************************************** */ @@ -68,11 +68,18 @@ typedef struct s_env int wide; int deep; t_vec_d playerPos; - t_vec_d playerDir; + t_vec_d playerDir; + t_vec_d camPlan; } t_env; +void render_minimap(t_env *env); +void render_view(t_env *env); +void render(t_env *env); + int rgb_to_int(char **rgb); -void set_vec(t_vec_d *vec, int x, int y); +void set_vec(t_vec_d *vec, double x, double y); +double vec_len(t_vec_d vec); + t_env *parse_envFile(char *filename); char *get_next_line(int fd); diff --git a/maps/scene.cub b/maps/scene.cub index 9577a46..7206318 100755 --- a/maps/scene.cub +++ b/maps/scene.cub @@ -3,8 +3,8 @@ EA ./textures/colorstone.xpm SO ./textures/wood.xpm WE ./textures/wood.xpm -F 147, 159,153 -C 219,213,213 +F 18, 176, 12 +C 27, 210, 227 11110000 100100000 diff --git a/sources/main.c b/sources/main.c index 7855bc1..7bf73e9 100644 --- a/sources/main.c +++ b/sources/main.c @@ -6,7 +6,7 @@ /* By: narnaud +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/05/21 19:22:50 by narnaud #+# #+# */ -/* Updated: 2022/05/31 09:13:28 by narnaud ### ########.fr */ +/* Updated: 2022/05/31 15:09:14 by narnaud ### ########.fr */ /* */ /* ************************************************************************** */ @@ -27,82 +27,39 @@ void init_window(t_env *env) env->win = window; } -void draw_square(t_env *env, t_vec vec, int size, int color) -{ - int step_x; - int step_y; - - step_y = 0; - while (step_y < size) - { - step_x = 0; - while (step_x < size) - { - env->buffer[(env->line_bytes * (vec.y * size + step_y)) + (vec.x * size + step_x)] = color; - step_x++; - } - step_y++; - } -} - -void render_minimap(t_env *env) -{ - char **map; - t_vec vec; - - vec.y = 0; - map = env->map; - while (map[vec.y]) - { - vec.x = 0; - while (map[vec.y][vec.x]) - { - if (map[vec.y][vec.x] == '0') - draw_square(env, vec, 6, 39424); - else if (map[vec.y][vec.x] == '1') - draw_square(env, vec, 6, 10420483); - vec.x++; - } - vec.y++; - } - vec.x = round(env->playerPos.x); - vec.y = round(env->playerPos.y); - draw_square(env, vec, 6, 255); -} - -void render_view(t_env *env) -{ - (void)env; -} - int key_hook_primary(int keycode, void *param) { t_env *env; + static t_vec_d new_pos; env = (t_env *)param; - env->img = mlx_new_image(env->mlx, WIN_X_SZ, WIN_Y_SZ); - env->buffer = (int *)mlx_get_data_addr(env->img, \ - &env->pixel_bits, &env->line_bytes, &env->endian); - env->line_bytes /= 4; if (keycode == KEY_ARROW_UP) - set_vec(&env->playerPos, env->playerPos.x + env->playerDir.x, env->playerPos.y + env->playerDir.y); + set_vec(&new_pos, env->playerPos.x + env->playerDir.x, env->playerPos.y + env->playerDir.y); else if (keycode == KEY_ARROW_DOWN) - set_vec(&env->playerPos, env->playerPos.x - env->playerDir.x, env->playerPos.y - env->playerDir.y); - else if (keycode == KEY_ARROW_LEFT) + set_vec(&new_pos, env->playerPos.x - env->playerDir.x, env->playerPos.y - env->playerDir.y); + if (env->map[(int)floor(new_pos.y)][(int)floor(new_pos.x)] == '0') + env->playerPos = new_pos; + else + new_pos = env->playerPos; + if (keycode == KEY_ARROW_LEFT) { set_vec(&env->playerDir, - cos(-M_PI / 2) * env->playerDir.x - sin(-M_PI / 2) * env->playerDir.y, - sin(-M_PI / 2) * env->playerDir.x + cos(-M_PI / 2) * env->playerDir.y); + cos(-M_PI / 9) * env->playerDir.x - sin(-M_PI / 9) * env->playerDir.y, + sin(-M_PI / 9) * env->playerDir.x + cos(-M_PI / 9) * env->playerDir.y); + set_vec(&env->camPlan, + cos(-M_PI / 9) * env->camPlan.x - sin(-M_PI / 9) * env->camPlan.y, + sin(-M_PI / 9) * env->camPlan.x + cos(-M_PI / 9) * env->camPlan.y); } else if (keycode == KEY_ARROW_RIGHT) { set_vec(&env->playerDir, - cos(M_PI / 2) * env->playerDir.x - sin(M_PI / 2) * env->playerDir.y, - sin(M_PI / 2) * env->playerDir.x + cos(M_PI / 2) * env->playerDir.y); + cos(M_PI / 9) * env->playerDir.x - sin(M_PI / 9) * env->playerDir.y, + sin(M_PI / 9) * env->playerDir.x + cos(M_PI / 9) * env->playerDir.y); + set_vec(&env->camPlan, + cos(M_PI / 9) * env->camPlan.x - sin(M_PI / 9) * env->camPlan.y, + sin(M_PI / 9) * env->camPlan.x + cos(M_PI / 9) * env->camPlan.y); } - render_minimap(env); - render_view(env); - mlx_put_image_to_window(env->mlx, env->win, env->img, 0, 0); + render(env); return (1); } @@ -129,6 +86,7 @@ int main(int argc, char **argv) printf("%s\n", env->map[y++]); } init_window(env); + render(env); mlx_key_hook(env->win, key_hook_primary, env); mlx_loop(env->mlx); return (EXIT_SUCCESS); diff --git a/sources/parsing.c b/sources/parsing.c index b188a8a..42545d0 100644 --- a/sources/parsing.c +++ b/sources/parsing.c @@ -6,7 +6,7 @@ /* By: narnaud +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/05/23 17:20:29 by narnaud #+# #+# */ -/* Updated: 2022/05/31 09:00:17 by narnaud ### ########.fr */ +/* Updated: 2022/05/31 12:25:58 by narnaud ### ########.fr */ /* */ /* ************************************************************************** */ @@ -123,6 +123,9 @@ int init_player(t_env *env, int x, int y) set_vec(&env->playerDir, 1, 0); else if (orientation == 'W') set_vec(&env->playerDir, -1, -1); + set_vec(&env->camPlan, + 2 * (cos(M_PI / 2) * env->playerDir.x - sin(M_PI / 2) * env->playerDir.y) / 3, + 2 * (sin(M_PI / 2) * env->playerDir.x + cos(M_PI / 2) * env->playerDir.y) / 3); return (1); } diff --git a/sources/render.c b/sources/render.c new file mode 100644 index 0000000..601454f --- /dev/null +++ b/sources/render.c @@ -0,0 +1,181 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* render.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: narnaud +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2022/05/31 09:33:02 by narnaud #+# #+# */ +/* Updated: 2022/05/31 13:46:43 by narnaud ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../includes/cub3d.h" + +void draw_vert(t_env *env, int x, int *startEnd, int color) +{ + int y; + + y= 0; + while (y < startEnd[0]) + { + env->buffer[env->line_bytes * y + x] = env->ceilColor; + y++; + } + while (startEnd[0] < startEnd[1]) + { + env->buffer[env->line_bytes * startEnd[0] + x] = color; + startEnd[0]++; + } + y = startEnd[0]; + while (y < WIN_Y_SZ) + { + env->buffer[env->line_bytes * y + x] = env->floorColor; + y++; + } +} + +void draw_square(t_env *env, t_vec vec, int size, int color) +{ + int step_x; + int step_y; + + step_y = 0; + while (step_y < size) + { + step_x = 0; + while (step_x < size) + { + env->buffer[(env->line_bytes * (vec.y * size + step_y)) + (vec.x * size + step_x)] = color; + step_x++; + } + step_y++; + } +} + +void render_minimap(t_env *env) +{ + char **map; + t_vec vec; + + vec.y = 0; + map = env->map; + while (map[vec.y]) + { + vec.x = 0; + while (map[vec.y][vec.x]) + { + if (map[vec.y][vec.x] == '0') + draw_square(env, vec, 6, 39424); + else if (map[vec.y][vec.x] == '1') + draw_square(env, vec, 6, 11885067); + vec.x++; + } + vec.y++; + } + vec.x = round(env->playerPos.x); + vec.y = round(env->playerPos.y); + draw_square(env, vec, 6, 255); +} + +double get_wall_dist(t_env *env, int x) +{ + double camX; + t_vec_d ray; + t_vec_d dDist; + t_vec_d sDist; + t_vec cell; + t_vec step; + int hit; + int side; + + camX = 2 * x / (double)WIN_X_SZ - 1; + set_vec(&ray, env->playerDir.x + env->camPlan.x * camX, env->playerDir.y + env->camPlan.y * camX); + cell.x = round(env->playerPos.x); + cell.y = round(env->playerPos.y); + if (ray.x == 0) + dDist.x = 1e30; + else + dDist.x = fabs(1 / ray.x); + if (ray.y == 0) + dDist.y = 1e30; + else + dDist.y = fabs(1 / ray.y); + hit = 0; + if (ray.x < 0) + { + step.x = -1; + sDist.x = (env->playerPos.x - cell.x) * dDist.x; + } + else + { + step.x = 1; + sDist.x = (cell.x + 1.0 - env->playerPos.x) * dDist.x; + } + if (ray.y < 0) + { + step.y = -1; + sDist.y = (env->playerPos.y - cell.y) * dDist.y; + } + else + { + step.y = 1; + sDist.y = (cell.y + 1.0 - env->playerPos.y) * dDist.y; + } + while (hit == 0) + { + if (sDist.x < sDist.y) + { + sDist.x += dDist.x; + cell.x += step.x; + side = 0; + } + else + { + sDist.y += dDist.y; + cell.y += step.y; + side = 1; + } + if (env->map[cell.y][cell.x] > '0') + hit = 1; + } + if (side == 0) + return (sDist.x - dDist.x); + else + return (sDist.y - dDist.y); +} + +void render_view(t_env *env) +{ + int x; + double perpWallDist; + int startEnd[2]; + int lineHeight; + + x = 0; + while (x < WIN_X_SZ) + { + perpWallDist = get_wall_dist(env, x); + lineHeight = (int)(WIN_Y_SZ / perpWallDist); + startEnd[0] = -lineHeight / 2 + WIN_Y_SZ / 2; + if (startEnd[0] < 0) + startEnd[0] = 0; + startEnd[1] = lineHeight / 2 + WIN_Y_SZ / 2; + if(startEnd[1] >= WIN_Y_SZ) + startEnd[1] = WIN_Y_SZ - 1; + draw_vert(env, x, startEnd, 11885067); + x++; + } +} + +void render(t_env *env) +{ + env->img = mlx_new_image(env->mlx, WIN_X_SZ, WIN_Y_SZ); + env->buffer = (int *)mlx_get_data_addr(env->img, \ + &env->pixel_bits, &env->line_bytes, &env->endian); + env->line_bytes /= 4; + render_view(env); + render_minimap(env); + mlx_put_image_to_window(env->mlx, env->win, env->img, 0, 0); + mlx_destroy_image(env->mlx, env->img); +} diff --git a/sources/utils.c b/sources/utils.c index 582cef9..db24837 100644 --- a/sources/utils.c +++ b/sources/utils.c @@ -6,13 +6,18 @@ /* By: narnaud +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/05/31 08:59:01 by narnaud #+# #+# */ -/* Updated: 2022/05/31 09:00:10 by narnaud ### ########.fr */ +/* Updated: 2022/05/31 12:22:41 by narnaud ### ########.fr */ /* */ /* ************************************************************************** */ #include "../includes/cub3d.h" -void set_vec(t_vec_d *vec, int x, int y) +double vec_len(t_vec_d vec) +{ + return (sqrt(vec.x * vec.x + vec.y * vec.y)); +} + +void set_vec(t_vec_d *vec, double x, double y) { vec->x = x; vec->y = y;