지금까지의 그래픽 지식을 가지고 첫 번째 그래픽 라이브러리 gx 를 만들도록 하겠습니다. 첫 번째 버전이라 도형 출력을 중심으로 단순하게 사용하는 방법으로 구성해 보았습니다.

gx lib ver 0.0.1 특징

gx lib ver 0.0.1은 그래픽 라이브러리의 이해를 돕고 version 1.0.0 으로 가기 위한 중간 버전으로 가급적 struct를 사용하지 않고 쉽게 읽고 이해할 수 있도록 만들어 졌습니다.

이렇게 하기 위하여,

  • 함수에서도 필요한 모든 값을 인수로 전달하도록 처리했습니다.

    필요한 모든 데이터를 인수로 받아 함수 내에서 처리하기 때문에 함수 하나를 따로 생각하고 이해하는데 도움을 주도록 했습니다.

  • 화면의 범위를 벗어나는 좌표에 대해서는 출력하지 않도록 처리했습니다.

    이렇게 하지 않으면 라이브러리를 이용하는 프로그램에서 화면 범위를 벗어나지 않도록 주의해야 하며, 만일 좌표가 화면 범위를 벗어 나면 엉뚱한 메모리를 Access하게 되므로 심각한 에러가 발생합니다.

  • 사각형과 원, 타원 같이 면적이 있는 도형은 테두리 색상과 내부에 채워지는 색상을 따로 지정하여 그려 지도록 했습니다.

  • 칼라에 clr_clear을 사용하면 화면에 그려지지 않도록 했습니다.

    즉, 테두리를 백색, 내부 채워지는 색을 clr_clear 로 지정했다면 도형은 백색 테두리만 그려지게 됩니다. 반대로 테두리는 clr_clear로 하고, 내부 색을 빨강으로 지정하면 빨강색으로 채워진 사각형이 그려지게 됩니다.

gx lib 함수 설명

gx에 포함된 함수는 아래와 같습니다.

함수 이름 함수 설명
gx_init() 그래픽 라이브러리를 초기화합니다.
gx_close() 그래픽 라이브러리 사용을 종료합니다.
gx_clear() 특정 색으로 화면 전체를 칠합니다.
gx_color() red, green, blue 를 인수로 칼라 값을 구합니다.
gx_dot() 점을 찍습니다.
gx_hline() 수평선을 긋습니다.
gx_vline() 수직선을 긋습니다.
gx_line() 직선을 긋습니다.
gx_border() 사각형 테두리를 그립니다.
gx_box() 내부가 채워진 사각형을 그립니다.
gx_rectangle() 테두리와 내부 색으로 채워지는 사각형을 그립니다.
gx_ellipse() 테두리와 내부 색으로 채워지는 타원을 그립니다.

gx_init() 초기화 함수를 실행하면 화면 정보를 갖는 gxscreen 정보가 생성되며, 광역 변수입니다.

속성 이름 속성 설명
screen.width 화면의 폭
screen.height 화면의 높이
screen.size 화면의 도트 개수

이번 시간에는 gx 라이브러리 파일만 올려 드리며, 다음 시간부터 함수 내용을 자세히 설명하도록 하겠습니다. 우선 gx 를 이용한 샘플을 보시겠습니다.

#include <stdio.h>
#include <stdlib.h>        // abs
#include <string.h>
#include <unistd.h>        // sleep
#include <time.h>          // time

#include <gx.h>

