Chapter 3. 뷰잉(Viewing).

Slides:



Advertisements
Similar presentations
LOGO OpenGL Project ( 해 결 사 ) 여태기 이수원 정화영 정유나 여태기 이수원 정화영 정유나.
Advertisements

School of Computer, Information and Communication Engineering
제6장 조건문.
Chapter 4 컬러( COLOR ) 학기 가상현실.
3D Computer Graphics 5. Viewing 동신대학교 멀티미디어컨텐츠 연구센터 Viewing Process first part : model-view in Chapter 4 second part : projection in Chapter.
2.1 The Sierpinski Gasket.
CG Programming (Modeling)
CG Programming (Modeling)
Implement of Input and Interaction
OpenGL 실습 12 로봇.
OpenGL Programming (III) 1. Drawing in 3D 2. Manipulating 3D Space
OpenGL 실습 1주차.
5. 좌표변환과 OpenGL행렬 이론.
OpenGL 시작하기.
OpenGL 발표일 : 발표자 : 조윤혜.
블렌딩 안티앨리어싱, 안개효과 그리고 폴리곤 오프셋
Lecture #7 제 4 장. 기하학적 객체와 변환 (2).
기하학적 객체와 변환.
4장 기하학적 객체와 변환 – OpenGL 변환 학습목표 OpenGL 에서 어떻게 변환을 수행하는지 OpenGL 행렬모드 회전
Chapter 5. 라이팅(Lighting)
7장 디스플레이 리스트.
텍 스 처 매 핑.
Practice - texture mapping
OpenGL 이란 그래픽스 하드웨어에 대한 소프트웨어 인터페이스 OpenGL의 전신은 실리콘그래픽스사의 IRIS GL
구조체 활용 구조체 활용.
선 택 과 피 드 백.
1장 – 그래픽스 시스템과 모델 2장 – 그래픽스 프로그래밍 3장 – 입력과 상호작용 4장 – 기하학적 객체와 변환 5장 관측
학습목표 7장. 투상변환과 뷰포트변환 평행투상과 원근투상의 차이점을 이해한다. 가시부피 설정방식을 이해한다.
학습목표 7장. 투상변환과 뷰포트변환 평행투상과 원근투상의 차이점을 이해한다. 가시부피 설정방식을 이해한다.
Department of Computer Engineering
OpenGL Programming (II) 3D Graphics Fundamentals
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
6 프로세스 생성과 실행.
Sang Il Park Sejong University
Department of Computer Engineering
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 02. 프로그램의 기본구성.
테 셀 레 이 션 과 이차 곡 면.
Chapter 06. 선택문.
4. OpenGL 상태들과 기본 도형들.
1장 – 그래픽스 시스템과 모델 2장 – 그래픽스 프로그래밍 3장 – 입력과 상호작용 4장 – 기하학적 객체와 변환
Hanyang University Jungsik Park
3차원 물체 그리기.
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
OpenGL PROJECT 우광식 성기영 서창수 이인주.
Matrix 및 Rendering 파이프라인
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
프 레 임 버 퍼.
adopted from KNK C Programming : A Modern Approach
Open GL GLUT 라이브러리 국내 관련사이트 다운받으세요.
Computer Graphics OpenGL 설치 및 설정
핸드폰 시뮬레이션 김 형 도 송 미 경.
광원 제어 하기.
컴퓨터의 기초 제 2강 - 변수와 자료형 , 연산자 2006년 3월 27일.
Draw the basic Geometry Objects
컴퓨터 프로그래밍 기초 - 4th : 수식과 연산자 -
Chapter 4 컬러( COLOR ).
제어문 & 반복문 C스터디 2주차.
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
Fflush 사용이유 및 방법 [이유] 키보드에서 입력된 내용은 입력버퍼에 저장되었다가 Enter 키가 들어오면 프로그램으로 전달됨 이 때 입력버퍼에 있는 Enter 키도 프로그램으로 전달됨 그러므로 아래와 같은 프로그램에서 문자 하나를 입력해도 Enter키도 입력된 것으로.
OpenGL Introduction 컴퓨터 그래픽스 김 창 헌.
OpenGL 프로젝트 김병욱 김상진 김성환.
Department of Computer Engineering
Part III 애니메이션 Chapter 9 곡선.
쉽게 풀어쓴 C언어 Express 제6장 조건문 C Express Slide 1 (of 28)
쉽게 풀어쓴 C언어 Express 제6장 조건문 C Express.
실습과제 1번 생성된 파일 basic.txt를 프로젝트 폴더에서 메모장으로 열고 내용을 확인
2장 선과 글자 모양에 따른 분류 제품 제작을 하기 위한 도면에는 제품의 정보인 형상, 치수,
argc, argv 의 사용방법 #include <stdio.h>
C 13장. 입출력 라이브러리 #include <stdio.h> int main(void) { int num;
C.
Presentation transcript:

