Presentation is loading. Please wait.

Presentation is loading. Please wait.

프 레 임 버 퍼.

Similar presentations


Presentation on theme: "프 레 임 버 퍼."— Presentation transcript:

1 프 레 임 버 퍼

2 프레임 버퍼 “ 버퍼와 버퍼의 사용 ” “ 프래그먼트의 테스트와 연산 ” “ 누적 버퍼 ” 2009-2학기 가상현실

3 버퍼와 버퍼의 사용 OpenGL 시스템은 다음의 버퍼들을 다룸 컬러 버퍼 깊이 버퍼 스텐실 버퍼 누적 버퍼
2009-2학기 가상현실

4 각 픽셀의 버퍼 저장을 위한 매개변수 요청 glGetIntegerv() 사용 매개변수 설명
GL_RED_BITS, GL_GREEN_BITS, GL_BLUE_BITS, GL_ALPHA_BITS 컬러 버퍼에서 R,G,B,A 구성 요소당 비트의 개수 GL_INDEX_BITS 컬러 버퍼에서 참조당 비트의 개수 GL_DEPTH_BITS 깊이 버퍼에서 픽셀당 비트의 개수 GL_STENCIL_BITS 스텐실 버퍼에서 픽셀당 비트의 개수 GL_ACCUM_RED_BITS, GL_ACCUM_GREEN_BITS, GL_ACCUM_BLUE_BITS, GL_ACCUM_ALPHA_BITS 누적 버퍼에서R,G,B,A 구성 요소당 비트의 개수 2009-2학기 가상현실

5 컬러 버퍼 컬러 버퍼는 사용자가 보통 그리기 위해서 사용하는 버퍼
컬러 인덱스나 RGB 컬러 자료를 가짐, 알파값을 가지기도 함 입체적인 시각 정보를 위해 왼쪽과 오른쪽의 입체적 영상을 나타내기 위하여 좌측과 우측의 컬러 버퍼를 가진다. 양(더블) 버퍼 시스템은 전위 버퍼와 후위 버퍼를 가지며, 단일 버퍼 시스템은 전위 버퍼만 가진다. 선택적이며 표시되지 않는 보조 컬러 버퍼가 제공되는 경우도 있다. 사용자는 자신의 시스템이 입체 버퍼링인지 양 버퍼링 인지를 알기 위해 GL_STEREO나 GL_DOUBLEBUFFER를 사용 입체 버퍼링 양 버퍼링 2009-2학기 가상현실

6 깊이 버퍼(Depth Buffer) 깊이버퍼는 각각의 픽셀의 깊이값을 지니고 있다. 깊이는 눈과의 거리로 측정
큰 값의 깊이 버퍼를 갖는 픽셀들은 작은 값을 갖는 픽셀들에 의해 덧씌워짐 깊이 버퍼는 Z버퍼로도 불림 Z 값은 화면에 수직인 거리(눈과 화면과의 거리)를 나타냄 2009-2학기 가상현실

7 스텐실 버퍼(Stencil Buffer)
스텐실 버퍼의 한 가지 사용법 카드 스텐실이 스프레이 페인트로 매우 정밀한 이미지를 만들 수 있는 것처럼 화면의 특정 부분의 사용을 제한하는 것 예를 들어 사용자가 자동차의 바람막이 유리를 통해서 보이는 형태의 이미지를 그리는 경우 사용자는 바람막이 형태의 이미지를 스텐실 버퍼에 저장한 후 전체 장면을 그림 스텐실 버퍼는 바람막이 유리를 통해 보이지 않는 장면을 제거 2009-2학기 가상현실

8 누적 버퍼(Accumulation Buffer)
누적 버퍼는 RGBA 모드에서 컬러 버퍼들이 동작하는 것처럼 RGBA 컬러 자료들을 가지고 있다. 보통의 이미지들을 혼합된 이미지들로 축적하는데 사용 사용자는 장면 안티앨리어싱과 같은 작업들을 수행할 수 있다. 사용자는 직접적으로 누적 버퍼에 그리지는 않음 누적 작업은 직사각형의 블록 내에서 수행, 블록들은 자료를 컬러 버퍼 안으로 또는 컬러 버퍼에서 이동시키는 역할 2009-2학기 가상현실

9 버퍼 초기화 간단한 그래픽 작업에서 초기화 연산은 그림의 나머지보다 더 많은 시간을 요구
만약 사용자가 컬러 버퍼와 깊이 버퍼 그리고 스텐실 버퍼를 초기화하고자 하면 초기화 연산은 세 배의 시간이 걸림 이 문제를 해결하기 위해 일부 장치들은 한번에 한 개 이상의 버퍼를 초기화하기 위한 하드웨어 가짐 2009-2학기 가상현실

10 void glClearIndex(GLfloat iudex); void glClearDepth(GLclampd depth);
컬러(RGBA, 컬러인덱스모드), 깊이, 스텐실, 누적버퍼의 현재 초기화 값들을 명세, 다음 연산들은 각각의 버퍼들의 초기화 값 void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); void glClearIndex(GLfloat iudex); void glClearDepth(GLclampd depth); void glClearStencil(GLint s); void glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat of alpha); GLclampf 와 GLclamd 타입들은 0.0과 1.0 사이에서 고정 깊이 초기화 기본값은 1.0, 다른 초기화 기본값은 0이다. 2009-2학기 가상현실

