Top Banner
Chapter 3. Chapter 3. 뷰뷰 뷰뷰 (Viewing) (Viewing)
86

Chapter 3. 뷰잉 (Viewing)

Jan 06, 2016

Download

Documents

jaeger

Chapter 3. 뷰잉 (Viewing). 3 차원 좌표들의 변환과정. 다음의 세 가지 컴퓨터 연산이 순차적으로 실행되면서 스크린 상의 픽셀로 변환 모델링 , 뷰잉 , 투영 연산 등과 같은 행렬 곱셈으로 표현된 변환 회전 변환 , 평행이동 변환 , 크기 변환 , 반사 , 직교투영 , 원근 투영 등이 포함됨 장면은 사각형 윈도우에 렌더링되기 때문에 오브젝트 또는 오브젝트의 일부가 윈도우 밖에 놓여지는 경우 잘라내는 클리핑 수행 변환된 좌표와 스크린 픽셀을 서로 연결시켜주는 뷰포트 변환. - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Chapter 3.  뷰잉 (Viewing)

Chapter 3. Chapter 3. 뷰잉뷰잉 (Viewing)(Viewing)

Page 2: Chapter 3.  뷰잉 (Viewing)

33 차원 좌표들의 변환과정차원 좌표들의 변환과정 다음의 세 가지 컴퓨터 연산이 순차적으로 실행되면서 스크린 상의

픽셀로 변환◦ 모델링 , 뷰잉 , 투영 연산 등과 같은 행렬 곱셈으로 표현된 변환

회전 변환 , 평행이동 변환 , 크기 변환 , 반사 , 직교투영 , 원근 투영 등이 포함됨

◦ 장면은 사각형 윈도우에 렌더링되기 때문에 오브젝트 또는 오브젝트의 일부가 윈도우 밖에 놓여지는 경우 잘라내는 클리핑 수행

◦ 변환된 좌표와 스크린 픽셀을 서로 연결시켜주는 뷰포트 변환

2013-2 학기 3 장 뷰잉

Page 3: Chapter 3.  뷰잉 (Viewing)

2013-2 학기

뷰잉뷰잉 (viewing)(viewing)

카메라 구조

뷰잉 및 모델링 변환

투영 변환

뷰포트 변환

변환에 관련된 문제 해결 방법

행렬 스택 조작하기

부가적인 클리핑 평면

여러가지 변환 함께 사용하기

변환을 역으로 수행하거나 흉내내기

3 장 뷰잉

Page 4: Chapter 3.  뷰잉 (Viewing)

카메라 구조카메라 구조 원하는 장면을 생성하기 위해 거치는 변환 과정은 카메라로

사진을 찍는 것에 비유

◦ 삼각대를 세우고 , 카메라가 장면을 향하도록 설정 ( 뷰잉 변환 )◦ 원하는 장면을 화면에 담도록 모델을 정리 ( 모델링 변환 )◦ 사용할 카메라 렌즈를 선택하거나 줌을 조절 ( 투영 변환 )◦ 사진의 크기를 결정한다 ( 뷰포트 변환 ).

2013-2 학기 3 장 뷰잉

Page 5: Chapter 3.  뷰잉 (Viewing)

정점 변환의 단계정점 변환의 단계 뷰잉 , 모델링 , 투영 변환을 설정하려면 4 * 4 행렬 M 을 만들고 장면의

각 정점 v 에 대한 좌표와 곱해서 수행◦ v’ = Mv

사용자가 지정한 뷰잉 및 모델링 변환을 통해 모델 뷰 행렬을 만들 수 있는데 이는 입력된 오브젝트 좌표에 적용 , 눈좌표 (eye coordinates) 생성

투영 행렬을 적용하여 클립 좌표 (clip coordinate) 를 생성

좌표값을 w 로 나누는 투시분할 (perspective division) 을 실행하여 정규화 장치 좌표를 생성

변환된 좌표는 뷰포트 변환을 거쳐 윈도우 좌표로 변환

2013-2 학기 3 장 뷰잉

Page 6: Chapter 3.  뷰잉 (Viewing)

정점 변환의 단계정점 변환의 단계

2013-2 학기

xyzw

Modelviewmatrix

Projectionmatrix

Perspectivematrix

Viewporttransformation

Vertex

눈좌표

클립좌표

정규화장치좌표

윈도우좌표

오브젝트좌표

3 장 뷰잉

Page 7: Chapter 3.  뷰잉 (Viewing)

정육면체를 그리는 간단한 정육면체를 그리는 간단한 [[ 예제 예제 3 3 –– 1]: cube.c 1]: cube.c#include <GL/glut.h>#include <stdlib.h>

void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_FLAT); }

void display(void){ glClear (GL_COLOR_BUFFER_BIT); glColor3f (1.0, 1.0, 1.0); glLoadIdentity (); /* 행렬을 클리어 */ gluLookAt (0.0,0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); /* 뷰잉변환

*/ glScalef (1.0, 2.0, 1.0); /* 모델 변환 */ glutWireCube (1.0); glFlush (); }

2013-2 학기 3 장 뷰잉

Page 8: Chapter 3.  뷰잉 (Viewing)

void reshape (int w, int h){ glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0); glMatrixMode (GL_MODELVIEW);}

void keyboard(unsigned char key, int x, int y){ switch (key) { case 27: exit(0); break; }}

2013-2 학기 3 장 뷰잉

Page 9: Chapter 3.  뷰잉 (Viewing)

int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0;}

2013-2 학기 3 장 뷰잉

Page 10: Chapter 3.  뷰잉 (Viewing)

실행결과실행결과

2013-2 학기 3 장 뷰잉

Page 11: Chapter 3.  뷰잉 (Viewing)

뷰잉 변환뷰잉 변환 뷰잉 변환은 카메라의 위치와 방향을 지정하는 것에 비유

위의 [ 예제 3 – 1]

◦ glLoadIdentity() 를 사용 , 현재 행렬을 단위행렬로 설정◦ 행렬을 초기화 후 , gluLookAt() 으로 뷰잉 변환 지정

gluLookAt() 을 호출하지 않으면 디폴트 위치와 방향설정 카메라 위치 , 바라볼 방향 , 어느쪽이 위쪽인지를 지정

