[mlx.3]
NAME
MiniLibX - Simple X-Window Interface Library for students
SYNOPSYS
#include <mlx.h>
void *
mlx_init ();
DESCRIPTION
MiniLibX is an easy way to create graphical software, without any X-Window programming knowl‐
edge. It provides simple window creation, a drawing tool, image and basic events management.
- MiniLibX는 X-Window 프로그래밍 지식 없이 그래픽 소프트웨어를 쉽게 만들 수 있는 방법입니다. 간단한 창 만들기,
그리기 도구, 이미지 및 기본 이벤트 관리를 제공합니다.
X-WINDOW CONCEPT
X-Window is a network-oriented graphical system for Unix. It is based on two main parts:
On one side, your software wants to draw something on the screen and/or get keyboard & mouse
entries.
On the other side, the X-Server manages the screen, keyboard and mouse (It is often refered to
as a "display").
A network connection must be established between these two entities to send drawing orders
(from the software to the X-Server), and keyboard/mouse events (from the X-Server to the soft‐
ware).
- X-Windows는 UNIX용 네트워크 지향 그래픽 시스템입니다. 이는 두가지 주요 부분을 기반으로 합니다:
한 쪽에서는 소프트웨어가 화면에 무언가를 그리거나 키보드와 마우스 입력을 받기를 원합니다.
다른 쪽에서는 X-Server가 화면, 키보드와 마우스(흔히 "디스플레이"라고 불립니다.)를 관리합니다.
드로잉 오더(소프트웨어 -> X-Server로) 및 키보드/마우스 이벤트(X-Server -> 소프트웨어로)를 전송하려면 이 두 엔티티 사이에 네트워크 연결을 설정해야 합니다.
(소프트웨어(또는 프로그램)에 설정된 기능 기반으로 키보드나 마우스 입력등을 누르면 (즉, Event를 발생시키는 것),
Event가 서버로 전송되고, 서버에서 해당 이벤트를 매칭 시켜서 생성된 window에 반영한다)
INCLUDE FILE
mlx.h should be included for a correct use of the MiniLibX API. It only contains function
prototypes, no structure is needed.
- MiniLibX API를 올바르게 사용하려면 mlx.h가 include 되어야 합니다.
함수 프로토타입만 포함되어 있고 구조(구조체)는 필요하지 않습니다.
(일반적인 그래픽 라이브러리들은 API 설계에서 구조체 함수를 주로 사용을 하나, MiniLibX 에선 단순 함수 호출만으로도 사용이 가능하기 때문에 별도의 구조체 생성이 필요없고, 프로토타입 선언만 해주면 된다)
LIBRARY FUNCTIONS
First of all, you need to initialize the connection between your software and the display.
Once this connection is established, you'll be able to use other MiniLibX functions to send
the X-Server messages, like "I want to draw a yellow pixel in this window" or "did the user
hit a key?".
- 우선 소프트웨어와 디스플레이 간의 연결을 초기화해야 합니다.
이 연결이 설정되면 다른 MiniLibX 기능을 사용하여 "이 창에 노란색 픽셀을 그리고 싶어요" 또는 "사용자가 키를 눌렀나요?" 등의 X-Server에 메시지를 보낼 수 있습니다.
The mlx_init function will create this connection. No parameters are needed, ant it will re‐
turn a void * identifier, used for further calls to the library routines.
mlx_init 함수가 이 연결을 생성합니다.
매개 변수는 필요하지 않으며 라이브러리 루틴에 대한 추가 호출에 사용되는 void *식별자를 반환합니다.
(서버와 소프트웨어(프로그램)을 연결하려면 mlx_init() 함수의 사용이 우선 및 필수적이다)
All other MiniLibX functions are described in the following man pages:
다른 모든 MiniLibX 기능은 다음 man 페이지에 설명되어 있습니다:
mlx_new_window : manage windows
mlx_pixel_put : draw inside window
mlx_new_image : manipulate images
mlx_loop : handle keyboard or mouse events
LINKING MiniLibX
To use MiniLibX functions, you'll need to link your software with several libraries, including
the MiniLibX library itself. To do this, simply add the following arguments at linking time:
-lmlx -lXext -lX11
You may also need to specify the path to these libraries, using the -L flag.
- MiniLibX 기능을 사용하려면 MiniLibX 라이브러리 자체를 포함한 여러 라이브러리와 소프트웨어를 링크해야 합니다. 이렇게 하려면 컴파일 링크 단계에서 다음 인수를 추가하기만 하면 됩니다:
-lmlx -lXext -lX11
-L 플래그를 사용하여 이러한 라이브러리에 대한 경로를 지정해야 할 수도 있습니다.
(cc -Wall -Werror -Wextra -L(라이브러리 경로) -lmlx -lGL -lX11 -lXext)
RETURN VALUES
If mlx_init() fails to set up the connection to the X server, it will return NULL, otherwise a
non-null pointer is returned as a connection identifier.
- mlx_init()가 X 서버에 대한 연결을 설정하지 못하면 NULL을 반환하고 그렇지 않으면 NULL이 아닌 포인터(void *)가 연결 식별자로 반환됩니다.
[mlx_new_window.3]
NAME
MiniLibX - Managing windows
SYNOPSYS
void *
mlx_new_window ( void *mlx_ptr, int size_x, int size_y, char *title );
int
mlx_clear_window ( void *mlx_ptr, void *win_ptr );
int
mlx_destroy_window ( void *mlx_ptr, void *win_ptr );
DESCRIPTION
The mlx_new_window () function creates a new window on the screen, using the size_x and size_y
parameters to determine its size, and title as the text that should be displayed in the win‐
dow's title bar. The mlx_ptr parameter is the connection identifier returned by mlx_init ()
(see the mlx man page). mlx_new_window () returns a void * window identifier that can be used
by other MiniLibX calls. Note that the MiniLibX can handle an arbitrary number of separate
windows.
- mlx_new_window() 함수는 size_x 및 size_y 매개 변수를 사용하여 크기를 결정하고 제목을 창 제목 표시줄에 표시할 텍스트로 사용하여 화면에 새 창을 만듭니다. mlx_ptr 매개 변수는 mlx_init()에서 반환되는 연결 식별자입니다(mlx man 페이지 참조). mlx_new_window()는 다른 MiniLibX 호출에서 사용할 수 있는 void * window 식별자를 반환합니다. MiniLibX는 임의의 수의 개별 창을 처리할 수 있습니다.
mlx_clear_window () and mlx_destroy_window () respectively clear (in black) and destroy the
given window. They both have the same parameters: mlx_ptr is the screen connection identifier,
and win_ptr is a window identifier.
- mlx_clear_window() 및 mlx_destroy_window()는 각각 지정된 창을 지우고 제거합니다. 둘 다 동일한 매개 변수를 갖습니다. mlx_ptr은 화면 연결 식별자이고 win_ptr은 창 식별자입니다.
(mlx_ptr = mlx_init() 을 통해 식별자를 할당하고, win_ptr = mlx_new_window(mlx_ptr, int size_x, int_size y, char *title)
을 통해 가로 x , 세로 y 사이즈에 title에 해당하는 제목으로 window 에 할당해서 생성한다.
생성된 window 를 제거할 땐 mlx_destroy_window() 나 mlx_clear_window() 를 호출하면 된다)
mlx_destroy_window() 를 호출하고, 그려진 내용만 지우려면 mlx_clear_window()를 호출하면 된다)
RETURN VALUES
If mlx_new_window() fails to create a new window (for wathever reason), it will return NULL,
otherwise a non-null pointer is returned as a window identifier. mlx_clear_window and mlx_de‐
stroy_window right now return nothing.
- mlx_new_window()가 새 창을 만들지 못하면 NULL을 반환합니다. 그렇지 않으면 null이 아닌 포인터가 창 식별자로 반환됩니다. mlx_clear_window와 mlx_destroy_window는 지금 당잔은 아무것도 반환하지 않습니다.
[mlx_pixel_put.3]
NAME
MiniLibX - Drawing inside windows
SYNOPSYS
int
mlx_pixel_put ( void *mlx_ptr, void *win_ptr, int x, int y, int color );
int
mlx_string_put ( void *mlx_ptr, void *win_ptr, int x, int y, int color, char *string );
DESCRIPTION
The mlx_pixel_put () function draws a defined pixel in the window win_ptr using the ( x , y )
coordinates, and the specified color . The origin (0,0) is the upper left corner of the win‐
dow, the x and y axis respectively pointing right and down. The connection identifier, mlx_ptr
, is needed (see the mlx man page).
- mlx_pixel_put() 함수는 (x, y) 좌표와 지정된 색상을 사용하여 win_ptr 창에 정의된 픽셀을 그립니다. 원점(0,0)은 창의 왼쪽 상단 모서리이며, x축과 y축은 각각 오른쪽과 아래를 가리킵니다. 연결 식별자인 mlx_ptr이 필요합니다(mlx man 페이지 참조).
(배열 해석으로 (x ,y) 를 바라본다면 y 의 변화에 따라 가로로 픽셀을 찍어나간다고 생각했었는데,
그래픽은 수학적으로 계산된거기 때문에 그래프를 기준으로 생각해야 돼서 y가 바뀔 때마다 상위로 픽셀을 찍어나간다. 하지만 MiniLibX 의 window 와 image의 원점(0, 0)은 왼쪽 상위 모서리로 잡혀 있기 때문에 y값을 상위로 찍을 수 없어 하위로 찍히겠끔 설정해두었다.
mlx.h 에서 mlx_put_pixel() 호출 부분을 보면 주석으로 <y down is positive> 라고 적혀있는 것을 확인할 수 있다. 즉, x 축은 기존 그래프처럼 가로 우측 방향으로 값이 증가하나 y 축은 하단으로 내려가면서 0, 1, 2, 3, 4 ... 식으로 양수 값이 증가한다)
Parameters for mlx_string_put () have the same meaning. Instead of a simple pixel, the speci‐
fied string will be displayed at ( x , y ).
- mlx_string_put()에 대한 매개 변수는 동일한 의미를 갖습니다. 단순한 픽셀 대신 지정된 문자열이 (x, y)에 표시됩니다.
In both functions, it is impossible to display anything outside the specified window, nor dis‐
play in another window in front of the selected one.
- 두 기능 모두에서 지정된 창 밖에 있는 것을 표시하거나 선택한 창 앞에 있는 다른 창에 표시하는 것은 불가능합니다.
COLOR MANAGEMENT
The color parameter has an integer type. The displayed color needs to be encoded in this inte‐
ger, following a defined scheme. All displayable colors can be split in 3 basic colors: red,
green and blue. Three associated values, in the 0-255 range, represent how much of each color
is mixed up to create the original color. Theses three values must be set inside the integer
to display the right color. The three least significant bytes of this integer are filled as
shown in the picture below:
- 색상 매개 변수는 정수 유형을 가지고 있습니다. 표시되는 색상은 정의된 방식에 따라 이 정수로 인코딩되어야 합니다. 표시 가능한 모든 색상은 빨간색, 녹색 및 파란색의 세 가지 기본 색상으로 나눌 수 있습니다. 0-255 범위의 세 가지 관련 값은 각 색상을 얼마나 혼합하여 원래 색상을 만드는지 나타냅니다. 올바른 색상을 표시하려면 정수 내부에 이 세 가지 값을 설정해야 합니다. 이 정수의 가장 중요하지 않은 세 바이트는 아래 그림과 같이 채워집니다:
| 0 | R | G | B | color integer
+---+---+---+---+
While filling the integer, make sure you avoid endian problems. Remember that the "blue" byte
should always be the least significant one.
- 정수를 채울 때 endian 문제를 방지해야 합니다. "파란색" 바이트는 항상 중요도가 가장 낮은 바이트여야 한다는 것을 기억하십시오.
[mlx_new_image.3]
NAME
MiniLibX - Manipulating images
SYNOPSYS
void *
mlx_new_image ( void *mlx_ptr, int width, int height );
char *
mlx_get_data_addr ( void *img_ptr, int *bits_per_pixel, int *size_line, int *endian );
int
mlx_put_image_to_window ( void *mlx_ptr, void *win_ptr, void *img_ptr, int x, int y );
unsigned int
mlx_get_color_value ( void *mlx_ptr, int color );
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 );
int
mlx_destroy_image ( void *mlx_ptr, void *img_ptr );
DESCRIPTION
mlx_new_image () creates a new image in memory. It returns a void * identifier needed to ma‐
nipulate this image later. It only needs the size of the image to be created, using the width
and height parameters, and the mlx_ptr connection identifier (see the mlx manual).
- mlx_new_image()는 메모리에 새 이미지를 생성합니다. 나중에 이 이미지를 조작하는 데 필요한 void * 식별자를 반환합니다. 너비 및 높이 매개 변수와 mlx_ptr 연결 식별자를 사용하여 생성할 이미지의 크기만 있으면 됩니다(mlx 매뉴얼 참조).
The user can draw inside the image (see below), and can dump the image inside a specified win‐
dow at any time to display it on the screen. This is done using mlx_put_image_to_window ().
Three identifiers are needed here, for the connection to the display, the window to use, and
the image (respectively mlx_ptr , win_ptr and img_ptr ). The ( x , y ) coordinates define
where the image should be placed in the window.
- 사용자는 이미지 내부에 그림을 그릴 수 있으며(아래 참조), 지정된 창 내부에 이미지를 언제든지 dump하여 화면에 표시할 수 있습니다. 이것은 mlx_put_image_to_window()를 사용하여 수행됩니다. 여기서 디스플레이 연결, 사용할 창 및 이미지(각각 mlx_ptr, win_ptr 및 img_ptr)에 대한 세 개의 식별자가 필요합니다. (x, y) 좌표는 이미지가 창에서 배치될 위치를 정의합니다.
(img = mlx_new_image() 로 image 식별자를 할당하고, 이미 할당된 mlx_ptr 과 win_ptr 통해 생성된 window 에 image를 출력하는 것으로 window 사이즈와 별개로 image 사이즈를 조절할 수 있다)
mlx_get_data_addr () returns information about the created image, allowing a user to modify it
later. The img_ptr parameter specifies the image to use. The three next parameters should be
the addresses of three different valid integers. bits_per_pixel will be filled with the num‐
ber of bits needed to represent a pixel color (also called the depth of the image). size_line
is the number of bytes used to store one line of the image in memory. This information is
needed to move from one line to another in the image. endian tells you wether the pixel color
in the image needs to be stored in little endian ( endian == 0), or big endian ( endian == 1).
- mlx_get_data_addr()는 생성된 이미지에 대한 정보를 반환하여 사용자가 나중에 수정할 수 있도록 합니다. img_ptr 매개 변수는 사용할 이미지를 지정합니다. 다음 세 개의 매개 변수는 세 개의 서로 다른 유효한 정수의 주소여야 합니다. bits_per_pixel은 픽셀 색상을 나타내는 데 필요한 비트 수(이미지의 깊이라고도 함)로 채워집니다.
size_line은 이미지의 한 줄을 메모리에 저장하는 데 사용되는 바이트 수입니다. 이 정보는 이미지에서 한 줄에서 다른 줄로 이동하는 데 필요합니다. endian은 이미지의 픽셀 색상을 little endian(endian == 0) 또는 big endian(endian == 1)으로 저장해야 하는지 알려줍니다.
(size_line 은 bits_per_pixel 값이 32 인 시스템에서 image 에 설정된 x값의 4배가 나온다.
리틀 엔디안(Little Endian)은 가장 낮은 바이트가 가장 낮은 주소에 저장된다.
빅 엔디안(Big Endian)은 가장 높은 바이트가 가장 낮은 주소에 저장된다. endian 은 컴퓨터 시스템의 호환성을 위해 확인하는 것으로 호환까지 생각하지 않는다면 활용 부분이 없을 것으로 보인다)
mlx_get_data_addr returns a char * address that represents the begining of the memory area
where the image is stored. From this adress, the first bits_per_pixel bits represent the color
of the first pixel in the first line of the image. The second group of bits_per_pixel bits
represent the second pixel of the first line, and so on. Add size_line to the adress to get
the begining of the second line. You can reach any pixels of the image that way.
-mlx_get_data_addr은 이미지가 저장된 메모리 영역의 시작을 나타내는 char * 주소를 반환합니다. 이 주소에서 첫 번째 bits_per_pixel 비트는 이미지의 첫 번째 줄에 있는 첫 번째 픽셀의 색상을 나타냅니다. bits_per_pixel 비트의 두 번째 그룹은 첫 번째 줄의 두 번째 픽셀을 나타냅니다. 두 번째 줄의 시작을 얻으려면 size_line을 주소에 추가하십시오. 그런 식으로 이미지의 모든 픽셀에 도달할 수 있습니다.
mlx_destroy_image destroys the given image ( img_ptr ).
mlx_destroy_image가 지정된 이미지를 제거합니다(img_ptr).
STORING COLOR INSIDE IMAGES
Depending on the display, the number of bits used to store a pixel color can change. The user
usually represents a color in RGB mode, using one byte for each component (see mlx_pixel_put
manual). This must be translated to fit the bits_per_pixel requirement of the image, and make
the color understandable to the X-Server. That is the purpose of the mlx_get_color_value ()
function. It takes a standard RGB color parameter, and returns an unsigned int value. The
bits_per_pixel least significant bits of this value can be stored in the image.
- 디스플레이에 따라 픽셀 색상을 저장하는 데 사용되는 비트 수가 변경될 수 있습니다. 사용자는 일반적으로 각 구성 요소에 대해 하나의 바이트를 사용하여 RGB 모드에서 색상을 나타냅니다(mlx_pixel_put 매뉴얼 참조). 이것은 이미지의 bits_per_pixel 요구 사항에 맞게 변환해야 하며, 색상을 X-Server가 이해할 수 있도록 해야 합니다. 이것이 mlx_get_color_value() 함수의 목적입니다. 표준 RGB 색상 매개 변수가 필요하며, 부호가 없는 int 값을 반환합니다. 이 값의 bits_pixel당 비트 수는 이미지에 저장될 수 있습니다.
Keep in mind that the least significant bits position depends on the local computer's endian.
If the endian of the image (in fact the endian of the X-Server's computer) differs from the
local endian, then the value should be transformed before being used.
- 최소 비트 위치는 로컬 컴퓨터의 endian에 따라 달라집니다.
이미지의 endian(사실 X-Server 컴퓨터의 endian)이 로컬 endian과 다른 경우 값을 변환한 후 사용해야 합니다.
XPM IMAGES
The mlx_xpm_to_image () and mlx_xpm_file_to_image () functions will create a new image the
same way. They will fill it using the specified xpm_data or filename , depending on which
function is used. Note that MiniLibX does not use the standard Xpm library to deal with xpm
images. You may not be able to read all types of xpm images. It however handles transparency.
mlx_xpm_to_image()와 mlx_xpm_file_to_image() 함수는 동일한 방식으로 새 이미지를 만듭니다. 어떤 함수가 사용되는지에 따라 지정된 xpm_data 또는 파일 이름을 사용하여 이미지를 채웁니다. MiniLibX는 xpm 이미지를 처리하기 위해 표준 Xpm 라이브러리를 사용하지 않습니다. 모든 유형의 xpm 이미지를 읽을 수는 없습니다. 그러나 투명성을 처리합니다.
RETURN VALUES
The three functions that create images, mlx_new_image() , mlx_xpm_to_image() and
mlx_xpm_file_to_image() , will return NULL if an error occurs. Otherwise they return a non-
null pointer as an image identifier.
mlx_new_image(), mlx_xpm_to_image() 및 mlx_xpm_file_to_image()의 이미지를 생성하는 세 함수는 오류가 발생하면 NULL을 반환합니다. 그렇지 않으면 NULL이 아닌 포인터를 이미지 식별자로 반환합니다.
[mlx_loop.3]
NAME
MiniLibX - Handle events
SYNOPSYS
int
mlx_loop ( void *mlx_ptr );
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 );
int
mlx_loop_hook ( void *mlx_ptr, int (*funct_ptr)(), void *param );
X-WINDOW EVENTS
The X-Window system is bi-directionnal. On one hand, the program sends orders to the screen to
display pixels, images, and so on. On the other hand, it can get information from the keyboard
and mouse associated to the screen. To do so, the program receives "events" from the keyboard
or the mouse.
- X-Windows 시스템은 양방향입니다.
한편으론, 프로그램은 픽셀, 이미지 등을 표시하라는 명령을 화면에 보냅니다.
다른 한편으론, 화면과 연관된 키보드와 마우스로부터 정보를 얻을 수 있습니다. 그렇게 하기 위해, 프로그램은 키보드나 마우스로부터 "Event"를 받습니다.
(위의 mlx.3 의 X-WINDOW CONCEPT의 설명과 동일)
DESCRIPTION
To receive events, you must use mlx_loop (). This function never returns. It is an infinite
loop that waits for an event, and then calls a user-defined function associated with this
event. A single parameter is needed, the connection identifier mlx_ptr (see the mlx manual).
- Event 를 받으려면 mlx_loop()을 사용해야 합니다. 이 함수는 결코 반환되지 않습니다.
Event 를 기다린 다음 이 Event 와 관련된 사용자 정의 함수를 호출하는 무한 루프입니다.
단일 매개 변수인 연결 식별자 mlx_ptr(mlx 매뉴얼 참조)이 필요합니다.
(mlx_loop() 를 실행하면 무한 루프가 시작되면서, 별도로 루프 종료 기능이 세팅된 기능을 입력하거나, 강제 종료 또는 에러가 발생하지 않는 이상 루프는 계속 돌아가고, 루프가 돌아가는 동안 키를 입력하거나 함수를 호출할 수 있다. linux 의 here_doc 기능과 유사하게 작동)
You can assign different functions to the three following events:
- A key is pressed
- The mouse button is pressed
- A part of the window should be re-drawn (this is called an "expose" event, and it is your
program's job to handle it).
Each window can define a different function for the same event.
- 다음 세 가지 이벤트에 서로 다른 기능을 할당할 수 있습니다:
- 키를 누릅니다
- 마우스 버튼을 눌렀습니다
- window의 일부를 다시 그려야 합니다(이것을 "노출" Event 라고 하며, 이를 처리하는 것이 프로그램의 일입니다).
- 각 창은 동일한 이벤트에 대해 다른 기능을 정의할 수 있습니다.
(키 입력시 해당 키에 원하는 기능을 부여 가능, 마우스 클릭시 원하는 기능 부여 가능, window 에 다시 그리는 기능을 구현 가능하다)
The three functions mlx_key_hook (), mlx_mouse_hook () and mlx_expose_hook () work exactly the
same way. funct_ptr is a pointer to the function you want to be called when an event occurs.
This assignment is specific to the window defined by the win_ptr identifier. The param adress
will be passed to the function everytime it is called, and should be used to store the parame‐
ters it might need.
- mlx_key_hook(), mlx_mouse_hook(), mlx_exposure_hook() 세 함수는 정확히 같은 방식으로 작동합니다.
funct_ptr은 Event 가 발생했을 때 호출하려는 함수를 가리키는 포인터입니다(핸들러 함수).
이 할당은 win_ptr 식별자에 의해 정의된 창에만 적용됩니다. 매개 변수 주소는 호출될 때마다 함수에 전달되며, 함수가 필요할 수 있는 매개 변수를 저장하는 데 사용되어야 합니다.
(mlx_key_hook(), mlx_mouse_hook(), mlx_exposure_hook() 세 함수 사용 방식(Event 가 발생하면 작동을 한다)이 동일하고, funct_ptr 은 세 함수를 통해 실행하고자 하는 함수의 주소(함수 포인터)이며, 세 함수는 win_prt 식별자에 할당된 내용을 통해서 사용이 가능하다)
The syntax for the mlx_loop_hook () function is identical to the previous ones, but the given
function will be called when no event occurs.
- mlx_loop_hook() 함수의 구문은 이전 함수와 동일하지만 Event 가 발생하지 않을 때 지정된 함수가 호출됩니다.
(mlx_loop_hook() 함수는 mlx_key_hook(), mlx_mouse_hook(), mlx_exposure_hook() 함수들과 같은 구문으로 이뤄져있지만, 세 함수와는 다르게 Event 가 발생하지 않았을 때의 동작을 작동 시키를 함수이다)
When it catches an event, the MiniLibX calls the corresponding function with fixed parameters:
- 이벤트를 포착하면 MiniLibX는 고정된 매개 변수를 사용하여 해당 함수를 호출합니다:
expose_hook(void *param);
key_hook(int keycode,void *param);
mouse_hook(int button,int x,int y,void *param);
loop_hook(void *param);
These function names are arbitrary. They here are used to distinguish parameters according to
the event. These functions are NOT part of the MiniLibX.
- 이 함수들의 이름은 임의적입니다. 여기서는 Event 에 따라 매개 변수를 구별하는 데 사용됩니다. 이러한 함수들은 MiniLibX의 일부가 아닙니다.
(위에 나열된 함수들은 hook 계열 함수들을 어떻게 사용할지에 대해 예시로 작성된거라 MiniLibX 에는 존재하지 않는 함수로 사용자가 작성한 함수이다.
만약 mlx_key_hook() 를 사용하고 싶을 때, (*funct_ptr)() 파라미터의 인자로 위의 예시 함수 중 key_hook( ) 함수를 전달하면된다
mlx_key_hook(void *win_ptr, key_hook, NULL) 처럼 호출하면된다. 그럼 key_hook 에 설정된 파라미터 int keycode 를 MiniLibX가 찾아서 전달해주고, *param 에는 전달 받은 NULL 을 입력해준다
즉,_hook 계열의 함수들은 사용자가 구현하고자 하는 기능(어떤 키를 눌렀을 때 어떻게 작동하고싶은지, 마우스를 클릭했을 때 어떤 동작을 구현하고 싶은지)을 작성한 함수들을 MiniLibX 에 설정된 내용 안에서 구현 가능하게 해주는 함수이다.
그러면 사용자 함수를 직접 호출하지 않고 hook 계열 함수를 통해서 호출하게 되는데 인자를 어떻게 던져줄 수 있는가? 에 대해 생각해봐야 되는데 그 부분은 hook 계열 함수들의 (*funct_ptr)() 인자(or 파라미터) 이후로 기입되는 인자들은 사용자 함수의 인자들로 매칭시켜서 전달하기 때문에 사용자 함수에 작성된 인자들을 그대로 적어주면 된다.
예를 들어 key_hook() 함수의 파라미터로 (int keycode, void *param, int num, char *str) 라고 작성 했을 때, mlx_key_hook() 함수에도 똑같이 mlx_key_hook(void *win_ptr, key_hook, NULL, num, str) 이렇게 작성해주면 된다)
param is the address specified in the mlx_*_hook calls. This address is never used nor modi‐
fied by the MiniLibX. On key and mouse events, additional information is passed: keycode tells
you which key is pressed (look for the X11 include file "keysymdef.h"), ( x , y ) are the co‐
ordinates of the mouse click in the window, and button tells you which mouse button was
pressed.
- param은 mlx_*_hook 호출에 지정된 주소입니다. 이 주소는 MiniLibX에 의해 사용되거나 수정되지 않습니다. 키와 마우스 이벤트에서 추가 정보가 전달됩니다. 키코드는 어떤 키가 눌러졌는지 알려줍니다(X11의 "keysymdef.h" 찾아보세요), (x, y)는 창에서 마우스 클릭의 좌표이며, 버튼은 어떤 마우스 버튼이 눌러졌는지 알려줍니다.
(위에서 설명했듯이 hook 계열의 함수들은 키와 마우스가 입력되면, 입력된 내용을 바탕으로 값을 찾아서 사용자 함수의 파라미터에 전달하고, void *pram 에는 사용자가 원하는 내용(문자열, 또는 배열, 또는 MiniLibX 에서 사용되는 win_prt 이나 mlx_ptr 등)을 수정하거나 조작하지 않고 그대로 사용자 함수에 전달해준다) 값이나 변수 설정을 하고 싶을 때는 usr/include/X11/keysymdef.h 를 찾아서 활용하면 된다. 이 내용을 토대로하면 위의 사용자 함수 중 mouse_hook() 에 설정된 x, y 값은 물론 마우스의 버튼값 까지 MiniLibX 가 전달해준다는 것이다)
GOING FURTHER WITH EVENTS
The MiniLibX provides a much generic access to all X-Window events. The mlx.h include define
mlx_hook() in the same manner mlx_*_hook functions work. The event and mask values will be
taken from the X11 include file "X.h".
- MiniLibX는 모든 X-Window Event 에 대한 훨씬 일반적인 액세스를 제공합니다. mlx.h 에는 mlx_*_hook 함수가 작동하는 것과 동일한 방식으로 mlx_hook()을 정의합니다. Event 및 마스크 값은 X11 의 X.h 파일에서 가져옵니다.
(X.h 는 usr/include/X11/X.h 경로에 있다)
See source code of mlx_int_param_event.c to find out how the MiniLibX will call your own func‐
tion for a specific event.
- mlx_int_param_event.c의 소스 코드를 참조하여 특정 이벤트에 대해 MiniLibX가 자신의 함수를 호출하는 방법을 확인하십시오
입력 샘플
(입력 되어있는 숫자들은 z 값으로 나중에 높이 표현시 필요, 우선 18 x 11 에 맞춰서 사각형 모양의 픽셀을 찍어서 표현해보고자 한다.)
#include "fdf.h"
#include <fcntl.h>
typedef struct s_data
{
void *img;
char *addr;
int bits_per_pixl;
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_pixl / 8));
*(unsigned *)dst = color;
}
int key_win1(int key, void *mlx_ptr)
{
if (key == 0xFF1B)
mlx_loop_end(mlx_ptr);
return (1);
}
int main(int argc, char **argv)
{
void *mlx_ptr;
void *win_ptr;
t_data img;
t_info *pos;
t_info *tmp;
if (argc <= 1)
return (0);
pos = create_coordinates(open(argv[1], O_RDONLY)); //좌표 설정 코드
mlx_ptr = mlx_init();
win_ptr = mlx_new_window(mlx_ptr, 1000, 1000, argv[1]);
img.img = mlx_new_image(mlx_ptr, 1000, 1000);
img.addr = mlx_get_data_addr(img.img, &img.bits_per_pixl, &img.line_length, &img.endian);
//img.line_length = x * 4 (img.bits_per_pixl == 32 기준)
mlx_pixel_put(mlx_ptr, win_ptr, 0, 0, 0xff0000);
my_mlx_pixel_put(&img, 0, 0, 0xffffff);
tmp = pos;
while (tmp != NULL)
{
printf("xyzc = %d %d %d %d\n", tmp->x, tmp->y, tmp->z, tmp->clr);
// mlx_get_color_value(mlx_ptr, tmp->clr);
// mlx_pixel_put(mlx_ptr, win_ptr, (tmp->x + 10) * 30, (tmp->y + 10) * 30, tmp->clr);
my_mlx_pixel_put(&img, tmp->x, tmp->y, tmp->clr);
mlx_put_image_to_window(mlx_ptr, win_ptr, img.img, tmp->x * 30, tmp->y * 30);
tmp = tmp->next;
}
mlx_key_hook(win_ptr, key_win1, mlx_ptr);
mlx_loop(mlx_ptr);
mlx_destroy_image(mlx_ptr, img.img);
mlx_destroy_window(mlx_ptr, win_ptr);
mlx_destroy_display(mlx_ptr);
free(mlx_ptr);
return (0);
}
결과물
#include "fdf.h"
#include <fcntl.h>
typedef struct s_data
{
void *img;
char *addr;
int bits_per_pixl;
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_pixl / 8));
*(unsigned *)dst = color;
}
int key_win1(int key, void *mlx_ptr)
{
if (key == 0xFF1B)
mlx_loop_end(mlx_ptr);
return (1);
}
int main(int argc, char **argv)
{
void *mlx_ptr;
void *win_ptr;
t_data img;
t_info *pos;
t_info *tmp;
if (argc <= 1)
return (0);
pos = create_coordinates(open(argv[1], O_RDONLY)); //좌표 설정 코드
mlx_ptr = mlx_init();
win_ptr = mlx_new_window(mlx_ptr, 1000, 1000, argv[1]);
img.img = mlx_new_image(mlx_ptr, 1000, 1000);
img.addr = mlx_get_data_addr(img.img, &img.bits_per_pixl, &img.line_length, &img.endian);
//img.line_length = x * 4 (img.bits_per_pixl == 32 기준)
mlx_pixel_put(mlx_ptr, win_ptr, 0, 0, 0xff0000);
my_mlx_pixel_put(&img, 0, 0, 0xffffff);
tmp = pos;
while (tmp != NULL)
{
// mlx_get_color_value(mlx_ptr, tmp->clr);
mlx_pixel_put(mlx_ptr, win_ptr, (tmp->x) * 20, (tmp->y) * 20, tmp->clr);
// my_mlx_pixel_put(&img, tmp->x, tmp->y, tmp->clr);
mlx_put_image_to_window(mlx_ptr, win_ptr, img.img, tmp->x * 30, tmp->y * 30);
tmp = tmp->next;
}
// mlx_pixel_put(mlx_ptr, win_ptr, 250, 250, 0xFFFFFF);
mlx_key_hook(win_ptr, key_win1, mlx_ptr);
mlx_loop(mlx_ptr);
mlx_destroy_image(mlx_ptr, img.img);
mlx_destroy_window(mlx_ptr, win_ptr);
mlx_destroy_display(mlx_ptr);
free(mlx_ptr);
return (0);
}
결과물
#include "fdf.h"
#include <fcntl.h>
typedef struct s_data
{
void *img;
char *addr;
int bits_per_pixl;
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_pixl / 8));
*(unsigned *)dst = color;
}
int key_win1(int key, void *mlx_ptr)
{
if (key == 0xFF1B)
mlx_loop_end(mlx_ptr);
return (1);
}
int main(int argc, char **argv)
{
void *mlx_ptr;
void *win_ptr;
t_data img;
t_info *pos;
t_info *tmp;
if (argc <= 1)
return (0);
pos = create_coordinates(open(argv[1], O_RDONLY)); //좌표 설정 코드
mlx_ptr = mlx_init();
win_ptr = mlx_new_window(mlx_ptr, 1000, 1000, argv[1]);
img.img = mlx_new_image(mlx_ptr, 1000, 1000);
img.addr = mlx_get_data_addr(img.img, &img.bits_per_pixl, &img.line_length, &img.endian);
//img.line_length = x * 4 (img.bits_per_pixl == 32 기준)
mlx_pixel_put(mlx_ptr, win_ptr, 0, 0, 0xff0000);
my_mlx_pixel_put(&img, 0, 0, 0xffffff);
tmp = pos;
while (tmp != NULL)
{
// mlx_get_color_value(mlx_ptr, tmp->clr);
mlx_pixel_put(mlx_ptr, win_ptr, (tmp->x) * 20, (tmp->y) * 20, tmp->clr);
// my_mlx_pixel_put(&img, tmp->x, tmp->y, tmp->clr);
// mlx_put_image_to_window(mlx_ptr, win_ptr, img.img, tmp->x * 30, tmp->y * 30);
tmp = tmp->next;
}
// mlx_pixel_put(mlx_ptr, win_ptr, 250, 250, 0xFFFFFF);
mlx_key_hook(win_ptr, key_win1, mlx_ptr);
mlx_loop(mlx_ptr);
mlx_destroy_image(mlx_ptr, img.img);
mlx_destroy_window(mlx_ptr, win_ptr);
mlx_destroy_display(mlx_ptr);
free(mlx_ptr);
return (0);
}
결과물
좌표를 조금 이동시켜보자
#include "fdf.h"
#include <fcntl.h>
typedef struct s_data
{
void *img;
char *addr;
int bits_per_pixl;
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_pixl / 8));
*(unsigned *)dst = color;
}
int key_win1(int key, void *mlx_ptr)
{
if (key == 0xFF1B)
mlx_loop_end(mlx_ptr);
return (1);
}
int main(int argc, char **argv)
{
void *mlx_ptr;
void *win_ptr;
t_data img;
t_info *pos;
t_info *tmp;
if (argc <= 1)
return (0);
pos = create_coordinates(open(argv[1], O_RDONLY)); //좌표 설정 코드
mlx_ptr = mlx_init();
win_ptr = mlx_new_window(mlx_ptr, 1000, 1000, argv[1]);
img.img = mlx_new_image(mlx_ptr, 1000, 1000);
img.addr = mlx_get_data_addr(img.img, &img.bits_per_pixl, &img.line_length, &img.endian);
//img.line_length = x * 4 (img.bits_per_pixl == 32 기준)
mlx_pixel_put(mlx_ptr, win_ptr, 0, 0, 0xff0000);
my_mlx_pixel_put(&img, 0, 0, 0xffffff);
tmp = pos;
while (tmp != NULL)
{
// mlx_get_color_value(mlx_ptr, tmp->clr);
mlx_pixel_put(mlx_ptr, win_ptr, (tmp->x + 20) * 20, (tmp->y + 20) * 20, tmp->clr);
// 기본 좌표에 20 추가
// my_mlx_pixel_put(&img, tmp->x, tmp->y, tmp->clr);
// mlx_put_image_to_window(mlx_ptr, win_ptr, img.img, tmp->x * 30, tmp->y * 30);
tmp = tmp->next;
}
// mlx_pixel_put(mlx_ptr, win_ptr, 250, 250, 0xFFFFFF);
mlx_key_hook(win_ptr, key_win1, mlx_ptr);
mlx_loop(mlx_ptr);
mlx_destroy_image(mlx_ptr, img.img);
mlx_destroy_window(mlx_ptr, win_ptr);
mlx_destroy_display(mlx_ptr);
free(mlx_ptr);
return (0);
}
결과물
솔직히 이것저것 만져보면서 성공한지라 각 뭐 때문에 실패했고, 각 함수들이 어떻게 반영되는지에 대해선 구체적으로 알아낸 바는 없다. 시간만 여유롭다면 더 파고 싶지만 그렇지 못한 관계로 다음을 이어가고자 한다.
현재 위의 구현방식은 window 에만 그려진 것일 뿐 생성된 image 에는 그려지지 않았다
window 자체에 그리는 것과 image 에 그리는 것은 다른 경우이고, 하단의 예시가 image 가 아닌 window 에 그린 경우이다
뭐가 다른걸까? 싶다면 하단의 이미지를 보면된다. window를 1000 x 1000 사이즈로 설정하고, image 를 100 x 100 사이즈로 설정했을 때, window 에만 그림을 그렸다면 다음과 같은 이미지가 나온다 (캡쳐본을 놓쳐서 같은 상황의 이미지로 대체합니다.)
보시다시피 window 에 그려진 픽셀 위에 100 x 100 사이즈 만큼의 왼쪽 상단에 image가 아무것도 안그려진 채로 겹쳐서 검은 사각형이 존재하는 것을 확인할 수 있다.
추가로 window 자체에 그리는 것과 image 에 그리는 것은 그림(?)이 완성됐을 때 실행을 해보면
window 에만 그렸을 시에는 애니메이션처럼 픽셀이 실시간으로 그려지게 된다(입력된 픽셀을 실시간으로 적용시켜서 보여줌)
image 에 그렸다는 것은 image 에 픽셀을 그린 후, 그려진 image 를 window 에 띄우는 것이기 때문에, 그림이 한 번에 띄워지는 것을 볼 수 있다.
(물론 이 차이도 어느 정도 조율하면 해결할 수 있지 않을까 싶은데, 시간이 여유롭지 않은 관계로 따로 테스트해보진 않았다)
픽셀의 주소에 컬러값을 넣을 수 있겠끔 함수를 작성해주고 mlx_put_window_to_image() 함수를 실행하면 다음과 같이 image에 픽셀을 그려넣을 수 있다.
#include "fdf.h"
#include <fcntl.h>
typedef struct s_data
{
void *img;
char *addr;
int bits_per_pixl;
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_pixl / 8));
*(unsigned *)dst = color;
}
int key_win1(int key, void *mlx_ptr)
{
if (key == 0xFF1B)
mlx_loop_end(mlx_ptr);
return (1);
}
int main(int argc, char **argv)
{
void *mlx_ptr;
void *win_ptr;
t_data img;
p_list *list;
t_info *tmp;
if (argc <= 1)
return (0);
list = create_coordinates(open(argv[1], O_RDONLY));
mlx_ptr = mlx_init();
win_ptr = mlx_new_window(mlx_ptr, 1000, 1000, argv[1]);
img.img = mlx_new_image(mlx_ptr, 1000, 1000);
img.addr = mlx_get_data_addr(img.img, &img.bits_per_pixl, &img.line_length, &img.endian);
tmp = list->head;
while (tmp != NULL)
{
printf("xyzc = %d %d %d %d\n", tmp->x, tmp->y, tmp->z, tmp->clr);
my_mlx_pixel_put(mlx_ptr, win_ptr, (tmp->x + 20) * 20, (tmp->y + 20) * 20, tmp->clr);
tmp = tmp->next;
}
printf("cnt = %d\n", cnt);
mlx_put_image_to_window(mlx_ptr, win_ptr, img.img, 0, 0);
mlx_key_hook(win_ptr, key_win1, mlx_ptr);
mlx_loop(mlx_ptr);
mlx_destroy_image(mlx_ptr, img.img);
mlx_destroy_window(mlx_ptr, win_ptr);
mlx_destroy_display(mlx_ptr);
free(mlx_ptr);
free_list(list->head);
free(list);
return (0);
}
최종적으로 image 에다 그린 결과물이다.
(사진은 image 크기를 window 크기와 같게 했기 때문에 달라진게 없어 보이지만, image 크기를 줄여본다면 비교가 가능 할 것으로 보인다.)