Chapter 3. 뷰잉(Viewing)

3차원 좌표들의 변환과정 다음의 세 가지 컴퓨터 연산이 순차적으로 실행되면서 스크린 상의 픽셀로 변환 다음의 세 가지 컴퓨터 연산이 순차적으로 실행되면서 스크린 상의 픽셀로 변환 모델링, 뷰잉, 투영 연산 등과 같은 행렬 곱셈으로 표현된 변환 회전 변환, 평행이동 변환, 크기 변환, 반사, 직교투영, 원근 투영 등이 포함됨 장면은 사각형 윈도우에 렌더링되기 때문에 오브 젝트 또는 오브젝트의 일부가 윈도우 밖에 놓여 지는 경우 잘라내는 클리핑 수행 변환된 좌표와 스크린 픽셀을 서로 연결시켜주는 뷰포트 변환 2012-2학기 3장 뷰잉

뷰잉(viewing) 카메라 구조 뷰잉 및 모델링 변환 투영 변환 뷰포트 변환 변환에 관련된 문제 해결 방법 행렬 스택 조작하기 부가적인 클리핑 평면 여러가지 변환 함께 사용하기 변환을 역으로 수행하거나 흉내내기 2012-2학기 3장 뷰잉

카메라 구조 원하는 장면을 생성하기 위해 거치는 변환 과정은 카메라로 사진을 찍는 것 에 비유 원하는 장면을 생성하기 위해 거치는 변환 과정은 카메라로 사진을 찍는 것 에 비유 삼각대를 세우고, 카메라가 장면을 향하도 록 설정(뷰잉 변환) 원하는 장면을 화면에 담도록 모델을 정리 (모델링 변환) 사용할 카메라 렌즈를 선택하거나 줌을 조 절(투영 변환) 사진의 크기를 결정한다(뷰포트 변환). 2012-2학기 3장 뷰잉

정점 변환의 단계 뷰잉, 모델링, 투영 변환을 설정하려면 4 * 4 행렬 M을 만들고 장면의 각 정점 v에 대한 좌표와 곱해서 수행 v’ = Mv 사용자가 지정한 뷰잉 및 모델링 변환을 통해 모델 뷰 행렬을 만들 수 있 는데 이는 입력된 오브젝트 좌표에 적용, 눈좌표(eye coordinates) 생성 투영 행렬을 적용하여 클립 좌표(clip coordinate)를 생성 좌표값을 w로 나누는 투시분할(perspective division)을 실행하여 정규화 장치 좌표를 생성 변환된 좌표는 뷰포트 변환을 거쳐 윈도우 좌표로 변환 2012-2학기 3장 뷰잉

정점 변환의 단계 x y Vertex z w 눈좌표 Modelview matrix 오브젝트 좌표 Projection 클립좌표 정규화장치좌표 Perspective matrix Viewport transformation 윈도우좌표 2012-2학기 3장 뷰잉

정육면체를 그리는 간단한 [예제 3 – 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 (); } 2012-2학기 3장 뷰잉

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; 2012-2학기 3장 뷰잉

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; } 2012-2학기 3장 뷰잉

실행결과 2012-2학기 3장 뷰잉

뷰잉 변환 뷰잉 변환은 카메라의 위치와 방향을 지정하는 것에 비유 위의 [예제 3 – 1] glLoadIdentity()를 사용, 현재 행렬을 단위행렬로 설정 행렬을 초기화 후, gluLookAt()으로 뷰잉 변환 지정 gluLookAt()을 호출하지 않으면 디폴트 위치와 방향설정 카메라 위치, 바라볼 방향, 어느쪽이 위쪽인지를 지정 카메라 위치: (0, 0, 5) 바라볼 방향: (0, 0, 0) 업벡터(up-vector): (0, 1, 0) 2012-2학기 3장 뷰잉