카메라 위치 : (0, 0, 5) 바라볼 방향 : (0, 0, 0) 업벡터 (up-vector): (0, 1, 0)

2013-2 학기 3 장 뷰잉

Page 12: Chapter 3.  뷰잉 (Viewing)

모델링 변환모델링 변환모델의 위치와 방향은 모델링 변환으로 조절

◦ 모델을 회전 변환 , 평행이동 변환 , 크기 변환 등을 사용

◦ [ 예제 3 – 1] 에서 glScalef() 를 사용하여 모델링 변환정육면체를 볼 수 있도록 뷰잉 변환으로 카메라를

이동하는 대신 모델링 변환으로 카메라로부터 떨어지도록 설정 가능◦ 이원성 (duality) 존재로 뷰잉 변환과 모델링 변화을

하나의 모델뷰 행렬 (modelview matrix) 로 설정

2013-2 학기 3 장 뷰잉

Page 13: Chapter 3.  뷰잉 (Viewing)

투영 변환투영 변환 투영 변환을 설정하는 것은 카메라 렌즈를 고르는 것과 비슷 화각 (field of view) 이나 관측 공간 (viewing volume) 을 결정 어떤 오브젝트가 관측 공간 안에 들어 있게 되는지 , 어느 정도

보이게 되는지 결정 투영의 방식 ( glFrustum() 사용 )

◦ 원근 (perspective) 투영 멀리 있는 물체는 가까이 있는 것보다 작게 나타남 glFrustum() 커맨드 사용

◦ 직교 (orthographic) 투영 상대적인 크기에 관계 없이 물체를 스크린에 그대로 매핑 건축설계 및 CAD 설계용 응용 프로그램에서 주로 사용하며 ,

정확한 물체의 크기를 표현하는데 중점을 둠

2013-2 학기 3 장 뷰잉

Page 14: Chapter 3.  뷰잉 (Viewing)

뷰포트 변환뷰포트 변환 투영 변환과 뷰포트 변환은 장면과 컴퓨터 스크린이 매핑되는 방식을

결정◦ 투영변환은 매핑이 구체적으로 어떻게 이루어지는지 결정◦ 뷰포트 변환은 스크린을 매핑할 스크린 영역의 모양 나타냄

glViewport() 의 인자는 스크린 공간에 대한 원점 , 영역의 폭과 높이 설정 , 픽셀 단위로 표현◦ 이 커맨드는 reshape() 루틴 안에서 호출되어야 함◦ 윈도우의 크기를 변경하면 뷰포트 역시 변경해야 함

2013-2 학기 3 장 뷰잉

Page 15: Chapter 3.  뷰잉 (Viewing)

장면 그리기장면 그리기 장면에 나온 모든 오브젝트의 각 정점을 모델링 및 뷰잉 변환에

따라 변환 변환된 정점들은 투영 변환에 따라 변환 투영 변환에서 지정된 공간을 벗어나는 오브젝트들은 잘라냄

(Clip) 변환된 정점들을 w 로 나눈 후 뷰포트에 매핑

2013-2 학기 3 장 뷰잉

Page 16: Chapter 3.  뷰잉 (Viewing)

범용 변환 커맨드범용 변환 커맨드 변환을 직접 설정하는데 유용한 커맨드

◦ glMatrixMode()◦ glLoadIdentity()◦ glLoadMatrix*()◦ glMultMatrix*()◦ gluLookAt()◦ glScale()

void glMatrixMode(GLenum mode)◦ 변환 커맨드를 실행하기 전에 모델뷰 , 투영 , 텍스처 행렬을 수정할지

여부 결정◦ mode : GL_MODELVIEW, GL_PROJECTION, GL_TEXTURE

void glLoadIdentity(void);◦ 나중에 실행할 변환 커맨드를 위해 수정 가능한 행렬을 클리어◦ 현재 수정 가능한 행렬을 4x4 단위 행렬로 설정

2013-2 학기 3 장 뷰잉

Page 17: Chapter 3.  뷰잉 (Viewing)

현재 행렬로 로드할 행렬을 명시적으로 지정하기 위한 커맨드◦ void glLoadMatrix{fd}(const TYPE *m);

현재 행렬의 16 개 값 (4 * 4) 을 m 으로 지정된 행렬의 값으로 설정

◦ void glMultMatrix{fd}(const TYPE *m); m 이 가리키는 16 개 값으로 지정된 행렬을 현재 행렬과

곱하고 , 그 결과를 현재 행렬에 저장

2013-2 학기

m1 m5 m9 m13

m2 m6 m10 m14

m3 m7 m11 m15

m4 m8 m12 m16

M =

[ 주의사항 ]행렬을 m[4][4] 로 선언했다면m[i][j] 원소는 OpenGL 변환행렬의 j 행 , i 열에 있음 .C 와는 반대

3 장 뷰잉

Page 18: Chapter 3.  뷰잉 (Viewing)

뷰잉 및 모델링 변환뷰잉 및 모델링 변환 모델링 변환이나 뷰잉 변환을 실행하기 위해서는 반드시

glMatrixMode() 에 GL_MODELVIEW 를 인자로 주고 호출해야 함 .

변환 이해하기

◦ 모든 뷰잉 변환 및 모델링 변환은 4 * 4 행렬로 표현◦ glMultMatrix*() 과 같은 변환 커맨드들은 새로 주어진 4 *

4 행렬 M 을 현재 모델뷰 행렬 C 와 곱하여 CM 을 생성◦ 그 다음 , 정점 v 를 현재 모델뷰 행렬에 곱함◦ 즉 , 프로그램 상에서 가장 늦게 호출한 변환 커맨드가

정점에 가장 먼저 적용 (CMv)

2013-2 학기 3 장 뷰잉

Page 19: Chapter 3.  뷰잉 (Viewing)

예제 glMatrixMode (GL_MODELVIEW); glLoadIdentity(); glMultMatrix(N); glMultMatrix(M); glMultMtrix(L); glBegin(GL_POINTS); glVertex3f(v); glEnd();

모델뷰 행렬은 I, N, NM, NML 순서로 변경 정점변환은 N(M(Lv)) 와 같이 수행 v 에 대해 변환을 수행한 결과는 이들을 지정한 순서와는

