[42cursurs]mlx 튜토리얼 - mlx 초기화, 창 생성, 창에 이미지 넣기

이상헌·2020년 9월 23일


miniRT는 창(window)제어와 computer graphic의 입문을 목표로 한다.

mlx(Minilibx)

mlx는 창(window)제어와 그래픽 작업을 위한 라이브러리다.
42docs의 예제를 따라가며 살펴보도록 하자.

macos에서 컴파일 명령은 아래와 같이해보자.
mlx는 mac 자체적으로 보유하고 있어서 macos에서는 별 준비 없이 사용할 수 있다.

gcc -lmlx -framework OpenGl -framework AppKit -Imlx 소스파일명.c

mlx 초기화

#include <mlx.h>

int     main(void)
{
    void    *mlx;

    mlx = mlx_init();
}

아직 아무것도 없이 초기화만된 상태다.

void * mlx_init ();

mlx 사용을 위해 가장 먼저 사용하는 함수다.
내 소프트웨어와 디스플레이를 연결해준다.

return:
연결 실패시 NULL 리턴
성공하면 non-null pointer 리턴

창(window) 생성

#include <mlx.h>

int     main(void)
{
    void    *mlx;
    void    *mlx_win;

    mlx = mlx_init();
    mlx_win = mlx_new_window(mlx, 1920, 1080, "Hello world!");// 창을 생성한고 창의 식별자를 반환 받는다. 
    mlx_loop(mlx);// 새로 생성한 window가 있는 mlx를 rendering
}     

mlx_new_window 함수로 1920x1080 크기의 "Hello world!"라는 타이틀의 창을 생성해서 띄웠다.

void mlx_new_window ( void mlx_ptr, int size_x, int size_y, char *title );

새 창을 스크린에 띄운다.

size_x, size_y = 창 사이즈
title = 창의 타이틀 바에 표시됨
mlx_ptr = mlx_init이 반환한 연결 식별자.

return:
다른 MiniLibX 호출에서 사용할 수있는 void* 인 창 식별자를 리턴.
창 생성 실패시 NULL 리턴
참고: MiniLibX는 n개의 각기 다른 창들을 제어할 수 있다. 식별자는 창들 각각을 식별하는 고유 값이다.

그래픽 시스템은 양방향이다. 한쪽에서는 스크린에 디스플레이할 픽셀, 이미지 등을 명령하고, 한쪽에서는 키보드나 마우스로부터 “이벤트”를 받는다.

int mlx_loop ( void *mlx_ptr );

이벤트를 받기위해서 꼭 써야하는 함수.
키보드나 마우스로부터 받은 이벤트를 기다리는 무한루프고, 이벤트에 연결되는 사용자정의 함수를 호출한다.

mlx_ptr 요 한 개의 파라미터가 필요함(see the mlx manual)

return:
이 함수는 리턴 안함.
mac에서는 key, mouse 두 가지 입력에 대한 이벤트만 신경 쓰면 된다.

창(windoe)에 이미지 넣기

#include <mlx.h>

typedef struct	s_data {
	void	*img;
	char	*addr;
	int		bits_per_pixel;
	int		line_length;
	int		endian;
}				t_data;

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->bits_per_pixel / 8));
	*(unsigned int*)dst = color;
}

int	main(void)
{
	void	*mlx;
	void	*mlx_win;
	t_data	img;

	mlx = mlx_init();
	mlx_win = mlx_new_window(mlx, 1920, 1080, "Hello world!");
	img.img = mlx_new_image(mlx, 1920, 1080);// 이미지 instance 생성
	img.addr = mlx_get_data_addr(img.img, &img.bits_per_pixel, &img.line_length, &img.endian);
	//이미지의 주소 할당
	for(int i = 0; i < 100 ; i++) {
		my_mlx_pixel_put(&img, i, i, 0x00FF0000);// 붉은색 선을 대각선으로 그린다.
		my_mlx_pixel_put(&img, 5, i, 0x00FF0000);// 붉은색 선을 세로으로 그린다.
		my_mlx_pixel_put(&img, i, 5, 0x00FF0000);// 붉은색 선을 가로으로 그린다.
	}
	mlx_put_image_to_window(mlx, mlx_win, img.img, 0, 0);//이미지를 윈도우에 올린다.
	mlx_loop(mlx);
}

구석에 붉은 점 하나 찍는 코드가 눈에 잘 안 띄어서 약간 수정 했다.

void mlx_new_image ( void mlx_ptr, int width, int height );

새 이미지를 메모리에 생성시킨다.

이미지 사이즈(width, height), mlx_ptr를 매개변수로 갖는다.

return:
에러 발생시 NULL 리턴
성공 시 이미지 식별자(void *) 리턴

char mlx_get_data_addr ( void img_ptr, int bits_per_pixel, int size_line, int *endian );

img_ptr는 사용할 이미지를 지정합니다.
bits_per_pixel = 픽셀 색상 (이미지의 깊이라고도 함)을 나타내는 데 필요한 비트 수.
다음 세 개의 매개 변수는 세 개의 다른 유효한 정수의 주소여야 합니다
size_line =이미지의 한 줄을 메모리에 저장하는 데 사용되는 바이트 수. 이 정보는 이미지에서 한 줄에서 다른 줄로 이동하는 데 필요.
endian = 이미지의 픽셀 색상을 리틀 엔디안(endian == 0) 또는 빅 엔디안(endian == 1)으로 저장해야하는지 알려줍니다. (( macos에서는 필요 없습니다. 클라이언트와 그래픽 프레임워크가 동일한 엔디언을 갖습니다. ))

return:
mlx_get_data_addr ()는 생성된 이미지에 대한 정보를 리턴해서 사용자가 나중에 이미지를 수정할 수 있도록 합니다.

profile
배고픈 개발자 sayi입니다!

0개의 댓글