GLUT 초기화

이번 장에선 glut 를 사용하는 어플리케이션의 main 함수를 만들어 볼거에요. main 함수는 필요한 초기화를 수행하고 이벤트 처리 루프를 시작한답니다. GLUT 에 있는 모든 함수들은 접두어로 "glut" 를 갖습니다. 그리고 초기화에 관련된 함수는 접두어로 "glutInit" 를 갖지요. glut 를 사용할 때 제일 먼저 호출해야할 함수가 바로 glutInit 함수입니다.

void glutInit(int *argc, char **argv); 

인자 설명:
argc - main 함수에 전달되는 argc 변수의 포인터로 전혀 가공되지 않은 데이타입니다.
argv - main 함수에 전달되는 argv 변수의 포인터로 전혀 가공되지 않은 데이타입니다.

GLUT 가 초기화되고 나면, 창(Window)을 만들어야합니다. 우선 창의 위치를 설정해야하는데, 창의 왼쪽(Left), 위쪽(Top) 코너를 설정하는 걸 말합니다. 창의 위치를 설정하기 위해서 glutInitWindowPosition 함수를 사용하면 됩니다.

void glutInitWindowPosition(int x, int y); 

인자 설명:
x - 화면에서 왼쪽으로 몇 픽셀 떨어져 있는지를 설정합니다. -1 값이 기본값인데, 이 값의 의미는 창이 나타날 때 윈도우즈가 알아서 위치를 결정하라는 뜻입니다. 기본값을 사용하지 않으려면 화면크기 내에서 알맞은 양수 값을 입력하세요.
y - 화면의 위쪽에서 몇 픽셀 떨어져 있는지를 설정합니다. 나머지는 x 인자의 설명과 동일합니다.

창의 위치를 설정할 때 입력하는 값들은 단지 윈도우 관리자에게 '위치가 이정도면 좋겠다' 라고 제안하는 것일 뿐입니다. 따라서 다른 위치에 창이 나타날 수 있습니다. 다음에는 창의 크기를 설정해야하는데 이 것은 glutInitWindowSize 함수를 사용하면 됩니다.

void glutInitWindowSize(int width, int height); 

인자 설명:
width - 창의 너비
height - 창의 높이

마찬가지로 여기서 전달하는 크기값들도 역시 윈도우 관리자에게 "크기가 이정도면 적당하겠군!" 이라고 제안하는 것일 뿐입니다. 그리고 값을 설정할 때에는 음수값으로 설정하지 마세요!

여기까지 한 다음에는 glutInitDisplayMode 함수를 사용해서 "디스플레이모드" 를 설정해야합니다.

void glutInitDisplayMode(unsigned int mode) 

인자 설명:
mode - "디스플레이모드" 의 종류값

mode 인자는 GLUT 라이브러리에 정의되어 있는 값들을 OR 비트 연산하여 합한 값인데, 색상(color) 모드와 버퍼의 수 , 버퍼의 종류를 설정해야합니다.

아래는 미리 정의되어 있는 색상 모델(color model)의 상수입니다.

  • GLUT_RGBA 또는 GLUT_RGB - RGBA 창을 만듭니다. 이 값은 glut 가 사용하는 기본 색상 모드입니다.

  • GLUT_INDEX - 인덱스 색상 모드로 설정합니다.

디스플레이 모드는 단일버퍼 창을 만들 것인지 아니면 이중버퍼 창을 만들 것인지 결정하는 것인데, 아래에 설정할 수 있는 상수가 있습니다.:

  • GLUT_SINGLE - 단일버퍼(single buffer) 창을 마든다.

  • GLUT_DOUBLE - 이중버퍼(double buffer) 창을 만든다. 부드러운 에니메이션을 만들 때 필요합니다.

그리고 여러분이 원한다면 특정 버퍼로 설정된 창을 만들 수 있습니다. 아래는 가장 많이 설정하는 버퍼입니다.:

  • GLUT_ACCUM - 어큐뮬레이션 버퍼( The accumulation buffer )

  • GLUT_STENCIL - 스텐실 버퍼 ( The stencil buffer )

  • GLUT_DEPTH - 깊이 버퍼 ( The depth buffer )