모델링 변환 모델의 위치와 방향은 모델링 변환으로 조절 모델을 회전 변환, 평행이동 변환, 크기 변환 등을 사용 [예제 3 – 1] 에서 glScalef()를 사용하여 모델링 변환 정육면체를 볼 수 있도록 뷰잉 변환으로 카메라를 이동하 는 대신 모델링 변환으로 카메라로부터 떨어지도록 설정 가능 이원성(duality) 존재로 뷰잉 변환과 모델링 변화을 하나의 모델뷰 행렬(modelview matrix) 로 설정 2012-2학기 3장 뷰잉

투영 변환 투영 변환을 설정하는 것은 카메라 렌즈를 고르는 것과 비슷 화각(field of view)이나 관측 공간(viewing volume)을 결정 어떤 오브젝트가 관측 공간 안에 들어 있게 되는지, 어느 정도 보이게 되는지 결정 투영의 방식 ( glFrustum() 사용 ) 원근(perspective) 투영 멀리 있는 물체는 가까이 있는 것보다 작게 나타남 glFrustum() 커맨드 사용 직교(orthographic) 투영 상대적인 크기에 관계 없이 물체를 스크린에 그대로 매핑 건축설계 및 CAD 설계용 응용 프로그램에서 주로 사용하며, 정확한 물체의 크기를 표현하는데 중점을 둠 2012-2학기 3장 뷰잉

뷰포트 변환 투영 변환과 뷰포트 변환은 장면과 컴퓨터 스크린이 매핑 되는 방식을 결정 투영변환은 매핑이 구체적으로 어떻게 이루어지는지 결 정 뷰포트 변환은 스크린을 매핑할 스크린 영역의 모양 나 타냄 glViewport()의 인자는 스크린 공간에 대한 원점, 영역의 폭 과 높이 설정, 픽셀 단위로 표현 이 커맨드는 reshape()루틴 안에서 호출되어야 함 윈도우의 크기를 변경하면 뷰포트 역시 변경해야 함 2012-2학기 3장 뷰잉

장면 그리기 장면에 나온 모든 오브젝트의 각 정점 을 모델링 및 뷰잉 변환에 따라 변환 변환된 정점들은 투영 변환에 따라 변 환 투영 변환에서 지정된 공간을 벗어나 는 오브젝트들은 잘라냄(Clip) 변환된 정점들을 w로 나눈 후 뷰포트 에 매핑 2012-2학기 3장 뷰잉

범용 변환 커맨드 변환을 직접 설정하는데 유용한 커맨드 glMatrixMode() glLoadIdentity() glLoadMatrix*() glMultMatrix*() gluLookAt() glScale() void glMatrixMode(GLenum mode) 변환 커맨드를 실행하기 전에 모델뷰, 투영, 텍스처 행렬을 수정할지 여부 결정 mode : GL_MODELVIEW, GL_PROJECTION, GL_TEXTURE void glLoadIdentity(void); 나중에 실행할 변환 커맨드를 위해 수정 가능한 행렬을 클리어 현재 수정 가능한 행렬을 4x4 단위 행렬로 설정 2012-2학기 3장 뷰잉

현재 행렬로 로드할 행렬을 명시적으로 지정하기 위한 커맨드 void glLoadMatrix{fd}(const TYPE *m); void glMultMatrix{fd}(const TYPE *m); m이 가리키는 16개 값으로 지정된 행렬을 현재 행렬과 곱하고, 그 결과를 현재 행렬에 저장 m1 m5 m9 m13 [주의사항] 행렬을 m[4][4]로 선언했다면 m[i][j] 원소는 OpenGL 변환 행렬의 j행, i 열에 있음. C와는 반대 m2 m6 m10 m14 M = m3 m7 m11 m15 m4 m8 m12 m16 2012-2학기 3장 뷰잉

