[so_long] mlx(MiniLibX) 함수 정리

강송주·2021년 8월 20일
3

42SEOUL

목록 보기
1/1

Mac OS에서 Minilibx 연결하기

MiniLibX에는 AppKit과 X11이 필요하기 때문에 컴파일시 연결이 필요합니다. 기본 컴파일 프로세스는 다음과 같습니다.

개체 파일의 경우 프로젝트 루트에 mlx이름이 지정된 디렉토리에 소스 가 있다고 가정하고 메이크파일에 다음 규칙을 추가할 수 있습니다.

%.o: %.c
	$(CC) -Wall -Wextra -Werror -Imlx -c $< -o $@

필요한 내부 macOS API(애플리케이션 프로그래밍 인터페이스, 응용 프로그램에서 사용할 수 있도록, 운영 체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스)와 연결하려면 :

$(NAME): $(OBJ)
	$(CC) -Lmlx -lmlx -framework OpenGL -framework AppKit -o $(NAME)

libmlx.dylib동적 라이브러리이므로 빌드 대상과 동일한 디렉토리에 있어야 합니다 .

OpenGL : 오픈 그래픽 라이브러리은 1992년 실리콘 그래픽스사에서 만든 2차원 및 3차원 그래픽스 표준 API 규격으로, 프로그래밍 언어 간 플랫폼 간의 교차 응용 프로그래밍을 지원합니다.
AppKit : 일반적으로 AppKit이라고 하는 Application Kit는 NeXTSTEP의 그래픽 사용자 인터페이스 툴킷 입니다. Foundation 및 Display PostScript 와 함께 OpenStep API 사양의 핵심 부분 중 하나입니다. macOS와 함께 번들로 제공되는 대부분의 응용 프로그램 (예 : Finder , TextEdit , Calendar 및 Preview)은 AppKit을 사용하여 사용자 인터페이스를 제공합니다.

참고


mlx_init()

#include  <mlx.h>

void  *mlx_init();

먼저 소프트웨어와 디스플레이 간의 연결을 초기화하기 위해 mlx_init()을 사용합니다.
필요할 때 다른 함수에 전달할 수 있도록 모든 MLX 및 창 포인터를 일종의 구조체에 저장합니다.
이 연결이 설정되면 다른 MiniLibX 기능을 사용하여 "이 창에 노란색 픽셀을 그리고 싶습니다" 또는 "사용자가 키를 눌렀습니까?"와 같은 그래픽 명령을 보낼 수 있습니다.

반환값

현재 MLX 인스턴스(일반적으로 실행 중인 임의의 프로세스, 클래스의 현재 생성된 오브젝트)의 위치를 반환

→그래픽 서버와의 연결에 대한 식별자를 반환

mlx_ptr_t

typedef struct		mlx_ptr_s
{
  void			*appid;
  mlx_win_list_t	*win_list;
  mlx_img_list_t	*img_list;
  void			(*loop_hook)(void *);
  void			*loop_hook_data;
  void			*loop_timer;
  mlx_img_list_t	*font;
  int			main_loop_active;
} mlx_ptr_t;

mlx_init으로 리턴받는 식별자입니다.
과제를 진행하며 항상 사용하게 될 식별자로 소프트웨어와 디스플레이를 연결합니다.
아래에 나올 mlx_win_list_t 구조체와 mlx_img_list_t 구조체에 대한 포인터를 멤버로 가집니다. 각각 구조체는 연결 리스트 형태를 띄고 있어 한 개의 포인터로 모든 식별자를 관리하는 것으로 보입니다.

참고


mlx_get_screen_size()

int		mlx_get_screen_size(void *mlx_ptr, int *sizex, int *sizey)

void *mlx_ptr	the mlx instance;
int  *sizex		the screen width;
int  *sizey		the screen height
return	int				has no return value (bc).

현재 스크린의 사이즈(최대 해상도)를 구하는 함수입니다.

참고


mlx_new_window()

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

새 창을 생성하는 함수입니다.

parameter

  • mlx_ptr : 연결 식별자(mlx_init 리턴값)
  • size_x, size_y : 새 창의 가로, 세로.
  • title : 타이틀바에 보일 문자열

반환값

윈도우 사용 식별자인 win_ptr 포인터를 리턴한다. 실패 시 NULL을 리턴합니다.
실질적으로 리턴되는 식별자는 mlx_ptr->win_list입니다.
동적할당된 새로운 win 식별자는 mlx 식별자의 win 식별자 연결리스트의 헤드를 차지하게 됩니다.

mlx_win_list_t

typedef struct	mlx_win_list_s
{
  void			*winid;
  mlx_img_ctx_t		*img_list;
  int			nb_flush;
  int			pixmgt;
  struct mlx_win_list_s	*next;
} mlx_win_list_t;

