diff options
| -rw-r--r-- | Makefile | 3 | ||||
| -rw-r--r-- | include/cub3d.h | 30 | ||||
| m--------- | libft | 0 | ||||
| -rw-r--r-- | minimalist.cub | 12 | ||||
| -rw-r--r-- | src/error.c | 2 | ||||
| -rw-r--r-- | src/helper.c | 12 | ||||
| -rw-r--r-- | src/parse/parse.c | 6 | ||||
| -rw-r--r-- | src/parse/parse_check.c | 36 | ||||
| -rw-r--r-- | src/parse/parse_color.c | 2 | ||||
| -rw-r--r-- | src/render.c | 56 | ||||
| -rw-r--r-- | src/render_sprite.c | 121 | ||||
| -rw-r--r-- | src/render_state.c | 85 | ||||
| -rw-r--r-- | src/sprite_sort.c | 51 | ||||
| -rw-r--r-- | src/state.c | 29 | ||||
| -rw-r--r-- | src/texture.c | 26 | ||||
| -rw-r--r-- | src/vector.c | 17 |
16 files changed, 260 insertions, 228 deletions
@@ -28,7 +28,8 @@ SRCFILES = main.c \ error.c \ capture.c \ texture.c \ - render_sprite.c + render_sprite.c \ + sprite_sort.c SRC = $(addprefix $(SRCDIR)/,$(SRCFILES)) $(info $(SRC)) OBJ = $(SRC:$(SRCDIR)/%.c=$(OBJDIR)/%.o) diff --git a/include/cub3d.h b/include/cub3d.h index 9c4a79f..30b3b74 100644 --- a/include/cub3d.h +++ b/include/cub3d.h @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/11/15 06:40:37 by cacharle #+# #+# */ -/* Updated: 2020/02/04 00:26:19 by cacharle ### ########.fr */ +/* Updated: 2020/02/04 02:54:03 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ #include <stdio.h> @@ -145,6 +145,20 @@ typedef struct s_render_state t_cell target; } t_render_state; +typedef struct +{ + t_vector sprite; + double inverse_det; + t_vector transform; + int sprite_window_x; + int draw_start_x; + int draw_end_x; + int sprite_height; + int sprite_width; + int draw_end_y; + int draw_start; +} t_sprite_state; + typedef t_bool (*t_option_parser_func)(t_state *state, char *line); typedef struct s_option_parser @@ -217,19 +231,16 @@ int render_update(void *param); void render_update_window(t_state *state); void render_column(t_state *state, int x); void render_window_column(t_state *state, t_render_state *rstate); -void render_texture(t_state *state, t_render_state *rstate, int *i); /* ** vector.c */ t_vector vector_add(t_vector a, t_vector b); -t_vector vector_sub(t_vector a, t_vector b); t_vector vector_scale(t_vector v, double scalar); t_vector vector_rotate(t_vector v, double angle); double vector_norm(t_vector v); t_vector vector_new(double x, double y); -t_vector vector_apply(t_vector v, double (*f)(double)); /* ** error.c @@ -256,9 +267,8 @@ t_bool state_init_sprites(t_state *state); ** render_state.c */ -void rstate_ray(t_state *state, t_render_state *rstate); -void rstate_delta(t_render_state *rstate); -void rstate_init_probe(t_state *state, t_render_state *rstate); +void rstate_init(t_state *state, t_render_state *rstate, int x); +void rstate_post(t_state *state, t_render_state *rstate); void rstate_perp_dist(t_state *state, t_render_state *rstate); void rstate_line_height(t_state *state, t_render_state *rstate); void rstate_next_probe(t_render_state *rstate); @@ -267,6 +277,7 @@ void rstate_next_probe(t_render_state *rstate); ** texture.c */ +void texture_render(t_state *state, t_render_state *rstate, int *i); t_image *texture_select(t_state *state, t_render_state *rstate); int texture_x(t_state *state, t_render_state *rstate, t_image *texture); @@ -287,5 +298,10 @@ void bmp_fill_header(t_image *image, t_byte file_header[FILE_HEADER_SIZE], void render_update_sprite(t_state *state); +/* +** sprite_sort.c +*/ + +void sprite_sort(t_state *state); #endif diff --git a/libft b/libft -Subproject f4e1232957b1270da70f57fcad4cd6371947e44 +Subproject 435fec311c0c5173ae99c32b8f4e6431bd1e43d diff --git a/minimalist.cub b/minimalist.cub index 5a691b0..a5470f0 100644 --- a/minimalist.cub +++ b/minimalist.cub @@ -1,8 +1,8 @@ R 1201 900 -NO ./textures/cacharle_filled.xpm -SO ./textures/cacharle_filled.xpm -WE ./textures/cacharle_filled.xpm -EA ./textures/cacharle_filled.xpm +NO ./textures/greystone.xpm +SO ./textures/greystone.xpm +WE ./textures/greystone.xpm +EA ./textures/greystone.xpm S ./textures/cacharle.xpm F 10,10,10 C 40,40,40 @@ -17,7 +17,7 @@ C 40,40,40 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 0 1 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 1 1 0 1 0 1 0 1 1 1 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 0 1 0 0 0 1 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 0 1 0 N 0 1 1 1 0 0 0 0 0 0 1 1 0 1 0 1 0 1 1 1 1 1 0 1 1 1 1 0 0 0 1 -1 1 1 1 0 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 0 1 1 1 1 0 N 0 1 +1 1 1 1 0 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 0 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 diff --git a/src/error.c b/src/error.c index eb94c9f..03352e1 100644 --- a/src/error.c +++ b/src/error.c @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/01/11 13:33:14 by cacharle #+# #+# */ -/* Updated: 2020/01/11 13:34:18 by cacharle ### ########.fr */ +/* Updated: 2020/02/04 02:17:53 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/helper.c b/src/helper.c index 957a5de..ca0f879 100644 --- a/src/helper.c +++ b/src/helper.c @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/01/11 07:32:20 by cacharle #+# #+# */ -/* Updated: 2020/02/02 22:16:14 by cacharle ### ########.fr */ +/* Updated: 2020/02/04 02:17:38 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -57,7 +57,6 @@ void helper_init_dir_plane(t_state *state, int y, int x) state->plane = vector_rotate(state->dir, M_PI_2); state->plane = vector_scale(state->plane, 1.0 / vector_norm(state->plane)); state->plane = vector_scale(state->plane, 0.66); - state->plane = vector_apply(state->plane, &fabs); } t_bool state_init_sprites(t_state *state) @@ -76,16 +75,15 @@ t_bool state_init_sprites(t_state *state) counter++; } state->sprites_num = counter; - if ((state->sprites = (t_sprite*)malloc(sizeof(t_sprite) * counter)) == NULL) + if ((state->sprites = malloc(sizeof(t_sprite) * counter)) == NULL) return (FALSE); - counter = 0; - i = -1; - while (++i < state->map_height) + while (i-- > 0) { j = -1; while (++j < state->map_width) if (state->map[i][j] == CELL_ITEM) - state->sprites[counter++].pos = vector_new((double)j + 0.5, (double)i + 0.5); + state->sprites[--counter].pos = + vector_new((double)j + 0.5, (double)i + 0.5); } return (TRUE); } diff --git a/src/parse/parse.c b/src/parse/parse.c index 581056a..63ffb71 100644 --- a/src/parse/parse.c +++ b/src/parse/parse.c @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/11/15 09:29:21 by cacharle #+# #+# */ -/* Updated: 2020/02/01 11:35:32 by cacharle ### ########.fr */ +/* Updated: 2020/02/04 02:28:12 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -32,8 +32,10 @@ t_state *parse(char *filename) "parse configuration", state, lines)); } if ((state = parse_map(state, lines + i)) == NULL) + { return (error_put_return_lines_state_destroy("parse map", state, lines)); + } helper_free_splited(lines); return (state); } @@ -81,10 +83,12 @@ t_bool parse_line(t_state *state, char *line) return (TRUE); i = -1; while (++i < (int)(sizeof(g_option_parsers) / sizeof(t_option_parser))) + { if (ft_strncmp(g_option_parsers[i].id, line, ft_strlen(g_option_parsers[i].id)) == 0) return (g_option_parsers[i].func( state, line + ft_strlen(g_option_parsers[i].id) + 1)); + } return (FALSE); } diff --git a/src/parse/parse_check.c b/src/parse/parse_check.c index 5fc2674..5a36179 100644 --- a/src/parse/parse_check.c +++ b/src/parse/parse_check.c @@ -6,40 +6,54 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/01/11 10:59:15 by cacharle #+# #+# */ -/* Updated: 2020/02/02 19:42:34 by cacharle ### ########.fr */ +/* Updated: 2020/02/04 02:26:18 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ #include "cub3d.h" -t_state *parse_check(t_state *state) +static t_bool check_player_count(t_state *state) { int i; int j; int player_count; + player_count = 0; + i = -1; + while (++i < state->map_height) + { + j = -1; + while (++j < state->map_width) + if (helper_is_player_cell(state->map[i][j])) + player_count++; + } + return (player_count == 1); +} + +t_state *parse_check(t_state *state) +{ + int i; + i = -1; while (++i < state->map_width) + { if (state->map[0][i] != CELL_WALL || state->map[state->map_height - 1][i] != CELL_WALL) return (error_put_return_state_destroy( "validate map without borders", state)); + } i = -1; while (++i < state->map_height) + { if (state->map[i][0] != CELL_WALL || state->map[i][state->map_width - 1] != CELL_WALL) return (error_put_return_state_destroy( "validate map without borders", state)); - player_count = 0; - i = -1; - while (++i < state->map_height) + } + if (!check_player_count(state)) { - j = -1; - while (++j < state->map_width) - if (helper_is_player_cell(state->map[i][j])) - player_count++; + return (error_put_return_state_destroy( + "validate map with other than one player", state)); } - if (player_count != 1) - return (error_put_return_state_destroy("only one player allowed", state)); return (state); } diff --git a/src/parse/parse_color.c b/src/parse/parse_color.c index 3c025de..5385c0c 100644 --- a/src/parse/parse_color.c +++ b/src/parse/parse_color.c @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/01/11 09:52:34 by cacharle #+# #+# */ -/* Updated: 2020/02/01 11:32:33 by cacharle ### ########.fr */ +/* Updated: 2020/02/04 02:26:46 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/render.c b/src/render.c index 87379a0..de7e843 100644 --- a/src/render.c +++ b/src/render.c @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/01/11 13:37:17 by cacharle #+# #+# */ -/* Updated: 2020/02/02 23:30:17 by cacharle ### ########.fr */ +/* Updated: 2020/02/04 02:31:57 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,9 +25,8 @@ int render_update(void *param) } render_update_window(state); render_update_sprite(state); - mlx_put_image_to_window(state->mlx_ptr, state->window_ptr, state->window.id, 0, 0); - /* for (int i = 0; i < state->window.width * state->window.height; i++) */ - /* ((unsigned int*)state->window.data)[i] = 0xff000000; */ + mlx_put_image_to_window(state->mlx_ptr, state->window_ptr, + state->window.id, 0, 0); return (0); } @@ -44,65 +43,30 @@ void render_column(t_state *state, int x) { t_render_state rstate; - rstate.x = x; - rstate_ray(state, &rstate); - rstate.map_pos = vector_new((double)((int)state->pos.x), (double)((int)state->pos.y)); - rstate_delta(&rstate); - rstate_init_probe(state, &rstate); - rstate.map_step = vector_new(rstate.ray.x < 0.0 ? -1.0 : 1.0, rstate.ray.y < 0.0 ? -1.0 : 1.0); + rstate_init(state, &rstate, x); while (TRUE) { rstate.side = rstate.probe.x < rstate.probe.y ? SIDE_WE : SIDE_NS; rstate_next_probe(&rstate); - if (state->map[(int)rstate.map_pos.y][(int)rstate.map_pos.x] == CELL_WALL) + if (state->map[(int)rstate.map_pos.y][(int)rstate.map_pos.x] + == CELL_WALL) break ; } - rstate_perp_dist(state, &rstate); - state->z_buffer[x] = rstate.perp_dist; - /* printf("%f\n", state->z_buffer[x]); */ - rstate_line_height(state, &rstate); - rstate.draw_start = state->window.height / 2 - rstate.line_height / 2; - rstate.draw_end = state->window.height / 2 + rstate.line_height / 2; - if (rstate.draw_start < 0) - rstate.draw_start = 0; - if (rstate.draw_end > state->window.height - 1) - rstate.draw_end = state->window.height - 1; + rstate_post(state, &rstate); render_window_column(state, &rstate); } void render_window_column(t_state *state, t_render_state *rstate) { int i; - t_color white; - white.hexcode = 0x00ffffff; i = 0; while (i < rstate->draw_start) - ((t_color*)state->window.data)[i++ * state->window.width + rstate->x] = state->ceilling_color; + ((t_color*)state->window.data)[i++ * state->window.width + rstate->x] = + state->ceilling_color; i--; - render_texture(state, rstate, &i); + texture_render(state, rstate, &i); while (i < state->window.height) ((t_color*)state->window.data)[i++ * state->window.width + rstate->x] = state->floor_color; } - -void render_texture(t_state *state, t_render_state *rstate, int *i) -{ - int tex_x; - int tex_y; - double tex_step; - double tex_pos; - t_image *texture; - - texture = texture_select(state, rstate); - tex_x = texture_x(state, rstate, texture); - tex_step = (double)texture->height / (double)rstate->line_height; - tex_pos = (rstate->draw_start - state->window.height / 2 + rstate->line_height / 2) * tex_step; - while ((*i)++ < rstate->draw_end) - { - tex_y = (int)tex_pos & (texture->height - 1); - tex_pos += tex_step; - ((t_color*)state->window.data)[*i * state->window.width + rstate->x] = - ((t_color*)texture->data)[texture->height * tex_y + tex_x]; - } -} diff --git a/src/render_sprite.c b/src/render_sprite.c index 0570a71..379f67a 100644 --- a/src/render_sprite.c +++ b/src/render_sprite.c @@ -6,79 +6,82 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/02 17:39:07 by cacharle #+# #+# */ -/* Updated: 2020/02/02 23:52:29 by cacharle ### ########.fr */ +/* Updated: 2020/02/04 03:38:53 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ #include "cub3d.h" -int sprite_compar(const void *a, const void *b) +static void draw_stripe(t_state *state, t_sprite_state *sstate, int stripe) { - const t_sprite *sprite_a; - const t_sprite *sprite_b; + int tex_width; + int tex_height; + int tex_x; + int y; - sprite_a = a; - sprite_b = b; - if (sprite_a->dist > sprite_b->dist) - return -1; - if (sprite_a->dist < sprite_b->dist) - return 1; - return 0; + tex_width = state->textures[TEX_SPRITE].width; + tex_height = state->textures[TEX_SPRITE].height; + tex_x = (int)(256 * (stripe - (-sstate->sprite_width / 2 + sstate->sprite_window_x)) + * tex_width / sstate->sprite_width) / 256; + if (!(sstate->transform.y > 0 && stripe > 0 && stripe < state->window.width && sstate->transform.y < state->z_buffer[stripe])) + return ; + y = sstate->draw_start - 1; + while (++y < sstate->draw_end_y) + { + int d = y * 256 - state->window.height * 128 + sstate->sprite_height * 128; + int tex_y = ((d * tex_height) / sstate->sprite_height) / 256; + t_color color = ((t_color*)state->textures[TEX_SPRITE].data)[tex_width * tex_y + tex_x]; + if ((color.hexcode & 0x00FFFFFF) != 0) + ((t_color*)state->window.data)[y * state->window.width + stripe] = color; + } } -void sprites_dist(t_state *state) +static void sprite_boundary(t_state *state, t_sprite_state *sstate) { - int i; - - i = -1; - while (++i < state->sprites_num) - state->sprites[i].dist = vector_norm(vector_sub(state->sprites[i].pos, state->pos)); + sstate->sprite_height = ft_abs((int)(state->window.height + / (sstate->transform.y))); + sstate->draw_start = -sstate->sprite_height / 2 + state->window.height / 2; + if(sstate->draw_start < 0) + sstate->draw_start = 0; + sstate->draw_end_y = sstate->sprite_height / 2 + state->window.height / 2; + if(sstate->draw_end_y >= state->window.height) + sstate->draw_end_y = state->window.height - 1; + sstate->sprite_width = ft_abs( (int) (state->window.height + / (sstate->transform.y))); + sstate->draw_start_x = -sstate->sprite_width / 2 + sstate->sprite_window_x; + if (sstate->draw_start_x < 0) + sstate->draw_start_x = 0; + sstate->draw_end_x = sstate->sprite_width / 2 + sstate->sprite_window_x; + if (sstate->draw_end_x >= state->window.width) + sstate->draw_end_x = state->window.width - 1; } -void render_update_sprite(t_state *state) +static void render_sprite(t_state *state, int i) { - sprites_dist(state); - ft_qsort(state->sprites, state->sprites_num, sizeof(t_sprite), sprite_compar); - for(int i = 0; i < state->sprites_num; i++) - { - double sprite_x = state->sprites[i].pos.x - state->pos.x; - double sprite_y = state->sprites[i].pos.y - state->pos.y; + int stripe; + t_sprite_state sstate; - double inverse_det = 1.0 / (state->plane.x * state->dir.y - state->dir.x * state->plane.y); - double transform_x = inverse_det * (state->dir.y * sprite_x - state->dir.x * sprite_y); - double transform_y = inverse_det * (-state->plane.y * sprite_x + state->plane.x * sprite_y); - int sprite_window_x = (int)((state->window.width / 2) * (1 + transform_x / transform_y)); - - int sprite_height = abs((int)(state->window.height / (transform_y))); - int draw_start = -sprite_height / 2 + state->window.height / 2; - if(draw_start < 0) - draw_start = 0; - int draw_end_y = sprite_height / 2 + state->window.height / 2; - if(draw_end_y >= state->window.height) - draw_end_y = state->window.height - 1; + sstate.sprite.x = state->sprites[i].pos.x - state->pos.x; + sstate.sprite.y = state->sprites[i].pos.y - state->pos.y; + sstate.inverse_det = 1.0 / (state->plane.x + * state->dir.y - state->dir.x * state->plane.y); + sstate.transform.x = sstate.inverse_det + * (state->dir.y * sstate.sprite.x - state->dir.x * sstate.sprite.y); + sstate.transform.y = sstate.inverse_det * (-state->plane.y + * sstate.sprite.x + state->plane.x * sstate.sprite.y); + sstate.sprite_window_x = (int)((state->window.width / 2) + * (1 + sstate.transform.x / sstate.transform.y)); + sprite_boundary(state, &sstate); + stripe = sstate.draw_start_x - 1; + while (++stripe < sstate.draw_end_x) + draw_stripe(state, &sstate, stripe); +} - int sprite_width = abs( (int) (state->window.height / (transform_y))); - int draw_start_x = -sprite_width / 2 + sprite_window_x; - if (draw_start_x < 0) - draw_start_x = 0; - int draw_end_x = sprite_width / 2 + sprite_window_x; - if (draw_end_x >= state->window.width) - draw_end_x = state->window.width - 1; +void render_update_sprite(t_state *state) +{ + int i; - for(int stripe = draw_start_x; stripe < draw_end_x; stripe++) - { - int tex_width = state->textures[TEX_SPRITE].width; - int tex_height = state->textures[TEX_SPRITE].height; - int tex_x = (int)(256 * (stripe - (-sprite_width / 2 + sprite_window_x)) * tex_width / sprite_width) / 256; - if(transform_y > 0 && stripe > 0 && stripe < state->window.width && transform_y < state->z_buffer[stripe]) - for(int y = draw_start; y < draw_end_y; y++) - { - int d = y * 256 - state->window.height * 128 + sprite_height * 128; - int tex_y = ((d * tex_height) / sprite_height) / 256; - t_color color = ((t_color*)state->textures[TEX_SPRITE].data)[tex_width * tex_y + tex_x]; - if ((color.hexcode & 0x00FFFFFF) != 0) // if not empty pixel - ((t_color*)state->window.data)[y * state->window.width + stripe] = color; - } - } - } + i = -1; + while (++i < state->sprites_num) + render_sprite(state, i); } diff --git a/src/render_state.c b/src/render_state.c index 904e564..09f6f0c 100644 --- a/src/render_state.c +++ b/src/render_state.c @@ -6,13 +6,14 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/01/15 14:40:14 by cacharle #+# #+# */ -/* Updated: 2020/02/02 17:39:59 by cacharle ### ########.fr */ +/* Updated: 2020/02/04 02:09:43 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ #include "cub3d.h" /* +** ray: ** -1 0 1 <-- camera_x ** v v v ** ################ @@ -23,17 +24,8 @@ ** camera_x is the x column from the camera percpective ** scaling the plane vector and adding it to the direction vector ** to create a vector in the *direction* of the column x. -*/ - -void rstate_ray(t_state *state, t_render_state *rstate) -{ - double camera_x; - - camera_x = 2.0 * (double)rstate->x / (double)state->window.width - 1.0; - rstate->ray = vector_add(state->dir, vector_scale(state->plane, camera_x)); -} - -/* +** +** delta: ** delta between each grid unit form the vector percpective ** ** if we have a vector v = [2 3]: @@ -50,20 +42,14 @@ void rstate_ray(t_state *state, t_render_state *rstate) ** This can be simplified (for some obscure reason): ** dx = |1 / v_1| ** dy = |1 / v_2| -*/ - -void rstate_delta(t_render_state *rstate) -{ - rstate->delta.x = fabs(1 / rstate->ray.x); //vector_norm(rstate->ray) / rstate->ray.x; - rstate->delta.y = fabs(1 / rstate->ray.y); // vector_norm(rstate->ray) / rstate->ray.y; -} - -/* +** +** init probe: ** first delta between player position and first grid unit ** ** current x and y are the perpendicular distance to the nearest wall, ** we multiply them by their corresponding delta. -** 0 <= perpendicular distance <= 1 is a ratio, how much of the full delta we need to take. +** 0 <= perpendicular distance <= 1 is a ratio, +** how much of the full delta we need to take. ** ** if (rstate->ray.x < 0) ** rstate->probe.x = state->pos.x - rstate->map_pos.x; @@ -77,23 +63,29 @@ void rstate_delta(t_render_state *rstate) ** rstate->probe.y *= rstate->delta.y; */ -void rstate_init_probe(t_state *state, t_render_state *rstate) +void rstate_init(t_state *state, t_render_state *rstate, int x) { + double camera_x; + + rstate->x = x; + camera_x = 2.0 * (double)rstate->x / (double)state->window.width - 1.0; + rstate->ray = vector_add(state->dir, vector_scale(state->plane, camera_x)); + rstate->map_pos = vector_new((int)state->pos.x, (int)state->pos.y); + rstate->delta.x = fabs(1 / rstate->ray.x); + rstate->delta.y = fabs(1 / rstate->ray.y); if (rstate->ray.x < 0) rstate->probe.x = (state->pos.x - rstate->map_pos.x) * rstate->delta.x; else - rstate->probe.x = (rstate->map_pos.x + 1.0 - state->pos.x) * rstate->delta.x; + rstate->probe.x = (rstate->map_pos.x + 1.0 - state->pos.x) + * rstate->delta.x; if (rstate->ray.y < 0) - rstate->probe.y = (state->pos.y - rstate->map_pos.y) * rstate->delta.y; + rstate->probe.y = (state->pos.y - rstate->map_pos.y) + * rstate->delta.y; else - rstate->probe.y = (rstate->map_pos.y + 1.0 - state->pos.y) * rstate->delta.y; - /* rstate->probe = VECTOR_SUB(state->pos, rstate->map_pos); */ - /* if (rstate->ray.x > 0) */ - /* rstate->probe.x += 1.0; */ - /* if (rstate->ray.y > 0) */ - /* rstate->probe.y += 1.0; */ - /* rstate->probe.x *= rstate->delta.x; */ - /* rstate->probe.y *= rstate->delta.y; */ + rstate->probe.y = (rstate->map_pos.y + 1.0 - state->pos.y) + * rstate->delta.y; + rstate->map_step = vector_new(rstate->ray.x < 0.0 ? -1.0 : 1.0, + rstate->ray.y < 0.0 ? -1.0 : 1.0); } /* @@ -141,21 +133,26 @@ void rstate_next_probe(t_render_state *rstate) ** from a south/north percepective, ** if we had hit it form west/east, we would use the x component instead. */ - -void rstate_perp_dist(t_state *state, t_render_state *rstate) -{ - if (rstate->side == SIDE_WE) - rstate->perp_dist = (rstate->map_pos.x - state->pos.x + (1 - rstate->map_step.x) / 2) / rstate->ray.x; - else - rstate->perp_dist = (rstate->map_pos.y - state->pos.y + (1 - rstate->map_step.y) / 2) / rstate->ray.y; -} - /* ** 0 <= 1 / perp_dist <= 1 ** height * (1 / perp_dist) is how much of the screen height do we take */ -void rstate_line_height(t_state *state, t_render_state *rstate) +void rstate_post(t_state *state, t_render_state *rstate) { - rstate->line_height = (int)((double)state->window.height / rstate->perp_dist); + if (rstate->side == SIDE_WE) + rstate->perp_dist = (rstate->map_pos.x - state->pos.x + + (1 - rstate->map_step.x) / 2) / rstate->ray.x; + else + rstate->perp_dist = (rstate->map_pos.y - state->pos.y + + (1 - rstate->map_step.y) / 2) / rstate->ray.y; + rstate->line_height = (int)((double)state->window.height / + rstate->perp_dist); + rstate->draw_start = state->window.height / 2 - rstate->line_height / 2; + rstate->draw_end = state->window.height / 2 + rstate->line_height / 2; + if (rstate->draw_start < 0) + rstate->draw_start = 0; + if (rstate->draw_end > state->window.height - 1) + rstate->draw_end = state->window.height - 1; + state->z_buffer[rstate->x] = rstate->perp_dist; } diff --git a/src/sprite_sort.c b/src/sprite_sort.c new file mode 100644 index 0000000..4227743 --- /dev/null +++ b/src/sprite_sort.c @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sprite_sort.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/04 02:35:05 by cacharle #+# #+# */ +/* Updated: 2020/02/04 03:38:15 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "cub3d.h" + +static t_vector vector_sub(t_vector a, t_vector b) +{ + a.x -= b.x; + a.y -= b.y; + return (a); +} + +static int sprite_compar(const void *a, const void *b) +{ + const t_sprite *sprite_a; + const t_sprite *sprite_b; + + sprite_a = a; + sprite_b = b; + if (sprite_a->dist > sprite_b->dist) + return (-1); + if (sprite_a->dist < sprite_b->dist) + return (1); + return (0); +} + +static void sprites_dist(t_state *state) +{ + int i; + + i = -1; + while (++i < state->sprites_num) + state->sprites[i].dist = + vector_norm(vector_sub(state->sprites[i].pos, state->pos)); +} + +void sprite_sort(t_state *state) +{ + sprites_dist(state); + ft_qsort(state->sprites, state->sprites_num, + sizeof(t_sprite), sprite_compar); +} diff --git a/src/state.c b/src/state.c index 303ab60..414c2f1 100644 --- a/src/state.c +++ b/src/state.c @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/11/19 16:39:57 by cacharle #+# #+# */ -/* Updated: 2020/02/03 18:52:21 by cacharle ### ########.fr */ +/* Updated: 2020/02/04 03:37:21 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -28,38 +28,24 @@ t_state *state_new(t_state *state) if ((state->window_ptr = mlx_new_window(state->mlx_ptr, state->window.width, state->window.height, WINDOW_TITLE)) == NULL) return (state_destroy(state)); - printf("init mlx and mlx window\n"); - i = -1; while (++i < TEXTURES_NUM) { + puts(state->textures_path[i]); load_texture(state->mlx_ptr, &state->textures[i], state->textures_path[i]); if (state->textures[i].id == NULL) return (error_put_return_state_destroy("load texture", state)); } - if ((state->window.id = mlx_new_image(state->mlx_ptr, state->window.width, state->window.height)) == NULL) return (state_destroy(state)); state->window.data = mlx_get_data_addr(state->window.id, &state->window.depth, &state->window.size_line, &state->window.endian); - printf("init mlx window image\n"); - /* state->sprite_window.width = state->window.width; */ - /* state->sprite_window.height = state->window.height; */ - /* if ((state->sprite_window.id = mlx_new_image(state->mlx_ptr, */ - /* state->window.width, state->window.height)) == NULL) */ - /* return (state_destroy(state)); */ - /* state->sprite_window.data = mlx_get_data_addr(state->sprite_window.id, */ - /* &state->sprite_window.depth, &state->sprite_window.size_line, */ - /* &state->sprite_window.endian); */ - /* printf("init mlx sprite image\n"); */ state_init_player(state); - printf("init player\n"); - if ((state->z_buffer = (double*)malloc(sizeof(double) * state->window.width)) == NULL) + if ((state->z_buffer = malloc(sizeof(double) * state->window.width)) == NULL) return (error_put_return_state_destroy("create z buffer", state)); - printf("init z_buffer\n"); if (!state_init_sprites(state)) return (error_put_return_state_destroy("create sprites pos", state)); return (state); @@ -94,7 +80,6 @@ t_state *state_new_empty(void) state->mlx_ptr = NULL; state->window_ptr = NULL; state->window.id = NULL; - /* state->sprite_window.id = NULL; */ i = -1; while (++i < TEXTURES_NUM) { @@ -126,21 +111,15 @@ void *state_destroy(t_state *state) if (state->mlx_ptr != NULL && state->textures[i].id != NULL) mlx_destroy_image(state->mlx_ptr, state->textures[i].id); } - printf("free window image\n"); if (state->mlx_ptr != NULL && state->window.id != NULL) mlx_destroy_image(state->mlx_ptr, state->window.id); - /* printf("free sprite window image\n"); */ - /* if (state->mlx_ptr != NULL && state->sprite_window.id != NULL) */ - /* mlx_destroy_image(state->mlx_ptr, state->sprite_window.id); */ - printf("free window\n"); if (state->mlx_ptr && state->window_ptr) mlx_destroy_window(state->mlx_ptr, state->window_ptr); - printf("free map\n"); if (state->map != NULL) while (state->map_height-- > 0 && state->map[state->map_height] != NULL) free(state->map[state->map_height]); free(state->map); - printf("free state\n"); + printf("===free state\n"); free(state); return (NULL); } diff --git a/src/texture.c b/src/texture.c index 5be0ca1..a5bf611 100644 --- a/src/texture.c +++ b/src/texture.c @@ -6,16 +6,36 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/01 11:38:43 by cacharle #+# #+# */ -/* Updated: 2020/02/02 18:09:00 by cacharle ### ########.fr */ +/* Updated: 2020/02/04 03:34:54 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ #include "cub3d.h" +void texture_render(t_state *state, t_render_state *rstate, int *i) +{ + int tex_x; + int tex_y; + double tex_step; + double tex_pos; + t_image *texture; + + texture = texture_select(state, rstate); + tex_x = texture_x(state, rstate, texture); + tex_step = (double)texture->height / (double)rstate->line_height; + tex_pos = (rstate->draw_start - state->window.height / 2 + + rstate->line_height / 2) * tex_step; + while ((*i)++ < rstate->draw_end) + { + tex_y = (int)tex_pos & (texture->height - 1); + tex_pos += tex_step; + ((t_color*)state->window.data)[*i * state->window.width + rstate->x] = + ((t_color*)texture->data)[texture->height * tex_y + tex_x]; + } +} + t_image *texture_select(t_state *state, t_render_state *rstate) { - /* if (rstate->target == CELL_ITEM) */ - /* return (state->textures + TEX_SPRITE); */ if (rstate->side == SIDE_NS) { if (rstate->map_pos.y < state->pos.y) diff --git a/src/vector.c b/src/vector.c index 49a7344..4af891a 100644 --- a/src/vector.c +++ b/src/vector.c @@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/11/18 01:28:01 by cacharle #+# #+# */ -/* Updated: 2020/02/02 22:29:59 by cacharle ### ########.fr */ +/* Updated: 2020/02/04 02:13:38 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,13 +19,6 @@ t_vector vector_add(t_vector a, t_vector b) return (a); } -t_vector vector_sub(t_vector a, t_vector b) -{ - a.x -= b.x; - a.y -= b.y; - return (a); -} - t_vector vector_scale(t_vector v, double scalar) { v.x *= scalar; @@ -48,7 +41,6 @@ t_vector vector_rotate(t_vector v, double angle) double vector_norm(t_vector v) { - /* return (sqrt(SQUARE(v.x) + SQUARE(v.y))); */ return (hypot(v.x, v.y)); } @@ -60,10 +52,3 @@ t_vector vector_new(double x, double y) v.y = y; return (v); } - -t_vector vector_apply(t_vector v, double (*f)(double)) -{ - v.x = f(v.x); - v.y = f(v.y); - return (v); -} |
