Browse Source

add: render view and player motion

master
narnaud 3 years ago
parent
commit
b733d9c6b9
  1. 21
      Makefile
  2. 68
      README.md
  3. 13
      includes/cub3d.h
  4. 4
      maps/scene.cub
  5. 84
      sources/main.c
  6. 5
      sources/parsing.c
  7. 181
      sources/render.c
  8. 9
      sources/utils.c

21
Makefile

@ -1,20 +1,21 @@
NAME = cub3d NAME = cub3d
LIBFT = libft.a LIBFT = libft.a
SRCS = sources/main.c sources/parsing.c sources/getline.c sources/utils.c SRCS = sources/main.c sources/parsing.c sources/getline.c sources/utils.c
OBJS = ${SRCS:.c=.o} SRCS += sources/render.c
OBJS = ${SRCS:.c=.o}
CC = gcc CC = gcc
RM = rm -rf RM = rm -rf
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Linux) 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 endif
ifeq ($(UNAME_S), Darwin) ifeq ($(UNAME_S), Darwin)
LFLAGS = -lmlx -framework OpenGL -framework AppKit -L. -lft LFLAGS = -lmlx -framework OpenGL -framework AppKit -L. -lft
endif endif
CFLAGS = -Werror -Wall -Wextra -O3 -ffast-math -funsafe-math-optimizations CFLAGS = -Werror -Wall -Wextra -O3 -ffast-math -funsafe-math-optimizations
%.o:%.c %.o:%.c
${CC} ${CFLAGS} -c $< -o ${<:.c=.o} ${CC} ${CFLAGS} -c $< -o ${<:.c=.o}

68
README.md

@ -10,44 +10,30 @@ CUBE3D
- [Tester & maps](https://github.com/MichelleJiam/cub3D_tester) - [Tester & maps](https://github.com/MichelleJiam/cub3D_tester)
## Program life cycle : ## Program life cycle :
- map parsing : ### Parsing
- [o] read file, - [x] read file,
- [o] extract walls textures, - [x] extract walls textures,
- [o] extract sky and ceil colors - [x] extract sky and ceil colors
- [o] import map into chained list, - [x] import map into chained list,
- [-] comvert list to 2D array. - [x] comvert list to 2D array.
- [ ] save player pos, - [x] save player pos,
- [ ] handle errors, - [ ] handle errors,
- initialize env - [-] not closed map
- generate window - [ ] texture files not exist, not permited or with wrong extension
- display view - [ ] impossible color used
- enable commands - [-] missing map
- react to commands : ### Init
- calculate new pos, ### Window
- display new view, ### Render
- clean and exit - [x] display ceil, walls and floor
- [ ] display wall's texture
## thoughts : ### Control
- [x] enable commands
## verify map validity : - [ ] wasd to move
The map must be closed with the player inside the walls. - [x] arrows to move
- calloc a 2D array as X size is the size of the longer - [ ] react to commands :
line and y is the numbers of map lines. - [x] calculate new pos,
- set the array cells to 1 for floor, 2 for walls - [x] display new view,
- outside cells will be zeros. - [-] avoid colisions
- read line by line until you encounter first wall then turn around ### Quit
the map following the walls and never going on an already visited - [ ] clean and exit
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

13
includes/cub3d.h

@ -6,7 +6,7 @@
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ /* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/05/21 19:24:12 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 wide;
int deep; int deep;
t_vec_d playerPos; t_vec_d playerPos;
t_vec_d playerDir; t_vec_d playerDir;
t_vec_d camPlan;
} t_env; } 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); 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); t_env *parse_envFile(char *filename);
char *get_next_line(int fd); char *get_next_line(int fd);

4
maps/scene.cub

@ -3,8 +3,8 @@ EA ./textures/colorstone.xpm
SO ./textures/wood.xpm SO ./textures/wood.xpm
WE ./textures/wood.xpm WE ./textures/wood.xpm
F 147, 159,153 F 18, 176, 12
C 219,213,213 C 27, 210, 227
11110000 11110000
100100000 100100000

84
sources/main.c

@ -6,7 +6,7 @@
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ /* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/05/21 19:22:50 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; 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) int key_hook_primary(int keycode, void *param)
{ {
t_env *env; t_env *env;
static t_vec_d new_pos;
env = (t_env *)param; 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) 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) else if (keycode == KEY_ARROW_DOWN)
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_LEFT) 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, set_vec(&env->playerDir,
cos(-M_PI / 2) * env->playerDir.x - sin(-M_PI / 2) * env->playerDir.y, cos(-M_PI / 9) * env->playerDir.x - sin(-M_PI / 9) * env->playerDir.y,
sin(-M_PI / 2) * env->playerDir.x + cos(-M_PI / 2) * 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) else if (keycode == KEY_ARROW_RIGHT)
{ {
set_vec(&env->playerDir, set_vec(&env->playerDir,
cos(M_PI / 2) * env->playerDir.x - sin(M_PI / 2) * env->playerDir.y, cos(M_PI / 9) * env->playerDir.x - sin(M_PI / 9) * env->playerDir.y,
sin(M_PI / 2) * env->playerDir.x + cos(M_PI / 2) * 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(env);
render_view(env);
mlx_put_image_to_window(env->mlx, env->win, env->img, 0, 0);
return (1); return (1);
} }
@ -129,6 +86,7 @@ int main(int argc, char **argv)
printf("%s\n", env->map[y++]); printf("%s\n", env->map[y++]);
} }
init_window(env); init_window(env);
render(env);
mlx_key_hook(env->win, key_hook_primary, env); mlx_key_hook(env->win, key_hook_primary, env);
mlx_loop(env->mlx); mlx_loop(env->mlx);
return (EXIT_SUCCESS); return (EXIT_SUCCESS);

5
sources/parsing.c

@ -6,7 +6,7 @@
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ /* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/05/23 17:20:29 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); set_vec(&env->playerDir, 1, 0);
else if (orientation == 'W') else if (orientation == 'W')
set_vec(&env->playerDir, -1, -1); 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); return (1);
} }

181
sources/render.c

@ -0,0 +1,181 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* render.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

9
sources/utils.c

@ -6,13 +6,18 @@
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ /* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/05/31 08:59:01 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" #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->x = x;
vec->y = y; vec->y = y;

Loading…
Cancel
Save