뷰잉 및 모델링 변환 모델링 변환이나 뷰잉 변환을 실행하기 위해서는 반드시 glMatrixMode()에 GL_MODELVIEW 를 인자로 주고 호출해야 함. 변환 이해하기 모든 뷰잉 변환 및 모델링 변환은 4 * 4행렬로 표현 glMultMatrix*()과 같은 변환 커맨드들은 새로 주어진 4 * 4행 렬 M을 현재 모델뷰 행렬 C와 곱하여 CM을 생성 그 다음, 정점 v를 현재 모델뷰 행렬에 곱함 즉, 프로그램 상에서 가장 늦게 호출한 변환 커맨드가 정점 에 가장 먼저 적용(CMv) 2012-2학기 3장 뷰잉

glMatrixMode (GL_MODELVIEW); glLoadIdentity(); glMultMatrix(N); 예제 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 에 적용. 2012-2학기 3장 뷰잉

고정 좌표계 모델의 위치, 방향, 크기 등에 영향을 미치는 행렬 곱셈을 고정 좌표계 (Grand, Fixed Coordinate System) 관점에서 생각할 경우, 코드에 나온 순서와 반대로 곱셈이 수행 연산(회전, 평행 이동)을 수행한 후 오브젝트가 좌표축에 놓여 있도록 하기 위해서는(오브젝트는 원점에서 생성) 회전을 먼저 한 후, 평행이동 시켜야 함 명령문 예(역순으로 지정해야) glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMultMatrixf(T); /* 평행이동 */ glMultMatrixf(R); /* 회 전 */ Draw_the_object(); 1-Rotate 2-Translate 2012-2학기 3장 뷰잉

로컬 좌표계 이동하기 행렬 곱셈을 바라볼 때 변환할 오브젝트가 고정 좌 표계에 있지 않고, 오브젝트에 로컬 좌표계가 달려 있는 것처럼 생각 모든 연산들은 이러한 좌표계에 상대적으로 수행 이러한 접근 방식에서는 행렬 곱셈이 코드상에 지정 된 순서대로 실행 앞의 예제를 다음과 같이 실행하게 된다. 좌표계가 달린 오브젝트를 그리고 오브젝트와 오브젝트에 지정된 좌표계를 X축으로 평행 이동시킨다. 원점에 대해 회전시키면 오브젝트는 X축상의 평 행 이동된 위치에서 회전하게 됨. 2012-2학기 3장 뷰잉

모델링 변환 모델링 변환을 위해 세가지 커맨드들을 제공 평행이동 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*() 사용보다는 위의 세 루틴 사용이 좀 더 빠르게 동작함. 2012-2학기 3장 뷰잉

모델링 변환 예제 솔리드 와이어프레임 삼각형을 아무런 모델링 변환도 적용 안함 솔리드 와이어프레임 삼각형을 아무런 모델링 변환도 적용 안함 삼각형을 대시 모양의 라인 스티플과 평행이동 변환을 사용 높이(y축)는 절반 줄이고 폭(x축)은 50% 늘인 긴 대시 모양의 라인 스티플 삼각형을 점선으로 표현, 회전 2012-2학기 3장 뷰잉

#include <GL/glut. h> #include <stdlib #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(); 2012-2학기 3장 뷰잉

뷰잉 및 모델링 변환 void display(void){ glClear (GL_COLOR_BUFFER_BIT); glColor3f (1.0, 1.0, 1.0); glLoadIdentity (); draw_triangle (); glEnable (GL_LINE_STIPPLE); glLineStipple (1, 0xF0F0); glTranslatef (-20.0, 0.0, 0.0); 2012-2학기 3장 뷰잉

glDisable (GL_LINE_STIPPLE); glFlush (); } glLineStipple (1, 0xF00F); glLoadIdentity (); glScalef (1.5, 0.5, 1.0); draw_triangle (); glLineStipple (1, 0x8888); glRotatef (90.0, 0.0, 0.0, 1.0); glDisable (GL_LINE_STIPPLE); glFlush (); } 2012-2학기 3장 뷰잉

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); } 2012-2학기 3장 뷰잉

void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; } 2012-2학기 3장 뷰잉

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; } 2012-2학기 3장 뷰잉

실행결과 2012-2학기 3장 뷰잉