mlx_new_window로 리턴받는 식별자입니다. 말 그대로 윈도우 창과 연관된 식별자입니다.
자기 자신에 대한 포인터를 멤버로 가집니다. 연결 리스트 형태로 모든 윈도우를 관리합니다. 윈도우를 새로 생성할 때마다 새로 생성한 포인터가 next를 mlx_ptr_t의 mlx_win_list_t 포인터를 가리키며 헤드를 차지하게 됩니다.

참고


mlx_new_image()

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

메모리에 새로운 이미지를 생성합니다.
mlx_put_image_to_window ()를 사용하여 언제든지 지정된 창 내에서 이미지를 덤프하여 화면에 표시 할 수 있습니다.

parameter

  • mlx_ptr : 연결 식별자(mlx_init 리턴값)
  • width : 생성될 이미지의 길이
  • height : 생성될 이미지의 높이

반환값

나중에 이 이미지를 조작 하는 데 필요한 식별자(mlx_ing_list_t)를 반환합니다. 실패 시 NULL을 리턴합니다.

mlx_img_list_t

typedef struct	mlx_img_list_s
{
  int			width;
  int			height;
  char			*buffer;
  GLfloat		vertexes[8];
  struct mlx_img_list_s	*next;
} mlx_img_list_t;

mlx_new_image로 리턴받는 식별자입니다.
mlx_win_list_t처럼 하나의 연결 리스트로 모든 이미지를 관리하게 됩니다.

참고


mlx_get_data_addr()

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

mlx_new_image함수를 사용하여 이미지 주소(이미지 식별자 포인터)는 가졌지만 픽셀의 주소는 가지고 있지 않습니다. 이때 픽셀의 바이트가 우리가 생각하는 이미지의 모양대로 정렬되지 않았다는 것을 이해하고 있어야 합니다.(픽셀의 주소가 char*형이므로 이차원 배열이 아님) 이때의 size_line은 실제의 창 너비와는 다릅니다. (창 너비를 더한다고 픽셀이 다음 줄으로 넘어가지 않는다) 따라서 우리는 항상 mlx_get_data_addr함수로 설정된 라인 길이를 사용하여 메모리 오프셋(픽셀의 주소)을 계산해야 합니다.

다음 공식을 사용하여 매우 쉽게 계산할 수 있습니다.

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

parameter

  • img_ptr : 이미지 식별자(mlx_new_img 리턴값), 다음의 세 개의 매개 변수를 사용하여 사용할 이미지를 지정합니다.
  • bits_per_pixel : 픽셀 하나(색상 하나)를 표현하는 데 필요한 비트 수 (= depth of the image) (mlx에서는 색을 ARGB로 표현하기 때문에 32로 고정)
  • size_line : 메모리에 이미지의 한 줄을 저장하는 데 사용되는 바이트 수. 이미지에서 한 줄에서 다른 줄로 이동하는 데 필요합니다. (mlx_img.swift에서 정해져오는 값)
  • endian : 픽셀 색깔을 저장하는 변수가 리틀엔디안(endian == 0)인지 혹은 빅엔디안(endian == 1) 방식인지 나타냅니다. (MacOS에서는 필요없다. 클라이언트와 그래픽 프레임워크가 동일한 엔디언을 가집니다.)

반환값

생성된 이미지에 대한 정보를 리턴해서 사용자가 나중에 이미지를 수정할 수 있도록 합니다.
사용자가 나중에 수정할 수 있도록 mlx_new_image에서 생성된 이미지에 대한 메모리 주소의 시작 부분의 포인터를 반환합니다.

반환된 주소를 사용하는 방법

→반환된 주소로부터, 첫 번째 bits_per_pixel 비트가 이미지의 제일 첫 줄의 첫 번째 픽셀의 색상을 나타낸다.
→두 번째 그룹의 bits_per_pixel 비트는 첫째 줄의 두번째 픽셀을 나타내고 그런 식으로 쭉 나간다.
→주소에 size_line을 추가해서 두 번째 줄 시작점을 얻는다.
→그런 식으로 이미지의 모든 픽셀에 도달 할 수 있습니다.

리턴값을 unsigned int형으로 변환하는 이유

char * 포인터에 연속으로 색상을 저장할 때 4칸 간격으로 저장하고 저장한 값을 뽑아올 때도 4칸 간격으로 가져오기 때문에 unsigned int형으로 형변환합니다.
int형이 아닌 unsigned int로 하는 이유는 ARGB가 가질 수 있는 값은 0x00000000 ~ 0xFFFFFFFF 로 (unsigned int) 범위와 동일하기 때문입니다.

참고


mlx_xpm_file_to_image()

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

mlx_new_image와 유사하게 메모리에 새로운 이미지를 생성합니다. 이때 new_image는 빈 이미지이고, mlx_xpm_file_to_image는 xpm파일을 메모리에 생성하는 것입니다.

