miniRT 진행(3) 창에 색 띄우기

chanykim·2021년 1월 4일
0

첫번째로 진행했을 때 pixel에 색 지정하는 함수인 mlx_pixel_put(....)사용하여서 나타냈었습니다.
하지만 창에 한번에 랜더링되서 나오는 것이 아니라 한줄 한줄 랜더링되면서 나오는 형식이었습니다. 그래서 mlx_pixel_put(....)를 사용하지 않고 바로 나오는 코드를 짜기로 했습니다.
mlx_new_image()함수로 메모리에 새로운 이미지를 생성하고 다음에 바로
data.addr = mlx_get_data_addr() 함수로 data.addr에 저장합니다.
mlx_get_data_addr은 이미지가 저장되어 있는 메모리의 시작 지점을 나타내는 char * 주소를 반환합니다.
이 주소로부터, 첫 번째 bits_per_pixel 비트는 이미지에서 첫 번째 줄의 첫 번째 픽셀 색상을 나타냅니다. 두 번째 bits_per_pixel 비트는 첫 번째 줄의 두 번째 픽셀을 나타냅니다. 나머지도 마찬가지입니다. 주소에 size_line을 추가하여 두 번째 줄의 시작 부분을 가져옵니다. 이와 같은 방식으로 이미지의 어떤 픽셀에 접근이 가능합니다.
이제 메모리에 새로운 이미지도 생성했고, 이미지 주소까지 만들었습니다. 하지만 여전히 픽셀이 없습니다. 시작하기 전에 바이트가 정렬되어 있지 않다는 것을 이해해야합니다.
이것은 size_line실제 창 너비와 다르다는 것을 의미합니다 . 따라서 우리는 항상로 설정된 라인 길이를 사용하여 메모리 오프셋을 계산해야합니다. 이 계산은 다음 공식을 사용하여 매우 쉽게 계산할 수 있습니다.

int offset = (y * line_length + x * (bits_per_pixel / 8));


double        clamp(double color, double min, double max)
{
    if (color < min)
        return (min);
    else if (color > max)
        return (max);
    return (color);
}


int			get_grb_val(double trans, t_vec *color)
{
    int     t;
	int		r;
	int		g;
	int		b;

    t = clamp(trans, 0.0, 1.0) * 255.999;
	r = clamp(color->x, 0.0, 1.0) * 255.999;
	g = clamp(color->y, 0.0, 1.0) * 255.999;
	b = clamp(color->z, 0.0, 1.0) * 255.999;
	return (t << 24 | r << 16 | g << 8 | b);

}


void            my_mlx_pixel_put(t_data *data, int x, int y, t_vec *color)
{
    char    *dst;
    double transparency;

    transparency = 0;
    dst = data->addr + (y * data->size_line + x * (data->bits_per_pixel / 8));
    *(unsigned int*)dst = get_grb_val(transparency, color);
}


void         ft_draw_grad(t_data *data, t_images *imgs)
{
	double      x;
	double      y;
	t_vec       color;
    double      h;
    double      w;
    
	y = -1;
    printf("draw_start...");
    sleep(0.5);
    printf("OK!\n");
    h = imgs->height - 1;
    w = imgs->width - 1;
	while ((++y) < imgs->height)
	{
		x = -1;
		while ((++x) < imgs->width)
		{
			ft_vec_create(&color, x / w, y / h, 0.25);
			my_mlx_pixel_put(data, x, h - y, &color);
		}
	}
	mlx_put_image_to_window(data->mlx, data->win, data->img, 0, 0);
}

백터구조체를 만들고 이것을 이용하여 벡터를 만듭니다.

typedef struct  s_vec
{
    double x;
    double y;
    double z;
}               t_vec;


t_vec           *ft_vec_create(t_vec *new_vec, double x, double y, double z)
{
    new_vec->x = x;
    new_vec->y = y;
    new_vec->z = z;
    return (new_vec);
}

픽셀의 (x좌표 / 너비), (y좌표 / 높이)로 r값과 g값을 지정하고 b값은 0.25로 고정하는 벡터입니다.
그리고 알아온 공식을 이용하여 픽셀에 값을 지정해줍니다.
그러면 아래와 같이 rgb값이 픽셀에 적용되어 나오는 것을 볼 수 있습니다.

참고
https://raytracing.github.io/books/RayTracingInOneWeekend.html
https://github.com/cos18/ray-tracing-in-one-weekend-mlx
https://harm-smits.github.io/42docs/libs/minilibx/getting_started.html
https://github.com/psj3205/MiniLibX_man_kor/blob/main/mlx_new_image.md

profile
오늘보다 더 나은 내일

0개의 댓글