Presentation is loading. Please wait.

Presentation is loading. Please wait.

Implement of transformation,projection, viewing Hanyang University Jungsik Park.

Similar presentations


Presentation on theme: "Implement of transformation,projection, viewing Hanyang University Jungsik Park."— Presentation transcript:

1 Implement of transformation,projection, viewing Hanyang University Jungsik Park

2 Division of Electrical and Computer Engineering, Hanyang University 변환 파이프라인 모델링 변환 : 모델좌표계의 3D 객체들을 월드좌표계로 가져옴 뷰잉 변환 : 월드좌표계에서 표현된 3D 객체들을 뷰잉좌표계로 변환  모델링 변환과 뷰잉 변환을 합쳐 모델뷰 변환으로 나타냄. 투영 : 뷰잉좌표계로 변환된 3D 객체들을 2 차원 뷰평면에 투영 윈도우 - 뷰포트 변환 : 투영좌표계의 결과를 출력장치의 장치좌표계로 표현

3 Division of Electrical and Computer Engineering, Hanyang University Homogeneous Coordinate System Homogeneous Coordinate System 이용  perspective projection 을 matrix 형태로 표현 가능  여러 단계의 변환을 행렬 곱셈으로 하나의 행렬로 표현 2D 3D

4 Division of Electrical and Computer Engineering, Hanyang University OpenGL 변환 행렬 OpenGL 에서는 3D 기하 변환을 위해 4x4 행렬을 사용한다 (homogeneous coordinate system). 열 우선 (column major order) 행렬의 사용  일반적인 프로그래밍에서 행렬을 표현하는 방식인 행 우선 (row major order) 이 아닌 열 우선으로 행렬 표현.  변환 행렬에서 각각 x,y,z 축 방향 벡터와 translation 벡터를 나타내는 열벡터의 복사를 빠르게 수행. 행렬 곱으로 여러 변환을 하나의 행렬로 표현 가능하므로 현재의 변환 행렬만 유지하여 사용한다.  단, 트리 / 그래프 구조의 모델을 순회할 때 현재의 변환 행렬을 저장하기 위해 행렬 스택을 이용한다.

5 Division of Electrical and Computer Engineering, Hanyang University 행렬 관련 함수 void glMatrixMode(GLenum mode)  현재 행렬을 설정한다. mode GL_MODELVIEW : 행렬 연산이 모델 관측 스택에 적용된다.  - 장면 상에서 물체를 이동할 때 사용한다. GL_PROJECTION : 행렬 연산이 투영 행렬 스택에 적용된다.  - 클리핑 공간을 정의할 때 사용한다. GL_TEXTURE : 행렬 연산이 텍스쳐 행렬 스택에 적용된다.  - 텍스쳐 좌표를 조작한다. void glLoadIdentity()  이 함수는 현재 변환 행렬을 주어진 단위 행렬로 바꾼다 glMatrixMode(GL_MODELVIEW); glLoadIdentity();

6 Division of Electrical and Computer Engineering, Hanyang University 행렬 관련 함수 void glLoadMatrixf(const GLfloat *M)  현재 행렬을 주어진 행렬로 설정한다. void glMultMatrixf(const GLfloat *M)  현재 행렬을 주어진 행렬과 곱한다. *M : 이 배열은 현재 변환 행렬로 설정될 4X4 행렬을 나타낸다. 이 배열은 16 개의 연속된 값을 가지며, 열 우선순위로 저장되어 있다 glMatrixMode(GL_MODELVIEW); float m[] = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; glLoadMatrixf(m); glMultiMatrixf(m);

7 Division of Electrical and Computer Engineering, Hanyang University 행렬 관련 함수 void glGetFloatv(Glenum pname, GLfloat *params)  현재의 modelview 행렬을 가져오는 경우 void glPushMatrix ()  현재 행렬을 행렬 스택에 Push 한다 void glPopMatrix ()  현재 행렬을 행렬 스택에서 Pop 한다. float *m; glGetFloatv(GL_MODELVIEW_MATRIX, m);

8 Division of Electrical and Computer Engineering, Hanyang University Modelview 변환 행렬 함수 void glTranslatef(GLfloat dx, GLfloat dy, GLfloat dz)  현재 행렬을 이동 변환 행렬과 곱한다. dx, dy, dz : x, y, z 축 좌표값 void glScalef(GLfloat sx, GLfloat sy, GLfloat sz)  현재 행렬과 크기 변환 행렬을 곱한다. sx, sy, sz : x, y, z 축에 대한 크기 변환 인수 void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)  현재 행렬과 회전 변환 행렬을 곱한다. angle : 회전각을 도 (degree) 단위로 나타낸다. x, y, z : 회전축이 되는 방향 벡터의 x, y, z 성분

9 Division of Electrical and Computer Engineering, Hanyang University // 방법 1 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(45.0, 0.0, 0.0, 1.0); glTranslatef(0.5, -0.5, 0.0); glutSolidCube(0.3); // 방법 2 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.707, 0.0, 0.0); glRotatef(45.0, 0.0, 0.0, 1.0); glutSolidCube(0.3);

