[miniRT] 핵심개념 - MiniLibX, mlx.h

sham·2022년 5월 20일
0

[miniRT]

목록 보기
14/19

개요

MiniLibX와 “mlx.h”는 같은 말로, 스크린에 무언가를 렌더링 할 수 있게 해주는 작은 그래픽 라이브러리다.

"mlx.h"에서 제공하는 기능들은 내부적으로 Mac OS X의 OpenGL과 AppKit을 이용하기 때문에 실행파일로 링킹하는 단에서 OpenGL과 AppKit을 프레임워크로써 이용하겠다고 명시해야 한다.

  • OpenGL : 오픈 그래픽 라이브러리은 1992년 실리콘 그래픽스사에서 만든 2차원 및 3차원 그래픽스 표준 API 규격으로, 프로그래밍 언어 간 플랫폼 간의 교차 응용 프로그래밍을 지원한다.
  • AppKit : 일반적으로 AppKit이라고 하는 Application Kit는 NeXTSTEP의 그래픽 사용자 인터페이스 툴킷 으로, Foundation 및 Display PostScript 와 함께 OpenStep API 사양의 핵심 부분 중 하나다.

컴파일 방법

목적 파일

  • 컴파일하려면 일련의 처리가 필요하다.
    • 설정되어 있는 헤더 디렉토리에서 자동으로 찾는 방법.
      • gcc -lmlx -framework OpenGl -framework AppKit ...
    • 라이브러리의 경로를 직접 지정하는 방법.
      • cc -L /(라이브러리 경로) -lmlx -framework OpenGL -framework AppKit ...
      • 만약 해당 경로에 라이브러리가 존재하지 않는다면 내장 라이브러리에서 찾는다.
      • 실제 라이브러리 파일이 존재해야 한다! 위의 명령만으로는 Makefile을 실행하지 않는다!

실행 파일

  • 링킹하려면 일련의 처리가 필요하다.
    • 설정되어 있는 lib 디렉토리에서 내장 라이브러리를 찾는 방법.
      • gcc -lmlx -framework OpenGl -framework AppKit ...
    • 라이브러리의 경로를 직접 지정하는 방법.
      • cc -L /(라이브러리 경로) -lmlx -framework OpenGL -framework AppKit ...
      • 만약 해당 경로에 라이브러리가 존재하지 않는다면 내장 라이브러리에서 찾는다.
      • 실제 라이브러리 파일이 존재해야 한다! 위의 명령만으로는 Makefile을 실행하지 않는다!

예제

mlx_init - 초기화

#include <mlx.h>

int main(void)
{
	void *mlx_ptr;

	mlx_ptr = mlx_init();
	return (0);
}

mlx.h 파일에 선언되어 있는 mlx_init함수를 활용해서 포인터를 초기화할 수 있는데, mlx_ptr은 mlx_init()함수가 리턴하는 mlx 구조체의 주소를 가리키게 된다.

mlx_new_window - 화면 띄우기

#include <mlx.h>

int main()
{
	void	*mlx_ptr;
	void	*win_ptr; // 생성할 윈도우를 가리키는 포인터
	
	mlx_ptr = mlx_init();	
	win_ptr = mlx_new_window(mlx_ptr, 500, 500, "Hellow World!"); 
	mlx_loop(mlx_ptr); // loop를 돌면서 event를 기다리고, 생성한 윈도우를 Rendering한다. 
	return (0);
}

화면에 빈 모니터를 띄울 수 있다.

data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==

만약 초기화 하지 않은 mlx_ptr이 mlx_new_window함수로 전달된다면 segfault를 발생한다.

이 함수는 창을 생성하는 것 까지만 작동하고 실제로 모니터상에 창을 띄우진 않는다. mlx_loop 함수를 주석처리해보면 실행파일을 실행했을 때, 아무것도 보이지 않는 것을 알 수 있다.

