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

68
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

13
includes/cub3d.h

@ -6,7 +6,7 @@
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);

4
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

84
sources/main.c

@ -6,7 +6,7 @@
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);

5
sources/parsing.c

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

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> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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;

Loading…
Cancel
Save