440 likes | 800 Views
OpenGL 이란. 그래픽스 하드웨어에 대한 소프트웨어 인터페이스 OpenGL 의 전신은 실리콘그래픽스사의 IRIS GL IRIS 그래픽스 전용 워크스테이션에서 사용하는 3D 프로그래밍 API 이 하드웨어는 행렬변환을 초고속으로 수행할 수 있고 depth 버퍼링을 하드웨어로 지원 OpenGL 은 IRIS GL 을 다른 하드웨어 플랫폼으로 이식할 때 생기는 여러 문제를 해결해서 이식성을 높이기 위해 SGI 에서 제작된 개방형 (Open) API OpenGL 의 작동 방식
E N D
OpenGL 이란 • 그래픽스 하드웨어에 대한 소프트웨어 인터페이스 • OpenGL의 전신은 실리콘그래픽스사의 IRIS GL • IRIS 그래픽스 전용 워크스테이션에서 사용하는 3D 프로그래밍 API • 이 하드웨어는 행렬변환을 초고속으로 수행할 수 있고 depth 버퍼링을 하드웨어로 지원 • OpenGL 은 IRIS GL을 다른 하드웨어 플랫폼으로 이식할 때 생기는 여러 문제를 해결해서 이식성을 높이기 위해 SGI에서 제작된 개방형(Open) API • OpenGL 의 작동 방식 • OpenGL API를 이용한 함수 호출로 구성되며 200개 이상의 명령과 함수들로 구성. • Lighting, Shading, Texture mapping, Blending, Transparency, Animation 등 특수 효과 포함 Chapter 1 OpenGL 소개
OpenGL은 윈도우 관리나 파일 입출력, 사용자와의 상호작용에 관련된 기능은 지원하지 않는다. • 출력값을 스크린을 통해 나타내기 위해서는 GDI(Graphics Device Interface)라는 Windows API 호출. • GDI는 윈도우에서 텍스트를 쓰거나 간단한 2D 라인을 그릴 수 있는 메소드를 가진다(그림). Chapter 1 OpenGL 소개
일반 어플리케이션에서 OpenGL의 위치 어플리케이션 프로그램 OS 서비스 I/O 서비스 GDI OpenGL 디스플레이/ 윈도우시스템 소프트웨어 래스터라이저 Chapter 1 OpenGL 소개
라이브러리와 헤더파일 • Microsoft Windows에는 소프트웨어 렌더링을 사용하는 OpenGL 이 포함되어 있다. • Windows 시스템 디렉토리에 있는 opengl32.dll 로 OpenGL이 구현되어 있음. • Windows 98: C:\Windows\System • Windows 2000, XP: C:\WINNT\System32 C:\Windows\System32 • OpenGL 유틸리티(glu32.dll) • 특수 행렬 연산과 같이 자주 수행되거나 복잡한 작업을 수행하는 함수들로 구성 • 곡선이나 곡면 등의 그리기를 지원 Chapter 1 OpenGL 소개
모든 OpenGL 함수의 프로토타입과 자료형, 매크로 등은 gl.h 라는 헤더 파일에 있다. 유틸리티 라이브러리는 glu.h 라는 파일에 있다. • #include <windows.h> • #include <gl\gl.h> • #include <gl\glu.h> • GLUT 라이브러리 설치: glut32.dll과 glut32.lib • GLUT 헤더 파일 설치: glut.h • C:\Windows\system32 <= glut32.dll • C:\Program Files\Microsoft Visual Studio\VC98\lib <= glut32.lib • C:\Program Files\Microsoft Visual Studio\VC98\Include\GL <= glut.h Chapter 1 OpenGL 소개
1장 OpenGL 의 소개 OpenGL 이란 무엇인가 OpenGL 코드 구조 OpenGL 커맨드 문법 상태기계로 본 OpenGL OpenGL 렌더링 파이프라인 OpenGL 관련 라이브러리 애니메이션 Chapter 1 OpenGL 소개
예제 소스 프로그램 • ftp://ftp.sgi.com/opengl/opengl14.zip • GLUT 소스 코드나 최신 버전의 프로그램 및 예제 • http://www.opengl.org/resources/libraries/glut/ Chapter 1 OpenGL 소개
OpenGL 이란 무엇인가 • OpenGL은 그래픽스 하드웨어에 대한 소프트웨어 인터페이스 • 대화형 3차원 응용프로그램제작에 필요한 객체를 구성하거나 연산을 수행하기 위한 250 여개의 커맨드로 구성. • 3차원객체 모델을 표현하기위한 하이레벨 커멘드를 제공하지는 않고 • 오직 점, 선, 폴리곤 등과 같은 기하 프리미티브만 사용하여 표현 • GLU(OpenGL Utility Library)와 같이 OpenGL상에서 동작하는 하이레벨의 라이브러리를 만들 수 있다. Chapter 1 OpenGL 소개
OpenGL 에서 수행하는 연산 • 기하 프리미티브로부터 도형을 만든다. 프리미티브에는 점, 선, 폴리곤, 이미지, 비트맵 등이 있다. • 구성한 오브젝트들을 3차원 공간에 놓은 다음, 이를 바라볼 시점을 선택 • 모든 오브젝트에 대한 컬러를 계산한다. 라이팅 조건 및 텍스춰매핑 수행 • 오브젝트의 수학적 표현과 컬러 정보를 스크린상의 픽셀로 변환. 이 과정을 래스터화(Rasterization) 라고 부른다. Chapter 1 OpenGL 소개
OpenGL 코드 구조 #include <whateverYouNeed.h> main(){ InitializeAWindowPlease(); glClearColor(0.0, 0.0, 0.0, 0.0); /* 윈도우 클리어 결정(지정색)*/ glClear(GL_COLOR_BUFFER_BIT); /*해당 윈도우를 실제로 클리어 */ glColor3f(1.0, 1.0, 1.0); /*오브젝트를 그릴 때 사용할 컬러지정(흰색) */ glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); /*최종 이미지를 스크린에 매핑할 때 사용할 좌표계 지정*/ glBegin(GL_POLYGON); /*오브젝트를 정의하는 코드 glBegin에서 glEnd까지 */ glVertex3f(0.25,0.25, 0.0); /*각 꼭지점 지정 (x,y,z)*/ glVertext3f(0.75,0.25,0.0); Chapter 1 OpenGL 소개
glVertext3f(0.75,0.75,0.0); glVertext3f(0.25,0.75,0.0); glEnd(); glFlush(); /*그동안 버퍼(buffer)에 저장된 드로잉 커맨드들이 실제로 실행 */ UpdateTheWindowAndCheckforEvnets(); /* 윈도우 내용을 관리, 이벤트 처리하는 코드가 들어갈 자리 */ } Chapter 1 OpenGL 소개
OpenGL 커맨드 문법 모든 OpenGL 커맨드 앞에는 gl이라는 접두사가 붙음 상수들은 “GL_”로 시작. 커맨드 접미사 - glColor3f() : f는 부동 소수점을 의미, 3은 함수 인자가 3개 Chapter 1 OpenGL 소개
접미사에 v 는 여러 개의 인자를 하나의 벡터(또는 배열)에 담아서 여기에 대한 표인터를 커맨드에 전달한다는 것을 의미 • glColor3f(1.0, 0.0, 0.0);GLfloat color_array[] = {1.0, 0.0, 0.0} ;glColor3fv(color_array); Chapter 1 OpenGL 소개
상태 기계로 본 OpenGL • OpenGL은 일종의 상태기계 • 특정한 상태나 모드로 설정해두면 이를 변경할 때까지 그 상태로 남아 있음. • 현재 컬러를 흰색으로 설정하였다면 이 값이 변하지 않는 한 모든 오브젝트들은 흰색 으로 그려짐. • 컬러, 뷰 설정, 투영 변환, 선 폴리곤 패턴, 폴리곤 드로잉 모드, 빛 위치, 재질 속성 등 제어 • 대다수의 상태 변수들은 glEnable() 및 glDisable()커맨드를 통해 켜거나 끌 수 있음. Chapter 1 OpenGL 소개
OpenGL 렌더링 파이프라인 • 대다수의 OpenGL 구현들은 OpenGL 렌더링 파이프라인 구조를 가짐 • 정점, 선, 폴리곤 등과 같은 기하 데이터는 평가자(evaluator)와 per-vertex 연산을 거침 • 픽셀, 이미지, 비트맵 등과 같은 픽셀 데이터 들은 이와 다른 경로를 거침 • 마지막단계(래스터화)에서는 만나며, 최종적으로 생성된 필셀 데이터는 프레임버퍼에 기록. Chapter 1 OpenGL 소개
Pixel Data Vertex Data Display list Pixel Operations Evaluators Resterization Per-vertex Operations and Primitive assembly Texture assembly Per-fragment operations FameBuffer OpenGL 렌더링 파이프라인 • 연산 순서 Chapter 1 OpenGL 소개
OpenGL 렌더링 파이프라인의 각 단계 • 디스플레이 리스트 • 기하학적인 정보를 나타내는 데이터든, 픽셀을 나타내는 데이터든 상관없이 디스플레이 리스트에 저장해 둘 수 있다. • 평가자: 제어점으로부터 정점을 구함, 표면 법선, 텍스처좌표, 컬러, 공간좌표를 얻음 • Per-vertex (정점연산): 평가자 단계를 거친 후 정점들을 4x4 부동소수점 행렬로 변환. 공간 좌표들은 스크린상의 한 점으로 투영됨. • 프리미티브 조립(primitive assembly) • 프리미티브 조립 단계의 주된 부분은 클리핑. Chapter 1 OpenGL 소개
픽셀 연산(Pixels operation) • 메모리상 배열에 다양한 포맷으로 저장되어 있는 픽셀들을 먼저 풀고 적절한 수의 컴포넌트에 넣음 • 이러한 데이터들에 대해 스케일(scale), 편중(bias) 등의 연산을 수행, 픽셀 맵에 따라 처리. • 그 다음 결과를 고정시키고, 이를 텍스쳐 메모리에 쓰거나 래스터화 단계로 보냄. • 텍스처 조립(Texture assembly) • 좀더 현실감 있는 표현을 위해 기하 오브젝트에 텍스처 이미지를 붙일 수 있는 기능을 제공. Chapter 1 OpenGL 소개
래스터화(rasterization) • 이 단계에서는 기하 데이터와 픽셀 데이터를 모두 프레그먼트 (fragment)들로 변환. • 각각의 프래그먼트들은 사각형으로 되어 있고 프레임버퍼의 한 픽셀에 대응 • 프레그먼트 연산 • 값들이 실제로 프레임 버퍼에 저장되기 전에, 일련의 연산을 수행하여 특정한 프레그먼트들을 변경하거나 제거. • 텍스처링, 안개효과, 블렌딩, 디더링, 논리연산 등의 추가 연산 수행 Chapter 1 OpenGL 소개
OpenGL관련 라이브러리 • OpenGL 에서는 강력한 렌더링 커맨드 들을 제공하고 있지만, 모두 기본적인 기능만 갖고 있기 때문에 하이레벨의 그림을 그릴 때에는 이들 커맨드로만 작업해야 하는 번거로움이 있다. 이와 같은 불편을 줄이기 위해 다음과 같은 라이브러리가 제공. • OpenGL 유틸리티 라이브러리(GLU, OpenGL Utility Library): • 로우 레벨의 OpenGL 커맨드들을 사용하여 뷰잉이나 투영을 위한 행렬 설정, 폴리곤 테셀레이션(tessellation), 표면렌더링 등과 같은 작업들을 수행하는 루틴들로 구성 • OpenGL Reference Manual 에서 설명 • GLU 루틴 앞에 glu 접두사가 붙음. • 렌더링을 지원하기 위해 기존 윈도우 시스템의 기능을 확장시켜주는 라이브러리 • X Window System의 경우: • GLX (OpenGL Extension to the X Window System) 라이브러리 제공 • glx 접두사가 붙음 Chapter 1 OpenGL 소개
MS window 95/98/NT : • WGL 라이브러리(접두사 wgl), • IBM OS/2 : • PGL(Presentation Manager to OpenGL interface), pgl 접두사 붙음 • Apple : • AGL 라이브러리(접두사 agl) • OpenGL 유틸리티 툴킷(GLUT) • 윈도우 시스템에 독립적인 툴킷으로 다양한 윈도우 시스템 API들 간의 차이점들을 추상화. • GLUT 루틴 앞에 glut 접두사가 붙음. • 파렌하이트 씬 그래프(FSG) • OpenGL에 기반한 객체 지향 툴킷으로 대화형 3차원 그래픽 응용프로그램을 제작하기 위한 객체와 메소드들을 제공 Chapter 1 OpenGL 소개
Include 파일 • OpenGL 응용프로그램을 구성하는 거의 대부분이 모든 파일에 gl.h 헤더파일추가. • 대부분의 응용프로그램들이 GLU를 사용하기 때문에 glu.h라는 헤더 파일도 추가. • #include <GL/gl.h> • #include <GL/glu.h> • MS Windows 에서는 MS Windows 버전의 gl.h와 glu.h에서 내부적으로 사용하는 일부 메크로들이 windows.h라는 파일에 정의, windows.h 추가 문장은 gl.h나 glu.h보다 먼저 작성. Chapter 1 OpenGL 소개
GLX 루틴에 접근하려면 • #include < X11/Xlib.h> • #include < GL/glx.h> • MS Windows에서 WGL 루틴에 접근하려면 • #include <windows.h> • 윈도우 관리 태스크를 관리하기 위해 GLUT를 사용하려면 • #include <GL/glut.h> • 표준 C 라이브러리 시스템 콜 사용 시 • #include <stdlib.h> • #include <stdio.h> Chapter 1 OpenGL 소개
GLUT – OpenGL 유틸리티 툴킷 • 렌더링 커맨드는 윈도우 시스템이나 운영체제와는 독립적으로 설계 • 마우스로부터 발생한 이벤트를 인식하기 위한 커맨드들은 OpenGL에 포함되어 있지 않다. • 사용자 입력이나 윈도우 처리를 위해 GLUT 사용 • 윈도우 관리 • 윈도우를 초기화 하기 위해서는 다섯 개의 루틴이 필요 • glutInit(int *argc, char **argv) • GLUT를 초기화하고 커맨드 라인 인자로 주어진 것들을 처리 Chapter 1 OpenGL 소개
glutInitDisplayMode(unsigned int mode) • 컬러 모델로 RGBA나 컬러 인덱스 모드를 사용할지 여부를 지정 • glutInitWindowPosition(int x, int y) • 스크린에서 윈도우의 좌측 상단 모서리에 해당하는 위치를 지정 • glutInitWindowSize(int width, int size) • 윈도우의 크기를 픽셀 단위로 지정. • int glutCreateWindow(char *string) • OpenGL 컨텍스트를 가진 윈도우를 생성. 윈도우에 대한 고유 식별 번호를 반환한다. • glutMainLoop() 호출 전까지는 생성된 윈도우가 화면에 나타나지 않음 Chapter 1 OpenGL 소개
디스플레이 콜백 • glutDisplayFunc(void (*func)(void)) • 장면을 다시 그리는 데 필요한 루틴들은 모두 이러한 디스플레이 콜백 함수에 포함되어 있어야 한다. • 프로그램 실행하기 • 마지막으로 해야 할 일은 glutMainLoop(void)를 호출하는 것. 이 루틴을 호출하면 지금까지 생성한 윈도우들과 여기에 그린 그림들이 비로소 화면에 나타나게 된다. Chapter 1 OpenGL 소개
GLUT를 사용한 간단한 OpenGL 프로그램 #include <GL/glut.h> #include <stdlib.h> void display(void) { glClear (GL_COLOR_BUFFER_BIT); /* 모든 픽셀을 지운다 */ /* (0.25, 0.25, 0.0) 과 (0.75, 0.75, 0.0)에 모서리를 둔 흰색 폴리곤을 그린다*/ glColor3f (1.0, 1.0, 1.0); glBegin(GL_POLYGON); glVertex3f (0.25, 0.25, 0.0); glVertex3f (0.75, 0.25, 0.0); Chapter 1 OpenGL 소개
glVertex3f (0.75, 0.75, 0.0); glVertex3f (0.25, 0.75, 0.0); glEnd(); glFlush (); /* 기다리지 않고, 버퍼에 저장된 OpenGL 루틴을 실행한다. */ } void init (void) { glClearColor (0.0, 0.0, 0.0, 0.0); /* 클리어 컬러를 선택한다 */ glMatrixMode(GL_PROJECTION); /* 뷰잉값을 초기화 한다 */ glLoadIdentity(); glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); } Chapter 1 OpenGL 소개
/* 초기 윈도우의 크기와 위치, 디스플레이 모드(싱글버퍼와 RGBA모드)를 설정한다. * 그리고 타이틀바에 “hello” 가 출력되는 윈도우를 연다. 초기화 루틴들을 실행시킨다 * 그래픽을 출력하도록 콜백 함수를 등록한다. *마지막으로, 메인 루프를 실행하고 이벤트를 처리한다. */ int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (250, 250); glutInitWindowPosition (100, 100); glutCreateWindow ("hello"); init (); glutDisplayFunc(display); glutMainLoop(); return 0; } Chapter 1 OpenGL 소개
입력 이벤트 처리 • 지정한 이벤트가 발생할 때 호출될 콜백 커멘드를 등록하기 위해서는 다음과 같은 루틴을 사용 • glutReshapeFunc(void (*func)(int w, int h)) • 윈도우 크기가 변경될 때 취할 동작지정 • glutKeyboardFunc(void (*func)(unsigned char key, int x, int y)) • 키 누를 때 루틴이 호출되도록 키보드 버튼과 루틴을 연결 • glutMouseFunc(void (*func)(int button, int state, int x, int y)) • 마우스 버튼을 누를 때 해당 루틴이 호출되도록 버튼과 연결 • glutMotionFunc(void (*func)(int button, int state, int x, int y)) • 마우스 버튼을 누른 채 마우스를 움직일 때 호출될 콜백 함수 등록 Chapter 1 OpenGL 소개
백그라운드 프로세스 관리 • 처리해야 할 이벤트가 없을 때, 즉 이벤트 루프가 유휴 상태에 있을 때 실행될 함수를 glutIdleFunc(void (*func)(void))로 지정. • 인자로 함수에 대한 포인터만 받는다. Chapter 1 OpenGL 소개
3차원 오브젝트 그리기 • GLUT에서는 다음과 같은 3차원 오브젝트를 그리기 위한 루틴 제공 Chapter 1 OpenGL 소개
이러한 오브젝트들은 와이어프레임 방식으로 그리거나, 표면 법선을 정의하여 솔리드 쉐이딩된 형태로 그릴 수 있다. 정육면체와 구를 그리기 위한 루틴들로 다음과 같은 것들이 제공 • void glutWireCube(GLdouble size); • void glutSolidCube(GLdouble size); • void glutWireSphere(GLdouble radius, GLint slices, GLint stacks); • void glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); • GLUT 참고 • http://www.opengl.org/resources/libraries/glut/spec3/spec3.html Chapter 1 OpenGL 소개
애니메이션 • 애니메이션 원리 open_window(); for (i = 0; i < 1000000; i++) { clear_the_window(); draw_frame(I); wait_until_a_24th_of_a_second_is_over(); } • 더블버퍼링을 사용한 부드러운 애니메이션 open_window_in_double_buffer_mode(); for (i = 0; i < 1000000; i++) { clear_the_window(); draw_frame(i); swap_the_buffers(); } Chapter 1 OpenGL 소개
불규칙 적인 리프레쉬 • 장면의 복잡도가 프레임 비율에 가까울 경우(1/60초 2/60초, 3/60초) 어떤 프레임은 이 시간을 초과하고 다른 것은 간신히 이 시간 내에 그려지기 때문에 비율이 일정하지 않게 되어 시각적으로 보기 좋지 않다. 이와 같은 경우 모든 프레임을 빠르게 처리할 수 있도록 장면을 간소화 할 수 없다면 처리 시간에 약간의 딜레이를 추가하여 느리지만 일정한 프레임 비율을 갖도록 하는 것이 좋다. Chapter 1 OpenGL 소개
움직임 = 다시 그리기 + 교체 • 에니메이션에서 오브젝트들은 단순히 변환만 달라짐. • 뷰어의 시점이 달라지거나, 자동차가 길을 따라 좀더 움직이거나, 오브젝트가 약간 회전하기만 하는 경우가 많음. • 드로잉에 관련 없는 연산에 대해 계산해야 할 것이 많아지면 프레임비율이 떨어짐. • Swap_the_buffer() 루틴 뒤에 나오는 유휴시간이 이러한 계산을 위해 사용될 수 있다. • X Window System • void glxSwapBuffers(Displays *dpy, Window window); • GLUT라이브러리를 사용할 경우 • void glutSwapBuffers(void); Chapter 1 OpenGL 소개
더블버퍼링을 사용한 프로그램 • glutSwapBuffers()를 사용하는 방법을 보여주고 있다. 마우스 버튼을 이용하여 회전을 켜고 끄도록 하였다. #include <GL/glut.h> #include <stdlib.h> static GLfloat spin = 0.0; void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_FLAT); } Chapter 1 OpenGL 소개
void display(void){ glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glRotatef(spin, 0.0, 0.0, 1.0); glColor3f(1.0, 1.0, 1.0); glRectf(-25.0, -25.0, 25.0, 25.0); glPopMatrix(); glutSwapBuffers(); } Chapter 1 OpenGL 소개
void spinDisplay(void) { spin = spin + 2.0; if (spin > 360.0) spin = spin - 360.0; glutPostRedisplay(); } void reshape(int w, int h) { glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } Chapter 1 OpenGL 소개
void mouse(int button, int state, int x, int y) { switch (button) { case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) glutIdleFunc(spinDisplay); break; case GLUT_MIDDLE_BUTTON: case GLUT_RIGHT_BUTTON: if (state == GLUT_DOWN) glutIdleFunc(NULL); break; default: break; } } Chapter 1 OpenGL 소개
/* 더블 버퍼 디스플레이 모드를 요청하고, 마우스 입력 콜백 함수를 등록 */ int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize (250, 250); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMouseFunc(mouse); glutMainLoop(); return 0; /* ANSI C requires main to return int. */ } Chapter 1 OpenGL 소개
소스파일 실행 ( 마우스 동작 실행 전 ) • 흰색 사각형이 회전하지 않는다. • 소스파일 실행 • 왼쪽 마우스 클릭으로 회전 • 오른쪽 마우스 클릭으로 중단 Chapter 1 OpenGL 소개
Nate Robins 의 OpenGL 튜토리얼 • http://www.xmission.com/~nate/tutors.html Chapter 1 OpenGL 소개