반대로 나타냄 . 실제로는 정점에 대해 모델뷰 행렬을 한번만 곱한다 . L, M, N

행렬들을 한번에 곱한 후 v 에 적용 .

2013-2 학기 3 장 뷰잉

Page 20: Chapter 3.  뷰잉 (Viewing)

고정 좌표계고정 좌표계 모델의 위치 , 방향 , 크기 등에 영향을 미치는 행렬 곱셈을 고정

좌표계 (Grand, Fixed Coordinate System) 관점에서 생각할 경우 , 코드에 나온 순서와 반대로 곱셈이 수행

연산 ( 회전 , 평행 이동 ) 을 수행한 후 오브젝트가 좌표축에 놓여 있도록 하기 위해서는 ( 오브젝트는 원점에서 생성 )

회전을 먼저 한 후 , 평행이동 시켜야 함

명령문 예 ( 역순으로 지정해야 )◦ glMatrixMode(GL_MODELVIEW);◦ glLoadIdentity();◦ glMultMatrixf(T); /* 평행이동 */◦ glMultMatrixf(R); /* 회 전 */◦ Draw_the_object();

2013-2 학기

1-Rotate

2-Translate

3 장 뷰잉

Page 21: Chapter 3.  뷰잉 (Viewing)

로컬 좌표계 이동하기로컬 좌표계 이동하기 행렬 곱셈을 바라볼 때 변환할 오브젝트가 고정 좌표계에 있지 않

고 , 오브젝트에 로컬 좌표계가 달려 있는 것처럼 생각 모든 연산들은 이러한 좌표계에 상대적으로 수행 이러한 접근 방식에서는 행렬 곱셈이 코드상에 지정된 순서대로

실행 앞의 예제를 다음과 같이 실행하게 된다 .

◦ 좌표계가 달린 오브젝트를 그리고◦ 오브젝트와 오브젝트에 지정된 좌표계를 X 축으로 평행

이동시킨다 .◦ 원점에 대해 회전시키면 오브젝트는 X 축상의 평행 이동된

위치에서 회전하게 됨 .

2013-2 학기 3 장 뷰잉

Page 22: Chapter 3.  뷰잉 (Viewing)

모델링 변환모델링 변환 모델링 변환을 위해 세가지 커맨드들을 제공

◦ 평행이동 void glTranslate{fd}(TYPE x, TYPE y, TYPE z);

◦ 회전 void glRotate{fd}(TYPE angle, TYPE x, TYPE y, TYPE z);

오브젝트 ( 또는 로컬좌표계 ) 를 원점에서 (x, y, z) 에 이르는 선을 기준으로 반시계 방향으로 angle 각도 만큼 회전

◦ 크기변환 void glScale{fd}(TYPE x, TYPE y, TYPE z);

평행이동 , 회전 , 크기변환 행렬 등을 계산한 뒤에 glMultMatrix*()의 인자로 전달하고 호출하는 것과 동일하다 .

glMultMatrix*() 사용보다는 위의 세 루틴 사용이 좀 더 빠르게 동작함 .

2013-2 학기 3 장 뷰잉

Page 23: Chapter 3.  뷰잉 (Viewing)

모델링 변환 예제모델링 변환 예제 솔리드 와이어프레임 삼각형을 아무런 모델링 변환도 적용 안함 삼각형을 대시 모양의 라인 스티플과 평행이동 변환을 사용 높이 (y 축 ) 는 절반 줄이고 폭 (x 축 ) 은 50% 늘인 긴 대시

모양의 라인 스티플 삼각형을 점선으로 표현 , 회전

2013-2 학기 3 장 뷰잉

Page 24: Chapter 3.  뷰잉 (Viewing)

#include <GL/glut.h>#include <stdlib.h>

void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_FLAT);}

void draw_triangle(void){ glBegin (GL_LINE_LOOP); glVertex2f(0.0, 25.0); glVertex2f(25.0, -25.0); glVertex2f(-25.0, -25.0); glEnd();}

2013-2 학기 3 장 뷰잉

Page 25: Chapter 3.  뷰잉 (Viewing)

뷰잉 및 모델링 변환뷰잉 및 모델링 변환void display(void){

glClear (GL_COLOR_BUFFER_BIT);

glColor3f (1.0, 1.0, 1.0);

glLoadIdentity ();

glColor3f (1.0, 1.0, 1.0);

draw_triangle ();

glEnable (GL_LINE_STIPPLE);

glLineStipple (1, 0xF0F0);

glLoadIdentity ();

glTranslatef (-20.0, 0.0, 0.0);

draw_triangle ();

2013-2 학기 3 장 뷰잉

Page 26: Chapter 3.  뷰잉 (Viewing)

glLineStipple (1, 0xF00F); glLoadIdentity (); glScalef (1.5, 0.5, 1.0); draw_triangle ();

glLineStipple (1, 0x8888); glLoadIdentity (); glRotatef (90.0, 0.0, 0.0, 1.0); draw_triangle (); glDisable (GL_LINE_STIPPLE);

glFlush ();}

2013-2 학기 3 장 뷰잉

Page 27: Chapter 3.  뷰잉 (Viewing)

void reshape (int w, int h)

{

glViewport (0, 0, (GLsizei) w, (GLsizei) h);

glMatrixMode (GL_PROJECTION);

glLoadIdentity ();

if (w <= h)

glOrtho (-50.0, 50.0, -50.0*(GLfloat)h/(GLfloat)w,

50.0*(GLfloat)h/(GLfloat)w, -1.0, 1.0);

else

glOrtho (-50.0*(GLfloat)w/(GLfloat)h,

50.0*(GLfloat)w/(GLfloat)h, -50.0, 50.0, -1.0, 1.0);

glMatrixMode(GL_MODELVIEW);

}

2013-2 학기 3 장 뷰잉

Page 28: Chapter 3.  뷰잉 (Viewing)

void keyboard(unsigned char key, int x, int y)

{ switch (key) { case 27: exit(0); break; }}

2013-2 학기 3 장 뷰잉

Page 29: Chapter 3.  뷰잉 (Viewing)

