본문 바로가기

기타/컴퓨터 그래픽스 & OpenGL

[OpenGL] 평행 투상과 원근 투상 / 2022.10.24

1. 평행 투상 

- 시점이 물체로부터 무한대의 거리에 있다고 간주하여 투상선을 나란히 가져가는 방법.

- 원래 물체의 평행선은 투상 후에도 평행

- 시점으로 부터의 거리와 무관하게 같은 길이의 물체는 같은 길이로 투상됨

- 평행 투상은 정사 투상, 축측 투상, 경사 투상으로 나뉨

평행 투상

2. 원근 투상

- 시점이 물체로부터 유한한 거리에 있다고 간주

- 투상선이 시점에서 출발하여 방사선 모양으로 퍼져감

- 실제로 카메라나 사람의 눈이 물체를 포착하는 방식

- 동일한 물체라도 시점으로부터 멀면 작게 보이고, 가까우면 크게 보인다. (원근감)

원근 투상

3. 예제를 통해 알아보자

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

int Width, Height;

void Init() {
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glOrtho(-2.0, 2.0, -2.0, 2.0, 0.5, 5.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void DrawScene() {
    glColor3f(0.7, 0.7, 0.7); //회색
    glPushMatrix();
    glTranslatef(0.0, -1.0, 0.0); // y축으로 이동해서
    glBegin(GL_QUADS); // 회색 사각형 그림
    glVertex3f(2.0, 0.0, 2.0);
    glVertex3f(2.0, 0.0, -2.0);
    glVertex3f(-2.0, 0.0, -2.0);
    glVertex3f(-2.0, 0.0, 2.0);
    glEnd();
    glPopMatrix();

    glColor3f(0.3, 0.3, 0.7); //청색
    glPushMatrix();
    glTranslatef(0.0, 0.0, -0.5); // z축으로 -0.5인 곳에
    glutWireTeapot(1.0); // 청색 주전자 그림
    glPopMatrix();
}

void MyDisplay() {
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0, 1.0, 1.0);
    // 1번 평행 투상
    glViewport(0, 0, Width / 2, Height / 2);
    glPushMatrix();
    gluLookAt(0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    DrawScene();
    glPopMatrix();
    // 2번 평행 투상
    glViewport(Width / 2, 0, Width / 2, Height / 2);
    glPushMatrix();
    gluLookAt(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    DrawScene();
    glPopMatrix();
    // 3번 평행 투상
    glViewport(0, Height / 2, Width / 2, Height / 2);
    glPushMatrix();
    gluLookAt(0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0);
    DrawScene();
    glPopMatrix();
    // 4번 원근 투상
    glViewport(Width / 2, Height / 2, Width / 2, Height / 2);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    gluPerspective(30, 1.0, 3.0, 50.0);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    gluLookAt(5.0, 5.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    DrawScene();
    glPopMatrix();
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glFlush();
}

void MyReshape(int w, int h) {
    Width = w;
    Height = h;
}

int main(int argc, char** argv) {
    Width = 500;
    Height = 500;
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
    glutInitWindowSize(Width, Height);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("OpenGL Sample Drawing");
    Init();
    glutDisplayFunc(MyDisplay);
    glutReshapeFunc(MyReshape);
    glutMainLoop();
    return 0;
}

 

실행 결과

 

- DrawScene() 에서 정의한 그림은 다음과 같다.

회색 사각형 위에 주전자가 있는 모습

3-1) 1번 평행 투상

gluLookAt() 함수에 의해 아래 그림과 같이 z축 기준으로 바라보는 주전자 모습이 출력된다.

z축 기준으로 바라봄
결과

3-2) 2번 평행 투상

gluLookAt() 함수에 의해 아래 그림과 같이 x축 기준으로 바라보는 주전자 모습이 출력된다.

x축 기준으로 바라봄
결과

3-3) 3번 평행 투상

gluLookAt() 함수에 의해 아래 그림과 같이 y축 기준으로 바라보는 주전자 모습이 출력된다.

위에서 바라보는 모습이기 때문에 주전자 아래의 회색 사각형도 출력된다.

y축 기준으로 바라봄
결과

3-4) 4번 원근 투상

- gluPerspective를 사용해 가시 부피를 먼저 설정한다,

- 시야각 30도, 종횡비 1.0, 전방 절단면 3.0 후방 절단면 50에 위치해 있다.

- gluLookAt()으로 시점 좌표계를 설정해준다.

- 전방 절단면 3.0은 설정한 시점 (5.0, 5.0, 5.0)에서 원점 (0.0, 0.0, 0.0)을 향하는 -z 축 방향으로 3.0의 거리에 있다.

- 말로는 이해가 잘 안 갈 수 있지만 함수의 파라미터 값들을 변화시켜보면 각각의 파라미터가 무엇을 의미하는지 더 잘 이해할 수 있을 것이다.

결과