10 Division of Electrical and Computer Engineering, Hanyang University Example void MyDisplay() { glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, 300, 300); glMatrixMode(GL_MODELVIEW); // 빨간 사각형 glColor3f(1.0, 0.0, 0.0); glLoadIdentity(); glutSolidCube(0.3); // 방법 1 녹색 사각형 glColor3f(0.0, 1.0, 0.0); glLoadIdentity(); glRotatef(45.0, 0.0, 0.0, 1.0); glTranslatef(0.6, 0.0, 0.0); glutSolidCube(0.3); // 방법 2 파란색 사각형 glColor3f(0.0, 0.0, 1.0); glLoadIdentity(); glTranslatef(0.6, 0.0, 0.0); glRotatef(45.0, 0.0, 0.0, 1.0); glutSolidCube(0.3); glFlush(); } int main(int argc, char** argv) { glutInitDisplayMode(GLUT_RGBA); glutInitWindowSize(300, 300); glutCreateWindow("OpenGL Sample Drawing"); glClearColor(1.0, 1.0, 1.0, 1.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); glutDisplayFunc(MyDisplay); glutMainLoop(); return 0; } 회전 및 평행이동 변환의 수행 순서에 따라 다른 결과가 나타난다

11 Division of Electrical and Computer Engineering, Hanyang University 타이머를 사용한 변환 시간의 변화에 따라 변환을 수행하도록 하는 경우, 타이머를 이용한다. void glutTimerFunc(unsigned int mills, void(*func)(int value), int value);  value : 이벤트 ID. 여러 타이머 이벤트를 처리하고자 할 경우 각 이벤트마다 다른 ID 를 부여.  타이머 콜백함수에서는 각 이벤트 ID 에 따라 처리를 해 주고, 타이머를 다시 설정해 준다.

12 Division of Electrical and Computer Engineering, Hanyang University Example #include static int Day = 0, Time = 0; void MyDisplay() { glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -2.0); /*** 지구 ***/ glPushMatrix(); // 지구의공전 glRotatef((float)Day, 0.0, 1.0, 0.0); glTranslatef(0.7, 0.0, 0.0); // 지구의자전 glRotatef((float)Time, 0.0, 1.0, 0.0); glColor3f(0.5, 0.6, 0.7); glutSolidSphere(0.1, 30, 8); /*** 달 ***/ glPushMatrix(); // 달의공전 glRotatef((float)Time, 0.0, 1.0, 0.0); glTranslatef(0.2, 0.0, 0.0); glColor3f(0.9, 0.8, 0.2); glutSolidSphere(0.04, 30, 8); glPopMatrix(); /*** 태양 ***/ glColor3f(1.0, 0.3, 0.4); glutSolidSphere(0.2, 30, 16); glutSwapBuffers(); } void MyTimer(int value) { Day = (Day + 10) % 360; Time = (Time + 5) % 360; glutTimerFunc(100, MyTimer, 1); glutPostRedisplay(); } int main(int argc, char** argv) { glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(500, 500); glutCreateWindow("Solar system"); glClearColor(0.0, 0.0, 0.0, 0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 3.0); glutDisplayFunc(MyDisplay); glutTimerFunc(100, MyTimer, 1); glutMainLoop(); return 0; }

13 Division of Electrical and Computer Engineering, Hanyang University

14 Division of Electrical and Computer Engineering, Hanyang University Example - 마우스를 이용한 모델의 회전 #include bool bDrag = false; float g_fDistance = -300.0f; float g_fSpinX = 0.0f; float g_fSpinY = 0.0f; int ptLastMousePositX, ptLastMousePositY; int ptCurrentMousePositX, ptCurrentMousePositY; void ChangeSize(GLsizei width, GLsizei height) { GLfloat fAspect = (GLfloat)width/(GLfloat)height; GLfloat nRange = height/4.0; if(height == 0) height = 1; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (width <= height) glOrtho (-nRange, nRange, -nRange/fAspect, nRange/fAspect, -nRange*4.0f, nRange*4.0f); else glOrtho (-nRange*fAspect, nRange*fAspect, -nRange, nRange, -nRange*4.0f, nRange*4.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void MyMouseClick(GLint Button, GLint State, GLint X, GLint Y) { if(Button == GLUT_LEFT_BUTTON ) { if (State == GLUT_DOWN) { ptLastMousePositX = ptCurrentMousePositX = X; ptLastMousePositY = ptCurrentMousePositY = Y; bDrag = true; } else if (State == GLUT_UP) bDrag = false; }