int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc (keyboard); glutMainLoop(); return 0;}

2013-2 학기 3 장 뷰잉

Page 30: Chapter 3.  뷰잉 (Viewing)

실행결과실행결과

2013-2 학기 3 장 뷰잉

Page 31: Chapter 3.  뷰잉 (Viewing)

Nate Robins Nate Robins 의 변환관련 의 변환관련 튜토리얼튜토리얼 http://www.cs.utah.edu/~narobins/opengl.html

transformation 프로그램 실행

2013-2 학기 3 장 뷰잉

Page 32: Chapter 3.  뷰잉 (Viewing)

뷰잉 변환뷰잉 변환 뷰잉 변환을 사용하면 시점의 위치와 방향을 변경 카메라 비유에서 본 것처럼 뷰잉 변환은 카메라를 삼각대에 놓고 ,

모델을 향하도록 조절하는 단계 뷰잉 변환은 일반적으로 이동 변환과 회전변환으로 구성 반시계 방향으로 오브젝트를 회전시키는 모델링 변환은 카메라를

시계 방향으로 회전시키는 뷰잉 변환과 동일한 효과를 얻을 수 있다 . 뷰잉 변환에 관련된 커맨드들은 반드시 모델링 변환을 수행하기 전에

호출해야만 오브젝트에 대한 모델링 변환의 효과가 먼저 나타나게 된다 .

뷰잉 변환의 다양한 방법◦ 한 개 이상의 모델링 변환 커맨드 사용

glTranslate*(), glRotate*() 등◦ 유틸리티 라이브러리 루틴인 gluLookAt() 사용 , 시선을 정의◦ 회전 변환 , 이동 변환을 캡슐화 하는 유틸리티를 직접 만듬

2013-2 학기 3 장 뷰잉

Page 33: Chapter 3.  뷰잉 (Viewing)

glTranslate*() glTranslate*() 와 와 glRotate*() glRotate*() 사용하기사용하기

뷰잉변환 표현을 위해 모델링 변환을 사용할 때◦ 오브젝트는 월드 공간에 고정시켜두고 시점만 이동시켜야 하는

경우가 있다 .◦ 초기에는 시점이 원점에 있고 , 대부분 오브젝트는 원점에

생성되어 있기 때문에 몇 가지 변환 필요◦ 카메라는 초기에 z 축의 음의 방향을 향하고 있음◦ 간단한 방법으로 시점을 오브젝트 뒤로 이동

glTranslatef(0.0, 0.0, -5.0); 오브젝트를 장면으로부터 z 축 방향으로 – 5만큼 이동시킨다 . 카메라를 z 축 방향으로 +5 만큼 이동시킨 것과 같은 효과

2013-2 학기 3 장 뷰잉

Page 34: Chapter 3.  뷰잉 (Viewing)

시점과 오브젝트 분리 : glTranslate(0.0, 0.0, -5.0) 한 후

2013-2 학기

x

y

z

카메라

z

카메라 x

y

3 장 뷰잉

Page 35: Chapter 3.  뷰잉 (Viewing)

오브젝트를 옆에서 보도록 설정하는 경우

◦ 고정 좌표계 방식으로 생각할 경우 오브젝트를 회전 카메라로부터 멀리 떨어지도록 이동 고정 좌표계에서는 실제 효과 순서와 역순으로 커맨드 호출

◦ 로컬 좌표계 방식으로 생각할 경우 오브젝트와 로컬 좌표계를 원점으로부터 이동 그 뒤 회전 변환은 이동된 좌표계를 기준으로 회전 로컬 좌표계는 순서대로 커맨드 호출

2013-2 학기 3 장 뷰잉

Page 36: Chapter 3.  뷰잉 (Viewing)

gluLookAt() gluLookAt() 유틸리티 유틸리티 사용하기사용하기

원점이나 그 밖의 편리한 위치에서 장면을 구성한 다음 이를 임의의 지점에서 바라보도록 코드를 작성

이 루틴은 시점의 위치를 나타내는 세 개의 인자를 받아서 카메라가 바라볼 기준점 (reference point) 과 어느뱡향이 위쪽인지 결정

gluLookAt() 루틴은 카메라를 상하 , 좌우로 움직이며 바라볼 때 특히 유용

관측공간이 x, y 모두에 대칭일 경우 점 (eyex, eyey, eyez) 는 항상 이미지의 중앙에 위치하기 때문에 이 점을 이동시키면 카메라를 상하 혹은 좌우로 이동시키는 효과를 얻는다 .

void gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, GLdouble upz)◦ 원하는 시점 : eyex, eyey, eyez◦ 바라보는 장면의 가운데 지점 : centerx, centery, centerz◦ 관측공간의 아래에서 위로의 방향 : upx, upy, upz

2013-2 학기 3 장 뷰잉

Page 37: Chapter 3.  뷰잉 (Viewing)

카메라의 디폴트 위치는 원점이고 디폴트 방향을 z 축의 음의 방향이며 위쪽에 대한 기본값을 y 축의 양의 방향일 때 ,◦ gluLookAt(0,0, 0.0, 0.0, 0.0, 0.0, -100, 0.0, 1.0,

0.0); 기준점의 z 값은 어떠한 음수로도 상관 없다 . 같은 효과 .

2013-2 학기

x

y

z

카메라

x

y

업벡터

3 장 뷰잉

Page 38: Chapter 3.  뷰잉 (Viewing)

gluLookAt(4.0, 2.0, 1.0, 2.0, 4.0, -3.0, 2.0, 2.0, -1.0);

2013-2 학기

x

y

z

카메라

(4.0, 2.0, 1.0)

(2.0, 4.0, -3.0)

(2,0, 2.0, -1.0)

3 장 뷰잉

Page 39: Chapter 3.  뷰잉 (Viewing)

Nate Robins 의 투영 관련 튜토리얼◦ projection 프로그램

2013-2 학기 3 장 뷰잉

Page 40: Chapter 3.  뷰잉 (Viewing)

투영 변환투영 변환 투영 변환은 관측 공간을 정의하는데 사용

◦ 두 가지 방식 오브젝트가 스크린에 투영 되는 형태 ( 원근 , 직교 투영 ) 최종 이미지에서 어떤 오브젝트가 클리핑 될지를 결정