11 초기화 값을 결정하고, 버퍼들을 초기화할 준비되면 glClear() 함수 사용
void glClear(GLbitfield mask); 지정된 버퍼들을 초기화 mask 값은 비트형식의 논리값인 OR로서 GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT, GL_ACCUM_BUFFER_BIT의 조합으로 이루어짐 2009-2학기 가상현실

12 읽기와 쓰기를 위한 컬러 버퍼의 선택 그리기와 읽기 연산은 컬러버퍼에 입력되거나 버퍼로부터 나옴
그리기를 할 때 그림을 그릴 오브젝트로 한 개 이상의 버퍼를 동시에 지정할 수 있다. glReadPixels(), glCopyPixels(), glCopyTexImage*(), glCopyTexSubImage*()의 소스가 될 버퍼를 선택하기 위해 glReadBuffer() 명령 사용 glDrawBuffer() 명령은 입체적 이미지를 나타내거나, 보조 버퍼에 내용을 표현할 버퍼를 선택하는데 사용 2009-2학기 가상현실

13 void glDrawBuffer(GLenum mode); 쓰기와 지우기를 위해 버퍼를 활성화 혹은 비활성화시킴 mode의 값
GL_AUXi 에서 i는 특정한 보조버퍼를 나타내는 숫자이다. 디폴트일 때 단일 버퍼의 모드값은 GL_FRONT로 나타내고 이중 버퍼의 경우에는 GL_BACK이다. GL_FRONT GL_FRONT_LEFT GL_AUXi GL_BACK GL_FRONT_RIGHT GL_FRONT_AND_BACK GL_LEFT GL_BACK_LEFT GL_NONE GL_RIGHT GL_BACK_RIGHT 2009-2학기 가상현실

14 void glReadBuffer(GLenum mode);
glReadBuffer()가 적용되는 버퍼들은 glDrawBuffer()를 표현하는 버퍼들과 동일 glReadPixels(), glCopyPixels(), glCopyTexImage*().. 등 사전 호출을 통하여 활성화된 컬러 버퍼를 선택한다. 단일버퍼의 디폴트값은 GL_FRONT, 이고 이중 버퍼일 경우에는 GL_BACK mode 값 GL_FRONT GL_FRONT_LEFT GL_AUXi GL_BACK GL_FRONT_RIGHT GL_LEFT GL_BACK_LEFT GL_RIGHT GL_BACK_RIGHT 2009-2학기 가상현실

15 버퍼 마스킹하기 활성화된 컬러, 깊이, 또는 스텐실 버퍼에 데이터를 입력하기 전에 마스크 연산이 자료들에 적용
void glIndexMask(Gluint mask); void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean of alpha); void glDepthMask(Glboolean flag); void glStencilMask(Gluint mask); 올바른 버퍼로 입력되도록 제어하기 위해 마스크를 설정 glIndexMask()로 설정된 마스크는 컬러 인덱스 모드에서만 적용 마스크에 1이 나타나 해당 비트가 입력되고 0이면 입력되지 않는다. 2009-2학기 가상현실

16 glColorMask()명령은 RGBA 모드에서 그릴 때에만 영향을 미친다.
GL_TRUE 일 때 R, G, B, A값이 일치하는 구성요소 입력 glDepthMask() 의 표시 문자가 GL_TRUE일 때 깊이 버퍼 입력 가능 glStencilMask() 의 마스크는 스텐실데이터를 위해 사용됨 2009-2학기 가상현실

17 프래그먼트의 테스트와 연산 OpenGL 프로그램이 프래그먼트들의 생성 여부와 각각의 컬러를 결정한 후에 프래그먼트들이 픽셀 형태로 프레임버퍼에 그려지는 방법을 제어하기 위한 처리 필요 프래그먼트들이 프레임 버퍼에 저장되기 전에 반드시 거쳐야 할 완벽한 테스트들과 프래그먼트들의 입력 등 마지막 단계 연산들에 대해 설명. 다음의 순서로 진행됨. 편집 테스트 알파 테스트 스텐실 테스트 깊이 테스트 블렌딩 디더링 논리적 연산 2009-2학기 가상현실

18 편집 테스트 사용자는 glScissor()커맨드를 이용하여 윈도우의 직사각형 분할 및 그 분할 내에서의 그릴 때의 제한 사항 등을 정의 void glScissor(GLint x, GLint y, GLsizei width, GLsizei height); 편집 사각형의 위치와 크기를 설정 변수는 좌측 아래에 있는 정점 좌표(x, y) 와 직사각형의 가로, 세로 길이로 정의 편집테스트는 GL_SCISSOR_TEST(glEnable(), glDisable())의 통과 여부로 판별 한 프래그먼트가 직사각형 내부에 존재할 때 편집 테스트를 통과하게 됨 디폴트는 직사각형 크기가 윈도우 크기와 동일하며 편집 테스트 통과는 불가능 2009-2학기 가상현실

19 알파 테스트 RGBA 모드에서 알파 테스트는 알파값에 기초한 프래그먼트의 수용이 가능한지를 알려줌
알파 테스트는 GL_ALPHA_TEST(glEnable(), glDisable())의 통과 여부에 따라 판별 알파 테스트의 가능성을 판정하기 위해 GL_ALPHA_TEST (glIsEnabled())와 함께 사용 프래그먼트는 이 비교 결과에 따라 허가되거나 기각된다. 참조값과 비교함수는 glAlphaFunc()로 설정 디폴트는 값이 0이고 비교함수는 GL_ALWAYS이며 알파테스트는 불가능 void glAlphaFunc(GLenum func, GLclampf ref); 알파테스트를 위한 참조값과 비교함수를 설정 참조값 ref 는 0과 1사이에서 조정됨 func 에 가능한 값(표10-2) 2009-2학기 가상현실

