Graphics Programming
2.1 The Sierpinski Gasket
Sierpinski gasket 예제문제로사용 원래, Fractal geometry 에서정의 만드는방법 삼각형을그린다. 삼각형내부에 random 하게점 P i 를선택, 출력 random 하게꼭지점중의하나 V i 선택 V i 와 P i 의중점을 P i+1 로선택, 출력 위과정을반복 2
Program Outline 전체구조 void main(void) { initialize_the_system( ); for (some_number_of_points) { pt = generate_a_point( ); display_the_point( pt ); } cleanup( ); } // 좌표계산 // 출력 제일먼저할일? 점을어떻게출력할것인가? 3
Pen-Plotter Model pen-plotter 2D 종이위에펜을움직여서출력 moveto(x, y); 정해진위치로펜을이동 lineto(x, y); 정해진위치까지선분출력 가장오래된 graphics output model 장점 : 간단. 2D 종이, 2D 화면에적합한 model printer 용언어, 초기 graphics system 에서사용 PostScript, PDF, LOGO, GKS, 단점 : 3D model 에는부적합 4
2D in a 3D Model 3D system에서의 2D 처리 2D 는 3D의특별한경우이다 3D 좌표 : (x, y, z) 2D로해석할때는 z = 0 : (x, y, 0) 간단하게 : (x, y) y z 3D space x 2D plane (z = 0) 5
Vertex space 상의위치 1개 graphics 에서는 2D, 3D, 4D space 사용 표기법 : column vector x p = y z geometric objects point : vertex 1개로정의 line segment : vertex 2개로정의 triangle : vertex 3개로정의 point 와헷갈리지말것 vertex triangle 6
Vertex 정의 in OpenGL OpenGL 에서 vertex 를정의하는함수 glvertex[n][t][v]( ); n : number of coordinates n = 2, 3, 4 t : coordinate type t = i (integer), f (float), d (double), v : vector or not v 가붙으면, vector (= array) form 모든 OpenGL 함수는 gl 로시작 7
OpenGL suffixes suffix data type C-language OpenGL type b 8-bit integer signed char GLbyte s 16-bit integer short GLshort i 32-bit integer int / long GLint, GLsizei f 32-bit floating pt. float GLfloat, GLclampf d 64-bit floating pt. double GLdouble, GLclampd ub 8-bit unsigned int unsigned char GLubyte, GLboolean us 16-bit unsigned int unsigned shrot GLushort ui 32-bit unsigned int unsigned int / GLuint, GLenum, unsigned long GLbitfield 8
Examples void glvertex2i(glint xi, GLint yi); 사용예 : glvertex2i(2, 3); void glvertex3f(glfloat x, GLfloat y, GLfloat y); 사용예 : glvertex3f(1.5, 2.3, 3.0); void glvertex3dv(gldouble v[3]); 사용예 : GLdouble vertex[3] = { 1, 2, 3 }; glvertex3dv(vertex); 9
Object 정의 in OpenGL geometric object 의정의 vertex 가여러개모여서하나의 object glbegin(type); glvertex*( ); glvertex*( ); /* 다른함수도가능 */ glend( ); 사용예 glbegin(gl_lines); glvertex2f(x1, y1); glvertex2f(x2, y2); glend( ); 10
Object-oriented Paradigm graphics program 들은 object-oriented paradigm 에적합 Java3D : fully object-oriented library Point3 old(2, 1, 3); Vector3 vec(1, 0, 0); Point3 new = old + vec; OpenGL : not object-oriented! C-based library 대안은 array 뿐 typedef GLfloat Point2[2]; Point2 p = { 2, 3 }; glvertex2fv(p); 11
Sierpinski gasket 구현예제 void display( void ) { point2 vertices[3]={{0.0,0.0},{250.0,500.0},{500.0,0.0}}; /* A triangle */ point2 p ={75.0,50.0}; /* An arbitrary initial point inside triangle */ int i, j, k; } for (k=0; k<5000; k++) { j=rand( ) % 3; /* pick a vertex at random */ /* Compute point halfway between selected vertex and old point */ p[0] = (p[0] + vertices[j][0]) / 2.0; p[1] = (p[1] + vertices[j][1]) / 2.0; /* plot new point */ glbegin(gl_points); glvertex2fv(p); glend( ); } glflush( ); /* flush buffers */ old (p[0], p[1]) new (p[0], p[1]) (vertices[j][0], vertices[j][1]) 12
Some questions int rand(void); integer random number generator see <stdlib.h>, void srand(void); void glflush(void); flush the graphics pipeline we still have some questions in what colors are we drawing? where on the screen does our image appear? how large will the image be? how do we create the window for our image? how much of our infinite 2D plane will appear? how long will the image remain on the screen? 13
Coordinate Systems 2D 좌표사용 : 좌표를어떻게해석할것인가? device-independent coordinate system world coordinate system = problem coordinate system 그림을정의하는좌표계 device coordinate system = physical-device / raster / screen coordinate system 그림이그려지는좌표계 14
2.2 The OpenGL API
Graphics API OpenGL 도이러한특성을가짐 Graphics API = hundreds of functions + α function 의구분 primitive functions 무엇을출력? attribute functions 어떤모양으로출력? viewing functions 카메라설정 transformation functions 물체위치변환 input functions 사용자입력 control functions window 관리 16
OpenGL 구성 특성 C-based library (not object-oriented) 3개의 library 로구성 GL : graphics library H/W에서지원하여야하는기본 primitives GLU : graphics utility library S/W로지원해도되는확장 primitives GLUT : GL utility toolkit window system들을위한지원함수들 17
OpenGL 구성 GLUT OpenGL application program GLU GL GLX X window system Frame buffer (video card) MS window extension MS window system 18
2.3 Primitives and Attributes
Line Primitives 기본구조 glbegin(type); glvertex*( ); glvertex*( ); glend( ); type 별출력예제 20
Polygon polygon : an object with the border polygon = loop + interior assumption : simple, convex, and flat simple : edge 끼리의 intersection 없음 convex : 볼록다각형 flat : 3D 에서하나의평면상에위치해야 flatness 보장을위해, triangle을주로사용 simple nonsimple convex concave 21
Polygon Primitives 일반적인경우 strips : 속도를높이기위해 22
Text text in computer graphics is problematic. 3D text 는일반적인 text 보다훨씬복잡 OpenGL : no text primitive (use window primitives) GLUT : minimal support glutbitmapcharacter( ); stroke font (= outline font) : graphics 에서주로사용 character = boundary를정의하는수학함수들 확대 / 축소에편리 제작 / 출력에많은시간필요 raster font (= bitmap font) : text-based application 용 character = raster pattern 23
Curved Objects curved object 의처리방법 tessellation polyline / polygon 으로근사 (approximation) 수학적으로직접표현 chap. 10 에서설명 24
Attributes attribute = any property that determines how a geometric primitve is to be rendered. point : color, size line : color, thickness, type (solid, dashed, dotted) polygon : fill color, fill pattern text : height, width, font, style (bold, italic) line attributes polygon attributes text attributes 25
2.4 Color
Light electromagnetic wave 흔히가시광선 (visible light) 를의미 red yellow green blue violet AM FM microwave infrared visible ultraviolet X-ray 10 4 10 6 10 8 10 10 10 12 10 14 10 16 10 18 10 20 frequency (Hz) 27
Color C(λ) : wave length λ 에대한 energy distribution C(λ) 에따라, color 결정 additive color model C(λ) 끼리더할수있음 three-color theory C = T 1 R + T 2 G + T 3 B 28
Human Visual System cones : red, green, blue 에민감하게반응 sensitive curve S i (λ) : wavelength에따른반응정도 brain perception values A S ( λ) C( λ)dλ = red, green,blue i = i i three-color theory 의기본이론 (A red, A green, A blue ) 값들이같으면, 같은 color로인식 C(λ) A i = S ( λ) C( λ) dλ i 29
Color Model color model color 를 computer H/W, S/W 에서표현하는방법 용도에따라, 다양 : RGB, CMY, YIQ, CIE, color gamut 특정 color model 이생성가능한모든 color color solid (= color cube) color model 에서흔히 three primary colors 사용 three primary color에의한 3차원 cube color gamut 표현가능 30
RGB color model Red, Green, Blue tri-stimulus theory 눈에가장민감한 3가지색상 RGB cube : 각각이 0 ~ 1 까지 Green C Y Blue M Red 31
CMY, CMYK color model hard copy 기계에서는잉크사용 subtractive system 감산색계 흰종이위에 cyan, magenta, yellow 사용 Yellow Magenta Cyan G B R C R R C 1 1 32 CMYK color model : K (black) 을첨가 이론상, cyan + magenta + yellow = black 실제로는 dark gray 해결책 :black(k) ink 를별도로 Magenta = = Y M C B G R B G R Y M C 1 1 1, 1 1 1
RGB vs. CMY RGB color system CMY color system additive primaries 더하면밝아진다 subtractive primiaries 더하면어두워진다 monitor 기준 형광물질로 R, G, B 사용 printer 기준 ink 로 C, M, Y 사용 graphics 는주로 RGB 기준 33
Direct color system 기본적인 video card 구조 3개의전자총, 3개의 frame buffer frame buffer 마다, pixel 당 n bit 할당 2 n 2 n 2 n colors = 2 3n colors 3n can be 8, 12, 24, 3n = 24 : true color system 34
Direct color system OpenGL functions 3n 값은 system 마다틀리다 color 설정은 RGB cube 기준 red, green, blue 모두 0.0 ~ 1.0 void glcolor*( ); void glcolor3f(glclampf red, GLclampf green, GLclampf blue); 현재색상정의 GLclampf : 0.0 보다작으면 0.0, 1.0 보다크면 1.0 see OpenGL manual 35
Direct color system RGBA color model RGB + A (alpha channel) alpha channel 은 opacity value : image 합성에사용 A = 1.0 이보통의경우 void glcolor4f(red, green, blue, alpha); void glclearcolor(glclampf red, GLclampf green, GLclampf blue, GLclampf alpha); clear color 설정 (= background color) void glclear(glbitfield mask); mask = GL_COLOR_BUFFER_BIT 이면, frame buffer 전체를 clear color 로 36
Indexed color system frame buffer size 를줄이는방법 color lookup table (LUT) (= palette) 2 3m bit 로 color 값 2 k 개를저장 frame buffer : k bit index 값저장 2 3m color 중에서 2 k 개만동시표현 color LUT 37
Indexed color system why indexed color system? image 표현에필요한 frame buffer size 축소 image file format 에서사용 : GIF, BMP, OpenGL functions LUT 의 setting 은 window system / GLUT 가담당 void glindex*( ); current color를 LUT의해당 index로설정 void glutsetcolor(int index, GLfloat red, green, blue); LUT의해당 index를새로운 color로 38
2.5 Viewing
Image Generation camera 로 object 를촬영 graphics program에서는 object들을배치 camera 가특정위치에서촬영 viewing graphics 에서, synthetic camera 의위치설정 40
2D Viewing 2D plane 상의어느부분이보여야하는가 viewing rectangle = clipping rectangle 화면에나올, 2D plane (z = 0) 상의사각형영역 clipping 화면에나오지않는부분을제거 (clipped out) z = 0 clipping operation 41
Orthographic View 3D viewing 의일종 2D viewing을단순히 3D로확장 주의 : 모든빛은 z축에평행. 실제 camera와는다름 (x, y, z) (x, y, 0) z = 0 OpenGL default : [ 1, 1] [ 1, 1] [ 1, 1] 을화면에표시 42
Orthographic View OpenGL function void glortho(gldouble left, right, GLdouble bottom, top, GLdouble near, far); void gluortho2d(gldouble left, right, GLdouble bottom, top); near = 1.0, far = 1.0 인경우로해석 43
Matrix Handling camera, object 의위치 / 방향제어 = matrix handling 행렬연산 OpenGL has: two matrix mode model-view matrices : object 용 projection matrices : camera 용 각각의역할이다름 chap 4. 간단한예제 [0, 500] [0,500] 인경우 glmatrixmode(gl_projection); glloadidentity( ); gluortho2d(0.0, 500.0, 0.0, 500.0); glmatrixmode(gl_modelview); 44
2.6 Control Functions
Window System 현재, 다양한 window system 사용중 예 : X window, Macintosh, Microsoft window OpenGL 관점에서는 window 생성, 제어방법이완전히다름 해결책 : GLUT 어디서나작동하는 window control 방법제공 OpenGL application program GLUT window system Frame buffer (video card) 46
GLUT functions void glutinit(int* argcp, char* argv[]); initialization. GLUT option 해석가능 int glutcreatewindow(char* title); window 생성 ( 화면에는표시되지않음 ) void glutinitdisplaymode(glut_rgb GLUT_DEPTH); display mode RGB : direct color 사용 DEPTH : z-buffer 사용 ( 뒤에설명 ) void glutinitwindowsize(int width, int height); void glutinitwindowposition(int x, int y); (x, y) 위치에서, width height 크기로 window 생성 47
Coordinate system 의차이 대부분의 window system 원점이 upper left ( 뒤집어진좌표계 ) glutwindowposition( ) : window system 기준 대부분의고급 graphics library OpenGL, PostScript, 기하학에서쓰는좌표계그대로 glvertex3f( ) : OpenGL 기준 window 좌표계 : pixel 단위 window OpenGL 좌표계 48
Viewport aspect ratio window 의화면비율 단순 mapping 일때는, mismatched image 가능 clipping rectangle window viewport window 영역중에서, clipping rectangle 이표시될부분 void glviewport(glint x, y, GLsizei w, h); (x, y) 위치에서, w h 영역에출력 49
Viewport 설정예제 50
Graphics Program 의특징 일반적인프로그램 : 출력이끝나면, program 끝 graphics 프로그램 : 출력을그대로유지해야 해결책 : 화면을그렸으면, infinite loop 로 또다른상황 window 가가려졌다가, 다시나타나면, graphics window 전체를새로그려야한다 해결책 : display callback callback : 미리등록해두면, 필요한상황에서자동으로 call 되는 function 51
GLUT 에서의해결책 void glutmainloop(void); 모든설정이끝난시점에서, infinite loop 로들어감 보통, OpenGL program 의마지막수행함수 void glutdisplayfunc(void (*func)(void)); 화면을그려야할때마다호출되는 callback 함수등록 callback 함수는 void functionname(void); 형태 52
Main function #include <GL/glut.h> // GLUT 사용 void myinit(void) { } // 따로작성 (sec 2.7) void display(void) { } // 따로작성 (sec 2.7) void main(int argc, char* argv[]) { // OpenGL program은대부분이런구조 glutinit(&argc, argv); glutinitdisplaymode(glut_rgb); glutinitwindowsize(500, 500); glutinitwindowposition(0, 0); glutcreatewindow( Sierpinski Gasket ); glutdisplayfunc(display); // callback 등록 myinit( ); // 미리설정할것들처리 glutmainloop( ); } 53
2.7 The Gasket Program
myinit function void myinit(void) { /* attributes */ glclearcolor(1.0, 1.0, 1.0, 1.0); /* white background */ glcolor3f(1.0, 0.0, 0.0); /* draw in red */ /* set up viewing */ /* 500 x 500 window with origin lower left */ glmatrixmode(gl_projection); glloadidentity(); gluortho2d(0.0, 500.0, 0.0, 500.0); glmatrixmode(gl_modelview); } 55
display function void display( void ) { point2 vertices[3]={{0.0,0.0},{250.0,500.0},{500.0,0.0}}; /* A triangle */ point2 p ={75.0,50.0}; /* An arbitrary initial point inside triangle */ int j, k; } glclear(gl_color_buffer_bit); /*clear the window */ for (k=0; k<5000; k++) { j=rand( ) % 3; /* pick a vertex at random */ /* Compute point halfway between selected vertex and old point */ p[0] = (p[0] + vertices[j][0]) / 2.0; p[1] = (p[1] + vertices[j][1]) / 2.0; /* plot new point */ glbegin(gl_points); glvertex2fv(p); glend( ); } glflush( ); /* flush buffers */ 56
실행결과 press to quit 57
2.8 Polygons and Recursion
Sierpinski Gasket, again Sierpinski gasket 의특징 각삼각형의가운데 ¼ 은항상비어있다 another way of generating Sierpinski gasket? recursion 59
Recursion triangle 의 subdivision a a v 0 v 1 b c b v 2 c 원래의삼각형 : (a, b, c) midpoints 계산 a+ b a+ c b+ c v0 =, v1=, v2 = 2 2 2 subdivided triangles : (a, v 0, v 1 ), (c, v 1, v 2 ), (b, v 2, v 0 ) 60
OpenGL 구현예제 #include <stdio.h> #include <stdlib.h> typedef float point2[2]; /* 2D point */ point2 v[]={{-1.0, -0.58}, {1.0, -0.58}, {0.0, 1.15}}; /* initial triangle */ void triangle( point2 a, point2 b, point2 c) { /* display one triangle */ glbegin(gl_triangles); glvertex2fv(a); glvertex2fv(b); glvertex2fv(c); glend(); } 61
OpenGL 구현예제 void divide_triangle(point2 a, point2 b, point2 c, int m) { /* triangle subdivision */ point2 v0, v1, v2; int j; if (m > 0) { for(j=0; j<2; j++) v0[j]=(a[j] + b[j]) / 2; for(j=0; j<2; j++) v1[j]=(a[j] + c[j]) / 2; for(j=0; j<2; j++) v2[j]=(b[j] + c[j]) / 2; divide_triangle(a, v0, v1, m 1); divide_triangle(c, v1, v2, m 1); divide_triangle(b, v2, v0, m 1); } else triangle(a,b,c); /* draw triangle at end of recursion */ } v x = a x + b 2 x, v y = a y + b 2 y void display(void) { glclear(gl_color_buffer_bit); divide_triangle(v[0], v[1], v[2], n); glflush(); } 62
OpenGL 구현예제 void myinit( ) { glmatrixmode(gl_projection); void main(int argc, char *argv[]) { if (argc!= 2) { glloadidentity(); fprintf(stderr, "usage: %s number\n", gluortho2d(-2.0, 2.0, -2.0, 2.0); argv[0]); /* 종료조건필요! */ glmatrixmode(gl_modelview); exit(0); glclearcolor (1.0, 1.0, 1.0, 1.0); } glcolor3f(0.0,0.0,0.0); n=atoi(argv[1]); } glutinit(&argc, argv); glutinitdisplaymode(glut_single GLUT_RGB ); } glutinitwindowsize(500, 500); glutcreatewindow("3d Gasket"); glutdisplayfunc(display); myinit(); glutmainloop(); 63
실행예제 gasket2 2 gasket2 6 64
2.9 The Three-Dimensional Gasket
3D Sierpinski gasket 2D triangle 3D tetrahedron 으로확장 typedef struct { float x, y, z; } point; point vertices[4] = {{0,0,0},{250,500,100},{500,250,250},{250,100,250}}; /* A tetrahedron */ point old_pt = {250,100,250}; /* start point */ point new_pt; /* new point */ 66
3D Sierpinski gasket void display(void) { /* computes and plots a single new point */ int i; j = rand( ) % 4; /* pick a vertex at random */ /* Compute point halfway between vertex and old point */ new_pt.x = (old_pt.x + vertices[j].x) / 2; new_pt.y = (old_pt.y + vertices[j].y) / 2; new_pt.z = (old_pt.z + vertices[j].z) / 2; glbegin(gl_points); /* plot point */ glcolor3f(1.0-new_pt.z/250.,new_pt.z/250.,0.); /* 거리감을위해서색깔구분 */ glvertex3f(new_pt.x, new_pt.y,new_pt.z); glend(); /* replace old point by new */ old_pt.x=new_pt.x; old_pt.y=new_pt.y; old_pt.z=new_pt.z; glflush(); } 67
Hidden Surface Removal 3D 확장시의근본적인문제 그리는순서대로출력하면, 안된다 camera 를기준으로서로가리는관계를반영해야 B, C 는 A 에의해서가려진다 hidden surface removal algorithm = visible surface algorithm camera 에서보이는부분만남기는 algorithm 68
Z-buffer algorithm Z-buffer algorithm (= depth-buffer algorithm) 가장간단한 HSR algorithm OpenGL 에서는기본적으로제공 void glutinitdisplaymode(glut_rgb GLUT_DEPTH); Z-buffer 를사용하기위해준비 glenable(gl_depth_test); Z-buffer를 on glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT); Z-buffer를 clear 69
실행예제 gasket3d.c : without Z-buffer point 만출력 tetra.c : with Z-buffer tetra 5 70
Suggested Readings OpenGL Architecture Review Board, OpenGL Programming Guide, 2 nd Ed., Addison-Wesley, (1997). OpenGL Architecture Review Board, OpenGL Reference Manual, 2 nd Ed., Addison-Wesley, (1997). Mark J. Kilgard, GLUT Specification, version 3, http://reality.sgi.com/opengl/spec3/spec3.html 71