Nate Robins 의 변환관련 튜토리얼 http://www.cs.utah.edu/~narobins/opengl.html transformation 프로그램 실행 2012-2학기 3장 뷰잉

뷰잉 변환 뷰잉 변환을 사용하면 시점의 위치와 방향을 변경 카메라 비유에서 본 것처럼 뷰잉 변환은 카메라를 삼각대에 놓고, 모 델을 향하도록 조절하는 단계 뷰잉 변환은 일반적으로 이동 변환과 회전변환으로 구성 반시계 방향으로 오브젝트를 회전시키는 모델링 변환은 카메라를 시 계 방향으로 회전시키는 뷰잉 변환과 동일한 효과를 얻을 수 있다. 뷰잉 변환에 관련된 커맨드들은 반드시 모델링 변환을 수행하기 전에 호출해야만 오브젝트에 대한 모델링 변환의 효과가 먼저 나타나게 된 다. 뷰잉 변환의 다양한 방법 한 개 이상의 모델링 변환 커맨드 사용 glTranslate*(), glRotate*() 등 유틸리티 라이브러리 루틴인 gluLookAt() 사용, 시선을 정의 회전 변환, 이동 변환을 캡슐화 하는 유틸리티를 직접 만듬 2012-2학기 3장 뷰잉

glTranslate*() 와 glRotate*() 사용하기 뷰잉변환 표현을 위해 모델링 변환을 사용할 때 오브젝트는 월드 공간에 고정시켜두고 시점만 이동시켜야 하는 경 우가 있다. 초기에는 시점이 원점에 있고, 대부분 오브젝트는 원점에 생성되어 있기 때문에 몇 가지 변환 필요 카메라는 초기에 z 축의 음의 방향을 향하고 있음 간단한 방법으로 시점을 오브젝트 뒤로 이동 glTranslatef(0.0, 0.0, -5.0); 오브젝트를 장면으로부터 z축 방향으로 –5만큼 이동시킨다. 카메라를 z축 방향으로 +5만큼 이동시킨 것과 같은 효과 2012-2학기 3장 뷰잉

시점과 오브젝트 분리: glTranslate(0.0, 0.0, -5.0) 한 후 y y 카메라 카메라 x x z z 2012-2학기 3장 뷰잉

고정 좌표계에서는 실제 효과 순서와 역순으로 커맨드 호출 오브젝트를 옆에서 보도록 설정하는 경우 고정 좌표계 방식으로 생각할 경우 오브젝트를 회전 카메라로부터 멀리 떨어지도록 이동 고정 좌표계에서는 실제 효과 순서와 역순으로 커맨드 호출 로컬 좌표계 방식으로 생각할 경우 오브젝트와 로컬 좌표계를 원점으로부터 이동 그 뒤 회전 변환은 이동된 좌표계를 기준으로 회전 로컬 좌표계는 순서대로 커맨드 호출 2012-2학기 3장 뷰잉

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 2012-2학기 3장 뷰잉

카메라의 디폴트 위치는 원점이고 디폴트 방향을 z 축의 음 의 방향이며 위쪽에 대한 기본값을 y축의 양의 방향일 때, gluLookAt(0,0, 0.0, 0.0, 0.0, 0.0, -100, 0.0, 1.0, 0.0); 기준점의 z 값은 어떠한 음수로도 상관 없다. 같은 효과. y y 업벡터 x 카메라 x z 2012-2학기 3장 뷰잉

gluLookAt(4.0, 2.0, 1.0, 2.0, 4.0, -3.0, 2.0, 2.0, -1.0); y (2.0, 4.0, -3.0) (2,0, 2.0, -1.0) 카메라 (4.0, 2.0, 1.0) x z 2012-2학기 3장 뷰잉

Nate Robins 의 투영 관련 튜토리얼 projection 프로그램 2012-2학기 3장 뷰잉

투영 변환 투영 변환은 관측 공간을 정의하는데 사용 두 가지 방식 오브젝트가 스크린에 투영 되는 형태(원근, 직교 투영) 최종 이미지에서 어떤 오브젝트가 클리핑 될지를 결정 여기에서 설명하는 커맨드를 호출하기 전에 반 드시 다음과 같은 커맨드를 호출 glMatrixMode(GL_PROJECTION); glLoadIdentity(); 2012-2학기 3장 뷰잉