20 표10-2 glAlphaFunc() 매개변수 값
설명 GL_NEVER 프래그먼트를 받아들이지 않는다. GL_ALWAYS 항상 프래그먼트를 받아들인다. GL_LESS 알파 < 참조알파 일 경우, 프래그먼트를 받아들인다. GL_LEQUAL 알파 <= 참조알파 일 경우, 프래그먼트를 받아들인다. GL_EQUAL 알파 = 참조알파 일 경우, 프래그먼트를 받아들인다. GL_GEQUAL 알파 >= 참조알파 일 경우, 프래그먼트를 받아들인다. GL_GREATER 알파 > 참조알파 일 경우, 프래그먼트를 받아들인다. GL_NOTEQUAL 알파, 참조알파가 같지 않을 경우, 프래그먼트를 받아들인다. 2009-2학기 가상현실

21 스텐실 테스트 스텐실 테스트는 스텐실 버퍼가 있을 때에만 사용
스텐실은 참조값과 스텐실 버퍼의 픽셀에 저장된 값과의 비교 테스트를 적용 테스트의 결과에 의해 스텐실 버퍼 내의 값은 변경 사용되는 특정한 비교함수와 참고값과 glStencilFunc(), glStencilOp() 함수로 수행되는 변화값을 선택 void glStencilFunc(GLenum func, GLint ref, GLuint mask); 스텐실 테스트를 사용하기 위해 비교 함수(func), 참조값(ref) 그리고 마스크(mask)를 설정 비교함수에 의해 스텐실 버퍼 값과 비교 비교함수: GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GREATER, GL_NOTEQUAL 예를 들어, GL_LESS 경우, 프래그먼트는 ref 값이 스텐실 버퍼의 값보다 작을 때 통과된다. 디폴트는 func 이 GL_ALWAYS 이며 ref 는 0, 마스크는 1, 스텐실은 불가능 2009-2학기 가상현실

22 void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass);
프래그먼트가 스텐실 테스트를 통과하거나 디폴트일 때 스텐실 버퍼의 자료가 어떻게 변화하는지 상술 fail, zfail, zpass 는 GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT가 될 수 있다. fail 함수는 프래그먼트가 스텐실 테스트에서 디폴트의 경우에 적용. 이것을 통과하면 zfail 함수가 깊이 테스트가 실패하고 깊이테스트가 성공하고 zpass 가 적용될 때 깊이테스트가 실행되지 않았을 때에 적용된다. 디폴트일 때 세 가지 스텐실 연산은 GL_KEEP이 된다. 2009-2학기 가상현실

23 스텐실 질의 질의 함수인 glGetIntegerv()와 표에 나타난 값들을 이용하여 6가지의 스텐실 관련 변수들의 값을 구할 수 있다. GL_STENCIL_TEST(glIsEnabled()와 함께)를 통해 스텐실 테스트의 가능 여부 판정 스텐실 테스트를 위한 질의 값 질의값 설명 GL_STENCIL_FUNC 스텐실 함수 GL_STENCIL_REF 스텐실 참조값 GL_STENCIL_VALUE_MASK 스텐실 마스크 GL_STENCIL_FAIL 스텐실 실패 액션 GL_STENCIL_PASS_DEPTH_FAIL 스텐실 패스와 깊이 버퍼 실패 액션 GL_STENCIL_PASS_DEPTH_PASS 스텐실 패스와 깊이 버퍼 패스 액션 2009-2학기 가상현실

24 스텐실 예제 스텐실 테스트를 사용하는 전형적인 방법 화면의 비정상적인 구역에 그림이 그려지지 않도록 마스크 사용
스텐실 마스크를 0으로 채운 뒤 원하는 형상을 스텐실 버퍼에 1이 설정되도록 그린다. 스텐실 구역을 정의한 후 참조값을 1로 설정하고, 참조값이 스텐실 평면의 값과 같을 경우, 프래그먼트가 통과하는 비교 함수를 설정 2009-2학기 가상현실

25 예제10-1 스텐실 테스트의 사용: stencil.c
#include <GL/glut.h> #include <stdlib.h> #define YELLOWMAT 1 #define BLUEMAT 2 void init (void) { GLfloat yellow_diffuse[] = { 0.7, 0.7, 0.0, 1.0 }; GLfloat yellow_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat blue_diffuse[] = { 0.1, 0.1, 0.7, 1.0 }; GLfloat blue_specular[] = { 0.1, 1.0, 1.0, 1.0 }; 2009-2학기 가상현실

26 GLfloat position_one[] = { 1.0, 1.0, 1.0, 0.0 };
glNewList(YELLOWMAT, GL_COMPILE); glMaterialfv(GL_FRONT, GL_DIFFUSE, yellow_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, yellow_specular); glMaterialf(GL_FRONT, GL_SHININESS, 64.0); glEndList(); glNewList(BLUEMAT, GL_COMPILE); glMaterialfv(GL_FRONT, GL_DIFFUSE, blue_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, blue_specular); glMaterialf(GL_FRONT, GL_SHININESS, 45.0); 2009-2학기 가상현실