15 Division of Electrical and Computer Engineering, Hanyang University void MyMouseMove(GLint X, GLint Y) { ptCurrentMousePositX = X; ptCurrentMousePositY = Y; if( bDrag ) { g_fSpinX -= (ptCurrentMousePositX - ptLastMousePositX); g_fSpinY -= (ptCurrentMousePositY - ptLastMousePositY); } ptLastMousePositX = ptCurrentMousePositX; ptLastMousePositY = ptCurrentMousePositY; glutPostRedisplay(); } void RenderScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(0.0f, 0.0f, g_fDistance); glRotatef( -g_fSpinY, 1.0f, 0.0f, 0.0f ); glRotatef( -g_fSpinX, 0.0f, 1.0f, 0.0f ); glColor3f(0.0f, 1.0f, 0.0f); glutWireTeapot(100.0); glPopMatrix(); glutSwapBuffers(); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(600, 600); glutCreateWindow("Perspective Projection"); glutReshapeFunc(ChangeSize); glutMouseFunc(MyMouseClick); glutMotionFunc(MyMouseMove); glutDisplayFunc(RenderScene); glutMainLoop(); return 0; }

16 Division of Electrical and Computer Engineering, Hanyang University Projection View volume  뷰 평면의 윈도우 내에 투영되는 공간상의 일정 영역 Orthographic projection  직육면체의 공간을 뷰 평면에 투영 void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)

17 Division of Electrical and Computer Engineering, Hanyang University Projection Perspective projection  프러스텀의 뷰 볼륨을 뷰 평면에 투영  뷰 볼륨을 정규화된 정육면체로 변환하여 직각투영을 이용하면 투영과 클리핑이 간단해진다.

18 Division of Electrical and Computer Engineering, Hanyang University

19 Division of Electrical and Computer Engineering, Hanyang University Projection 변환 행렬 함수 void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)

20 Division of Electrical and Computer Engineering, Hanyang University Example source #include static GLfloat xRot = 0.0f; static GLfloat yRot = 0.0f; static int width, height; bool bPerspective = true; void SetProjection() { GLfloat fAspect = (GLfloat)width/(GLfloat)height; GLfloat nRange = height/4.0; if(height == 0) height = 1; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (bPerspective) gluPerspective(60.0f, fAspect, 1.0, 400.0); else { if (width <= height) glOrtho (-nRange, nRange, -nRange/fAspect, nRange/fAspect, -nRange*4.0f, nRange*4.0f); else glOrtho (-nRange*fAspect, nRange*fAspect, -nRange, nRange, -nRange*4.0f, nRange*4.0f); } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); }

21 Division of Electrical and Computer Engineering, Hanyang University Example source void ChangeSize(GLsizei w, GLsizei h) { width = w; height = h; SetProjection(); } void SpecialKeys(int key, int x, int y) { if(key == GLUT_KEY_UP)xRot-= 5.0f; if(key == GLUT_KEY_DOWN)xRot += 5.0f; if(key == GLUT_KEY_LEFT)yRot -= 5.0f; if(key == GLUT_KEY_RIGHT)yRot += 5.0f; xRot = (GLfloat)((const int)xRot % 360); yRot = (GLfloat)((const int)yRot % 360); if (key == GLUT_KEY_F1) { bPerspective = !bPerspective; SetProjection(); } glutPostRedisplay(); }

22 Division of Electrical and Computer Engineering, Hanyang University Example source void RenderScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(0.0f, 0.0f, -300.0f); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); glColor3f(1.0f, 0.0f, 0.0f); glutWireCube(100.0); glPopMatrix(); glutSwapBuffers(); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(600, 600); glutCreateWindow("Perspective Projection"); glutReshapeFunc(ChangeSize); glutSpecialFunc(SpecialKeys); glutDisplayFunc(RenderScene); glutMainLoop(); return 0; }

23 Division of Electrical and Computer Engineering, Hanyang University Orthogonal projection Perspective projection

24 Division of Electrical and Computer Engineering, Hanyang University 시점 이동 (gluLookAt) void gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, Gldouble upz)  Eye : 카메라의 위치  Center : 바라볼 장면의 중앙  Up : 카메라의 위쪽 방향을 향하는 상향 벡터 임의의 시점으로 이동시키는 경우 간단히 사용할 수 있으나, 카메라의 이동에 x 축 /z 축을 회전축으로 회전하는 성분이 있을 경우 up 벡터를 그에 맞춰 계산해 주어야 한다.

25 Division of Electrical and Computer Engineering, Hanyang University 카메라 오브젝트 카메라 오브젝트를 만들어 시점 이동에 이용  Position, forward vector, along vector, up vector 를 직접 관리 (glRotate, glTranslate 등을 사용하지 않음 )  up, forward, along vector 는 각각 서로 직교한다.  시점이 이동되어야 할 경우 삼각함수와 벡터연산으로 up, forward, along vector 및 position 를 계산하여 업데이트  up, forward, along vector 및 position 으로부터 변환 행렬을 만들어 glLoadMatrix() 로 로드시켜 사용.

26 Division of Electrical and Computer Engineering, Hanyang University 카메라 오브젝트 class Camera { private: Vector3D Position; Vector3D Along; Vector3D Up; Vector3D Forward; public: void Pitch(GLfloat theta); void Yaw(GLfloat theta); void Roll(GLfloat theta); void Update();... }; struct Vector3D { float x; float y; float z; };


Download ppt "Implement of transformation,projection, viewing Hanyang University Jungsik Park."

Similar presentations


Ads by Google