miniRT(0) 따라잡기

YP J·2022년 7월 20일
0

miniRT

목록 보기
2/3

mlx 활용과 color 표현 하는 방법

화면에 색 표현하기 mlx 활용!

Minilibx 소개!

X-Window?

  • 유닉스용 네트워크 지향 그래픽 시스템이다.
  • 원격 데스크톰에 연결할 때 사용된다.
  • 이러한 구현의 가장 일반적인 것은 TeamViewer.

MacOS

  • MacOS는 화면에 대한 그래픽액세스를 처리하지만 이에 액세스를 하려면, 윈도우 시스템, 키보드 및 마우스를 처리하는 기본 MacOS 그래픽 프레임 워크에 애플리케이션을 등록해야한다.

화면을 띄워보자

만약 makefile을 만들고 컴파일을 진행했는데 libmlx.dylib파일을 찾을 수 없다고 나온다면 위 예시파일처럼 아래 명령어를 추가해보자! 실행파일에 연결될 라이브러리의 디렉토리설정을 다시 해준다.

install_name_tool -change libmlx.dylib mlx/libmlx.dylib $(NAME)

1) mlx 초기화 하기

  • mlx_init함수를 활용해서 포인터를 초기화 할 수 있다.
#include <mlx.h>

int main(void)
{
	void *mlx_ptr;

	mlx_ptr = mlx_init();
	return (0);
}
  • 이제 mlx_ptr 은 mlx_init() 함수가 리턴하는 주소를 가리키게 된다.
  • mlx_init() 함수는 디스플레이와 우리의 프로그램을 연결시켜주는 초기화함수이다.

2) 창 생성하기

#include <mlx.h>

int main(void)
{
	void *mlx_ptr;
	void *win_ptr; // 생성할 윈도우를 가리키는 포인터

	mlx_ptr = mlx_init();
	win_ptr = mlx_new_window(mlx_ptr,500,500, "Halo alo!");
	mlx_loop(mlx_ptr); // loop 을 돌면서 event를 기다리고 ,생성한윈도ㄹ우를 Rendering한다.

	return (0);
}
// 창을 생성하는 함수
void mlx_new_window(void mlx_ptr, int size_x, int size_y, char *title)
  • mlx_ptr : mlx_init이 반환한 연결 식별자

  • size_x : 창의 가로 사이즈

  • size_y : 창의 세로 사이즈

  • title : 타이틀 바에 표시될 문자열

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

  • 이 함수는 창을 생성하는 것 까지만 작동하고 실제로 모니터 상에 창을 띄우진 않는다

  • mlx_loop 함수를 주석 처리 해보면 아무것도 보이지 않는것을 알수있다.

// 이벤트를 받는 함수의 prototype
int mlx_loop(void *mlx_ptr)
  • mlx_ptr : 디스플레이에 연결 되어 있는 mlx_ptr

  • return value : no return

  • 이벤트를 받기 위해서 꼭 사용 해야한다고 나와있지만,

  • 실제로 이 함수를 사용하지 않으면 윈도우 자체가 뜨지 않는다.

3) 창에 이미지 넣기!

#include <mlx.h>
#include <unistd.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)
{
	void *mlx_ptr;
	void *win_ptr; // 생성할 윈도우를 가리키는 포인터
	t_data image;

	mlx_ptr = mlx_init();
	win_ptr = mlx_new_window(mlx_ptr,500,500, "Halo alo!");

	//이미지 객체 생성
	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);
			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); // loop 을 돌면서 event를 기다리고 ,생성한윈도ㄹ우를 Rendering한다.
	return (0);
}
  • 주석은 창에 픽셀을 하나하나 찍고 출력 하는것(mlx_pixel_put()을 활용해서)

  • 현재는 이미지를 생성해서 이미지를 화면에 올리는방법 (my_pixel_put())

    • my_new_image()는 메모리에 새 이미지를 만든다.
    • 즉, 우리가 지정한 가로 세로 만큼의 그림을 보이지 않는 공간에 미리 그려두는것.
    • 이후 이 이미지를 mlx_put_image_to_window() 함수를 활용 해서 생성한 윈도우에 올리는것 !
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;
}
  • y좌표에 line_length를 곱해서 원하는 y좌표가 있는 주소까지 점프시킨다.
  • 이제 x좌표 만큼만 이동하면 된다.
  • x에 곱해주는 (data->bits_per_pixel / 8)은 픽셀에 들어있는 비트수를 8로 나눈 값을 곱하게 된다!
  • 우리는 픽셀당 32개의 bit가 들어있기 때문에 x \times 4x×4 가 되는 것이다.(주소는 byte단위로 이동하기 때문에!!)
  • 우리는 그 위치에 우리가 매개변수로 넘겨준 color값을 넣어주면 끝이다!
  • 나중에 프로그램이 해당 메모리를 읽으면서 좌표마다 32비트의 color값을 읽게 되고 우리가 띄운 디스플레이 상의 윈도우 x, y좌표에 해당하는 color를 표현하게 된다!

4) esc 누르면 꺼지는 윈도우 만들기

  • return은 함수를 종료하는 키워드입니다. 어떤 함수에서든 return 키워드를 사용하면 해당 함수를 종료하고, 함수를 호출한 곳으로 jump하게 됩니다.
  • 그런데 main() 함수에서 return 키워드를 사용하면 어디로 가죠? main() 함수는 어떤 함수에서 호출한 것이 아니라, 프로그램이 실행되면서 처음 실행되는 함수입니다.
  • 그래서 main() 함수에서 return을 하면 프로그램을 종료하게 됩니다.
  • 반면 exit() 함수는 프로그램을 종료하는 함수입니다. 이 함수를 호출하면, 호출한 위치에 관계없이 프로그램이 종료됩니다.
  • 정리하면, main 함수 내에서는 return이나 exit가 같은 기능을 합니다.
  • 하지만 main 함수가 아닌 다른 함수 내에서는 완전히 다르게(return: 함수 종료, exit(): 프로그램 종료) 동작합니다.

Hooking

  • 컴퓨터 프로그래밍에서 Hooking이라는 용어는 소프트웨어 구성 요소간에 전달되는 함수 호출이나 메시지 또는 이벤트를 가로 채서
  • 운영 체제, 응용 프로그램 또는 기타 소프트웨어 구성 요소의 동작을 변경하거나 강화하는 데 사용되는 다양한 기술을 포함한다.
  • 이러한 가로채는 함수 호출, 이벤트 또는 메시지를 처리하는 코드를 Hook라고한다.
// hooking을 도와주는 함수들
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_hook(void *win_ptr, int x_event, int x_mask, int (*funct)(), void *param);
  • win_ptr : 적용할 윈도우
  • (*funct_ptr)() : 호출하고 싶은 함수 포인터
  • *param : 필요한 매개변수를 저장하는데 사용
profile
be pro

0개의 댓글