27 glLightfv(GL_LIGHT0, GL_POSITION, position_one); glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); glClearStencil(0x0); glEnable(GL_STENCIL_TEST); } /* 토러스에서 윈도우 중앙의 다이아몬드 모양의 부분에 구를 그림 */ 2009-2학기 가상현실

28 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* 스텐실이 1인 부분에서는 청색 구를 그림 */ glStencilFunc (GL_EQUAL, 0x1, 0x1); glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); glCallList (BLUEMAT); glutSolidSphere (0.5, 15, 15); 2009-2학기 가상현실

29 /* 스텐실이 1이 아닌 부분에서는 토러스를 그림 */ glStencilFunc (GL_NOTEQUAL, 0x1, 0x1);
/* 스텐실이 1이 아닌 부분에서는 토러스를 그림 */ glStencilFunc (GL_NOTEQUAL, 0x1, 0x1); glPushMatrix(); glRotatef (45.0, 0.0, 0.0, 1.0); glRotatef (45.0, 0.0, 1.0, 0.0); glCallList (YELLOWMAT); glutSolidTorus (0.275, 0.85, 15, 15); glRotatef (90.0, 1.0, 0.0, 0.0); glPopMatrix(); } 2009-2학기 가상현실

30 /* 위도우가 다시 그려질 때마다 좌표계를 다시 정의하고, 스텐실 영역을 다시 그림 */
/* 위도우가 다시 그려질 때마다 좌표계를 다시 정의하고, 스텐실 영역을 다시 그림 */ void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); /* 다이아몬드 모양의 스텐실 영역을 생성 */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); 2009-2학기 가상현실

31 gluOrtho2D(-3.0, 3.0, -3.0*(GLfloat)h/(GLfloat)w,
if (w <= h) gluOrtho2D(-3.0, 3.0, -3.0*(GLfloat)h/(GLfloat)w, 3.0*(GLfloat)h/(GLfloat)w); else gluOrtho2D(-3.0*(GLfloat)w/(GLfloat)h, 3.0*(GLfloat)w/(GLfloat)h, -3.0, 3.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClear(GL_STENCIL_BUFFER_BIT); glStencilFunc (GL_ALWAYS, 0x1, 0x1); glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE); 2009-2학기 가상현실

32 glMatrixMode(GL_PROJECTION); glLoadIdentity();
glBegin(GL_QUADS); glVertex2f (-1.0, 0.0); glVertex2f (0.0, 1.0); glVertex2f (1.0, 0.0); glVertex2f (0.0, -1.0); glEnd(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (GLfloat) w/(GLfloat) h, 3.0, 7.0); glMatrixMode(GL_MODELVIEW); glTranslatef(0.0, 0.0, -5.0); } 2009-2학기 가상현실

33 void keyboard(unsigned char key, int x, int y) { switch (key) {
case 27: exit(0); break; } 2009-2학기 가상현실

34 int main(int argc, char** argv) { glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH | GLUT_STENCIL); glutInitWindowSize (400, 400); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutReshapeFunc(reshape); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; } 2009-2학기 가상현실

35 샐행결과 2009-2학기 가상현실

36 스텐실 테스트의 사용 캐핑(capping)
여러 개 폴리곤의 닫힌 볼록 폴리곤에서, 평면이 볼록 폴리곤을 만날 때 몇 개의 표면들로 그 폴리곤을 덮으려고 하는 경우 스텐실 버퍼를 0으로 초기화한 후, 스텐실이 가능하고 스텐실 비교함수가 항상 프래그먼트를 수용하도록 그림 반투명 폴리곤의 겹침 각각의 프래그먼트가 투명 면의 하나의 부분으로 덮힐 수 있도록 스텐실 평면을 사용 스텐실 평면을 0으로 초기화한 후 스텐실 평면이 0일 때만 그리고 스텐실 평면의 값을 그리는 중에 증가시킨다. 스티플링 한 이미지를 점으로만 표현하려고 할 때 스티플 방식을 스텐실 버퍼에 입력하고 스텐실 버퍼의 배부 조건에 따라 그린다. 2009-2학기 가상현실

37 깊이 테스트 화면의 각각의 픽셀에 대해 깊이 버퍼는 시점과 오브젝트에 포함된 각 픽셀 사이의 거리 정보를 유지
깊이 버퍼는 은면(숨어있는 표면)제거에 주로 사용 어떤 픽셀에 표현될 새로운 컬러가 나타나면 이 컬러가 기존의 컬러보다 가까울 경우에만 그려짐 처음에 깊이 버퍼의 초기값은 시점으로부터 가능한 먼 거리였으며, 따라서 어떠한 픽셀들이라도 초기값보다 가까운 거리를 가짐 void glDepthfunc(Glenum func); 깊이 테스트에서 비교하는 함수 설정 func : GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL 기본값은 GL_LESS: 입력된 프래그먼트가 z-값이 깊이 버퍼 값보다 작다면 테스트를 지나감 2009-2학기 가상현실