◦ 여기에서 설명하는 커맨드를 호출하기 전에 반드시 다음과 같은 커맨드를 호출 glMatrixMode(GL_PROJECTION); glLoadIdentity();

2013-2 학기 3 장 뷰잉

Page 41: Chapter 3.  뷰잉 (Viewing)

원근 투영원근 투영 (perspective (perspective projection)projection)

원근투영의 가장 큰 특징은 바로 포쇼트닝 (foreshortening) Foreshortening : 단축법 , 오브젝트가 카메라로부터 멀리

떨어질수록 작게 그리는 기법◦ 이런 효과는 관측 공간을 피라미드의 절두체로 정의할 때 나타남◦ 절두체 : frustum, 밑면과 평행으로 꼭지 부분을 잘라낸 피라미드

오브젝트들은 피라미드의 정점 (apex) 방향으로 투영하며 이 지점에 카메라 혹은 시점 위치

시점에 가까이 놓여진 오브텍트들은 먼 것보다 크게 보임

2013-2 학기

Wikipedia Figure shows two different projections of a stack of two cubes, illustrating oblique parallel projection foreshortening ("A") and perspective foreshortening ("B").

3 장 뷰잉

Page 42: Chapter 3.  뷰잉 (Viewing)

void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);

◦ 원근 투영을 나타내는 행렬을 생성하고 이를 현재 행렬과 곱한다 .

◦ 관측 공간 ( 절두체 ) 은 이 공간 밖에 놓인 오브젝트들을 클리핑 하는데 사용됨

◦ 절두체 정의 (left, bottom, -near) 와 (right, top, -near) 각각 카메라와 가까운 곳에 위치한 클리핑 평면의 좌측 하단

모서리와 우측 상단 모서리 좌표를 나타냄 near 와 far 인자는 항상 양수로 정해야 함

2013-2 학기 3 장 뷰잉

Page 43: Chapter 3.  뷰잉 (Viewing)

void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far);

◦ glFrustum() 과 같은 관측 공간 생성 , 지정방식의 차이가 있다 .◦ fovy 는 y 축 방향의 FOV 각도를 나타냄◦ aspect 인자는 절두체의 종횡비 (x/y, 정사각형의 경우 종횡비는 1.0 이다 )

2013-2 학기

카메

wh

Aspect = w/h

fovy

near far

3 장 뷰잉

Page 44: Chapter 3.  뷰잉 (Viewing)

직교 투영직교 투영 (Orthogonal (Orthogonal projection)projection) 평행 육면체 모양의 관측 공간을 사용 .

원근 투영과 달리 관측 공간의 양 끝면의 크기가 일정 . 카메라의 거리가 오브젝트의 모양에 영향을 안 미침 . 건축 설계도나 CAD 설계 등과 같이 오브젝트의 크기와 각도를 정확히

유지해야 하는 응용 프로그램에서 주로 사용

2013-2 학기

관측공간

top

left

far

right

bottomnear

시점방향

3 장 뷰잉

Page 45: Chapter 3.  뷰잉 (Viewing)

직교형 관측 공간의 생성◦ glOrtho() 커맨드로 생성◦ void glOrtho(GLdouble left, GLdouble right, GLdouble

bottom, GLdouble top, GLdouble near, GLdouble far); 직교관측공간의 행렬을 생성하고 이를 현재 행렬과 곱한다 . glFrustum() 과 동일한 방식의 인자 .

near 클리핑 평면의 좌측 하단 모서리와 우측 상단 모서리에 해당하는 점인 (left, bottom, -near) 와 (right, top, -near) 는 각각 뷰포트 윈도우의 좌측 하단 및 우측 상단 모서리에 매핑된다 .

투영의 방향은 z 축과 평행하며 , 시점은 z 축의 음의 방향

2013-2 학기 3 장 뷰잉

Page 46: Chapter 3.  뷰잉 (Viewing)

이미지를 2차원 스크린에 투영하는 특수한 경우◦ void gluOrtho2D(GLdouble left, GLdouble right, GLdouble

bottom, GLdouble top);

◦ 2차원 좌표를 스크린에 투영하는 행렬을 생성하고 현재 행렬과 곱한다 . ◦ 클리핑 영역

좌측 하단 모서리 (left, bottom) 우측 상단 모서리 (right, top)

Nate Robins 의 투영 관련 튜토리얼◦ projection 프로그램

관측 공간 클리핑 (clipping)

◦ 장면에 있는 오브젝트 정점들을 모델뷰 행렬과 투영 행렬로 모두 변환하였다면 공간의 밖에 있는 모든 프리미티브 들은 클리핑된다 .

2013-2 학기 3 장 뷰잉

Page 47: Chapter 3.  뷰잉 (Viewing)

뷰포트 변환뷰포트 변환 뷰포트 변환

◦ 카메라에 비유하면 , 뷰포트 변환을 현상할 사진의 크기를 선택하는 단계

◦ 컴퓨터 그래픽스에서 뷰포트는 그려질 윈도우의 직사각형 모양의 영역

◦ 뷰포트는 윈도우 좌표로 측정◦ 측정된 좌표는 윈도우의 좌측 하단 모서리를 기준으로 스크린

상의 픽셀 위치로 표현

2013-2 학기 3 장 뷰잉

Page 48: Chapter 3.  뷰잉 (Viewing)

뷰포트 정의하기뷰포트 정의하기 스크린 상에 윈도우를 생성하는 작업은 OpenGL 이 아닌 윈도우

시스템이 담당 윈도우를 처음 생성할 때 전체 윈도우에 해당하는 픽셀 영역을

뷰포트로 설정 이보다 작은 영역을 뷰포트로 설정할 때는 glViewport() 커맨드

사용 void glViewport(GLint x, GLint y, Glsizei width, Glsizei

height);◦ 최종 이미지가 매핑될 윈도우의 픽셀 사각형을 정의한다 .◦ x, y 매개변수는 이러한 뷰포트의 좌측 하단 모서리 나타냄◦ width, 와 height 인자는 뷰포트의 크기를 지정

뷰포트의 종횡비는 관측공간의 종횡비와 비슷하다 . 두 비율이 서로 다르면 투영된 이미지가 서로 뒤틀리게 된다 .

