열렬히.뛰기

mlx : 그림 101

école 42 > fdf (fil de fer) > mlx & 그래픽 기초 > mlx : 그림 101

그림 그리기 1 : 점 찍기

put_pixel을 이용해 하나하나 찍는 방법에 대해서 알아보자.

점을 이어보면 그림이 된다.

예시 코드

c
#include "fdf.h"

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

	dst = data->addr + (y * data->line_length + x * (data->bpp / 8));
	*(unsigned int*)dst = color;
}

int main(void)
{
    void    *mlx;
    void    *win;
    t_data  image;

    mlx = mlx_init();
    win = mlx_new_window(mlx, 1920, 1080, "hello world");
    
		// 이미지 넣기 파트
    image.img = mlx_new_image(mlx, 500, 500); // 이미지 객체 생성
    image.addr = mlx_get_data_addr(image.img, &image.bpp, &image.line_length, \
    &image.endian); // 이미지 주소 할당
    for (int i = 0 ; i < 500 ; i++)
		{
			for (int j = 0 ; j < 500 ; j++)
				mlx_pixel_put (mlx, win, i, j, 0x00FFFFFF);
		}
		// 이미지 넣기 파트

    mlx_loop(mlx);
    return (0);
}

다음 코드를 치고 실행시켜보자.

캔버스와 도화지

우리가 집중적으로 봐야할 코드는 여기이다.

c
image.img = mlx_new_image(mlx, 500, 500); // 이미지 객체 생성
image.addr = mlx_get_data_addr(image.img, &image.bpp, &image.line_length, \
  &image.endian); // 이미지 주소 할당
for (int i = 0 ; i < 500 ; i++)
{
	for (int j = 0 ; j < 500 ; j++)
		mlx_pixel_put (mlx, win, i, j, 0x00FFFFFF);
}

목표 : win 이라는 캔버스 위에 500 x 500 의 도화지를 올리는 것.

이때, 컴퓨터의 (0, 0)은 왼쪽 위 상단임을 생각하자.

함수 설명

  • mlx_new_image : 메모리에 새 이미지를 만든다.

    구조는 다음처럼 생각하면 된다 : mlx_new_image(캔버스, x 길이, y 길이)

  • mlx_get_data_addr : 생성된 이미지의 정보(address)를 돌려준다.

    image.img = 사용할 이미지를 의미

    image.bpp = bits per pixel의 줄임말로 픽셀 색상을 지정하는데 필요한 비트 수

    image.line_length = 이미지 한줄을 메모리에 저장하는데 사용된 바이트 수.

    이미지를 한 줄에서 다음 줄로 넘길 때 필요.

    image.endian : 픽셀 저장방식. (리틀엔디언 = 0, 빅엔디언 = 1)

엔디언이란?

엔디언(Endianness)은 컴퓨터의 메모리와 같은 1차원의 공간에 여러 개의 연속된 대상을 배열하는 방법을 뜻하며, 바이트를 배열하는 방법을 특히 바이트 순서(Byte order)라 한다.

그림 그리기 2 : 이미지

image를 이용해서 그림을 그리는 법에 대해 알아보자.

좀 더 빠르다는 장점이 있다.

예시코드

다음 코드를 쳐보고 실행시켜 보자.

c
#include "fdf.h"

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

	dst = data->addr + (y * data->line_length + x * (data->bpp / 8));
	*(unsigned int*)dst = color;
}

int create_argb(int a, int r, int g, int b)
{
    return (a << 24 | r << 16 | g << 8 | b);
}

static void image(void)
{
    void    *mlx;
    void    *win;
    t_data  image;

    mlx = mlx_init();
    win = mlx_new_window(mlx, 1920, 1080, "hello world");
    
    image.img = mlx_new_image(mlx, 1920, 1080);
    image.addr = mlx_get_data_addr(image.img, &image.bpp, &image.line_length, \
		&image.endian);

    for (int x = 0; x < 200; x++) {
        for (int y = 0; y < 200; y++) {
            char *dst2;
            dst2 = image.addr + (y * image.line_length + x * image.bpp / 8);
            *(unsigned int *)dst2 = create_argb(0, 0, 255, 0);
        }
    }
    mlx_put_image_to_window(mlx, win, image, 20, 100);
		// image를 
    mlx_loop(mlx);
}

int main(int ac, char **av)
{
    image();
}