38 블렌딩 디더링, 논리적 연산 블렌딩 블렌딩은 입력된 프래그먼트의 R, G, B, A와 알파값이 이미 그 위치에 저장된 픽셀들의 값과 함께 결합하는 것 디더링 시스템에서 적은 수의 컬러 비트평면을 사용하여 이미지에서 컬러를 디더링 함으로써 공간적인 해상도를 향상 디더링은 신문의 하프톤과 같은 것 다양한 회색 음영 효과를 내기 위해 흑색과 백색 점의 패턴과 밀도가 변화되는 처리 과정을 통한다. 디더링은 하드웨어 의존적 OpenGL은 사용자가 디더링을 켜고 끄는 것만 할 수 있도록 함. 기본값은 활성화 상태. 디더링은 RGBA와 컬러 인덱스 모드 둘 다 적용 2009-2학기 가상현실

39 프래그먼트의 마지막 연산은 OR, XOR, INVERT와 같은 논리적인 연산 들어오는 컬러버퍼 또는 프래그먼트 값에 적용
논리적인 연산들 프래그먼트의 마지막 연산은 OR, XOR, INVERT와 같은 논리적인 연산 들어오는 컬러버퍼 또는 프래그먼트 값에 적용 프래그먼트 연산들은 특히 비트-블록 이동-형식의 기계에 유용 GL_INDEX_LOGIC_OP, GL_COLOR_LOGIC_OP 를 glEnable(), glDisable()로 넘김으로써 컬러 인덱스 모드나 RGBA 모드에서 논리적 연산의 활성화, 비활성화 함 glLogicOp()를 이용, 반드시 16가지의 연산들 가운데 선택 2009-2학기 가상현실

40 void glLogicOp(Glenum opcode);
프래그먼트와 컬러 버퍼에 저장되어 있는 픽셀에 의해 주어진 연산 중에서 수행하고 논리적인 연산을 선택 매개변수 연산 GL_CLEAR GL_AND s ^ d GL_COPY s GL_OR s v d GL_NOOP d GL_NAND -(s ^ d) GL_SET 1 GL_NOR -(s v d) GL_COPY_INVERTED -s GL_XOR s XOR d GL_INVERT -d GL_EQUIV -(S XOR d) GL_AND_REVERSE S ^ -d GL_AND_INVERTED -s ^ d GL_OR_REVERSE S v -d GL_OR_INVERTED -s v d 2009-2학기 가상현실

41 누적 버퍼 장면 안티앨리어싱이나 모션 블러, 어떤 필드의 사진적인 깊이에 대한 시뮬레이팅, 복합적인 빛으로 인해 생기는 작은 그림자의 계산 등에 사용 마치 사진작가가 복합 노출을 위해 필름을 이용하는 것과 같은 방법으로 누적 버퍼를 이용할 수 있다. 사진작가는 복합 노출을 필름의 교체없이 같은 장면을 계속 찍어서 표현 void glAccum(GLenum op, GLfloat value); 누적 버퍼를 제어하는 커맨드이다. op 변수는 연산 선택 value는 연산에서 사용되는 숫자 가능한 연산에는 GL_ACCUM, GL_LOAD, GL_RETURN, GL_ADD 그리고 GL_MULT 가 있다. 2009-2학기 가상현실

42 장면 안티앨리어싱 장면 안티앨리어싱을 수행하기 위해서 우선 누적 버퍼를 초기화, 프론트 버퍼의 입력과 사용이 가능해야 한다.
n회 동안 지터를 수행하고 이미지를 그리는 코드를 반복 glAccum(GL_ACCUM, 1.0/n); 로 자료를 누적하고 glAccum(GL_RETURN, 1.0) 을 호출한다. 각각의 부가적인 조각들이 누적되는 것처럼 이미지의 변화하는 단계를 보여줌 이미지가 원하는 형태가 되었을 때 과정을 멈추게 할 수 있는 사용자 인터페이스를 제공 glAccum() 커맨드 사용(GL_RETURN을 매개변수로) 2009-2학기 가상현실

43 예제10-2, 3 뷰잉볼륨저장, 장면 안티앨리어싱: accpersp.c
#include <GL/glut.h> #include <stdlib.h> #include <math.h> #include "jitter.h" #define PI_ void accFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar, GLdouble pixdx, GLdouble pixdy, GLdouble eyedx, GLdouble eyedy, GLdouble focus) { GLdouble xwsize, ywsize; GLdouble dx, dy; GLint viewport[4]; 2009-2학기 가상현실

44 glGetIntegerv (GL_VIEWPORT, viewport); xwsize = right - left;
ywsize = top - bottom; dx = -(pixdx*xwsize/(GLdouble) viewport[2] + eyedx*zNear/focus); dy = -(pixdy*ywsize/(GLdouble) viewport[3] + eyedy*zNear/focus); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum (left + dx, right + dx, bottom + dy, top + dy, zNear, zFar); glMatrixMode(GL_MODELVIEW); glTranslatef (-eyedx, -eyedy, 0.0); } 2009-2학기 가상현실

45 void accPerspective(GLdouble fovy, GLdouble aspect,
GLdouble zNear, GLdouble zFar, GLdouble pixdx, GLdouble pixdy, GLdouble eyedx, GLdouble eyedy, GLdouble focus){ GLdouble fov2,left,right,bottom,top; fov2 = ((fovy*PI_) / 180.0) / 2.0; top = zNear / (cos(fov2) / sin(fov2)); bottom = -top; right = top * aspect; left = -right; accFrustum (left, right, bottom, top, zNear, zFar, pixdx, pixdy, eyedx, eyedy, focus); } 2009-2학기 가상현실