2013-2 학기 3 장 뷰잉

Page 49: Chapter 3.  뷰잉 (Viewing)

변환된 깊이 좌표변환된 깊이 좌표 뷰포트 변환이 수행되는 동안 깊이 (z) 좌표는 인코딩 Z 값을 원하는 범위 내에서 조절하려면 glDepthRange() 사용 윈도우의 x, y 좌표와는 달리 OpenGL 에서 z 좌표는 항상 0.0 과

1.0 사이에 있는 것으로 취급된다 .

void glDepthRange(GLclampd near, GLclampd far);◦ 뷰포트 변환에서 사용될 z 좌표를 인코딩한다 . ◦ near, far 인자는 깊이 버퍼에 저장될 최소 및 최대 수정 범위◦ 기본적으로 이 값은 0.0 과 1.0 으로 설정

2013-2 학기 3 장 뷰잉

Page 50: Chapter 3.  뷰잉 (Viewing)

행렬 스택 조작하기행렬 스택 조작하기 행렬 스택은 단순한 모델로 부터 복잡한 모델을 구성하는 것처럼 모델을

계층적으로 구성할 때 유용 행렬연산 (glLoadMatrix(), glMultMatrix(), glLoadIdentity()) 과 특정한

변환행렬을 생성하는 커맨드들은 현재 행렬이나 스택의 top 행렬을 처리 . 현재 행렬에 대한 복사본을 수택의 top 에 복사하는 glPushMatrix() 나 ,

스택의 top 행렬을 버리는 glPopMatrix() 와 같은 커맨드를 사용 , top 의 원소를 지정◦ glPushMatrix() : 현재 위치를 저장◦ glPopMatrix() : 이전 위치로 되돌려 놓는다 .

void glPushMatrix(void):◦ 현재 스택에 있는 모든 행렬들을 한 단계 아래로 이동 (push)

void glPopMatrix(void);◦ 스택의 top 원소 ( 행렬 ) 를 뽑아낸다 (pop)

현재 스택은 glMatrixMode() 로 결정한다 .

2013-2 학기 3 장 뷰잉

Page 51: Chapter 3.  뷰잉 (Viewing)

예제 예제 3-4 3-4 행렬을 행렬을 push push 또는 또는 pop pop 하기하기

draw_wheel_and_bolts()

{

long i;

draw_wheel();

for (i = 0; i < 5; i++) { glPushMatrix();

glRotatef(72.0*i, 0.0, 0.0, 1.0); glTranslatef(3.0, 0.0, 0.0); draw_bolt();

glPopMatrix();

}

}

2013-2 학기 3 장 뷰잉

Page 52: Chapter 3.  뷰잉 (Viewing)

draw_body_and_wheel_and_bolts()

{

draw_car_body();

glPushMatrix(); glTranslatef(40, 0, 30); /* 첫번째 바퀴의 위치로 이동 */ draw_wheel_and_bolts();

glPopMatrix();

glPushMatrix(); glTranslatef(40, 0, -30); /* 두 번째 바퀴의 위치로 이동 */ draw_wheel_and_bolts();

glPopMatrix();

}

2013-2 학기 3 장 뷰잉

Page 53: Chapter 3.  뷰잉 (Viewing)

모델뷰 행렬 스택모델뷰 행렬 스택 모델뷰 행렬에는 뷰잉 및 모델링 변환 행렬을 곱한 값들이

누적되어 있다 . 각각의 뷰잉 또는 모델링 변환들은 현재 모델뷰 행렬과 곱할

새로운 행렬을 생성 변환의 결과로 생성된 행렬은 새로운 현재 행렬로 설정 모델뷰 행렬 스택에는 최소 32 개의 4x4 행렬들을 저장할 수

있다 . 초기에는 스택의 Top 원소로 단위 행렬이 저장 스택의 최대 저장 개수 확인

◦ glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH, GLint *params);

2013-2 학기 3 장 뷰잉

Page 54: Chapter 3.  뷰잉 (Viewing)

투영 행렬 스택투영 행렬 스택 투영행렬 스택은 관측 공간을 구성하는 투영 변환을 위한 행렬을

저장 투영 행렬을 직접 작성하지 않기 때문에 투영 변환을 수행하기

전에 glLoadIdentity() 를 호출 스택의 깊이를 확인

◦ glGetIntegerv(GL_MAX_PROJECTION_STACK_DEPTH, GLlint *params);

2013-2 학기 3 장 뷰잉

Page 55: Chapter 3.  뷰잉 (Viewing)

부가적인 클리핑 평면부가적인 클리핑 평면 관측공간에 존재하는 여섯 개의 클리핑 평면 (left, right, bottom, top, near,

far)외에도 , 부가적인 클리핑 평면을 최대 여섯 개 까지 정의하여 관측 공간에 좀더 제한을 가할 수 있다 .

오브젝트의 단면을 보여줄 때와 같이 (cutaway view) 오브젝트의 불필요한 부분을 제거할 때 유용하다 .

각 평면은 다음과 같은 방적식의 계수로 표현◦ Ax + By + Cz + D = 0;

void glClipPlane(GLenum plane, const GLdouble *equation);◦ 클리핑 평면을 정의한다 .◦ equation 인자는 평면방정식의 4 개의 계수를 나타낸다 .◦ plane 인자는 GL_CLIP_PLANEi 로서 i는 사용 가능한 클리핑 공간을

가리킨다 .

정의한 클리핑 평면들은 다음과 같이 활성화시킨다 .◦ glEnable(GL_CLIP_PLANEi);

비활성화시킬 때는 ◦ glDisable(GL_CLIP_PLANEi);

2013-2 학기 3 장 뷰잉

Page 56: Chapter 3.  뷰잉 (Viewing)

클리핑 평면에 대한 코드 클리핑 평면에 대한 코드 [[ 예제 예제 3 3 –– 5 ]: clip.c5 ]: clip.c

#include <GL/glut.h>#include <stdlib.h>

void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_FLAT);}

