[OpenGL] 3차원에서 폴리곤의 방향성 그래픽

OpenGL Programming Guide Chapter 2 내용 중에 가장 이해가 되질 않았던 부분 중 하나인 폴리곤의 방향성에 대해서 정리하고자 한다. 원서로 읽다 보니까 이해가 되지 않는 내용이 많았는데, 구글링을 통해 가까스로 이해하게 되었다.

여기에서 다루고자 하는 내용에 대한 gl 인터페이스는 아래와 같다.

  • void glFrontFace(GLenum mode)
  • void glCullFace(GLenum mode)
  • void glPolygonMode(GLenum face, GLenum mode)

3차원 공간의 물체에는 물체의 표면 부분(front face)과 그 반대인 뒷면 부분(back face)이 존재한다. 예를 들어, 네모난 모양의 빨간색 단면 색종이에서 색이 있는 면을 표면(front face)이라고 하고 색이 없는(하얀) 부분을 뒷면(back face)이라고 할 수 있다. 이러한 단면 색종이를 그리기 위해 점을 네 개 찍는다고 하였을 때, 주어진 점 4개 만으로는 두 개의 면(face) 중에 어느 쪽에다 색을 칠해야 할 지 결정할 수가 없다.

어느 쪽을 표면으로 할 것인가를 결정하기 위해 사용한 것이 물체를 바라보는 관점에서 점을 찍는 순서이다. 일반적으로 반시계 방향(counterclockwise) 순서로 찍힌 점을 front-facing 이라고 하며, 이 점들이 이루는 면은 front-face가 된다.

만일 반시계 방향의 front-facing 시스템에서 시계 방향으로 찍힌 점들로 이루어진 폴리곤을 구현했다면 표면이 보이지 않을 것이다. 이런 경우 glFrontFace()를 사용하여 표면이 나타나는 방향을 바꿀 수 있다. mode에 GL_CCW를 사용하면, 반시계 방향 순서로 보이는 면을 front-face로 할 것이고, GL_CW는 그 반대의 면을 front-face로 설정할 것이다. 

폴리곤의 방향성에 대해서는 수식으로도 계산할 수 있다.

GL_CCW 에서 a>0 이면, front-facing 이고, 반대의 경우는 back-facing이 될 것이다. GL_CW 에서는 a<0 일 경우 front-facing이 된다.

한편, 완전히 닫힌(completely enclosed) 폴리곤들로 이루어져서 back-facing 폴리곤이 없고 front-facing 폴리곤만이 나타나는 공간은 보이지 않는 면을 무시함으로써 드로잉 성능을 높일 수 있다(back-facing 폴리곤만 보이는 공간도 마찬가지). glCullFace()와 glEnable()을 사용하여 OpenGL에게 front 또는 back facing 폴리곤만 존재함을 알릴 수 있다. glCullFace()의 mode에는 GL_FRONT, GL_BACK, GL_FRONT_AND_BACK을 사용할 수 있고 각각 front-facing, back-factin, all polygons를 나타낸다.

마지막으로 glPolygonMode()는 폴리곤의 면을 표현하는 방식을 설정하는 인터페이스이다. face에는 GL_FRONT, GL_BACK, GL_FRONT_AND_BACK이 들어갈 수 있고, mode에는 GL_POINT, GL_LINE, GL_FILL 등이 들어간다.

glPolygonMode()를 이용해서 위에서 설명한 것들을 증명해 볼 수 있다. OpenGL 기본 예제(http://hijacker.egloos.com/2717178)에서 약간만 변형 하여 예제를 만들어 보았다.

위와 같이 P1, P2, P3, P4의 점으로 이루어진 폴리곤을 그린다고 하였을 때, P1 부터 시계 방향으로 그리게 되므로 위의 폴리곤은 back-facing이 된다. 정말 그러한지 살펴보기 위해 아래와 같이 glPolygonMode()를 사용해 보았다.

void display()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();

glColor3f(1.0, 1.0, 1.0);
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);

glPolygonMode(GL_FRONT, GL_POINT);
glPolygonMode(GL_BACK, GL_LINE);


glBegin(GL_POLYGON);
glVertex2f(-0.5, -0.5); // P1
glVertex2f(-0.5, 0.5); // P2
glVertex2f(0.5, 0.5); // P3
glVertex2f(0.5, -0.5); // P4
glEnd();

glFlush();
}

예상대로라면 사각형의 외곽선만 출력되어야 할 것이다.

그리고 아래 코드를 추가하면 front-face를 무시하게 되므로(culled) 아무 것도 출력되지 않을 것이다.

	glCullFace(GL_FRONT);
glEnable(GL_CULL_FACE);
※참고

덧글

  • 공대아름이 2011/11/29 18:19 # 삭제 답글

    cullface와 face방향에 대해 갈피를 못잡고 있었는데.. 다른 글들을 읽어도 이해가 안갔는데 여기와서 제대로 이해하고 갑니다..^^ 이해하기 쉽게 써주셔서 정말 감사합니다..^^
  • hijacker 2012/05/18 18:51 #

    도움이 되어서 다행입니다 ^^
댓글 입력 영역