46 GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
void init(void) { GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_position[] = { 0.0, 0.0, 10.0, 1.0 }; GLfloat lm_ambient[] = { 0.2, 0.2, 0.2, 1.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialf(GL_FRONT, GL_SHININESS, 50.0); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lm_ambient); 2009-2학기 가상현실

47 glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST);
glShadeModel (GL_FLAT); glClearColor(0.0, 0.0, 0.0, 0.0); glClearAccum(0.0, 0.0, 0.0, 0.0); } void displayObjects(void) { GLfloat torus_diffuse[] = { 0.7, 0.7, 0.0, 1.0 }; GLfloat cube_diffuse[] = { 0.0, 0.7, 0.7, 1.0 }; GLfloat sphere_diffuse[] = { 0.7, 0.0, 0.7, 1.0 }; GLfloat octa_diffuse[] = { 0.7, 0.4, 0.4, 1.0 }; 2009-2학기 가상현실

48 glMaterialfv(GL_FRONT, GL_DIFFUSE, torus_diffuse);
glPushMatrix (); glTranslatef (0.0, 0.0, -5.0); glRotatef (30.0, 1.0, 0.0, 0.0); glTranslatef (-0.80, 0.35, 0.0); glRotatef (100.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, torus_diffuse); glutSolidTorus (0.275, 0.85, 16, 16); glPopMatrix (); glTranslatef (-0.75, -0.50, 0.0); glRotatef (45.0, 0.0, 0.0, 1.0); 2009-2학기 가상현실

49 glMaterialfv(GL_FRONT, GL_DIFFUSE, cube_diffuse); glutSolidCube (1.5);
glRotatef (45.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, cube_diffuse); glutSolidCube (1.5); glPopMatrix (); glPushMatrix (); glTranslatef (0.75, 0.60, 0.0); glRotatef (30.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, sphere_diffuse); glutSolidSphere (1.0, 16, 16); glTranslatef (0.70, -0.90, 0.25); glMaterialfv(GL_FRONT, GL_DIFFUSE, octa_diffuse); 2009-2학기 가상현실

50 glutSolidOctahedron (); glPopMatrix ();
} #define ACSIZE 8 void display(void) { GLint viewport[4]; int jitter; glGetIntegerv (GL_VIEWPORT, viewport); 2009-2학기 가상현실

51 glClear(GL_ACCUM_BUFFER_BIT);
for (jitter = 0; jitter < ACSIZE; jitter++) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); accPerspective (50.0, (GLdouble) viewport[2]/(GLdouble) viewport[3], 1.0, 15.0, j8[jitter].x, j8[jitter].y, 0.0, 0.0, 1.0); displayObjects (); glAccum(GL_ACCUM, 1.0/ACSIZE); } glAccum (GL_RETURN, 1.0); glFlush(); 2009-2학기 가상현실

52 void reshape(int w, int h) {
glViewport(0, 0, (GLsizei) w, (GLsizei) h); } void keyboard(unsigned char key, int x, int y) switch (key) { case 27: exit(0); break; 2009-2학기 가상현실

53 int main(int argc, char** argv) { glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_ACCUM | GLUT_DEPTH); glutInitWindowSize (250, 250); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init(); glutReshapeFunc(reshape); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; } 2009-2학기 가상현실

54 2009-2학기 가상현실

55 예제10-4 정사영으로 지터링 하기: accanti.c
#include <GL/glut.h> #include <stdlib.h> #include "jitter.h" void init(void) { GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_position[] = { 0.0, 0.0, 10.0, 1.0 }; GLfloat lm_ambient[] = { 0.2, 0.2, 0.2, 1.0 }; 2009-2학기 가상현실

56 glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialf(GL_FRONT, GL_SHININESS, 50.0); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lm_ambient); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glShadeModel (GL_FLAT); glClearColor(0.0, 0.0, 0.0, 0.0); glClearAccum(0.0, 0.0, 0.0, 0.0); } 2009-2학기 가상현실

57 void displayObjects(void) {
GLfloat torus_diffuse[] = { 0.7, 0.7, 0.0, 1.0 }; GLfloat cube_diffuse[] = { 0.0, 0.7, 0.7, 1.0 }; GLfloat sphere_diffuse[] = { 0.7, 0.0, 0.7, 1.0 }; GLfloat octa_diffuse[] = { 0.7, 0.4, 0.4, 1.0 }; glPushMatrix (); glRotatef (30.0, 1.0, 0.0, 0.0); glTranslatef (-0.80, 0.35, 0.0); glRotatef (100.0, 1.0, 0.0, 0.0); 2009-2학기 가상현실

58 glMaterialfv(GL_FRONT, GL_DIFFUSE, torus_diffuse);
glutSolidTorus (0.275, 0.85, 16, 16); glPopMatrix (); glPushMatrix (); glTranslatef (-0.75, -0.50, 0.0); glRotatef (45.0, 0.0, 0.0, 1.0); glRotatef (45.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, cube_diffuse); glutSolidCube (1.5); 2009-2학기 가상현실

59 glMaterialfv(GL_FRONT, GL_DIFFUSE, sphere_diffuse);
glPushMatrix (); glTranslatef (0.75, 0.60, 0.0); glRotatef (30.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, sphere_diffuse); glutSolidSphere (1.0, 16, 16); glPopMatrix (); glTranslatef (0.70, -0.90, 0.25); glMaterialfv(GL_FRONT, GL_DIFFUSE, octa_diffuse); glutSolidOctahedron (); 2009-2학기 가상현실

60 glGetIntegerv (GL_VIEWPORT, viewport); glClear(GL_ACCUM_BUFFER_BIT);
glPopMatrix (); } #define ACSIZE 8 void display(void) { GLint viewport[4]; int jitter; glGetIntegerv (GL_VIEWPORT, viewport); glClear(GL_ACCUM_BUFFER_BIT); for (jitter = 0; jitter < ACSIZE; jitter++) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix (); 2009-2학기 가상현실