void display(void){ GLdouble eqn[4] = {0.0, 1.0, 0.0, 0.0}; GLdouble eqn2[4] = {1.0, 0.0, 0.0, 0.0};

glClear(GL_COLOR_BUFFER_BIT);

2013-2 학기 3 장 뷰잉

Page 57: Chapter 3.  뷰잉 (Viewing)

glColor3f (1.0, 1.0, 1.0); glPushMatrix(); glTranslatef (0.0, 0.0, -5.0);

/* 아래쪽 절반 클리핑 -- y < 0 */ glClipPlane (GL_CLIP_PLANE0, eqn); glEnable (GL_CLIP_PLANE0); /* 왼쪽 절반 클리핑 -- x < 0 */ glClipPlane (GL_CLIP_PLANE1, eqn2); glEnable (GL_CLIP_PLANE1); glRotatef (90.0, 1.0, 0.0, 0.0); glutWireSphere(1.0, 20, 16); glPopMatrix(); glFlush ();}

2013-2 학기 3 장 뷰잉

Page 58: Chapter 3.  뷰잉 (Viewing)

void reshape (int w, int h){ glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0); glMatrixMode (GL_MODELVIEW);}

void keyboard(unsigned char key, int x, int y){ switch (key) { case 27: exit(0); break; }}

2013-2 학기 3 장 뷰잉

Page 59: Chapter 3.  뷰잉 (Viewing)

int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0;}

2013-2 학기 3 장 뷰잉

Page 60: Chapter 3.  뷰잉 (Viewing)

실행결과실행결과

2013-2 학기 3 장 뷰잉

Page 61: Chapter 3.  뷰잉 (Viewing)

여러가지 변환 함께 사용하기여러가지 변환 함께 사용하기 태양계 만들기

#include <GL/glut.h>

#include <stdlib.h>

static int year = 0, day = 0;

void init(void) {

glClearColor (0.0, 0.0, 0.0, 0.0);

glShadeModel (GL_FLAT);

}

2013-2 학기 3 장 뷰잉

Page 62: Chapter 3.  뷰잉 (Viewing)

void display(void){ glClear (GL_COLOR_BUFFER_BIT); glColor3f (1.0, 1.0, 1.0);

glPushMatrix(); glutWireSphere(1.0, 20, 16); /* 태양을 그린다 */ glRotatef ((GLfloat) year, 0.0, 1.0, 0.0); glTranslatef (2.0, 0.0, 0.0); glRotatef ((GLfloat) day, 0.0, 1.0, 0.0); glutWireSphere(0.2, 10, 8); /* 작은 행성을 그린다 */ glPopMatrix(); glutSwapBuffers();}

2013-2 학기 3 장 뷰잉

Page 63: Chapter 3.  뷰잉 (Viewing)

void reshape (int w, int h)

{

glViewport (0, 0, (GLsizei) w, (GLsizei) h);

glMatrixMode (GL_PROJECTION);

glLoadIdentity ();

gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

}

2013-2 학기 3 장 뷰잉

Page 64: Chapter 3.  뷰잉 (Viewing)

void keyboard (unsigned char key, int x, int y)

{

switch (key) {

case 'd':

day = (day + 10) % 360;

glutPostRedisplay();

break;

case 'D':

day = (day - 10) % 360;

glutPostRedisplay();

break;

2013-2 학기 3 장 뷰잉

Page 65: Chapter 3.  뷰잉 (Viewing)

case 'y': year = (year + 5) % 360; glutPostRedisplay(); break; case 'Y': year = (year - 5) % 360; glutPostRedisplay(); break; case 27: exit(0); break; default: break; }}

2013-2 학기 3 장 뷰잉

Page 66: Chapter 3.  뷰잉 (Viewing)

int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0;}

2013-2 학기 3 장 뷰잉

Page 67: Chapter 3.  뷰잉 (Viewing)

실행 결과실행 결과

2013-2 학기 3 장 뷰잉

Page 68: Chapter 3.  뷰잉 (Viewing)

로봇팔 만들기로봇팔 만들기#include <GL/glut.h>

#include <stdlib.h>

static int shoulder = 0, elbow = 0;

void init(void)

{

glClearColor (0.0, 0.0, 0.0, 0.0);

glShadeModel (GL_FLAT);

}

2013-2 학기 3 장 뷰잉

Page 69: Chapter 3.  뷰잉 (Viewing)

void display(void)

{

glClear (GL_COLOR_BUFFER_BIT);

glPushMatrix();

glTranslatef (-1.0, 0.0, 0.0);

glRotatef ((GLfloat) shoulder, 0.0, 0.0, 1.0);

glTranslatef (1.0, 0.0, 0.0);

glPushMatrix();

glScalef (2.0, 0.4, 1.0);

glutWireCube (1.0);

glPopMatrix();

2013-2 학기 3 장 뷰잉

Page 70: Chapter 3.  뷰잉 (Viewing)

glTranslatef (1.0, 0.0, 0.0);

glRotatef ((GLfloat) elbow, 0.0, 0.0, 1.0);

glTranslatef (1.0, 0.0, 0.0);

glPushMatrix();

glScalef (2.0, 0.4, 1.0);

glutWireCube (1.0);

glPopMatrix();

glPopMatrix();

glutSwapBuffers();

}

2013-2 학기 3 장 뷰잉

Page 71: Chapter 3.  뷰잉 (Viewing)

void reshape (int w, int h)

{

glViewport (0, 0, (GLsizei) w, (GLsizei) h);

glMatrixMode (GL_PROJECTION);

glLoadIdentity ();

gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

glTranslatef (0.0, 0.0, -5.0);

}

2013-2 학기 3 장 뷰잉

Page 72: Chapter 3.  뷰잉 (Viewing)

void keyboard (unsigned char key, int x, int y){ switch (key) { case 's': shoulder = (shoulder + 5) % 360; glutPostRedisplay(); break; case 'S': shoulder = (shoulder - 5) % 360; glutPostRedisplay(); break; case 'e': elbow = (elbow + 5) % 360; glutPostRedisplay(); break;

2013-2 학기 3 장 뷰잉

Page 73: Chapter 3.  뷰잉 (Viewing)

case 'E':

elbow = (elbow - 5) % 360;

glutPostRedisplay();

break;

case 27:

exit(0);

break;

default:

break;

}

}

