You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
5.0 KiB
174 lines
5.0 KiB
3 years ago
|
/* ************************************************************************** */
|
||
|
/* */
|
||
|
/* ::: :::::::: */
|
||
|
/* fdf_drawing.c :+: :+: :+: */
|
||
|
/* +:+ +:+ +:+ */
|
||
|
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */
|
||
|
/* +#+#+#+#+#+ +#+ */
|
||
|
/* Created: 2021/11/05 14:44:08 by narnaud #+# #+# */
|
||
|
/* Updated: 2022/02/24 13:45:03 by narnaud ### ########.fr */
|
||
|
/* */
|
||
|
/* ************************************************************************** */
|
||
|
|
||
|
#include "fdf.h"
|
||
|
|
||
|
/* Function : get_color
|
||
|
* --------------------
|
||
|
* return color as decimal value depending of altitude.
|
||
|
* point with an altitude of zero are green,
|
||
|
* points with negativ altitude tend to the blue
|
||
|
* points with positiv altitude tend to the red.
|
||
|
*
|
||
|
* db : map datas,
|
||
|
* x, y : points coordinates,
|
||
|
* coef : the position of the point through the line,
|
||
|
* negativ for vertical lines,
|
||
|
* positiv for horizontal lines,
|
||
|
*
|
||
|
* return : integer which give the color of the point formated as :
|
||
|
* Red * 256^2 + Green * 256 + Blue
|
||
|
* Red, Green and Blue beeing between 0 and 255.
|
||
|
*/
|
||
|
|
||
|
int get_color(t_datas *db, t_2di coord, float coef)
|
||
|
{
|
||
|
int z0;
|
||
|
float dz;
|
||
|
int height;
|
||
|
int color_coef;
|
||
|
|
||
|
if (coord.x > 0 && coef <= 0)
|
||
|
{
|
||
|
z0 = db->map->altitude[coord.y][coord.x - 1];
|
||
|
dz = (float)db->map->altitude[coord.y][coord.x] - (float)z0;
|
||
|
height = z0 - (int)round(coef * dz);
|
||
|
color_coef = (height * 254) / db->map->hightest + 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
z0 = db->map->altitude[coord.y - 1][coord.x];
|
||
|
dz = (float)db->map->altitude[coord.y][coord.x] - (float)z0;
|
||
|
height = z0 + (int)round(coef * dz);
|
||
|
color_coef = (height * 254) / db->map->hightest + 1;
|
||
|
}
|
||
|
if (height >= 0)
|
||
|
return (256 * 255 + color_coef * 256 * 255);
|
||
|
else
|
||
|
return (256 * 255 - color_coef);
|
||
|
}
|
||
|
|
||
|
/* Function : draw_line
|
||
|
* --------------------
|
||
|
* datas :
|
||
|
* start :
|
||
|
* end :
|
||
|
* buffer :
|
||
|
*
|
||
|
* return :
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
void draw_horiz_line(t_datas *datas, t_2di coord, int *buffer)
|
||
|
{
|
||
|
size_t i;
|
||
|
t_2df dp;
|
||
|
t_2df pos;
|
||
|
size_t len;
|
||
|
|
||
|
i = 0;
|
||
|
pos.x = (float)datas->cam->render[coord.y][coord.x - 1].x;
|
||
|
pos.y = (float)datas->cam->render[coord.y][coord.x - 1].y;
|
||
|
dp.x = (float)datas->cam->render[coord.y][coord.x].x - pos.x;
|
||
|
dp.y = (float)datas->cam->render[coord.y][coord.x].y - pos.y;
|
||
|
len = sqrt(dp.x * dp.x + dp.y * dp.y);
|
||
|
dp.x /= len;
|
||
|
dp.y /= len;
|
||
|
while (i < len)
|
||
|
{
|
||
|
pos.x += dp.x;
|
||
|
pos.y += dp.y;
|
||
|
if (pos.x >= 0 && pos.y >= 0 && \
|
||
|
pos.x < WIN_X_SZ && pos.y < WIN_Y_SZ)
|
||
|
buffer[datas->line_bytes * (int)floor(pos.y) + (int)floor(pos.x)] \
|
||
|
= get_color(datas, coord, -(float)i / (float)len);
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void draw_vert_line(t_datas *datas, t_2di coord, int *buffer)
|
||
|
{
|
||
|
size_t i;
|
||
|
t_2df dp;
|
||
|
t_2df pos;
|
||
|
size_t len;
|
||
|
|
||
|
i = 0;
|
||
|
pos.x = (float)datas->cam->render[coord.y - 1][coord.x].x;
|
||
|
pos.y = (float)datas->cam->render[coord.y - 1][coord.x].y;
|
||
|
dp.x = (float)datas->cam->render[coord.y][coord.x].x - pos.x;
|
||
|
dp.y = (float)datas->cam->render[coord.y][coord.x].y - pos.y;
|
||
|
len = sqrt(dp.x * dp.x + dp.y * dp.y);
|
||
|
dp.x /= len;
|
||
|
dp.y /= len;
|
||
|
while (i < len)
|
||
|
{
|
||
|
pos.x += dp.x;
|
||
|
pos.y += dp.y;
|
||
|
if (pos.x >= 0 && pos.y >= 0 && \
|
||
|
pos.x < WIN_X_SZ && pos.y < WIN_Y_SZ)
|
||
|
buffer[datas->line_bytes * (int)floor(pos.y) + (int)floor(pos.x)] \
|
||
|
= get_color(datas, coord, (float)i / (float)len);
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void get_coords(t_2di coord, t_datas *datas)
|
||
|
{
|
||
|
t_2df vars;
|
||
|
t_3d pt;
|
||
|
|
||
|
pt.x = coord.x - datas->map->width / 2;
|
||
|
pt.y = coord.y - datas->map->depth / 2;
|
||
|
pt.z = datas->map->altitude[coord.y][coord.x] * datas->map->z_mult;
|
||
|
pt.yaw.cos = datas->cam->ang.yaw.cos;
|
||
|
pt.yaw.sin = datas->cam->ang.yaw.sin;
|
||
|
pt.pitch.cos = datas->cam->ang.pitch.cos;
|
||
|
pt.pitch.sin = datas->cam->ang.pitch.sin;
|
||
|
vars.x = pt.yaw.cos * pt.x + pt.yaw.sin * pt.y;
|
||
|
vars.y = pt.pitch.sin * (pt.yaw.sin * pt.x - pt.yaw.cos * pt.y) - \
|
||
|
pt.pitch.cos * pt.z;
|
||
|
datas->cam->render[coord.y][coord.x].x = datas->cam->center.x + \
|
||
|
round(datas->cam->zoom * vars.x);
|
||
|
datas->cam->render[coord.y][coord.x].y = datas->cam->center.y + \
|
||
|
round(datas->cam->zoom * vars.y);
|
||
|
}
|
||
|
|
||
|
void draw_map(t_datas *datas)
|
||
|
{
|
||
|
t_2di coord;
|
||
|
int *buffer;
|
||
|
|
||
|
datas->img = mlx_new_image(datas->mlx, WIN_X_SZ, WIN_Y_SZ);
|
||
|
buffer = (int *)mlx_get_data_addr(datas->img, \
|
||
|
&datas->pixel_bits, &datas->line_bytes, &datas->endian);
|
||
|
datas->line_bytes /= 4;
|
||
|
coord.y = 0;
|
||
|
while (coord.y < datas->map->depth)
|
||
|
{
|
||
|
coord.x = 0;
|
||
|
while (coord.x < datas->map->width)
|
||
|
{
|
||
|
get_coords(coord, datas);
|
||
|
if (coord.x > 0)
|
||
|
draw_horiz_line(datas, coord, buffer);
|
||
|
if (coord.y > 0)
|
||
|
draw_vert_line(datas, coord, buffer);
|
||
|
coord.x++;
|
||
|
}
|
||
|
coord.y++;
|
||
|
}
|
||
|
mlx_put_image_to_window(datas->mlx, datas->win, datas->img, 0, 0);
|
||
|
draw_infos(datas);
|
||
|
mlx_destroy_image(datas->mlx, datas->img);
|
||
|
}
|