Graphics Programming OpenGL Camera OpenGL 에서는카메라가물체의공간 (drawing coordinates) 의원점 (origin) 에위치하며 z- 방향으로향하고있다. 관측공간을지정하지않는다면, 디폴트로 2x2x2 입방체의 viewing volume을사용한다. (1, 1, 1) 321190 2007년봄학기 3/16/2007 박경신 (-1, -1, -1) Viewing functions 직교투영 (Orthographic parallel projection) void glortho(gldouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble znear, GLdouble zfar); void gluortho2d(gldouble left, GLdouble right, GLdouble bottom, GLdouble top); - 2 차원그래픽스에사용 gluortho2d(0.0, 50.0, 0.0, 50.0); //2D glortho(-10, 10, -10, 10, -10, 10); Viewing functions 원근투영 (Perspective projection) void glfrustum(gldouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble znear, GLdouble zfar); void gluperspective(gldouble fovy, GLdouble aspect, GLdouble znear, GLdouble zfar); - 상하좌우값을설정하는대신 y 방향의시선각도 (FOV) 와종횡비 ( 가까운쪽클리핑평면의너비를높이로나눈값 ) 를사용 gluperspective(60.0, 1.0, 1.0, 10.0);
Viewport functions 뷰포트 (Viewport) 윈도우내부에설정한공간. 그리기가뷰포트내부로제한됨. void glviewport(glint x, GLint y, GLsizei width, GLsizei height) 윈도우를처음생성할때전체윈도우에해당하는픽셀영역을뷰포트로설정 ; 이보다작은영역을뷰포트로설정할때는 glviewport() 사용. 일반적으로윈도우전체를뷰포트로사용. Reshape function이있을경우, glviewport() 가반드시포함되어야함. Viewport functions void glscissor(glint x, GLint y, GLsizei width, GLsizei height) 윈도우의직사각형분할및그분할내에서의그릴때의제한사항등을정의 일반적으로 glviewport() 와동일하게정의함 glscissor(100, 100, 350, 350); glenable(gl_scissor_test); glviewport(0, 0, glutget(glut_window_width), glutget(glut_window_height)); Text Functions GLUT 에정의된문자집합제공. 문자열에는획 (stroke) 과래스터 (raster) 두종류가있다. Bitmap font (raster font) text void glutbitmapcharacter(void *font, int character); font 인자 고정폭폰트 - E.g. GLUT_BITMAP_8_BY_13, GLUT_BITMAP_9_BY_15 10, 12, 18 포인트비례간격폰트 e.g. GLUT_BITMAP_TIMES_ROMAN_10 character 인자는 ASCII Stroke font text void glutstrokecharacter(void *font, int character); font 인자 GLUT_STROKE_ROMAN, GLUT_STROKE_MONO_ROMAN Bitmap Text glutbitmapcharacter() 는비트맵 (bitmap = arrays of pixel data) 폰트를사용하여문자를그린다. 비트맵문자의위치는 glrasterpos* 를사용하여지정한다. glrasterpos2f(x, y) glrasterpos3f(x, y, z) 비트맵의문자는크기가변하지않는다. (unaffected by scaling or perspective) 화면에일정한곳에위치하고있다. 만약래스터위치가뷰포트밖에위치하고있다면비트맵문자는그려지지않는다.
Stroke Text Sierpinski Gasket glutstrokecharacter() 는 3차원선으로문자를그린다. 따라서, GL의변환 ( 즉, position, size, and orientation) 에의해영향을받는다. glutstrokecharacter() 는다음글자 (character) 를그리기위해자체적으로 transformation을한다. A sample problem of drawing of the Sierpinski gasket 1. Pick an initial point at random inside the triangle, P0 2. Select one of the 3 vertices at random, v1 3. Find the point halfway, P1 4. Display this new point 5. Replace the initial point with this new point 6. Return to step 2 Sierpinski Gasket (2D) 삼각형에서시작한다. 삼각형각변의이등분선 (bisector) 을연결하고, 중앙의 a 작은삼각형을지운다. 반복 (Repeat) a b c v0 v1 b c v2 5번 subdivision Sierpinski Gasket (2D) /* recursive subdivision of triangle to form Sierpinski gasket */ #include <GL/glut.h> /* initial triangle */ GLfloat v[3][2]=-1.0, -0.58, 1.0, -0.58, 0.0, 1.15; int n; void triangle( GLfloat *a, GLfloat *b, GLfloat *c) /* specify one triangle */ glvertex2fv(a); glvertex2fv(b); glvertex2fv(c); void divide_triangle(glfloat *a, GLfloat *b, GLfloat *c, int m) /* triangle subdivision using vertex numbers */ GLfloat v0[2], v1[2], v2[2]; 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 */ void display() glclear(gl_color_buffer_bit); glbegin(gl_triangles); divide_triangle(v[0], v[1], v[2], n); glend(); glflush(); void myinit() gluortho2d(-2.0, 2.0, -2.0, 2.0); glclearcolor (1.0, 1.0, 1.0, 1.0); glcolor3f(0.0,0.0,0.0); int main(int argc, char **argv) n=atoi(argv[1]); /* or set number of subdivision steps here */ glutinit(&argc, argv); glutinitdisplaymode(glut_single GLUT_RGB); glutinitwindowsize(500, 500); glutcreatewindow("sierpinski Gasket"); glutdisplayfunc(display); myinit(); glutmainloop();
3D Gasket 3D Gasket 3D Gasket 은각각의 4 면에서 subdivision 을한다. a mid2 mid0 mid1 d mid5 mid4 b mid3 c 사면체 (solid tetrahedron) 내부의작은사면체를지운다. 3D Gasket /* recursive subdivision of a tetrahedron to form 3D Sierpinski gasket */ #include <stdlib.h> #include <GL/glut.h> /* initial tetrahedron */ GLfloat v[4][3]=0.0, 0.0, 1.0, 0.0, 0.942809, -0.33333, -0.816497, -0.471405, -0.333333, 0.816497, -0.471405, -0.333333; GLfloat colors[4][3] = 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0; int n; void triangle(glfloat *va, GLfloat *vb, GLfloat *vc) glvertex3fv(va); glvertex3fv(vb); glvertex3fv(vc); void tetra(glfloat *a, GLfloat *b, GLfloat *c, GLfloat *d) glcolor3fv(colors[0]); triangle(a, b, c); glcolor3fv(colors[1]); triangle(a, c, d); glcolor3fv(colors[2]); triangle(a, d, b); glcolor3fv(colors[3]); triangle(b, d, c); void divide_tetra(glfloat *a, GLfloat *b, GLfloat *c, GLfloat *d, int m) GLfloat mid[6][3]; int j; if(m>0) /* compute six midpoints */ for(j=0; j<3; j++) mid[0][j]=(a[j]+b[j])/2; for(j=0; j<3; j++) mid[1][j]=(a[j]+c[j])/2; for(j=0; j<3; j++) mid[2][j]=(a[j]+d[j])/2; for(j=0; j<3; j++) mid[3][j]=(b[j]+c[j])/2; for(j=0; j<3; j++) mid[4][j]=(c[j]+d[j])/2; for(j=0; j<3; j++) mid[5][j]=(b[j]+d[j])/2; /* create 4 tetrahedrons by subdivision */ divide_tetra(a, mid[0], mid[1], mid[2], m-1); divide_tetra(mid[0], b, mid[3], mid[5], m-1); divide_tetra(mid[1], mid[3], c, mid[4], m-1); divide_tetra(mid[2], mid[4], d, mid[5], m-1); else(tetra(a,b,c,d)); /* draw tetrahedron at end of recursion */ void display() glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT); glbegin(gl_triangles); divide_tetra(v[0], v[1], v[2], v[3], n); glend(); glflush(); void myreshape(int w, int h) glviewport(0, 0, w, h); if (w <= h) glortho(-2.0, 2.0, -2.0 * (GLfloat) h / (GLfloat) w, 2.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0); else glortho(-2.0 * (GLfloat) w / (GLfloat) h, 2.0 * (GLfloat) w / (GLfloat) h, -2.0, 2.0, -10.0, 10.0); glutpostredisplay(); int main(int argc, char **argv) n=atoi(argv[1]); /* or enter number of subdivision steps here */ glutinit(&argc, argv); glutinitdisplaymode(glut_single GLUT_RGB GLUT_DEPTH); glutinitwindowsize(500, 500); glutcreatewindow("3d Gasket"); glutreshapefunc(myreshape); glutdisplayfunc(display); glenable(gl_depth_test); glclearcolor (1.0, 1.0, 1.0, 1.0); glutmainloop(); Z-buffer algorithm 사용
RECAP - GLUT Coordinate Systems Drawing commands that specify locations: glutinitwindowposition Position to open a new window at, given in desktop screen pixel coordinates glwindowpos Position for gldrawpixels, given in window pixel coordinates glrasterpos Position for gldrawpixels, given in drawing coordinates glvertex Position of a shape s vertex, given in drawing coordinates RECAP GL/GLUT Coordinate Systems - GLUT mouse pointer 는 GLUT screen coordinates 사용 - glviewport 는 GL screen coordinates 사용 RECAP Coordinate Systems RECAP RHS Coordinate Systems Screen coordinate systems = GLUT mouse pointer coordinate systems OpenGL drawing coordinate systems (0, 0) +y y-axis x-axis +x 1 unit = 1 pixel z (0, 0,0) y 1 unit = ½ width or height of window x Right Hand Coordinate System (RHS) z+ 가화면앞으로튀어나오는방향. Counter clockwise 방향으로 rotation 을함. X- 축으로 rotation 을하면, Y->Z 방향의회전이 positive Y- 축으로 rotation 을하면, Z->X 방향의회전이 positive Z- 축으로 rotation 을하면, X->Y 방향의회전이 positive z y x
RECAP LHS Coordinate Systems Left Hand Coordinate System (LHS) z+ 가화면안으로들어가는방향. Clockwise 방향으로 rotation 을함. X- 축으로 rotation 을하면, Y->Z 방향의회전이 positive Y- 축으로 rotation 을하면, Z->X 방향의회전이 positive Z- 축으로 rotation 을하면, X->Y 방향의회전이 positive y z x