티스토리 뷰

C

[42cursus] miniLibX(mlx) library

refigo 2021. 12. 27. 18:04

42cursus에 있는 grahics programming과 events programming 과제들을 하기위해서는 miniLibX(이하 mlx)라는 Library의 사용이 적극 권장된다. 잘 사용해서 grahics, events programming을 하기 위해 mlx가 무엇인지 알아보도록 하자.

 

1. mlx는 무엇일까?

MiniLibX - Simple X-Window Interface Library for students

mlx는 X-Window에 대한 지식 없이도 쉽게 그래픽 소프트웨어을 만들 수 있도록 제작되었다. 간단한 창 생성, 그리기 도구, 이미지 및 기본적인 이벤트 관리 기능을 제공한다. X-Window란 네트워크 기반 그래픽 시스템이다. X-Window에는 X-Server와 X-Client가 있다. X-Server는 X-Client에게 명령을 받아 요청의 결과로 디스플레이 장치에 출력해준다. 또한 키보드, 마우스와 같은 사용자의 입력(events)을 X-Client에게 전달해주는 역할을 한다. mlx API를 이용하기 위해서는 mlx.h를 include해야한다. 이 헤더파일은 mlx 함수의 prototype들 만 포함되어 있고 구조체는 포함되지 않는다.

 

2. mlx에는 어떤 것들이 있을까?

2-1. Initialize the connection

void *mlx_init();

가장 먼저, 소프트웨어와 디스플레이 사이의 연결을 초기화 시킬 필요가 있다. 연결이 한 번 설정이 되고 나면, X-Server에 메세지를 보내기 위해 mlx에 있는 다른 함수들을 사용할 수 있다. mlx_init()은 이러한 연결을 초기화해서 만든다. 성공한다면 포인터를 반환하는데 다른 mlx의 함수들을 호출할 때 사용되는 'Connection Identifier(or Screen Connection Identifier)'이다. 실패하면 NULL 포인터를 반환한다.

 

2-2. Managing windows

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

스크린에 새로운 윈도우 창을 만든다. size_x와 size_y를 이용해서 창의 크기를 결정한다. title은 창 위의 title bar에 적힐 텍스트 문자열이다. 성공한다면 포인터를 반환하는데 다른 mlx 함수들을 호출할 때 사용되는 Window Identifier다. mlx는 여러개의 윈도우 창들을 관리할 수 있다.

 

int mlx_clear_window(void *mlx_ptr, void *win_ptr);

주어진 윈도우 창을 검정색으로 clear하는 데 사용된다.

 

int mlx_destroy_window(void *mlx_ptr, void *win_ptr);

주어진 윈도우 창을 제거하는 데 사용된다.

 

2-3. Drawing inside windows

int mlx_pixel_put(void *mlx_ptr, void *win_ptr, int x, int y, int color);

윈도우 창 안에서 인자로 받은 (x, y)좌표에 주어진 color로 픽셀을 그린다. (0, 0)좌표는 윈도우 창의 왼쪽 상단 끝을 나타낸다.

 

int mlx_string_put(void *mlx_ptr, void *win_ptr, int x, int y, int color, char *string);

(x, y)좌표에 주어진 color 색상으로 주어진 string 문자열을 그린다. 위 함수들에서 color 파라미터는 int 타입을 가진다. 나타낼 수 있는 색깔은 Red, Green, Blue 3가지로 표현될 수 있다. 이 3가지 색깔은 각자 0~255사이의 값을 가지고 있다. 각 값들은 표현될 color에 대해 각 RGB가 나타내는 수치다. RGB의 값에 따라 color integer안의 byte들은 아래와 같이 채워진다.

 |  0  |  R  |  G  |  B  |   color integer

+---+---+---+---+

 

2-4. Manipulating images

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

새로운 image를 메모리에 만든다. width, height 인자들로 크기를 결정한다. 성공하면 image를 조작하는데 사용될 포인터를 반환한다. 사용자는 image 안에서 그릴 수 있고 언제라도 윈도우 창 안에 그 image를 나타낼 수 있다.

 

int mlx_put_image_to_window(void *mlx_ptr, void *win_ptr, void *img_ptr, int x, int y);

윈도우 창 안에 그 image를 나타낼 때 사용되는 함수다. (x, y)좌표는 윈도우 창 안에서 image가 위치할 좌표이다.

 

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

만들어진 image에 대한 정보가 저장된 곳의 시작 주소를 반환한다. 사용자가 수정할 수 있도록 하기 위해서다.

