MiniLibX(이하 mlx)는 X-Window와 Cocoa에 대한 지식 없이 화면에 무언가를 렌더링하기 위한 가장 기본적인 작업을 할 수 있는 작은 그래픽 라이브러리로, 즉 창(window) 제어와 그래픽 작업을 위한 라이브러리이다.
X-Window
유직스(Unix) 용 네트워크 지향 그래픽 시스템이다.
Cocoa
Apple에서 iOS, macOS 등의 Apple 운영 체제용 어플리케이션 제작 시 사용하는 프레임워크
이를 위해 다양한 함수들이 준비되어 있다.
macOS에서 컴파일 명령은 아래와 같다.(2021/6/22 swift 작성 버전 기준)
$> export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:~/(mlx_mms 절대경로) // 환경변수 설정
$> gcc <소스파일명.c> -Lmlx_mms -lmlx -framework Cocoa -framework Metal -framework MetalKit -framework QuartzCore -o <실행파일명>
아래에서는 mlx 내 함수와 함수 사용법 중 몇 가지를 살펴볼 것이다.
void *mlx_init();
mlx를 사용하기 위해 초기화하여 내 소프트웨어와 디스플레이를 연결시켜 주는 함수이다.
return value:
#include <mlx.h>
int main()
{
void *mlx;
mlx = mlx_init();
return 0;
}
void *mlx_new_window(void *mlx_ptr, int size_x, int size_y, char *title);
새 창을 스크린에 생성하여 띄워주는 함수이다.
return value:
참고
mlx는 n개의 각기 다른 창들을 제어할 수 있다. 각각의 인스턴스 창들 각각을 식별하는 고유 값이다.
int mlx_loop(void *mlx_ptr);
이벤트를 받기 위한 함수이다.
키보드나 마우스로부터 받은 이벤트를 기다리는 무한 루프이고, 이벤트에 연결되는 사용자 정의 함수를 호출한다.
return_value:
그래픽 시스템은 양방향이다.
한쪽에서는 스크린에 디스플레이할 픽셀, 이미지 등을 명령하고, 한쪽에서는 키보드나 마우스로부터 “이벤트”를 받는다.
따라서 키보드나 마우스로부터의 명령을 받기 위해서는 해당 함수가 필수적이다.
#include <mlx.h>
int main()
{
void *mlx;
void *mlx_win;
mlx = mlx_init();
// 1920x1080 크기의 "Hello World!" 라는 타이틀을 가지는 창을 생성하고 instance pointer 반환
mlx_win = mlx_new_window(mlx, 1920, 1080, "Hello World!");
// 새로 생성한 window가 있는 mlx를 랜더링(rendering)
mlx_loop(mlx);
}
void *mlx_new_image(void mlx_ptr, int width, int height);
새로운 mlx 호환 이미지를 만드는 함수이다.
렌더링 중인 이미지를 버퍼링하는 데 권장되는 방법이다.
return_value:
char *mlx_get_data_addr(void *img_ptr, int *bits_per_pixel, int *size_line, int *endian);
주어진 이미지의 메모리 주소를 가져오는 함수이다.
return_value:
int mlx_put_image_to_window(void *mlx_ptr, void *win_ptr, void *img_ptr, int x, int y);
(x, y) 위치에 지정된 window instance에 이미지를 넣는 함수이다.
한 번에 많은 양의 그래픽 데이터를 작성하는 데 권장되는 방법이다.
위치의 메모리를 변경할 때 창에 직접 표시된다.
return_value:
#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 *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); // image 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, 100, i, 0x00FF0000); // 붉은색 선을 세로으로 그린다.
my_mlx_pixel_put(&img, i, 100, 0x00FF0000); // 붉은색 선을 가로으로 그린다.
}
mlx_put_image_to_window(mlx, mlx_win, img.img, 0, 0); //이미지를 윈도우에 올린다.
mlx_loop(mlx);
}
int mlx_destroy_window(void *mlx_ptr, void *win_ptr);
window instance(즉, 생성된 창)을 닫는 함수이다.
return_value:
int mlx_destroy_image(void *mlx_ptr, void *img_ptr);
mlx instance에 존재하는 image instance를 삭제하는 함수이다.
return_value:
참고자료
https://velog.io/@sayi/42cursursftminiRTmlx-%ED%8A%9C%ED%86%A0%EB%A6%AC%EC%96%BC1#%EC%B0%BDwindoe%EC%97%90-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EB%84%A3%EA%B8%B0
https://harm-smits.github.io/42docs/libs/minilibx/prototypes.html#mlx_get_data_addr
https://harm-smits.github.io/42docs/libs/minilibx/introduction.html