void  test( void)
{
   int   x1,  y1,    x2,   y2;
   int   red, green, blue;
   int   ndx;

   for ( ndx = 1; ndx < 500; ndx ++)                  // 선 그리기 예제
   {
      x1    = rand() % gxscreen.width;    y1 = rand() % gxscreen.width;
      x2    = rand() % gxscreen.width;    y2 = rand() % gxscreen.width;
      red   = rand() % 255;
      green = rand() % 255;
      blue  = rand() % 255;
      gx_line( x1, y1, x2, y2, gx_color( red, green, blue));
   }

   for ( ndx = 1; ndx < 100; ndx ++)                  // 사각형 그리기 예제
   {
      x1    = rand() % gxscreen.width;    y1 = rand() % gxscreen.width;
      x2    = rand() % gxscreen.width;    y2 = rand() % gxscreen.width;
      red   = rand() % 255;
      green = rand() % 255;
      blue  = rand() % 255;
      gx_rectangle( x1, y1, x2, y2, gx_color( red, green, blue), gx_color( blue, red, green));
   }

   for ( ndx = 1; ndx < 100; ndx ++)                  // 타원 그리기 예제
   {
      x1    = rand() % gxscreen.width;    y1    = rand() % gxscreen.width;
      if ( 0 == x1)  x1 = 10;
      if ( 0 == y1)  y1 = 10;
      x2    = rand() % x1;                y2    = rand() % y1;

      red   = rand() % 255;
      green = rand() % 255;
      blue  = rand() % 255;
      gx_ellipse( x1, y1, x2, y2, gx_color( red, green, blue), gx_color( blue, red, green));
   }
}

int   main( int argc, char **argv)
{
   switch( gx_init( "/dev/fb") )
   {
      case  GXERR_NO_DEVICE      :  printf( "프레임 버퍼 장치가 없습니다.n"              ); return -1;
      case  GXERR_ACCESS_DEVICE  :  printf( "프레임 버퍼 장치 접근 권한이 없습니다.n"    ); return -1;
      case  GXERR_VSCREENINFO    :  printf( "FBIOGET_VSCREENINFO를 실행하지 못했습니다.n"); return -1;
      case  GXERR_FSCREENINFO    :  printf( "FBIOGET_FSCREENINFO를 실행하지 못했습니다.n"); return -1;
      case  GXERR_MEMORYMAPPING  :  printf( "메모리 매핑에 실패했습니다.n"               ); return -1;
   }

   srand( (unsigned)time(NULL));

   for( ;;)
      test();

   gx_close();

   return 0;
}

main() 함수부터 보겠습니다. gx_init() 를 이용하여 그래픽 라이브러리부터 초기화하고 있습니다. 프레임 버퍼 장치명을 넘겨 주면 실행 결과를 넘겨 줍니다.

switch( gx_init( "/dev/fb") )
{
   case  GXERR_NO_DEVICE      :  printf( "프레임 버퍼 장치가 없습니다.n"              ); return -1;
   case  GXERR_ACCESS_DEVICE  :  printf( "프레임 버퍼 장치 접근 권한이 없습니다.n"    ); return -1;
   case  GXERR_VSCREENINFO    :  printf( "FBIOGET_VSCREENINFO를 실행하지 못했습니다.n"); return -1;
   case  GXERR_FSCREENINFO    :  printf( "FBIOGET_FSCREENINFO를 실행하지 못했습니다.n"); return -1;
   case  GXERR_MEMORYMAPPING  :  printf( "메모리 매핑에 실패했습니다.n"               ); return -1;
}

프레임 버퍼 사용에 문제가 없다면 0 값인 GXERR_ NONE이 반환되며, 나머지는 실패에 대산 상수값은 위의 코드를 참고하여 주십시오. 함수 실행에 실패하면 자동으로 gx_close()를 호출하므로, 따로 gx_close()를 호출할 필요는 없습니다.

테스트를 위핸 srand()로 난수를 생성을 현재 시간 값으로 초기화했습니다. 그리고 직선과 사각형, 타원을 그리는 테스트 코드를 호출합니다.

srand( (unsigned)time(NULL));

for( ;;)
   test();

마지막으로 gx_close() 를 호출하여 그래픽 라이브러리 사용을 종료합니다.

gx_close();

프로그램 실행을 보시려면 아래의 동영상을 선택하여 주십시오.