원근 투영(perspective projection) 원근투영의 가장 큰 특징은 바로 포쇼트닝(foreshortening) Foreshortening : 단축법, 오브젝트가 카메라로부터 멀리 떨어질수록 작 게 그리는 기법 이런 효과는 관측 공간을 피라미드의 절두체로 정의할 때 나타남 절두체 : frustum, 밑면과 평행으로 꼭지 부분을 잘라낸 피라미드 오브젝트들은 피라미드의 정점(apex)방향으로 투영하며 이 지점에 카메 라 혹은 시점 위치 시점에 가까이 놓여진 오브텍트들은 먼 것보다 크게 보임 Wikipedia  Figure shows two different projections of a stack of two cubes, illustrating oblique parallel projection foreshortening ("A") and perspective foreshortening ("B"). 2012-2학기 3장 뷰잉

원근 투영을 나타내는 행렬을 생성하고 이를 현재 행렬과 곱한다. void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far); 원근 투영을 나타내는 행렬을 생성하고 이를 현재 행렬과 곱한다. 관측 공간(절두체)은 이 공간 밖에 놓인 오브젝트들을 클리핑 하 는데 사용됨 절두체 정의 (left, bottom, -near)와 (right, top, -near) 각각 카메라와 가까운 곳에 위치한 클리핑 평면의 좌측 하단 모서리와 우측 상단 모서리 좌표를 나타냄 near 와 far 인자는 항상 양수로 정해야 함 2012-2학기 3장 뷰잉

glFrustum()과 같은 관측 공간 생성, 지정방식의 차이가 있다. fovy는 y축 방향의 FOV 각도를 나타냄 void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far); glFrustum()과 같은 관측 공간 생성, 지정방식의 차이가 있다. fovy는 y축 방향의 FOV 각도를 나타냄 aspect 인자는 절두체의 종횡비(x/y, 정사각형의 경우 종횡비는 1.0 이다) fovy h w  near 카메라 far Aspect = w/h 2012-2학기 3장 뷰잉

직교 투영(Orthogonal projection) 평행 육면체 모양의 관측 공간을 사용. 원근 투영과 달리 관측 공간의 양 끝면의 크기가 일정. 카메라의 거리가 오브젝트의 모양에 영향을 안 미침. 건축 설계도나 CAD 설계 등과 같이 오브젝트의 크기와 각도를 정확히 유지해야 하는 응용 프로그램에서 주로 사용 top left far 관측공간 right 시점방향 bottom near 2012-2학기 3장 뷰잉

직교관측공간의 행렬을 생성하고 이를 현재 행렬과 곱한다. glFrustum()과 동일한 방식의 인자. 직교형 관측 공간의 생성 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축의 음의 방향 2012-2학기 3장 뷰잉

2차원 좌표를 스크린에 투영하는 행렬을 생성하고 현재 행렬과 곱한다. 클리핑 영역 좌측 하단 모서리 (left, bottom) 이미지를 2차원 스크린에 투영하는 특수한 경우 void gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top); 2차원 좌표를 스크린에 투영하는 행렬을 생성하고 현재 행렬과 곱한다. 클리핑 영역 좌측 하단 모서리 (left, bottom) 우측 상단 모서리 (right, top) Nate Robins 의 투영 관련 튜토리얼 projection 프로그램 관측 공간 클리핑(clipping) 장면에 있는 오브젝트 정점들을 모델뷰 행렬과 투영 행렬로 모두 변환하 였다면 공간의 밖에 있는 모든 프리미티브 들은 클리핑된다. 2012-2학기 3장 뷰잉

뷰포트 변환 뷰포트 변환 카메라에 비유하면, 뷰포트 변환을 현상할 사진의 크기를 선택하는 단계 뷰포트 변환 뷰포트 변환 카메라에 비유하면, 뷰포트 변환을 현상할 사진의 크기를 선택하는 단계 컴퓨터 그래픽스에서 뷰포트는 그려질 윈 도우의 직사각형 모양의 영역 뷰포트는 윈도우 좌표로 측정 측정된 좌표는 윈도우의 좌측 하단 모서리 를 기준으로 스크린 상의 픽셀 위치로 표 현 2012-2학기 3장 뷰잉

