애니메이션
애니메이션은 여러 프레임에 존재하는 이미지들을 빠른 속도로 계산, 재생함으로써 특정 물체가 부드럽게 움직이도록 한다.
그런데, 현재 우리가 보고 있는 동영상, 영화, 게임들은 하나의 객체만 처리하는 것이 아니고 수 많은 그래픽 작업들을 요구하게 된다. 프레임 마다의 장면을 처리함에 있어서 많은 처리량이 요구될 것이다. 따라서, 현 프레임의 장면을 계산하고 디스플레이에 뿌려준 다음 또 다시 프레임의 장면을 계산하고 디스플레이에 뿌려주는 단순한 방법으로 애니메이션을 처리한다면 Delay가 발생할 수 밖에 없다. 즉, 뚝뚝 끊켜 보일 것이다. 이를 처리하기 위해 Double Buffering기법이 요구된다.
Double Buffering
https://codejb.tistory.com/39 <- 여기서도 설명해놨다.
Double Buffering은, 애니메이션을 부드럽게 재생하기 위한 목적을 가지고, 다음 프레임에 처리해야할 작업을 미리 계산해놓고 버퍼에 저장해 놓은 다음, 현재 프레임을 디스플레이에 뿌려줬다면 계산해놓은 연산을 가져와 바로 디스플레이에 뿌려주는 것이다.
따라서, 프런트버퍼(현재) 백 버퍼(다음)으로 버퍼를 이중화 시켜놓고 현재 디스플레이에 뿌려줄 이미지를 연산한 데이터를 프런트 버퍼에 저장한다. 그 다음 비디오 컨트롤러에 의해 디스플레이에 뿌려준다. 이 동작 중에, 그래픽 프로세서는 다음 프레임에 대해 처리한 데이터를 미리 백 버퍼에 저장해 놓은 것이다. 프런트 버퍼의 작업이 완료되면 프런트 버퍼와 백 버퍼가 스왑버퍼에 의해 스왑되면서 다음 프레임을 곧 바로 비디오 컨트롤러에 의해 디스플레이에 뿌려줄 수 있는 것이다.
OpenGL Animation & Double Buffering 실습
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
#include <iostream>
GLfloat Delta = 0.0;
void MyDisplay(){
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glColor3f(0.0, 0.5, 0.8);
glVertex3f(-1.0 + Delta, -0.5, 0.0);
glVertex3f(0.0 + Delta, -0.5, 0.0);
glVertex3f(0.0 + Delta, 0.5, 0.0);
glVertex3f(-1.0 + Delta, 0.5, 0.0);
glEnd();
glutSwapBuffers(); //이중 버퍼의 데이터를 스왑해주는 버퍼로, Display 콜백함수 마지막에 호출
}
void MyTimer(int value){
Delta = Delta + 0.005; //약간씩 증가시켜서 움직이게 함
glutPostRedisplay();//새로그림
glutTimerFunc(10, MyTimer, value); //20ms 후에 다시 타이머를 호출함.
}
int main(int argc, char ** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); //이중 버퍼링을 위해 이중버퍼 사용
glutInitWindowSize(300, 300);
glutInitWindowPosition(0, 0);
glutCreateWindow("Animation & Double Buffering");
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);
glutTimerFunc(10, MyTimer, 1); // 20ms마다 MyTimer를 호출하라 1은 식별자(여러 타이머에 대한)
glutMainLoop();
}
void glutTimerFunc(unsigned int msecs, void (*func)(int value), int value)
//msec 시간에 맞춰 콜백 함수를 호출하는 함수이다.
//세번째 인자인 value는 여러 TimerFunc들을 식별하기 위한 식별자라고 볼 수 있다.
//타이머 함수인데 재귀적으로 호출해야 한다는게 조금 아이러니한 것 같다...
'Computer Graphics' 카테고리의 다른 글
Chapter06. 디스플레이 리스트 (0) | 2021.05.31 |
---|---|
Chapter 05. 정점 배열과 3차원 도형 그리기 (0) | 2021.05.28 |
Chapter03. 입력 콜백 (0) | 2021.05.27 |
Chapter02. OpenGL 시작 및 실습코드 (0) | 2021.05.26 |
Chapter 01-03. Graphics System & Model 상식 (0) | 2021.05.19 |