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

이상헌·2020년 9월 23일
0


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개의 댓글