뷰포트 정의하기 스크린 상에 윈도우를 생성하는 작업은 OpenGL이 아닌 윈도우 시스 템이 담당 윈도우를 처음 생성할 때 전체 윈도우에 해당하는 픽셀 영역을 뷰포 트로 설정 이보다 작은 영역을 뷰포트로 설정할 때는 glViewport() 커맨드 사용 void glViewport(GLint x, GLint y, Glsizei width, Glsizei height); 최종 이미지가 매핑될 윈도우의 픽셀 사각형을 정의한다. x, y 매개변수는 이러한 뷰포트의 좌측 하단 모서리 나타냄 width, 와 height 인자는 뷰포트의 크기를 지정 뷰포트의 종횡비는 관측공간의 종횡비와 비슷하다. 두 비율이 서로 다르면 투영된 이미지가 서로 뒤틀리게 된다. 2012-2학기 3장 뷰잉

변환된 깊이 좌표 뷰포트 변환이 수행되는 동안 깊이(z) 좌표는 인코딩 Z 값을 원하는 범위 내에서 조절하려면 glDepthRange()사용 윈도우의 x, y 좌표와는 달리 OpenGL 에서 z 좌표는 항상 0.0과 1.0 사이 에 있는 것으로 취급된다. void glDepthRange(GLclampd near, GLclampd far); 뷰포트 변환에서 사용될 z 좌표를 인코딩한다. near, far 인자는 깊이 버퍼에 저장될 최소 및 최대 수정 범위 기본적으로 이 값은 0.0 과 1.0 으로 설정 2012-2학기 3장 뷰잉

행렬 스택 조작하기 행렬 스택은 단순한 모델로 부터 복잡한 모델을 구성하는 것처럼 모델을 계층 적으로 구성할 때 유용 행렬연산(glLoadMatrix(), glMultMatrix(), glLoadIdentity())과 특정한 변환행렬을 생성하는 커맨드들은 현재 행렬이나 스택의 top행렬을 처리. 현재 행렬에 대한 복사본을 수택의 top에 복사하는 glPushMatrix()나, 스택의 top행렬을 버리는 glPopMatrix()와 같은 커맨드를 사용, top 의 원소를 지정 glPushMatrix() : 현재 위치를 저장 glPopMatrix() : 이전 위치로 되돌려 놓는다. void glPushMatrix(void): 현재 스택에 있는 모든 행렬들을 한 단계 아래로 이동(push) void glPopMatrix(void); 스택의 top원소(행렬) 를 뽑아낸다(pop) 현재 스택은 glMatrixMode()로 결정한다. 2012-2학기 3장 뷰잉

예제 3-4 행렬을 push 또는 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(); } 2012-2학기 3장 뷰잉

draw_body_and_wheel_and_bolts() { draw_car_body(); glPushMatrix(); glTranslatef(40, 0, 30); /* 첫번째 바퀴의 위치로 이동 */ draw_wheel_and_bolts(); glPopMatrix(); glTranslatef(40, 0, -30); /* 두 번째 바퀴의 위치로 이동 */ … } 2012-2학기 3장 뷰잉

모델뷰 행렬 스택 모델뷰 행렬에는 뷰잉 및 모델링 변환 행렬을 곱한 값들이 누적되 어 있다. 각각의 뷰잉 또는 모델링 변환들은 현재 모델뷰 행렬과 곱할 새로 운 행렬을 생성 변환의 결과로 생성된 행렬은 새로운 현재 행렬로 설정 모델뷰 행렬 스택에는 최소 32개의 4x4 행렬들을 저장할 수 있다. 초기에는 스택의 Top원소로 단위 행렬이 저장 스택의 최대 저장 개수 확인 glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH, GLint *params); 2012-2학기 3장 뷰잉

투영 행렬 스택 투영행렬 스택은 관측 공간을 구성하는 투영 변환을 위한 행렬을 저장 투영행렬 스택은 관측 공간을 구성하는 투영 변환을 위한 행렬을 저장 투영 행렬을 직접 작성하지 않기 때문에 투영 변환을 수행하기 전 에 glLoadIdentity()를 호출 스택의 깊이를 확인 glGetIntegerv(GL_MAX_PROJECTION_STACK_DEPTH, GLlint *params); 2012-2학기 3장 뷰잉

