OpenGL & GLUT & GLEW OpenGL & GLUT 321190 2013 년봄학기 3/12/2013 박경신 OpenGL http://www.opengl.org/ http://www.sgi.com/software/opengl Windows95 이후 OpenGL 이표준으로들어가있음. ftp://ftp.microsfot.com/softlib/mslfiles/opengl95.exe freeglut for Win32 http://freeglut.sourceforge.net/ freeglut-msvc-2.8.0-1.mp.zip 내려받기 glew for Win32 http://glew.sourceforge.net/ glew-1.9.0-win32.zip 내려받기 2 Installing OpenGL & GLUT & GLEW Libraries 를 Visual C++ 의 C:\Program Files\Microsoft SDKs\Windows\v7.0A\lib\ 에설치 freeglut.lib glew32.lib glew32mx.lib Include files 을 Visual C++ 의 C:\Program Files\Microsoft SDKs\Windows\v7.0A\include\GL\ 에설치 freeglut.h freeglut_ext.h freeglut_std.h glut.h glew.h glxew.h wglew.h Dynamically-linked libraries를 C:\Windows\system32 (Windows 7 32-bit 운영체제기준 ) 에설치 freeglut.dll, glew32.dll, glew32mx.dll C:\Windows\SysWOW64 (Windows 7 64-bit 운영체제기준 ) 에도 freeglut.dll, glew32.dll, glew32mx.dll 설치 3 Compiling OpenGL Programs Visual Studio 2010 VC++ 실행 프로젝트새로만들기 메뉴에서 File->New->Projects Win32 Console Application 선택 프로젝트이름지정 Linker 에 library files 을지정 메뉴에서 Project->Settings->link->Object/library modules (Project->Properties->Linker->Input->Additional dependencies) glew32.lib lib freeglut.liblib 를넣는다 프로젝트에파일새로만들기 메뉴에서 Project->Add to Project-> Files 파일이름지정 빌드 (build) (F7) 와실행 (execute) (F5) 4
Windows System 윈도우시스템 Microsoft Windows X Window systems 윈도우시스템과 OpenGL 시스템은모두래스터그래픽스시스템임 OpenGL 프로그래밍을하기위해서는 사용윈도우시스템에서제공하는래스터시스템을기반으로윈도우프로그래밍수행 윈도우프로그래밍문맥에서추상적인래스터시스템인 OpenGL 시스템을윈도우시스템에연결 OpenGL 에서제공하는함수들을사용하여 3 차원그래픽스프로그래밍을수행 원하는 OpenGL 작업이실제로하드웨어를제어하고있는사용윈도우시스템이효율적으로이해할수있는형태로전환 5 OpenGL 실리콘그래픽스사 (SGI) 가개발한 3차원그래픽스라이브러리 API (1992) 2차원그래픽스는 (z축의값을 0으로처리한 ) 3차원의특수경우로봄 OpenGL 그래픽스함수는프로그래밍언어에독립적인기능으로지정되어있음 C/C++, Java, Fortran, Python 등다수언어와사용가능 OpenGL 은하드웨어에중립적임 (Window system 이나 OS에독립적인 API) No I/O library No specific model loading mechanism No hardware specific functions (but available as extensions) 6 OpenGL Evolution 초창기에 Architectural Review Board (ARB) 에의해주도 SGI, Microsoft, Nvidia, HP, 3DLabs, IBM 등 현재는 Kronos Group OpenGL 31 3.1 전적으로 기반으로감. 즉, 모든응용프로그램은반드시 vertex 와 fragment shader 를사용해야함 대부분 2.5 함수는 deprecated ( 누락될것이라사용을권유하지않음 ) OpenGL ES 임베디드시스템용. Ver1.0은 OpenGL 2.1을간소화. Ver2.0은 OpenGL 3.1을간소화 WebGL OpenGL ES 2.0을 Javascript로구현 OpenGL 4.1 & 4.2 7 Geometry shader와 tesselator 추가 OpenGL 1.0 OpenGL 1.0은 1994년 7월 1일발표 OpenGL 1.0의그래픽스파이프라인은 fixed-function으로 OpenGL 1.1부터 OpenGL 2.0 (2004/09) 까지사용 Pixel Transform and Lighting Texture Store Primitive Setup and Rasterizati on Coloring and Texturing Blending
OpenGL 2.0 Programmable Pipeline OpenGL 2.0 은공식적으로 Programmable 를추가 그러나, Fixed-function i pipeline 도사용가능 Pixel Transform and Lighting Texture Store Primitive Setup and Rasterizati on Coloring and Texturing Blending OpenGL 3.0 OpenGL 3.0 은 deprecation model 을소개 OpenGL 30 3.0 이전버전까지는 backward compatibility 를지원하기위하여함수를추가해왔지만 OpenGL 3.0부터더이상 backward compatibility를지원하지않고새로운함수를제공함 OpenGL 3.1 (2009/03/24) 까지는그래픽스파이프라인이동일하게적용 OpenGL 3.1부터 forward compatible contexts를지원 Context Type Description Full Forward Compatible Includes all features (including those marked depr ecated) available in the current version of OpenGL Includes all non-deprecated features (i.e., creates a context that would be similar to the next versio nof OpenGL) Exclusively Programmable Pipeline OpenGL 3.1은 Fixed-function pipeline을제거함 프로그램은오로지 shader를사용해야함 추가적으로, 모든데이터는 GPU에보내어져서사용함 모든정점데이터는 buffer objects를사용하여보내어짐 Pixel Texture Store Primitive Setup and Rasterizati on Blending More Programmability OpenGL 3.2 (2009/09/03) 은 Geometry 단계를추가함 Pixel Texture Store Geometry Primitive Setup and Rasteriza tion Blending
More Evolution Context Profiles OpenGL 3.2 는 context profile 개념을소개 Profile이란응용프로그램에서 features를선택하기쉽게하기위하여제공 현재 2 가지 profile 이존재 : core & compatible OpenGL 4.1 & 4.3 OpenGL 4.1 (2010/07/25) 에서는 tessellation-control shader와 tessellation-evaluation shader를추가 가장최근버전은 OpenGL 4.3 Context Type Profile Description core All features of the current release Full compatible All features ever in OpenGL Forward Compa core All non-deprecated features tible compatible Not supported Pixel Tessellation Control Texture Store Tessellation Evaluation Geometry Primitive Setup and Rasterizatat ion Blending OpenGL Libraries OpenGL core library 윈도우시스템에서는 OpenGL32 유닉스 / 리눅스시스템에서는 libgl.a OpenGL Utility Library (GLU) OpenGL core를추가지원함 OpenGL Windows Toolkit Different platforms have different ways to integrate OpenGL with their windowing environment X Window System (GLX) Apple (AGL) Windows (WGL) IBM OS/2 (PGL) Cross-platform (GLUT OpenGL Utility Toolkit) 15 Freeglut & GLEW Freeglut는 GLUT를개선한버전 초기 GLUT는오래되고더이상개선되지않고있음. freeglut는 GLUT를개선한것으로추가적인기능제공함. GLEW (OpenGL Extension Wrangler Library) 하드웨어와연관이되어있는 OpenGL은사용하기어려움. 함수포인터를얻어내야하며 Extension 도신경써야함. GLEW는 GLSL같은 OpenGL extension을편리하게사용할수있도록함 OpenGL 응용프로그램에서 #include <glew.h> 와 glewinit() 를불러서초기화하면됨 16
OpenGL & GLSL 쉐이더기반의 OpenGL 대부분의 state variables, attibutes and related pre 3.1 OpenGL funtions 이더이상사용되지않음. 모든것이쉐이더를통해이루어짐 GLSL (OpenGL Shading Language) Nvidia 의 Cg 나 Microsoft HLSL 과비슷한 C 언어와흡사함 코드는쉐이더로보내어져서 GPU를통해렌더링이수행됨 17 단순히윈도우를여는프로그램예제 #include <GL/glew.h> #include <GL/freeglut.h> #include <GL/freeglut_ext.h> ext void display (void) int main(int argc, char *argv[]) glutinit(&argc, argv); glutinitdisplaymode(glut_rgba); glutinitwindowsize(512, 512); glutcreatewindow(argv[0]); t glewinit(); glutdisplayfunc(display); glutmainloop(); return 0; 18 윈도우를전부하얀색으로칠하는프로그램예제 void display (void) glclear(gl_color_buffer_bit); glflush(); void init (void) glclearcolor(1.0, 1.0, 1.0, 1.0); int main(int argc, char *argv[]) glutinit(&argc, argv); glutinitdisplaymode(glut_rgba); glutinitwindowsize(512, 512); glutcreatewindow(argv[0]); glewinit(); init(); glutdisplayfunc(display); glutmainloop(); return 0; 19 OpenGL/GLUT Program 작성예 gl 를이용한 OpenGL 2.x 프로그램 void display (void) glclear(gl_color_buffer_bit); glcolor3f(1.0, 0.0, 0.0); glbegin(gl_line_loop); gl3f(-0.75, -0.75, 0.0); gl3f(0.75, -0.75, 0.0); gl3f(0.75, 0.75, 0.0); glend(); glflush(); void init (void) /* 변경없음 */ int main(int argc, char*argv[]) argv[]) /* 변경없음 */ 20
gl 를이용한 OpenGL 2.x 프로그램 void display (void) glclear(gl_color_buffer_bit); glcolor3f(1.0, 0.0, 0.0); glbegin(gl_polygon); gl3f(-0.75, -0.75, 0.0); gl3f(0.75, -0.75, 0.0); gl3f(0.75, 0.75, 0.0); glend(); glflush(); OpenGL/GLUT Program 작성예 OpenGL 3.x 프로그램 void display (void) glclear(gl_color_buffer_bit); /* 이부분을쉐이더로작성 */ glflush(); 21 22 OpenGL 3.x Simplified Rendering Pipeline Application GPU Flow Vertices Vertices s Pixels Processing Rasterizer Processing Framebuffer Modern OpenGL Programming in a Nutshell Modern OpenGL (OpenGL 3.x) 프로그래밍은다음과같은단계로진행 1. 프로그램을만든다. 2. 자료를 Buffer Object (VBO) 와 Array Object (VAO) 를만들고이자료를쉐이더에로딩한다. 3. 이자료의위치와쉐이더의변수와 연결 (Connect) 한다. 4. 렌더링을수행한다.
OpenGL 3.x Program Structure OpenGL 3.x 프로그램의일반적인구조 main(): 관련콜백함수지정등 Specifies the callback functions Opens one or more windows with the required properties Enters event loop (last executable statement) init(): 상태변수 (state variables) 지정 Viewing Attributes init(): read, compile and link shaders callbacks Display function Input and window functions #include <GL/glew.h> #include <GL/freeglut.h> th includes gl.h lh #include <GL/freeglut_ext.h> int main(int argc, char** argv) specify window properties glutinit(&argc,argv); g g glutinitdisplaymode(glut_single GLUT_RGB); glutinitwindowsize(512,512); glutinitwindowposition(0,0); glutcreatewindow(argv[0]); glutdisplayfunc(display); display callback glewinit(); init(); set OpenGL state and initialize shaders glutmainloop(); enter event loop void glutinit(int *argc, char **argv) GLUT와 OpenGL 환경을초기화. 인수에는 main의인수를그대로건네줌. void glutinitwindowsize(int width, int height) void glutinitwindowposition(int x, int y) 윈도우크기를지정함. 윈도우위치를지정함. int glutcreatewindow(char *name) 윈도우를여는함수. 인수 name은그윈도우의이름이타이틀바에표시됨. void glutdisplayfunc(void (*func)(void)) 인수 func 는열린윈도우내에디스플레이하는 ( 즉, 그림을그리는 ) callback함수포인터. 윈도우가열리거나다른윈도우에의해숨겨진윈도우가다시디스플레이될때이함수가실행 void glutmainloop(void) GLUT 루프. 이함수의호출로프로그램은이벤트를기다리는 27 상태임. void glutinitdisplaymode(unsigned int mode) 디스플레이의표시모드를설정. Mode에 GLUT_RGBA를지정했을경우는색의지정을 RGB로사용함을지정. 그밖에인덱스칼라모드 (GLUT_INDEX) 를지정하면효율을향상시킬수있음. void glclearcolor(glclampf R, Glclampf G, Glclampf B, Glclampf A) 윈도우를전부칠할때의색을지정. R, G, B, A 는 0~1 사이의값을가짐. (0, 0, 0, 1) 을지정하면검정색의불투명을그림. void glclear(glbitfield mask) 윈도우를전부칠함. Mask에는전부칠하는버퍼를지정한다. OpenGL이관리하는화면상의버퍼 ( 메모리 ) 에는 color buffer, depth buffer, stencil buffer, overlay buffer, 등이겹쳐서존재함. GL_COLOR_BUFFER를지정했을때는컬러버퍼만전부칠해짐. void glflush(void) 이함수는아직실행되지않은 OpenGL 명령을전부실행. 28
Immediate Mode Graphics Geometry 는정점 (vertices) 으로지정 2 차원또는 3 차원공간에한지점에정점으로지정 Points, lines, circles, polygons, curves, surfaces Immediate mode 응용프로그램에서매번정점이지정되고, 그위치값이 GPU에보내어짐 과거에 gl를사용했었음 CPU 와 GPU 간에병목현상이발생함 OpenGL 3.1 부터사라짐 Retained Mode Graphics 모든정점 (vertex) 과속성 (attribute) 정보를배열 (array) 로지정 이배열을 GPU 에보내어저장하고렌더링에사용함 Display Callback void display() glclear(gl_color_buffer_bit); gldrawarrays(gl_triangles, 0, 3); glflush(); gldrawarrays 를사용하여그리기를수행함. 이때, 배열 (arrays) 는정점배열 (vertex arrays) 을가진버퍼객체 (buffer objects) 임 Arrays 정점 (Vertices) 속성들 Position Color Texture Coordinates Application data const float vertexpositions[] = -0.75f, -0.75f, 0.0f, 1.0f, 0.75f, -0.75f, 0.0f, 1.0f, 0 75f 0 75f 0 0f 1 0f 0.75f, 0.75f, 0.0f, 1.0f, ;
Array Object Array Object 는모든정점자료 (positions, colors,..) 를묶어줌. 하나의 VAO에여러개의 Buffer Object을가질수있음. 예로, 위치정보버퍼와색상정보를위한버퍼를 VAO에사용. 보통하나의 Mesh마다하나의 VAO를사용함 VAO 를생성하고, bind 함. GLuint vao; // vertex array object glgenarrays(1, &vao); glbindarray(vao); 이것은 Array만을가진다는의미로아직실제데이터 (content) 는없음. Buffer Object Buffer object 는대용량자료를 GPU 에보내줄수있음. 버퍼를생성하고, bind하고, 자료를넣어줌. GLuint buffer; // vertex buffer object glgenbuffers(1, &buffer); glbindbuffer(gl_array_buffer, buffer); glbuffer(gl _ ARRAYBUFFER, _ sizeof(vertexpositions), ete osto s), vertexpositions, GL_STATIC_DRAW); 그리고 glattribpointer를호출하여현재바인드된버퍼가몇번째 Attribute 버퍼인지어떤속성을갖는지알려줌. 다음 glenableattribarray(index) 를호출해야해당버퍼의정보가렌더링됨. glattribpointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); glenableattribarray(0); Initialization init() 에서 Array Objects 와 Buffer Objects 지정 또한일반적으로 GL 의 clear color 와 parameters 도지정 또한 shaders 도지정 Read Compile Link Functions glcreateprogram 프로그램 (vertex shader, geometry shader, fragment shader를포함하는파이프라인 ) 생성 glcreate GL에서쉐이더공간을만들어달라고요청. 단지공간을생성하기위한함수 glsource 할당한쉐이더공간과쉐이더소스파일을읽어들인버퍼를연결 glcompile 쉐이더를컴파일 glattach 컴파일된쉐이더를프로그램에붙임 gllinkprogram 링크하고에러체크. 링크가완료되면프로그램이준비완료된것임 gluseprogram 이프로그램을사용
// Create a NULL-terminated string by reading the provided file static char* readsource(const char* shaderfile) FILE* fp = fopen(shaderfile, "r"); if ( fp == NULL ) return NULL; fseek(fp, 0L, SEEK_END); long size = ftell(fp); fseek(fp, 0L, SEEK_SET); char* buf = new char[size + 1]; fread(buf, 1, size, fp); buf[size] = '\0'; fclose(fp); // Create a GLSL program object from vertex and fragment shader files GLuint Init(const char* vfile, const char* ffile) struct const char* filename; GLenum type; GLchar* source; shaders[2] = vfile, GL_VERTEX_SHADER, NULL, ffile, GL_FRAGMENT_SHADER, NULL ; GLuint program = glcreateprogram(); for ( int i = 0; i <2;++i ) & s = shaders[i]; s.source = readsource( s.filename ); if ( shaders[i].source == NULL ) std::cerr << "Failed to read " << s.filename << std::endl; exit( EXIT_FAILURE ); GLuint shader = glcreate( s.type ); return buf; glsource( shader, 1, (const GLchar**) &s.source, NULL ); glcompile( shader ); GLUT (OpenGL Utility Toolkit) // 중간생략 delete [] ssource; s.source; glattach( program, shader ); gllinkprogram(program); GLint linked; glgetprogramiv( program, GL_LINK_STATUS, &linked ); if (!linked ) std::cerr << " program failed to link" << std::endl; GLint logsize; glgetprogramiv( g (program, GL_ INFO_ LOG_ LENGTH, &logsize); char* logmsg = new char[logsize]; glgetprograminfolog( program, logsize, NULL, logmsg ); delete [] logmsg; g exit( EXIT_FAILURE ); gluseprogram(program); return program; Mark J. Kilgard가개발한 portable windowing and interaction API Prefix glut 로시작 대부분의 window system 에보편적인기능들을 wrapping 한상위 interface제공 (portable across all PC and workstation OS platforms) OpenGL이제공하는범위보다상위수준의 utility function도제공 UNIX/X-window에서개발된 code를그대로재사용가능 Win32, MFC, Xlib 을알필요가없음 그러나 Window system의기능을제한적으로만이용가능
GLUT Program Structure GLUT Callbacks GLUT defines a basic program structure - an event loop, with callback functions. Callback, a function that you provide for other code to call when needed; d the "other code" is typically in a library GLUT uses callbacks for drawing, keyboard & mouse input, and other events. Whenever the window must be redrawn, your drawing callback is called. Whenever an input event occurs, your corresponding callback is called. GLUT Callbacks glutdisplayfunc glutpostredisplay glutidlefunc gluttimerfunc glutgetmodifiers glutignorekeyrepeat glutkeyboardfunc glutkeyboardupfunc glutspecialfunc glutspecialupfunc GLUT Callbacks Handling Display Callbacks glutdisplayfunc(void (*func)(void)) Specifies a function that would draw the graphical contents Argument: display function name Handling Input Events glutreshapefunc(void (*func)(int w, int h)) What action should be taken when the window is resized glutkeyboardfunc(void (*func)(unsigned char key, int x, int y)) glutmousefunc(void (*func)(int button, int state, int x, int y)) Handle keyboard key and mouse button glutmotionfunc(void (*func)(int x, int y)) What to do when the mouse is moved while a mouse button is pressed
The Reshape Event Callback This callback sets up OpenGL to display images in a window of the new size The value w is the new width, and the value h is the new height void reshape(int w, int h) glviewport(0, 0, w, h); The Keyboard Event Callback This callback simply causes the program to exit when the user hits the ESC key void keyboard(unsigned char key, int x, int y) switch (key): /* ESC-key & q-key exits the program */ case 27: case q : exit(0); GLUT Functions glutmainloop(void) Enter the GLUT event processing loop glutpostredisplay() Ensures that the window gets drawn at most once each time GLUT goes through the event loop. In general, never call the display callback directly, but rather use the glutpostredisplay() whenever the display needs to be redrawn.