820 likes | 1.03k Views
프 레 임 버 퍼. 프레임 버퍼. “ 버퍼와 버퍼의 사용 ” “ 프래그먼트의 테스트와 연산 ” “ 누적 버퍼 ”. 버퍼와 버퍼의 사용. OpenGL 시스템은 다음의 버퍼들을 다룸 컬러 버퍼 깊이 버퍼 스텐실 버퍼 누적 버퍼 사용자의 특별한 OpenGL 실행 환경에 따라서 어떤 버퍼가 사용 가능한지 , 픽셀당 얼마나 많은 수의 비트를 각 버퍼들이 가지고 있는지 결정. 각 픽셀의 버퍼 저장을 위한 매개변수 요청. glGetIntegerv() 사용. 컬러 버퍼.
E N D
프레임 버퍼 “버퍼와 버퍼의 사용 ” “ 프래그먼트의 테스트와 연산 ” “ 누적 버퍼 ” 가상현실
버퍼와 버퍼의 사용 • OpenGL 시스템은 다음의 버퍼들을 다룸 • 컬러 버퍼 • 깊이 버퍼 • 스텐실 버퍼 • 누적 버퍼 • 사용자의 특별한 OpenGL 실행 환경에 따라서 어떤 버퍼가 사용 가능한지, 픽셀당 얼마나 많은 수의 비트를 각 버퍼들이 가지고 있는지 결정 가상현실
각 픽셀의 버퍼 저장을 위한 매개변수 요청 • glGetIntegerv() 사용 가상현실
컬러 버퍼 • 컬러 버퍼는 사용자가 보통 그리기 위해서 사용하는 버퍼 • 컬러 인덱스나 RGB 컬러 자료를 가짐, 알파값을 가지기도 함 • 입체적인 시각 정보를 위해 왼쪽과 오른쪽의 입체적 영상을 나타내기 위하여 좌측과 우측의 컬러 버퍼를 가진다. • 양(더블) 버퍼 시스템은 전위 버퍼와 후위 버퍼를 가지며, 단일 버퍼 시스템은 전위 버퍼만 가진다. • 선택적이며 표시되지 않는 보조 컬러 버퍼가 제공되는 경우도 있다. • 사용자는 자신의 시스템이 입체 버퍼링인지 양 버퍼링 인지를 알기 위해 GL_STEREO나 GL_DOUBLEBUFFER를 사용 • 입체 버퍼링 • 양 버퍼링 가상현실
깊이 버퍼(Depth Buffer) • 깊이버퍼는 각각의 픽셀의 깊이값을 지니고 있다. • 깊이는 눈과의 거리로 측정 • 큰 값의 깊이 버퍼를 갖는 픽셀들은 작은 값을 갖는 픽셀들에 의해 덧씌워짐 • 깊이 버퍼는 Z버퍼로도 불림 • Z 값은 화면에 수직인 거리(눈과 화면과의 거리)를 나타냄 가상현실
스텐실 버퍼(Stencil Buffer) • 스텐실 버퍼의 한 가지 사용법 • 카드 스텐실이 스프레이 페인트로 매우 정밀한 이미지를 만들 수 있는 것처럼 화면의 특정 부분의 사용을 제한하는 것 • 예를 들어 사용자가 자동차의 바람막이 유리를 통해서 보이는 형태의 이미지를 그리는 경우 • 사용자는 바람막이 형태의 이미지를 스텐실 버퍼에 저장한 후 전체 장면을 그림 • 스텐실 버퍼는 바람막이 유리를 통해 보이지 않는 장면을 제거 가상현실
누적 버퍼(Accumulation Buffer) • 누적 버퍼는 RGBA 모드에서 컬러 버퍼들이 동작하는 것처럼 RGBA 컬러 자료들을 가지고 있다. • 보통의 이미지들을 혼합된 이미지들로 축적하는데 사용 • 사용자는 장면 안티앨리어싱과 같은 작업들을 수행할 수 있다. • 사용자는 직접적으로 누적 버퍼에 그리지는 않음 • 누적 작업은 직사각형의 블록 내에서 수행, 블록들은 자료를 컬러 버퍼 안으로 또는 컬러 버퍼에서 이동시키는 역할 가상현실
버퍼 초기화 • 간단한 그래픽 작업에서 초기화 연산은 그림의 나머지보다 더 많은 시간을 요구 • 만약 사용자가 컬러 버퍼와 깊이 버퍼 그리고 스텐실 버퍼를 초기화하고자 하면 초기화 연산은 세 배의 시간이 걸림 • 이 문제를 해결하기 위해 일부 장치들은 한번에 한 개 이상의 버퍼를 초기화하기 위한 하드웨어 가짐 가상현실
컬러(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이다. 가상현실
초기화 값을 결정하고, 버퍼들을 초기화할 준비되면 glClear() 함수 사용 • void glClear(GLbitfield mask); • 지정된 버퍼들을 초기화 • mask 값은 비트형식의 논리값인 OR로서 GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT, GL_ACCUM_BUFFER_BIT의 조합으로 이루어짐 가상현실
읽기와 쓰기를 위한 컬러 버퍼의 선택 • 그리기와 읽기 연산은 컬러버퍼에 입력되거나 버퍼로부터 나옴 • 그리기를 할 때 그림을 그릴 오브젝트로 한 개 이상의 버퍼를 동시에 지정할 수 있다. • glReadPixels(), glCopyPixels(), glCopyTexImage*(), glCopyTexSubImage*()의 소스가 될 버퍼를 선택하기 위해 glReadBuffer() 명령 사용 • glDrawBuffer() 명령은 입체적 이미지를 나타내거나, 보조 버퍼에 내용을 표현할 버퍼를 선택하는데 사용 가상현실
void glDrawBuffer(GLenum mode); • 쓰기와 지우기를 위해 버퍼를 활성화 혹은 비활성화시킴 • mode의 값 • GL_AUXi 에서 i는 특정한 보조버퍼를 나타내는 숫자이다. • 디폴트일 때 단일 버퍼의 모드값은 GL_FRONT로 나타내고 이중 버퍼의 경우에는 GL_BACK이다. 가상현실
void glReadBuffer(GLenum mode); • glReadBuffer()가 적용되는 버퍼들은 glDrawBuffer()를 표현하는 버퍼들과 동일 • glReadPixels(), glCopyPixels(), glCopyTexImage*().. 등 사전 호출을 통하여 활성화된 컬러 버퍼를 선택한다. • 단일버퍼의 디폴트값은 GL_FRONT, 이고 이중 버퍼일 경우에는 GL_BACK • mode 값 가상현실
버퍼 마스킹하기 • 활성화된 컬러, 깊이, 또는 스텐실 버퍼에 데이터를 입력하기 전에 마스크 연산이 자료들에 적용 • 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이면 입력되지 않는다. 가상현실
glColorMask()명령은 RGBA 모드에서 그릴 때에만 영향을 미친다. • GL_TRUE 일 때 R, G, B, A값이 일치하는 구성요소 입력 • glDepthMask() 의 표시 문자가 GL_TRUE일 때 깊이 버퍼 입력 가능 • glStencilMask() 의 마스크는 스텐실데이터를 위해 사용됨 가상현실
프래그먼트의 테스트와 연산 • OpenGL 프로그램이 프래그먼트들의 생성 여부와 각각의 컬러를 결정한 후에 프래그먼트들이 픽셀 형태로 프레임버퍼에 그려지는 방법을 제어하기 위한 처리 필요 • 프래그먼트들이 프레임 버퍼에 저장되기 전에 반드시 거쳐야 할 완벽한 테스트들과 프래그먼트들의 입력 등 마지막 단계 연산들에 대해 설명. 다음의 순서로 진행됨. • 편집 테스트 • 알파 테스트 • 스텐실 테스트 • 깊이 테스트 • 블렌딩 • 디더링 • 논리적 연산 가상현실
편집 테스트 • 사용자는 glScissor()커맨드를 이용하여 윈도우의 직사각형 분할 및 그 분할 내에서의 그릴 때의 제한 사항 등을 정의 • void glScissor(GLint x, GLint y, GLsizei width, GLsizei height); • 편집 사각형의 위치와 크기를 설정 • 변수는 좌측 아래에 있는 정점 좌표(x, y) 와 직사각형의 가로, 세로 길이로 정의 • 편집테스트는 GL_SCISSOR_TEST(glEnable(), glDisable())의 통과 여부로 판별 • 한 프래그먼트가 직사각형 내부에 존재할 때 편집 테스트를 통과하게 됨 • 디폴트는 직사각형 크기가 윈도우 크기와 동일하며 편집 테스트 통과는 불가능 가상현실
알파 테스트 • 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) 가상현실
스텐실 테스트 • 스텐실 테스트는 스텐실 버퍼가 있을 때에만 사용 • 스텐실은 참조값과 스텐실 버퍼의 픽셀에 저장된 값과의 비교 테스트를 적용 • 테스트의 결과에 의해 스텐실 버퍼 내의 값은 변경 • 사용되는 특정한 비교함수와 참고값과 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, 스텐실은 불가능 가상현실
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이 된다. 가상현실
스텐실 질의 • 질의 함수인 glGetIntegerv()와 표에 나타난 값들을 이용하여 6가지의 스텐실 관련 변수들의 값을 구할 수 있다. • GL_STENCIL_TEST(glIsEnabled()와 함께)를 통해 스텐실 테스트의 가능 여부 판정 • 스텐실 테스트를 위한 질의 값 가상현실
스텐실 예제 • 스텐실 테스트를 사용하는 전형적인 방법 • 화면의 비정상적인 구역에 그림이 그려지지 않도록 마스크 사용 • 스텐실 마스크를 0으로 채운 뒤 원하는 형상을 스텐실 버퍼에 1이 설정되도록 그린다. • 스텐실 구역을 정의한 후 참조값을 1로 설정하고, 참조값이 스텐실 평면의 값과 같을 경우, 프래그먼트가 통과하는 비교 함수를 설정 가상현실
예제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 }; 가상현실
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); glEndList(); 가상현실
glLightfv(GL_LIGHT0, GL_POSITION, position_one); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); glClearStencil(0x0); glEnable(GL_STENCIL_TEST); } /* 토러스에서 윈도우 중앙의 다이아몬드 모양의 부분에 구를 그림 */ 가상현실
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); 가상현실
/* 스텐실이 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); glPushMatrix(); glRotatef (90.0, 1.0, 0.0, 0.0); glutSolidTorus (0.275, 0.85, 15, 15); glPopMatrix(); glPopMatrix(); } 가상현실
/* 위도우가 다시 그려질 때마다 좌표계를 다시 정의하고, 스텐실 영역을 다시 그림 */ void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); /* 다이아몬드 모양의 스텐실 영역을 생성 */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); 가상현실
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); 가상현실
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); glLoadIdentity(); glTranslatef(0.0, 0.0, -5.0); } 가상현실
void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; } } 가상현실
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; } 가상현실
샐행결과 가상현실
스텐실 테스트의 사용 • 캐핑(capping) • 여러 개 폴리곤의 닫힌 볼록 폴리곤에서, 평면이 볼록 폴리곤을 만날 때 몇 개의 표면들로 그 폴리곤을 덮으려고 하는 경우 • 스텐실 버퍼를 0으로 초기화한 후, 스텐실이 가능하고 스텐실 비교함수가 항상 프래그먼트를 수용하도록 그림 • 반투명 폴리곤의 겹침 • 각각의 프래그먼트가 투명 면의 하나의 부분으로 덮힐 수 있도록 스텐실 평면을 사용 • 스텐실 평면을 0으로 초기화한 후 스텐실 평면이 0일 때만 그리고 스텐실 평면의 값을 그리는 중에 증가시킨다. • 스티플링 • 한 이미지를 점으로만 표현하려고 할 때 • 스티플 방식을 스텐실 버퍼에 입력하고 스텐실 버퍼의 배부 조건에 따라 그린다. 가상현실
깊이 테스트 • 화면의 각각의 픽셀에 대해 깊이 버퍼는 시점과 오브젝트에 포함된 각 픽셀 사이의 거리 정보를 유지 • 깊이 버퍼는 은면(숨어있는 표면)제거에 주로 사용 • 어떤 픽셀에 표현될 새로운 컬러가 나타나면 이 컬러가 기존의 컬러보다 가까울 경우에만 그려짐 • 처음에 깊이 버퍼의 초기값은 시점으로부터 가능한 먼 거리였으며, 따라서 어떠한 픽셀들이라도 초기값보다 가까운 거리를 가짐 • void glDepthfunc(Glenum func); • 깊이 테스트에서 비교하는 함수 설정 • func : GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL • 기본값은 GL_LESS: 입력된 프래그먼트가 z-값이 깊이 버퍼 값보다 작다면 테스트를 지나감 가상현실
블렌딩 디더링, 논리적 연산 • 블렌딩 • 블렌딩은 입력된 프래그먼트의 R, G, B, A와 알파값이 이미 그 위치에 저장된 픽셀들의 값과 함께 결합하는 것 • 디더링 • 시스템에서 적은 수의 컬러 비트평면을 사용하여 이미지에서 컬러를 디더링 함으로써 공간적인 해상도를 향상 • 디더링은 신문의 하프톤과 같은 것 • 다양한 회색 음영 효과를 내기 위해 흑색과 백색 점의 패턴과 밀도가 변화되는 처리 과정을 통한다. • 디더링은 하드웨어 의존적 • OpenGL은 사용자가 디더링을 켜고 끄는 것만 할 수 있도록 함. 기본값은 활성화 상태. • 디더링은 RGBA와 컬러 인덱스 모드 둘 다 적용 가상현실
논리적인 연산들 • 프래그먼트의 마지막 연산은 OR, XOR, INVERT와 같은 논리적인 연산 • 들어오는 컬러버퍼 또는 프래그먼트 값에 적용 • 프래그먼트 연산들은 특히 비트-블록 이동-형식의 기계에 유용 • GL_INDEX_LOGIC_OP, GL_COLOR_LOGIC_OP 를 glEnable(), glDisable()로 넘김으로써 컬러 인덱스 모드나 RGBA 모드에서 논리적 연산의 활성화, 비활성화 함 • glLogicOp()를 이용, 반드시 16가지의 연산들 가운데 선택 가상현실
void glLogicOp(Glenum opcode); • 프래그먼트와 컬러 버퍼에 저장되어 있는 픽셀에 의해 주어진 연산 중에서 수행하고 논리적인 연산을 선택 가상현실
누적 버퍼 • 장면 안티앨리어싱이나 모션 블러, 어떤 필드의 사진적인 깊이에 대한 시뮬레이팅, 복합적인 빛으로 인해 생기는 작은 그림자의 계산 등에 사용 • 마치 사진작가가 복합 노출을 위해 필름을 이용하는 것과 같은 방법으로 누적 버퍼를 이용할 수 있다. 사진작가는 복합 노출을 필름의 교체없이 같은 장면을 계속 찍어서 표현 • void glAccum(GLenum op, GLfloat value); • 누적 버퍼를 제어하는 커맨드이다. • op 변수는 연산 선택 • value는 연산에서 사용되는 숫자 • 가능한 연산에는 GL_ACCUM, GL_LOAD, GL_RETURN, GL_ADD 그리고 GL_MULT 가 있다. 가상현실
장면 안티앨리어싱 • 장면 안티앨리어싱을 수행하기 위해서 • 우선 누적 버퍼를 초기화, 프론트 버퍼의 입력과 사용이 가능해야 한다. • n회 동안 지터를 수행하고 이미지를 그리는 코드를 반복 • glAccum(GL_ACCUM, 1.0/n); 로 자료를 누적하고 • glAccum(GL_RETURN, 1.0) 을 호출한다. • 각각의 부가적인 조각들이 누적되는 것처럼 이미지의 변화하는 단계를 보여줌 • 이미지가 원하는 형태가 되었을 때 과정을 멈추게 할 수 있는 사용자 인터페이스를 제공 • glAccum() 커맨드 사용(GL_RETURN을 매개변수로) 가상현실
예제10-2, 3 뷰잉볼륨저장, 장면 안티앨리어싱: accpersp.c #include <GL/glut.h> #include <stdlib.h> #include <math.h> #include "jitter.h" #define PI_ 3.14159265358979323846 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]; 가상현실
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); 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; 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 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); 가상현실
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 }; 가상현실
glPushMatrix (); glTranslatef (0.0, 0.0, -5.0); glRotatef (30.0, 1.0, 0.0, 0.0); glPushMatrix (); 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 (); 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); 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); glPopMatrix (); glPushMatrix (); glTranslatef (0.70, -0.90, 0.25); glMaterialfv(GL_FRONT, GL_DIFFUSE, octa_diffuse); 가상현실
glutSolidOctahedron (); glPopMatrix (); glPopMatrix (); } #define ACSIZE 8 void display(void) { GLint viewport[4]; int jitter; glGetIntegerv (GL_VIEWPORT, viewport); 가상현실