부가적인 클리핑 평면 관측공간에 존재하는 여섯 개의 클리핑 평면(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); 2012-2학기 3장 뷰잉

클리핑 평면에 대한 코드 [예제 3 – 5 ]: 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); 2012-2학기 3장 뷰잉

glColor3f (1. 0, 1. 0, 1. 0); glPushMatrix(); glTranslatef (0. 0, 0 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 (); } 2012-2학기 3장 뷰잉

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; 2012-2학기 3장 뷰잉

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; } 2012-2학기 3장 뷰잉

실행결과 2012-2학기 3장 뷰잉

여러가지 변환 함께 사용하기 태양계 만들기 #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); } 2012-2학기 3장 뷰잉

void display(void){ glClear (GL_COLOR_BUFFER_BIT); glColor3f (1. 0, 1 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(); } 2012-2학기 3장 뷰잉

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); } 2012-2학기 3장 뷰잉

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; 2012-2학기 3장 뷰잉

case 'y': year = (year + 5) % 360; glutPostRedisplay(); break; case 'Y': year = (year - 5) % 360; case 27: exit(0); default: break; } } 2012-2학기 3장 뷰잉

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; } 2012-2학기 3장 뷰잉

실행 결과 2012-2학기 3장 뷰잉

로봇팔 만들기 #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); } 2012-2학기 3장 뷰잉

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); glScalef (2.0, 0.4, 1.0); glutWireCube (1.0); glPopMatrix(); 2012-2학기 3장 뷰잉

glTranslatef (1. 0, 0. 0, 0. 0); glRotatef ((GLfloat) elbow, 0. 0, 0 glTranslatef (1.0, 0.0, 0.0); glRotatef ((GLfloat) elbow, 0.0, 0.0, 1.0); glPushMatrix(); glScalef (2.0, 0.4, 1.0); glutWireCube (1.0); glPopMatrix(); glutSwapBuffers(); } 2012-2학기 3장 뷰잉

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); } 2012-2학기 3장 뷰잉

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; case 'e': elbow = (elbow + 5) % 360; 2012-2학기 3장 뷰잉

case 'E': elbow = (elbow - 5) % 360; glutPostRedisplay(); break; case 27: exit(0); default: } 2012-2학기 3장 뷰잉

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; } 2012-2학기 3장 뷰잉

실행 결과 2012-2학기 3장 뷰잉

변환을 역으로 수행하거나 흉내내기 기하 처리 파이프 라인은 뷰잉 및 투영 행렬, 뷰포트를 통해 정점 의 월드(혹은 오브젝트)좌표를 윈도우(또는 스크린)좌표로 변환 이러한 처리 순서와 반대로 실행해야 하는 경우가 생김 3차원상의 위치를 마우스로 선택하는 경우 마우스는 스크린상의 커서의 위치를 나타내는 2차원 값만 반환 프로그램은 변환과정을 역으로 수행하여 마우스로 지정한 스크린의 위치에 대한 3차원 공간값을 결정해야 한다. gluUnProject() 와 gluUnProject4() 사용 2012-2학기 3장 뷰잉

함수가 성공적이면 GL_TRUE, 에러가 발생하면 GL_FALSE를 리 턴한다. 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를 리 턴한다. 2012-2학기 3장 뷰잉

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 좌표값 도 처리할 수 있다. 2012-2학기 3장 뷰잉

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를 리턴한다. 2012-2학기 3장 뷰잉

기하 프로세싱 파이프라인을 반대로 실행하기 [예제 3 – 8 ]: unproject.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(); 2012-2학기 3장 뷰잉

gluPerspective (45. 0, (GLfloat) w/(GLfloat) h, 1. 0, 100 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 월드 좌표 */ 2012-2학기 3장 뷰잉

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); 2012-2학기 3장 뷰잉

gluUnProject ((GLdouble) x, (GLdouble) realy, 1 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); default: 2012-2학기 3장 뷰잉

void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; } 2012-2학기 3장 뷰잉

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; } 2012-2학기 3장 뷰잉

실행 결과 2012-2학기 3장 뷰잉