parameter

  • mlx_ptr : 연결 식별자(mlx_init 리턴값)
  • filename : image로 만들 xpm파일 이름
  • width, height : xpm 파일의 가로, 세로 길이

반환값

이미지 식별자로 null이 아닌 포인터를 반환합니다. 실패시 NULL을 반환합니다.

참고


mlx_loop()

int mlx_loop(void *mlx_ptr)

그래픽 시스템은 양방향입니다. 한쪽에서는 스크린에 디스플레이할 픽셀, 이미지 등을 명령하고, 한쪽에서는 키보드나 마우스로부터 “이벤트”를 받습니다.
이때 이벤트를 수신하는 함수입니다. 이벤트를 기다린 다음 이 이벤트와 관련된 사용자 정의 함수를 호출하는 무한 루프입니다.

다음 세 가지 이벤트에 다른 기능을 할당할 수 있습니다.

  • 키를 눌렀다 (mlx_key_hook)
  • 마우스 버튼을 눌렀다 (mlx_mouse_hook)
  • 창의 일부를 다시 그려야 합니다 (이를 "expose" 이벤트라고 하며 이를 처리하는 것은 프로그램의 작업입니다). (mlx_expose_hook)

이 세가지 함수 말고도 mlx_hook이 모든 유형의 이벤트에 대한 훨씬 더 일반적인 액세스를 제공합니다. 이벤트 및 마스크 값은 X11에서 가져옵니다.

각 창은 동일한 이벤트에 대해 다른 기능을 정의할 수 있습니다.

무한루프이므로 함수 마지막에 쓰여야 합니다.

parameter

  • *mlx_ptr : 연결 식별자

반환값

없음

참고


mlx_hook()

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

이벤트를 생성하는 함수입니다.

hooking이란?

소프트웨어 구성 요소 간에 전달되는 함수 호출이나 메시지 또는 이벤트를 가로채서 운영체제, 응용 프로그램 또는 기타 소프트웨어 구성 요소의 동작을 변경하거나 증대하는데 사용되는 다양한 기술을 포함합니다. 가로채는 함수 호출, 이벤트 또는 메시지를 처리하는 코드를 후크라고 합니다.

parameter

  • *win_ptr : 윈도우 식별자 (mlx_new_window리턴값)

  • x_event : X11 라이브러리에서 정의된 event이다. 발생시키고 싶은 이벤트를 넣어주면 된다.

  • x_mask : MacOS에서는 사용되지 않는다. 기본적으로 0을 넣어줍니다.

  • int (*funct)() : 호출할 함수 포인터. 이벤트 핸들러.
    이벤트를 포착했을 경우, 핸들러 함수에 키, 마우스 이벤트에 있어서 추가적인 정보가 전달됩니다. 그 정보는 아래와 같습니다 :

    • keycode = 어떤 키가 눌려졌는지

    • x, y = 창에서 눌린 마우스 클릭 좌표(X11의 경우, include 파일 “keysymdef.h”를 확인하시고, MacOS의 경우 그냥 해보세요 :) )

    • button = 어느 마우스 버튼이 눌렸는지

  • *param : 호출한 함수 내에서 필요한 파라미터 데이터의 주소값

반환값

없음

mlx_key_hook과의 차이

mlx_key_hook는 key를 누를때마다 이벤트가 일시적으로 발생하지만, mlx_hook는 누르고있는 상태에서 이벤트가 무한히 반복된다.

참고


mlx_loop_hook()

int mlx_loop_hook(void *mlx_ptr, int (*funct_ptr)(), void *param)

아무 이벤트도 일어나지 않을 경우 인자로 받았던 함수가 호출됩니다.
이벤트 발생 조건 없이 (*funct_ptr)()에 매개변수로 입력된 함수를 무한대로 실행합니다.

parameter

*mlx_ptr : 윈도우 식별자 (mlx_new_window리턴값)

(*funct_ptr)() : 호출할 함수 포인터

*param : 호출한 함수 내에서 필요한 파라미터 데이터의 주소값

반환값

없음


mlx_destroy_image()

int               mlx_destroy_image ( void *mlx_ptr, void *img_ptr )

주어진 이미지(img_ptr)을 삭제합니다.

parameter

*mlx_ptr : 연결 식별자(mlx_init 리턴값)

*img_ptr : 이미지 식별자(mlx_new_img 리턴값)

반환값

없음

참고


mlx_destroy_window()

int       mlx_destroy_window ( void *mlx_ptr, void *win_ptr )

지정된 창을 끕니다.

parameter

*mlx_ptr : 연결 식별자(mlx_init 리턴값)

*win_ptr : 윈도우 식별자 (mlx_new_window리턴값)

반환값

없음

참고

profile
꾸준히 조금씩! 👩🏻‍💻

1개의 댓글

comment-user-thumbnail
2022년 7월 16일

너무 잘 봤어요. 감사합니다. 큰 도움이 됐어요. 꾸준히 올려주세요.

답글 달기