GlFrustum
원근 투영을 만드는 함수다.
Synopsis
void glFrustum( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far )
이 함수에서 인자들의 의미는 아래 그림에 자세하게 설명되어 있다.
GlFrustum.jpeg
위의 그림에서 (left, bottom) - (right, top) 에 의해서 정의 되는 면은 클립핑된 영역이며 이 면에 2D 의 그림이 그려지게 된다. 즉 육면체(절두체)에서 우리가 생각하는 3D 의 폴리곤이 그려지고 아핀변환이 일어난 후에 클리핑된 면으로 투영 변환(여기서는 원근변환, 3D 에서 2D 로 변환)이 일어나게 된다. 이 원근 투영의 변환 행렬은 아래와 같다.
Perspective_matrix.jpeg
glOrtho(직교 투영) vs glFrustum(원근 투영)
아핀 공간의 점은 p(x, y, z, w) 에서 w = 1 이다. 직교 투영 행렬은 w = 1 인 반면에 원근 투영 행렬은 w 가 1 이 아니다. 이 때문에 직교 투영은 아핀 변환의 특징인 평행성과 비율이 보존 되지만 원근 투영은 보존되지 않는다.
쉬운 버전
glFrustum() 함수를 좀 더 쉽게 쓰기 위해서 GLU의 gluPerspective 함수가 있는데 이 함수에 의해서 생성되는 원근 투영 행렬은 위의 행렬과는 다르다.
Example
GlFrustum_-_example_result.jpeg
아래의 그림은 아주 간단하게 만들어 본 원근 투영의 예제 프로그램 그림과 소스 코드이다. 원근감이 느껴진다.
void RenderWindow::OnSize(WPARAM wParam, LPARAM lParam)
{
GLsizei width = LOWORD(lParam);
GLsizei height = HIWORD(lParam);
if (height == 0)
height = 1;
glViewport( 0, 0, width, height );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0f, 1.0f, -1.0f, 1.0, 1.0f, 10.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
BOOL RenderWindow::InitGL(void)
{
Window::InitGL();
glEnable(GL_LIGHTING);
GLfloat lightPos[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glEnable(GL_LIGHT0);
return TRUE;
}
void RenderWindow::RenderGLScene(void)
{
Window::RenderGLScene();
glPushMatrix();
glTranslatef(0.0f, 0.0f, -2.0f);
glRotatef(33.0f, 1.0f, 0.0f, 0.0f);
glRotatef(33.0f, 0.0f, 1.0f, 0.0f);
glColor3f(0.5f, 0.5f, 0.5f);
glutSolidTeapot(0.4f);
glPopMatrix();
glPushMatrix();
glTranslatef(1.0f, 0.0f, -4.0f);
glRotatef(33.0f, 1.0f, 0.0f, 0.0f);
glRotatef(33.0f, 0.0f, 1.0f, 0.0f);
glColor3f(0.3f, 0.3f, 0.3f);
glutSolidTeapot(0.4f);
glPopMatrix();
glPushMatrix();
glTranslatef(-1.0f, 0.0f, -6.0f);
glRotatef(33.0f, 1.0f, 0.0f, 0.0f);
glRotatef(33.0f, 0.0f, 1.0f, 0.0f);
glColor3f(0.1f, 0.1f, 0.1f);
glutSolidTeapot(0.4f);
glPopMatrix();
}