61 glTranslatef (j8[jitter].x*4.5/viewport[2],
j8[jitter].y*4.5/viewport[3], 0.0); displayObjects (); glPopMatrix (); glAccum(GL_ACCUM, 1.0/ACSIZE); } glAccum (GL_RETURN, 1.0); glFlush(); void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); 2009-2학기 가상현실

62 glOrtho (-2.25, 2.25, -2.25*h/w, 2.25*h/w, -10.0, 10.0); else
if (w <= h) glOrtho (-2.25, 2.25, -2.25*h/w, 2.25*h/w, -10.0, 10.0); else glOrtho (-2.25*w/h, 2.25*w/h, -2.25, 2.25, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void keyboard(unsigned char key, int x, int y){ switch (key) { case 27: exit(0); break; 2009-2학기 가상현실

63 int main(int argc, char** argv) { glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_ACCUM | GLUT_DEPTH); glutInitWindowSize (250, 250); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init(); glutReshapeFunc(reshape); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; } 2009-2학기 가상현실

64 실행결과 2009-2학기 가상현실

65 장면에 정지 그리고 운동하고 있는 오브젝트가 있을 때 잔상이 보이는 이미지 만든다.
모션 블러 장면에 정지 그리고 운동하고 있는 오브젝트가 있을 때 잔상이 보이는 이미지 만든다. 누적버퍼를 설정, 이미지를 공간적으로 지터링 하는 대신에 일시적으로 지터링 전체 장면은 장면이 누적 버퍼에 그려질 때 glAccum(GL_MULT, decayFactor); 를 호출하여 성공적으로 만들 수 있다. decayFactor는 0.0 ~1.0 사이의 수 decayFactor가 작을수록 오브젝트는 빨리 움직이는 것처럼 보인다. 2009-2학기 가상현실

66 필드의 깊이(DOF, Depth of Field)
카메라의 필드 깊이는 커버할 수 있는 범위 안에 초점에서 벗어난 물체들이 위치하는 완벽한 초점 평면에 대한 영역 일반적인 환경에서 OpenGL로 그리는 모든 그림들은 초점이 맞는다. 누적버퍼에 의해 물체가 초점과의 거리가 멀어지면서 더 흐리게 보이는 실제 사진과 같은 효과를 낼 수 있다. 다른 인수들의 값을 가지는 glFrustum()을 호출하여 장면을 반복적으로 그린다. 현재 시점의 위치가 실제의 위치에 근접한 값을 가지도록 해서 각각의 절두체(frustum)가 완벽한 초점의 평면에 놓여진 공통의 직사각형을 공유할 수 있도록 인수 선택 2009-2학기 가상현실

67 예제10-5 필드 깊이 효과: dof.c #include <GL/glut.h>
#include <stdlib.h> #include <math.h> #include "jitter.h" #define PI_ GLuint teapotList; void accFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar, GLdouble pixdx, GLdouble pixdy, GLdouble eyedx, GLdouble eyedy, GLdouble focus) { GLdouble xwsize, ywsize; 2009-2학기 가상현실

68 glGetIntegerv (GL_VIEWPORT, viewport); xwsize = right - left;
GLdouble dx, dy; GLint viewport[4]; glGetIntegerv (GL_VIEWPORT, viewport); xwsize = right - left; ywsize = top - bottom; dx = -(pixdx*xwsize/(GLdouble) viewport[2] + eyedx*zNear/focus); dy = -(pixdy*ywsize/(GLdouble) viewport[3] + eyedy*zNear/focus); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum (left + dx, right + dx, bottom + dy, top + dy, zNear, zFar); 2009-2학기 가상현실

69 glMatrixMode(GL_MODELVIEW); glLoadIdentity();
glTranslatef (-eyedx, -eyedy, 0.0); } void accPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar, GLdouble pixdx, GLdouble pixdy, GLdouble eyedx, GLdouble eyedy, GLdouble focus) { GLdouble fov2,left,right,bottom,top; fov2 = ((fovy*PI_) / 180.0) / 2.0; 2009-2학기 가상현실

70 top = zNear / (cos(fov2) / sin(fov2)); bottom = -top;
right = top * aspect; left = -right; accFrustum (left, right, bottom, top, zNear, zFar, pixdx, pixdy, eyedx, eyedy, focus); } void init(void) { GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; 2009-2학기 가상현실

71 GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat position[] = { 0.0, 3.0, 3.0, 0.0 }; GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 }; GLfloat local_view[] = { 0.0 }; glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0, GL_POSITION, position); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view); 2009-2학기 가상현실

72 glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_AUTO_NORMAL);
glFrontFace (GL_CW); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glEnable(GL_DEPTH_TEST); glClearColor(0.0, 0.0, 0.0, 0.0); glClearAccum(0.0, 0.0, 0.0, 0.0); teapotList = glGenLists(1); glNewList (teapotList, GL_COMPILE); glutSolidTeapot (0.5); glEndList (); } 2009-2학기 가상현실