bits_per_pixel은 픽셀의 색깔을 나타내는데 필요한 bit 개수를 나타낸다.(image에 대한 깊이라고도 불린다.) 예를들어, 하나의 픽셀의 색깔을 나타내는데 4bytes가 필요하다면 4bytes * (8bits / 1byte) = 32이므로 32의 값이 저장된다.

size_line은 image의 한 줄을 메모리에 저장하는데 사용되는 byte들의 개수로 채워진다. size_line을 주소에 더하면 image의 2번째 줄에 있는 첫번째 픽셀의 주소로 이동할 수 있다. 이런 방식으로 image에 있는 모든 픽셀에 접근할 수 있다.

endian은 image 안에 있는 픽셀 샐깔들이 little endian나 big endian 둘 중 어떤 방식으로 저장되는지 말해준다. (endian: 컴퓨터의 메모리와 같은 1차원의 공간에 여러 개의 연속된 대상을 배열하는 방법을 뜻한다. endian은 보통 큰 단위가 앞에 나오는 빅 엔디언(Big-endian)과 작은 단위가 앞에 나오는 리틀 엔디언(Little-endian)으로 나눌 수 있다.) 

 

int mlx_destroy_image(void *mlx_ptr, void *img_ptr);

주어진 image를 제거한다.

 

unsigned int mlx_get_color_value(void *mlx_ptr, void *win_ptr, void *img_ptr, int x, int y);

디스플레이에 따라 픽셀의 샐깔을 저장하는데 사용되는 bits가 변경될 수 있다. image의 bits_per_pixel에 맞게 변환해야하고 X-Server가 이해할 수 있도록 만들어야 한다. 이러한 목적으로 만든 함수가 mlx_get_color_value()이다. RGB parameter를 unsigned int 타입으로 반환한다.

 

void *mlx_xpm_to_image(void *mlx_ptr, char **xpm_data, int *width, int *height);
void *mlx_xpm_file_to_image(void *mlx_ptr, char *filename, int *width, int *height);

위 함수들은 둘 다 같은 방식으로 새로운 image를 만든다. 각각 지정된 xpm_data나 filename 인자를 이용해서 image를 채운다. 성공하면 반환값으로 image를 다룰 수 있는 포인터를 반환한다.

 

2-5. Handle events

int mlx_loop(void *mlx_ptr);

event를 받기 위해선, 반드시 mlx_loop()를 사용해야 한다. 이 함수는 끝나지 않고 event를 기다리기 위해 무한 루프를 돈다. event를 받으면 그 event와 관련된 사용자가 정의한 함수를 호출한다. 받을 수 있는 events의 종류에는 3가지가 있다. : key, mouse, expose

1) key: 키보드의 key가 눌려졌을 때. 2) mouse: mouse의 버튼이 눌러졌을 때. 3) expose: 창(window)가 선택되어 모니터 상에서 나타났을 때

 

int mlx_key_hook(void *win_ptr, int (*funct_ptr)(), void *param);
int mlx_mouse_hook(void *win_ptr, int (*funct_ptr)(), void *param);
int mlx_expose_hook(void *win_ptr, int (*funct_ptr)(), void *param);

위 3개의 함수는 완전히 같은 방식으로 동작한다. funct_ptr는 event가 발생했을 때, 불러오길 원하는 함수의 포인터다. param 포인터는 함수가 호출될 때 마다 funct_ptr에 위치한 함수로 들어가는 인자다. param에는 필요한 parameters를 담은 구조체 주소를 사용하는 것이 유용하다.

 

int mlx_loop_hook(void *win_ptr, int (*funct_ptr)(), void *param);

위에 있는 hook 관련 함수들과 동일하게 동작하지만, mlx_loop_hook()은 아무런 event가 일어나지 않아도 호출된다. hook 관련 함수들이 호출되었을 때, fnct_ptr에 있는 함수들은 아래와 같이 인자들을 받는다.(함수들의 이름은 임의로 설정할 수 있다.)

 

key_hook(int keycode, void *param);
mouse_hook(int button, int x, int y, void *param);
expose_hook(void *param); loop_hook(void *param);

key_hook()에 있는 keycode는 키보드에 어떤 키가 눌려졌는지 알려주고, mouse_hook()에 있는 button과 (x, y) 좌표는 마우스의 어떤 버튼이 윈도우 창의 어느 좌표를 눌렀는지 알려준다.

 

int mlx_hook(void *win_ptr, int x_event, int x_mask, int (*funct)(), void *param);

일반적으로 사용이 가능하게 모든 X_Window의 events에 대해 접근가능한 mlx_hook()도 있다. 위에 있는 hook관련 함수들과 동작 방법은 같지만 x_event와 x_mask 인자를 추가로 받는다.

 

 

man mlx

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함