그림 그리기 1 : 점 찍기
put_pixel을 이용해 하나하나 찍는 방법에 대해서 알아보자.
점을 이어보면 그림이 된다.
예시 코드
c
#include "fdf.h"
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->bpp / 8));
*(unsigned int*)dst = color;
}
int main(void)
{
void *mlx;
void *win;
t_data image;
mlx = mlx_init();
win = mlx_new_window(mlx, 1920, 1080, "hello world");
// 이미지 넣기 파트
image.img = mlx_new_image(mlx, 500, 500); // 이미지 객체 생성
image.addr = mlx_get_data_addr(image.img, &image.bpp, &image.line_length, \
&image.endian); // 이미지 주소 할당
for (int i = 0 ; i < 500 ; i++)
{
for (int j = 0 ; j < 500 ; j++)
mlx_pixel_put (mlx, win, i, j, 0x00FFFFFF);
}
// 이미지 넣기 파트
mlx_loop(mlx);
return (0);
}
다음 코드를 치고 실행시켜보자.
캔버스와 도화지
우리가 집중적으로 봐야할 코드는 여기이다.
c
image.img = mlx_new_image(mlx, 500, 500); // 이미지 객체 생성
image.addr = mlx_get_data_addr(image.img, &image.bpp, &image.line_length, \
&image.endian); // 이미지 주소 할당
for (int i = 0 ; i < 500 ; i++)
{
for (int j = 0 ; j < 500 ; j++)
mlx_pixel_put (mlx, win, i, j, 0x00FFFFFF);
}
목표 : win 이라는 캔버스 위에 500 x 500 의 도화지를 올리는 것.
이때, 컴퓨터의 (0, 0)은 왼쪽 위 상단임을 생각하자.
함수 설명
-
mlx_new_image: 메모리에 새 이미지를 만든다.구조는 다음처럼 생각하면 된다 :
mlx_new_image(캔버스, x 길이, y 길이) -
mlx_get_data_addr: 생성된 이미지의 정보(address)를 돌려준다.image.img= 사용할 이미지를 의미image.bpp= bits per pixel의 줄임말로 픽셀 색상을 지정하는데 필요한 비트 수image.line_length= 이미지 한줄을 메모리에 저장하는데 사용된 바이트 수.이미지를 한 줄에서 다음 줄로 넘길 때 필요.
image.endian: 픽셀 저장방식. (리틀엔디언 = 0, 빅엔디언 = 1)
엔디언이란?
엔디언(Endianness)은 컴퓨터의 메모리와 같은 1차원의 공간에 여러 개의 연속된 대상을 배열하는 방법을 뜻하며, 바이트를 배열하는 방법을 특히 바이트 순서(Byte order)라 한다.
그림 그리기 2 : 이미지
image를 이용해서 그림을 그리는 법에 대해 알아보자.
좀 더 빠르다는 장점이 있다.
예시코드
다음 코드를 쳐보고 실행시켜 보자.
c
#include "fdf.h"
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->bpp / 8));
*(unsigned int*)dst = color;
}
int create_argb(int a, int r, int g, int b)
{
return (a << 24 | r << 16 | g << 8 | b);
}
static void image(void)
{
void *mlx;
void *win;
t_data image;
mlx = mlx_init();
win = mlx_new_window(mlx, 1920, 1080, "hello world");
image.img = mlx_new_image(mlx, 1920, 1080);
image.addr = mlx_get_data_addr(image.img, &image.bpp, &image.line_length, \
&image.endian);
for (int x = 0; x < 200; x++) {
for (int y = 0; y < 200; y++) {
char *dst2;
dst2 = image.addr + (y * image.line_length + x * image.bpp / 8);
*(unsigned int *)dst2 = create_argb(0, 0, 255, 0);
}
}
mlx_put_image_to_window(mlx, win, image, 20, 100);
// image를
mlx_loop(mlx);
}
int main(int ac, char **av)
{
image();
}