2026.05.01
glOrtho() 함수와 glPerspective() 함수 파라미터를 이해한다.투상(Projection) = 가시변환(Viewing Transformation)

투상면(View Plane, Projection Plane)
관찰자 위치(View Point, Eye Position)
= 카메라 위치(Camera Position) = 투상중심(Center of Projection, COP)
= 시점좌표계 원점(Origin of VCS)
투상선(Projectors): 물체 곳곳을 향함
시선(Line of Sight): WCS 원점 또는 초점을 향함

원근법을 고려하지 않고 시점이 물체로부터 무한대의 거리에 있다고 간주

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

원근감
동일한 크기의 물체라도
시점으로부터 멀리 있는 것은 작게 보이고, 가까운 것은 크게 보임
소실점이 생겨남
원근변환(Perspective Transformation)
투상: void glMatrixMode(GL_PROJECTION);
P' = MParallel · P

|1 0 0 0|
|0 1 0 0|
|0 0 0 -d|
|0 0 0 1|
역행렬이 존재하지 않음(특이변환)
해당 행렬은 암기해놓기
기본 평행투상
가시부피(View Volume): 장면의 범위를 지정할 필요성


void glOrtho(GLdouble left, righ, bottom, top, near, far)
near, far은 [-near, -far]로 변환된다(-z축의 방향이기 때문)정규화 가시부피(CVV: Canonical View Volume)
정규화 이유
평행투상, 원근투상을 동일한 모습의 정규화 가시부피로 변형
동일 파이프라인 사용
정육면체를 기준으로 하면 연산이 간단함
다양한 해상도의 화면 좌표계로 변환하기가 간단함


T변환(중점 이동) → S변환(크기변환) → R변환(z축 반대로 이동)

예제) 점(l,b,-n,1), (r,t,-f,1)의 변환 후 좌표를 구하시오.

이렇게 만들어진 좌표계를 절단 좌표계(Clip Coordinate System, CCS) 라고 함


4행의 3열에 특정 숫자가 있다 = 원근 투상이다?
현재
| x |
| y |
| -z |
| z/d |
에서 실제 3차원 공간의 x, y, z 좌표를 계산하기 위해서는
동차좌표의 마지막 요소(z/d)로 이전 요소로 나누는 작업이 필요함
이러한 작업을 원근분할(Perspective Division)이라고 함
평행투영은 원근분할이 필요 없고 원근투영만 필요함
절단 사각뿔(frustum) = 절두체


일반적 형태의 가시부피
void glFrustum(GLdouble left, right, bottom, top, near, far)


x, y 값에 대해서 영향을 미치고,z 값에 대해 영향을 미치고 있음

-z가 되고, 원근 분할에x, y, z 값이 마지막 요소인 -z에 의해 나눠지는데,


far 의 경우 기울기가 완만하기 때문이고
near 의 경우 기울기가 급하기 때문에
멀리 있는 물체는 깊이가 같다고 오판되기도 함
따라서 near 값을 미는 방식으로 해결함
void gluPerspective(GLdouble fov, aspect, near, far);

width/heightnear, far: 눈으로부터의 거리z 값으로 나누어야 하므로 0보다 큰 값을 주어야 함
코드 작성 순서는 아래에서 위 방향으로
ReShape 내에는 projection 변환만 사용하며,
translate, scale 등의 변환은 display 내부에서 사용
이전까지의 과정에서 정규화 가시부피 내에 모든 좌표를 표현
이제부터는 실제 화면 (1024 등으로 표현되는)에
어떻게 변환하여 출력할 것인가
정규화 장치좌표계(Normalized Device Coordinate System, NDCS)
(x', y', z', 1) = (x/w, y/w, z/w, 1)뷰포트 변환(Viewport Transformation)

void glViewport(GLint left, bottom, GLsizei width, height);


x, y 값만 변화됨
정규화 가시부피에서의 z값의 범위인 [-1, +1] 사이를
[0, 1] 사이로 사상
정점 사이의 상대적인 깊이는 유지
정규화 가시부피를 원점을 중심으로 해서
z 방향으로 1/2 만큼 크기조절 변환을 가한 후,
z 방향으로 1/2 만큼 평행 이동
P' = T(0, 0, 0.5) * S(1, 1, 0.5) * P

1. 모델 변환 (Model Transformation)
glTranslatef, glRotatef, glScalef2. 시점 변환 (View Transformation)
gluLookAt3. 투상 변환 (Projection Transformation)
glOrthogluPerspective, glFrustum4. 원근분할 (Perspective Division)
5. 뷰포트 변환 (Viewport Transformation)
glViewport(x, y, width, height)