2013-2 학기 3 장 뷰잉

Page 74: Chapter 3.  뷰잉 (Viewing)

int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0;}

2013-2 학기 3 장 뷰잉

Page 75: Chapter 3.  뷰잉 (Viewing)

실행 결과실행 결과

2013-2 학기 3 장 뷰잉

Page 76: Chapter 3.  뷰잉 (Viewing)

변환을 역으로 수행하거나 변환을 역으로 수행하거나 흉내내기흉내내기

기하 처리 파이프 라인은 뷰잉 및 투영 행렬 , 뷰포트를 통해 정점의 월드 ( 혹은 오브젝트 ) 좌표를 윈도우 ( 또는 스크린 )좌표로 변환

이러한 처리 순서와 반대로 실행해야 하는 경우가 생김◦ 3 차원상의 위치를 마우스로 선택하는 경우

마우스는 스크린상의 커서의 위치를 나타내는 2차원 값만 반환

프로그램은 변환과정을 역으로 수행하여 마우스로 지정한 스크린의 위치에 대한 3 차원 공간값을 결정해야 한다 .gluUnProject() 와 gluUnProject4() 사용

2013-2 학기 3 장 뷰잉

Page 77: Chapter 3.  뷰잉 (Viewing)

int gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz, const GLdouble modelMatrix[16], const GLdouble projMatrix[16], const GLint viewport[4], GLdouble *objx, GLdouble *objy, GLdouble *objz);

◦ 모델뷰 행렬 (modelMatrix) 과 투영행렬 (projMatrix), 뷰포트 (viewport) 로 정의된 변환을 사용하여 주어진 윈도우 좌표 (winx, winy, winz) 를 오브젝트 좌표 (objx, objy, objz) 에 매핑한다 .

◦ 함수가 성공적이면 GL_TRUE, 에러가 발생하면 GL_FALSE를 리턴한다 .

2013-2 학기 3 장 뷰잉

Page 78: Chapter 3.  뷰잉 (Viewing)

Int gluUnProject4(GLdouble winx, GLdouble winy, GLdouble winz, gldouble clipw, const GLdouble modelMatrix[16], const GLdouble projMatrix[16], const GLint viewport[4], Glclampd zNear, Glclampd zFar, GLdouble *objx, GLdouble *objy, GLdouble *objz);

◦ gluUnProject() 와 비슷 . GLU1.3 에서 변경되어 gluUnProject4() 는 표준값이 아닌 glDepthRange 값뿐만 아니라 1보다 큰 w 좌표값도 처리할 수 있다 .

2013-2 학기 3 장 뷰잉

Page 79: Chapter 3.  뷰잉 (Viewing)

Int gluProject(GLdouble objx, GLdouble objy, GLdouble objz, const GLdouble modelMatrix[16], const GLdouble projMatrix[16], const GLint viewport[4], GLdouble *winx, GLdouble *winy, GLdouble *winz);

◦모델뷰 행렬 (modelMatrix), 투영행렬 (projMatrix), 뷰포트 (viewport) 로 정의된 변환을 통해 주어진 오브젝트 좌표 (objx, objy, objz) 를 윈도우 좌표에 매핑한다 .

◦함수를 성공적으로 수행하면 GL_TRUE, 에러가 발생하면 GL_FALSE 를 리턴한다 .

2013-2 학기 3 장 뷰잉

Page 80: Chapter 3.  뷰잉 (Viewing)

기하 프로세싱 파이프라인을 반대로 기하 프로세싱 파이프라인을 반대로 실행하기 실행하기 [[ 예제 예제 3 3 –– 8 ]: 8 ]: unproject.cunproject.c

#include <GL/glut.h>#include <stdlib.h>#include <stdio.h>

void display(void){ glClear(GL_COLOR_BUFFER_BIT); glFlush();}void reshape(int w, int h){ glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity();

2013-2 학기 3 장 뷰잉

Page 81: Chapter 3.  뷰잉 (Viewing)

gluPerspective (45.0, (GLfloat) w/(GLfloat) h, 1.0, 100.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

}

void mouse(int button, int state, int x, int y)

{

GLint viewport[4];

GLdouble mvmatrix[16], projmatrix[16];

GLint realy; /* OpenGL y 좌표 위치 */

GLdouble wx, wy, wz; /* 변환된 x, y ,z 월드 좌표 */

2013-2 학기 3 장 뷰잉

Page 82: Chapter 3.  뷰잉 (Viewing)

switch (button) {

case GLUT_LEFT_BUTTON:

if (state == GLUT_DOWN) {

glGetIntegerv (GL_VIEWPORT, viewport);

glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);

glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);

/* viewport[3] 은 윈도우의 높이를 픽셀 단위로 나타낸다는 것 주의 */

realy = viewport[3] - (GLint) y - 1;

printf ("Coordinates at cursor are (%4d, %4d)\n", x, realy);

gluUnProject ((GLdouble) x, (GLdouble) realy, 0.0,

mvmatrix, projmatrix, viewport, &wx, &wy, &wz);

printf ("World coords at z=0.0 are (%f, %f, %f)\n",

wx, wy, wz);

2013-2 학기 3 장 뷰잉

Page 83: Chapter 3.  뷰잉 (Viewing)

gluUnProject ((GLdouble) x, (GLdouble) realy, 1.0, mvmatrix, projmatrix, viewport, &wx, &wy, &wz); printf ("World coords at z=1.0 are (%f, %f, %f)\n", wx, wy, wz); } break; case GLUT_RIGHT_BUTTON: if (state == GLUT_DOWN) exit(0); break; default: break; }}

2013-2 학기 3 장 뷰잉

Page 84: Chapter 3.  뷰잉 (Viewing)

void keyboard(unsigned char key, int x, int y)

{

switch (key) {

case 27:

exit(0);

break;

}

}

2013-2 학기 3 장 뷰잉

Page 85: Chapter 3.  뷰잉 (Viewing)

int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc (keyboard); glutMouseFunc(mouse); glutMainLoop(); return 0;}

2013-2 학기 3 장 뷰잉

Page 86: Chapter 3.  뷰잉 (Viewing)

실행 결과실행 결과

2013-2 학기 3 장 뷰잉