그럼, 단일 버퍼와 깊이 버퍼가 있고 RGB 색상 모드를 갖는 창을 만들려면 어떻게 해야할까요? 원하는 디스플레이 모드를 만들기 위해서 해당되는 상수들을 모두 OR 비트 연산해서 합쳐야합니다.

...
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT DEPTH);
...

위의 모든 과정을 수행한 다음에는 glutCreateWindow 함수를 사용해서 창을 만들어줍니다.

위의 모든 과정을 수행한 다음에는 glutCreateWindow 함수를 사용해서 창을 만들어줍니다.

glutCreateWindow 함수가 반환하는 값은 창을 구별할 수 있는 정수값인데 나중에 필요할 때 사용할 수 있습니다. 물론 이 값을 담고있는 변수는 함수 외부에 있어야 되겠죠.

자 그럼 모든 초기화 과정을 수행하는 코드를 구경해 봅시다.

#include <gl/glut.h> 
void main(int argc, char **argv) 
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(320,320);
    glutCreateWindow("3D Tech- GLUT Tutorial");
}

첫 줄을 보면 include 문이 있는데 GLUT 를 사용하기 위해서 반드시 필요합니다.

이 코드를 실행시켜 보면, OpenGL 창은 없고 검은색 바탕의 콘솔 윈도우만 볼 수 있습니다. 게다가 몇 초가 지나면 이 콘솔창 마저도 사라지죠. 그럼 해야할 일이 더 있는 건가요? 네 그렇습니다! 무엇을 그리기 위해서는 두 가지를 더 설정해 줘야합니다. 하나는 GLUT 에게 어떤 함수가 렌더링을 책임지고 수행하는지 알려주는 것입니다.

그럼 렌더링을 책임지는 함수를 만들어볼까요? 색상 버퍼를 깨끗이 지우고 삼각형 한개를 그리는 함수를 만들어보겠습니다.

...
void renderScene(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_TRIANGLES);
        glVertex3f(-0.5,-0.5,0.0);
        glVertex3f(0.5,0.0,0.0);
        glVertex3f(0.0,0.5,0.0);
    glEnd();
    glFlush();
}

우리는 함수의 이름만 봐도 이 함수가 렌더링에 관련된 함수라는 것을 알 수 있지만 GLUT 는 모르기 때문에 GLUT 에게 어떤 함수가 렌더링을 처리하는데 사용될 것인지 알려줘야합니다. 렌더링 함수로 정해진 함수는 콜백 함수로 등록되어 렌더링 을 할 때면 언제든지 호출됩니다. 지금 예제는 GLUT 에게 창을 다시 그려야할 때 renderScene 함수를 사용하라고 알려주는 것입니다. GLUT 에는 다시 그리기가 필요할 때 사용하는 함수이름을 인자로 받아 설정하는 함수가 있습니다. 단 주의할 점은 이 함수의 인자로 전달된 함수가 창이 만들어질 때도 호출된다는 것입니다. 다음은 이 함수의 설명입니다.

void glutDisplayFunc(void (*func)(void)); 

인자 설명:
func - 다시 그리기가 필요할 때 호출되는 함수의 이름입니다. 단, NULL 을 전달하면 안됩니다.

설정해줘야 할 것 중 마지막 하나는 GLUT 로 어플리케이션의 이벤트 처리 루프를 설정하는 것입니다. GLUT 는 이를 위해서 이벤트 루프를 제공합니다. 이 루프는 다음 이벤트가 일어날 때까지 항상 기다리고 있습니다. 그 GLUT 함수는 glutMainLoop 함수이고 아래는 이 함수의 설명입니다.:

void glutMainLoop(void)

예제의 전체 코드가 아래에 있는데 OpenGL 의 함수인 glClear, glBegin, glVertex3f, glEnd 등을 사용하기 위해서 include 문을 추가했습니다.

이 코드를 실행하면 콘솔 창과 하얀색의 삼각형이 그려져 있는 OpenGL 창을 볼 수 있습니다.

#include <gl/glut.h>
#include<gl/gl.h>

void renderScene(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_TRIANGLES);
        glVertex3f(-0.5,-0.5,0.0);
        glVertex3f(0.5,0.0,0.0);
        glVertex3f(0.0,0.5,0.0);
    glEnd();
    glFlush();
}

void main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(320,320);
    glutCreateWindow("3D Tech- GLUT Tutorial");
    glutDisplayFunc(renderScene);
    glutMainLoop();
}

Last updated