73 void renderTeapot (GLfloat x, GLfloat y, GLfloat z,
GLfloat ambr, GLfloat ambg, GLfloat ambb, GLfloat difr, GLfloat difg, GLfloat difb, GLfloat specr, GLfloat specg, GLfloat specb, GLfloat shine) { GLfloat mat[4]; glPushMatrix(); glTranslatef (x, y, z); mat[0] = ambr; mat[1] = ambg; mat[2] = ambb; mat[3] = 1.0; glMaterialfv (GL_FRONT, GL_AMBIENT, mat); mat[0] = difr; mat[1] = difg; mat[2] = difb; 2009-2학기 가상현실

74 glMaterialfv (GL_FRONT, GL_DIFFUSE, mat);
mat[0] = specr; mat[1] = specg; mat[2] = specb; glMaterialfv (GL_FRONT, GL_SPECULAR, mat); glMaterialf (GL_FRONT, GL_SHININESS, shine*128.0); glCallList(teapotList); glPopMatrix(); } void display(void) { int jitter; GLint viewport[4]; glGetIntegerv (GL_VIEWPORT, viewport); glClear(GL_ACCUM_BUFFER_BIT); 2009-2학기 가상현실

75 for (jitter = 0; jitter < 8; jitter++) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); accPerspective (45.0, (GLdouble) viewport[2]/(GLdouble) viewport[3], 1.0, 15.0, 0.0, 0.0, 0.33*j8[jitter].x, 0.33*j8[jitter].y, 5.0); renderTeapot (-1.1, -0.5, -4.5, , , , , , , , , , 0.6); 2009-2학기 가상현실

76 renderTeapot (-0.5, -0.5, -5.0, , , 0.0745, , , , , , , 0.4); renderTeapot (0.2, -0.5, -5.5, , , , , , , , , , 0.4); renderTeapot (1.0, -0.5, -6.0, , , , , , , 0.633, , 0.633, 0.6); renderTeapot (1.8, -0.5, -6.5, 0.0, 0.1, 0.06, 0.0, , , , , , .25); 2009-2학기 가상현실

77 void reshape(int w, int h){
glAccum (GL_ACCUM, 0.125); } glAccum (GL_RETURN, 1.0); glFlush(); void reshape(int w, int h){ glViewport(0, 0, (GLsizei) w, (GLsizei) h); void keyboard(unsigned char key, int x, int y){ switch (key) { case 27: exit(0); break; } 2009-2학기 가상현실

78 int main(int argc, char** argv) { glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_ACCUM | GLUT_DEPTH); glutInitWindowSize (400, 400); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init(); glutReshapeFunc(reshape); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; } 2009-2학기 가상현실

79 실행결과 2009-2학기 가상현실

80 다음 표는 몇 가지의 선택된 샘플 카운트에 대한 지터링 값 대부분 픽셀 안에서 균일 분포이며 모두 픽셀 안에 놓인다.
부드러운 그림자 다중 조명 소스로부터 얻어지는 부드러운 그림자들을 누적하기 위해서 동시에 켜진 상태인 조명을 가지고 그림자를 렌더링하고, 그것들을 함께 누적한다. 지터링 이미지를 안티앨리어스 하기 위해 9개나 16개의 샘플이 필요할 경우, 픽셀을 가로지르는 동일 간격의 격자 형태가 가장 적절한 위치 실제로는 가끔씩 근접한 픽셀들에 있는 위치를 구하거나, 픽셀의 중심으로 모여지는(클러스터링된) 균일 분포나 정규 분포를 선택할 수도 있다. 다음 표는 몇 가지의 선택된 샘플 카운트에 대한 지터링 값 대부분 픽셀 안에서 균일 분포이며 모두 픽셀 안에 놓인다. 2009-2학기 가상현실

81 Count 2 {0.25, 0.75},{0.75, 0.75} 3 { , }, { , }, { , } 4 {0.375,0.25}, {0.125,0.75}, {0.875,0.25}, {0.625,0.75} 5 {0.5,0.5}, {0.3,0.1}, {0.7,0.9}, {0.9,0.3}, {0.1,0.7} 6 { , }, { , }, { , }, { , } { , }, { , }, 8 {0.5625,0.4375}, {0.0625,0.9375}, {0.3125,0.6875}, {0.6875,0.8125}, {0.8125,0.1875}, {0.9375,0.5625}, {0.4375,0.0625}, {0.1875,0.3125} 2009-2학기 가상현실

82 Count 9 {0.5,0.5}, { , }, {0.5, }, {0.5, }, { , }, { , }, { , }, { , }, { , }, 12 { ,0.625}, { ,0.875}, {0.25,0.375}, { ,0.125}, {0.75,0.125}, { ,0.125}, {0.75,0.625}, {0.25,0.875}, { ,0.375}, { ,0.375}, { ,0.625}, { ,0.875}, 16 {0.375,0.4375}, {0.625,0.0625}, {0.875,0.1875}, {0.125,0.0625}, {0.375,0.6875}, {0.875,0.4375}, {0.625,0.5625}, {0.375,0.9375}, {0.625,0.3125}, {0.125,0.5625}, {0.125,0.8125}, {0.375,0.1875}, {0.875,0.9375}, {0.875,0.6875}, {0.125,0.3125}, {0.625,0.8125}, 2009-2학기 가상현실


Download ppt "프 레 임 버 퍼."

Similar presentations


Ads by Google