시점 변환
지난 시간까지 모델변환을 통해서 Object의 기하변환을 가하였고, 전역 좌표계와 모델 좌표계 등에 대해서 알았다. 이젠 Viewer의 관점에서 오브젝트를 어디서, 어떤 방향으로 볼 것인지를 결정해줄 것이다. 가장 핵심적인 함수는 gluLookat이고 이전 시간에도 사용해왔다.
void WINAPI gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,
GLdouble centerx,GLdouble centery,GLdouble centerz,
GLdouble upx,GLdouble upy,GLdouble upz
);
: View Transform Matrix를 정의하는 함수
: 시점 좌표계를 정의하는 함수로, (eyeX, eyeY, eyeZ)에 있는 카메라가 (centerX, centerY, cneterZ)에 있는
초점을 바라보는 것이다.
: (upX, upY, upZ)는 카메라 상향 벡터이다. 카메라의 머리를 어느 방향으로 하느냐에 따라서 카메라가 회전을 할 것이다
: 한마디로 카메라의 방향이라고 생각하면 된다.
sideVector는 UpVector와 ForwardVector의 외적이다. 두 벡터의 곱은, 두 벡터가 이루는 평면에 수직인 벡터를 만든다.
OpenGL 실습 : 카메라 회전과 애니메이션 적용
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
#include <math.h>
#include <iostream>
#define _WINDOW_WIDTH 800
#define _WINDOW_HEIGHT 800
int angle_upper = 0;
int angle_lower = 0;
int dir_upper = 1;
int dir_lower = 1;
GLfloat camPos_x = 0.5, camPos_y = 0.5, camPos_z = 1; //위치
GLfloat camAt_x = 0, camAt_y = 0, camAt_z = 0; //바라보는 곳
GLfloat camUp_x = 0, camUp_y = 1, camUp_z = 0; //방향
void MyReshape(int width, int height){
glViewport(0, 0, width, height);
GLfloat f_w = (GLfloat)width / (GLfloat)_WINDOW_WIDTH;
GLfloat f_h = (GLfloat)height / (GLfloat)_WINDOW_HEIGHT;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0*f_w, 1.0*f_w, -1.0*f_h, 1.0*f_h, -2, 2);
}
void drawXAxis(){
glBegin(GL_LINES);
//선
glVertex3f(0, 0, 0);
glVertex3f(0.3, 0, 0);
//선머리
glVertex3f(0.3, 0, 0);
glVertex3f(0.21, 0.09, 0);
//선머리
glVertex3f(0.3, 0, 0);
glVertex3f(0.21, -0.09, 0);
glEnd();
}
void drawAxis(){
glColor3f(1, 1, 1);
// glMatrixMode(GL_MODELVIEW);
// glLoadIdentity(); // 초기화
drawXAxis();
glPushMatrix();//행렬 스택에 push
glRotatef(90, 0, 0, 1);
drawXAxis();
glPopMatrix(); //모델 좌표계의 행렬스택중 Top Data삭제
glPushMatrix();
glRotatef(-90, 0, 1, 0);
drawXAxis();
glPopMatrix();
}
void drawCuboid(GLfloat sx, GLfloat sy, GLfloat sz){
glPushMatrix();
glScalef(sx, sy, sz);
glutWireCube(1);
glPopMatrix();
}
void drawBody(){
drawAxis();
drawCuboid(0.5,1,0.2);
}
void drawHead(){
glPushMatrix();
glTranslatef(0, 0.55, 0);
drawAxis();
drawCuboid(0.3, 0.1, 0.2);
glPopMatrix();
}
void drawUpperArm(GLfloat Angle){
glTranslatef(0.25,0.3, 0);
glRotatef(Angle, 0, 0, 1);
glTranslatef(0.25,0, 0);
drawCuboid(0.5, 0.2, 0.2);
}
void drawLowerArm(GLfloat Angle){
drawAxis();//Axis확인하면서 평행이동하면 편함
glTranslatef(0.25,0, 0);
glRotatef(Angle, 0, 0, 1);
glTranslatef(0.25,0, 0);
drawAxis();
drawCuboid(0.5, 0.2, 0.2);
}
void drawHand(){
glTranslatef(0.35, 0, 0);
glutWireSphere(0.1, 15, 15);
}
void drawFinger1(){
glPushMatrix();
glTranslatef(0.15, 0, 0);
drawCuboid(0.1, 0.05, 0.05);
glPopMatrix();
}
void drawFinger2(){
glPushMatrix();
glRotatef(30, 0, 0, 1);
glTranslatef(0.15, 0, 0);
drawCuboid(0.1, 0.05, 0.05);
glPopMatrix();
}
void MyDisplay(){
glClear(GL_COLOR_BUFFER_BIT);
//drawAxis();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(camPos_x, camPos_y, camPos_z, camAt_x, camAt_y, camAt_z, camUp_x,camUp_y, camUp_z);
drawBody();
drawHead();
drawUpperArm(angle_upper);//timer에 따라 angle 변함
drawLowerArm(angle_lower);//timer에 따라 angle 변함
drawHand();
drawFinger1();
drawFinger2();
//glFlush();
glutSwapBuffers(); //애니메이션 사용을 위해서 Flush없애고 스왑버퍼 호출
}
void MyTimer(int value){
angle_upper += dir_upper; //1도씩 움직이기
angle_lower += dir_lower; //5도씩 움직이기
if(angle_upper <= 0)
dir_upper = 1;
else if(angle_upper >= 60)
dir_upper = 0;
//std::cout << angle_upper << std::endl;
if(angle_lower <= -70)
dir_lower = 5;
else if(angle_lower >= 100)
dir_lower = -5;
glutTimerFunc(20, MyTimer, 1);
glutPostRedisplay();
}
void CameraAnimationTimer(int value){
GLfloat Theta = 0.01;
//모델의 y축 기준으로 카메라 회전시키기 회전공식 참고
camPos_x = camPos_x * cos(Theta) + camPos_z * sin(Theta);
camPos_z = camPos_x * -sin(Theta) + camPos_z * cos(Theta);
glutTimerFunc(20, CameraAnimationTimer, 2);
glutPostRedisplay();
}
int main(int argc, char ** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);
glutInitWindowSize(_WINDOW_WIDTH, _WINDOW_HEIGHT);
glutCreateWindow("title");
//콜백
glutDisplayFunc(MyDisplay);
glutReshapeFunc(MyReshape);
glutTimerFunc(20, MyTimer, 1);
glutTimerFunc(20, CameraAnimationTimer, 2);
glutMainLoop();
}
'Computer Graphics' 카테고리의 다른 글
Chapter10. 가시성 판단 (0) | 2021.06.06 |
---|---|
Chapter09. 투영변환(gluPerspective) & 뷰포트 변환(glViewport) (2) | 2021.06.05 |
Chapter07. GL-Viewing : 행렬&좌표계&모델 변환 (0) | 2021.06.01 |
Chapter06. 디스플레이 리스트 (0) | 2021.05.31 |
Chapter 05. 정점 배열과 3차원 도형 그리기 (0) | 2021.05.28 |