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축 기준으로 바라보는 주전자 모습이 출력된다.
3-2) 2번 평행 투상
gluLookAt() 함수에 의해 아래 그림과 같이 x축 기준으로 바라보는 주전자 모습이 출력된다.
3-3) 3번 평행 투상
gluLookAt() 함수에 의해 아래 그림과 같이 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의 거리에 있다.
- 말로는 이해가 잘 안 갈 수 있지만 함수의 파라미터 값들을 변화시켜보면 각각의 파라미터가 무엇을 의미하는지 더 잘 이해할 수 있을 것이다.
'기타 > 컴퓨터 그래픽스 & OpenGL' 카테고리의 다른 글
OpenGL로 배우는 3차원 컴퓨터 그래픽스 연습문제 10장 / 2022.12.10 (1) | 2022.12.10 |
---|---|
OpenGL로 배우는 3차원 컴퓨터 그래픽스 연습문제 9장 / 2022.12.06 (0) | 2022.12.06 |
[OpenGL] 타이머 콜백 / 2022.10.24 (0) | 2022.10.24 |
[OpenGL] 아이들 콜백 / 2022.10.23 (0) | 2022.10.23 |
[OpenGL] 메뉴 콜백 / 2022.10.23 (0) | 2022.10.23 |