mlx_loop에 mlx 포인터를 집어넣지 않으면 창이 떠오르지 않는다. mlx_loop는 loop를 돌면서 이벤트를 기다리는 동시에 화면을 모니터 상에 띄우는 작업을 한다.

mlx_pixel_put - 모니터에 픽셀 찍기

#include <unistd.h>
#include <mlx.h>

int main(
{
	void	*mlx_ptr;
	void	*win_ptr;
	t_data	image;

	mlx_ptr = mlx_init();
	win_ptr = mlx_new_window(mlx_ptr, 500, 500, "Hellow World!");
	image.img = mlx_new_image(mlx_ptr, 500, 500); // 이미지 객체 생성
	image.addr = mlx_get_data_addr(image.img, &image.bits_per_pixel, &image.line_length, &image.endian); // 이미지 주소 할당
	for (int i = 0 ; i < 500; i++)
	{
		for (int j = 0 ; j < 500; j++)
		{
			mlx_pixel_put(mlx_ptr, win_ptr, i, j, 0x00FFFFFF);
		}
	}
	mlx_loop(mlx_ptr);
	return (0);
}

mlx_pixel_put는 i, j에 해당하는 한 픽셀을 색칠하는 함수다.

mlx_new_image, mlx_get_data_addr - 이미지 생성, 색칠하기

#include <unistd.h>
#include <mlx.h>

//이미지의 정보를 나타내는 변수를 저장한 구조체
typedef struct s_data
{
	void 	*img;
	char	*addr;
	int		bits_per_pixel;
	int		line_length;
	int		endian;
}		t_data;

//이미지의 원하는 좌표에 해당하는 주소에 color값을 넣는 함수
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_ptr;
	void	*win_ptr;
	t_data	image;

	mlx_ptr = mlx_init();
	win_ptr = mlx_new_window(mlx_ptr, 500, 500, "Hellow World!");
	image.img = mlx_new_image(mlx_ptr, 500, 500); // 이미지 객체 생성
	image.addr = mlx_get_data_addr(image.img, &image.bits_per_pixel, &image.line_length, &image.endian); // 이미지 주소 할당
	for (int i = 0 ; i < 500 ; i++)
	{
		for (int j = 0 ; j < 500 ; j++)
		{
			my_mlx_pixel_put(&image, i, j, 0x00FFFFFF);
		}	
	}
	mlx_put_image_to_window(mlx_ptr, win_ptr, image.img, 0, 0);
	mlx_loop(mlx_ptr);
	return (0);
}

image.addr에 mlx_new_image를 통해 할당받는 img 구조체의 포인터 img에 대한 정보를 리턴하는데, 이때 정보는 해당 이미지를 한 줄로 쭉 늘인 형태와 같은 char 배열이 된다. 해당 위치에 TRGB 값에 해당하는 색깔을 집어넣으면 이미지의 해당 좌표가 색칠되는 형식이다.

이미지

색상은 int형식으로 표현된다. 우리는 ARGB값을 포함하는 int를 얻으려면 몇가지 규칙이 필요하다.
우리는 TRGB 형식을 사용하기 위해 비트연산을 활용한다. 색상을 표현하기 위현 형식은 0xTTRRGGBB와 같이 초기화해서 사용한다. 각 코드는 다음을 의미한다.

  • T Transparency;
  • R Red color;
  • G Green color;
  • B Blue color.

RGB 는 위와같이 초기화 할 수 있고, 몇 가지 예시는 아래와 같다.

  • Red: 0x00FF0000;
  • Green: 0x0000FF00;
  • Blue: 0x000000FF;

16진수이므로 두개의 자릿수는 16 * 16, 256의 값을 나타낼 수가 있다.

data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==


레퍼런스

miniRT

"mlx.h"

[so_long] mlx(MiniLibX) 함수 정리

(1) mlx 활용과 color 표현 하는 방법!

profile
씨앗 개발자

0개의 댓글