Geometric Objects and Transformation 321190 2007 년봄학기 4/17/2007 박경신 OpenGL Transformation OpenGL 은기본적인변환을수행하는함수를제공한다. Translation: 이동변환은 3 차원이동변위벡터 (dx, dy, dz) 를넣는다. Rotation: 회전변환은 axis( 회전축 ) 와 angle( 각도 ) 을넣는다. Scaling: 크기변환은 scaling factor ( 크기변환값 ) 를넣는다. 이각각의함수는 4x4 변환행렬을생성하여객체에적용이된다. OpenGL Transformation gltranslate*(dx, dy, dz) 이동변환인자 dx, dy, dz 는실수 2 차원이동 : dz = 0.0 gltranslatef(25.0, -10.0, 0.0); glrotate* (theta, vx, vy, vz) 회전변환인자 theta 는회전량각도 (rotation angle in degrees) 는 0~360 사이의값을가짐 벡터 (vx, vy, vz) 는회전축 (rotation axis) glrotatef(90, 0, 0, 1); glscale*(sx, sy, sz) 크기변환인자 sx, sy, sz 는실수 반사 (reflection) 는인자값에음수를적용 glscalef(2.0, -3.0, 1.0); Suffix code (*) 는 f (float) 또는 d (double) Translation in OpenGL gltranslatef(x, y, z) 객체를 (x, y, z) 만큼이동 2차원 gltranslate 함수는없다. Example: gltranslatef(0.5, -0.2, 0.0); glbegin(gl_triangles); glvertex2f(0.0, 0.0); glvertex2f(0.5, 0.0); glvertex2f(0.25, 0.5); glend();
Rotation in OpenGL glrotatef(angle, x, y, z) 임의의축 axis (x,y,z) 에대해각도 angle 만큼회전 2 차원회전은 z- 축 (0, 0, 1) 로사용한다. Example: glrotatef(90.0, 0.0, 0.0, 1.0); glbegin(gl_triangles); glvertex2f(0.5, 0.0); glvertex2f(0.8, 0.0); glvertex2f(0.65, 0.5); glend(); Scale in OpenGL glscalef(x, y, z) x-축으로 x만큼, y-축으로 y만큼, z-축으로 z만큼크기를변환 이때, scale factor>1 이면커지고, 0<scale factor<=1 이면작아지고, scale factor<0 면반사 (reflection) 된다. 2 차원크기변환은 z 에 1 을넣는다. Example: glscalef(0.25, 0.5, 1.0); glbegin(gl_triangles); glvertex2f(0.5, 0.0); glvertex2f(0.8, 0.0); glvertex2f(0.65, 0.5); glend(); Transformation Order OpenGL 에서모델링변환행렬들은객체에설정된반대순서로적용된다. 즉, 마지막변환 ( 즉, 기하함수호출바로전에쓰인것 ) 이정점데이터에먼저적용된다. gltranslatef(0.5, 0, 0); glrotatef(45, 0, 0, 1); drawtriangle(); M=T*R p =Mp Transformation Order glcolor3f(1.0, 0.0, 1.0); glutwirecube(1); glrotatef(45.0, 0.0, 0.0, 1.0); gltranslatef(1.5, 0.0, 0.0); glcolor3f(1.0, 0.0, 0.0); glutwirecube(1); glrotatef(45, 0, 0, 1); gltranslatef(0.5, 0, 0); drawtriangle(); M=R*T p = Mp gltranslatef(1.5, 0.0, 0.0); glrotatef(45.0, 0.0, 0.0, 1.0); glcolor3f(0.0, 1.0, 0.0); glutwirecube(1);
glmatrixmode(glenum mode) glmatrixmode 는행렬모드를설정한다. 현재의행렬이모델뷰 (model view), 투영 (projection), 텍스쳐 (texture) 행렬중어떤것인지를나타내는함수이다. glmatrixmode(gl_projection) 연속되는행렬연산을투영행렬 (projection matrix) 스택에적용한다. 투영행렬은 3D 공간에카메라설정을수학적으로표현한행렬이다. glmatrixmode(gl_model_view) 연속되는행렬연산을기하변환행렬 (geometric transformation matrix) 스택에적용한다. 3D 공간에물체의배치를수학적으로표현한행렬이다. 현재 modelview 모드에있으면, 모델링변환함수 ( 즉, 이동, 회전, 크기변환함수 ) 의행렬을기하변환행렬스택에적용한다. glloadidentity() 현재의행렬을 4x4 단위행렬 (identity matrix) 로설정한다. 즉, 현재의행렬을초기화한다. glloadmatrixd/f(const GLdouble/GLfloat *M) 현재행렬에임의의변환행렬 16 개의값 M 을대입한다. 이때, M 의 element 는열 - 중심 (column-major) 순서로지정해야한다. M= m 0 m 4 m 8 m 12 v 0 m 1 m 5 m 9 m 13 v 1 m 2 m 6 m 10 m 14 v 2 m 3 m 7 m 11 m 15 v 3 glmatrixmode(gl_modelview); GLfloat M[16]; GLint k; for (k=0; k<16; k++) elements[k] = float(k); glloadmatrixf(m); M = 0.0 4.0 8.0 12.0 1.0 5.0 9.0 13.0 2.0 6.0 10.0 14.0 3.0 7.0 11.0 15.0 glmultmatrixd/f(const GLdouble/GLfloat *M) 현재의행렬에 M을곱한다. 이때, M 의 16 개의값을가지고있고, 각 element 는열 - 중심 (columnmajor) 순서로지정해야한다. 현재의행렬은 glmultmatrix 에서지정한행렬에의해 postmultipy 된후값이바뀐다. // 물체를공간상에그리기위해행렬모드를 GL_MODELVIEW로설정 glmatrixmode(gl_modelview); glloadidentity(); // 행렬을초기화 glmultmatrixf(m2); // M2행렬을곱함 glmultmatrixf(m1); // M1행렬을곱함
glgetfloatv(gl_modelview_matrix, M) 현재의변환행렬을 M 으로돌려준다. GLfloat M[16]; glgetfloatv(gl_modelview, M); C I C C T C C S C C R C M glloadidentity(); gltranslatef(dx, dy, dz); glscalef(sx, sy, sz); glrotatef(angle, ax, ay, az); glloadmatrixf(ptr_to_matrix); glpushmatrix() & glpopmatrix() 행렬스택에 glpushmatrix() 는현재상태를저장하고 glpopmatrix() 는스택의맨위에저장된상태로복원시킨다. glmatrixmode(gl_modelview); glloadidentity(); gltranslatef(2.0, 1.0, 0.0); glrotatef(60, 1.0, 0.0, 0.0); gltranslatef(-2.0, 1.0, 0.0); drawobject(); // C = I // C = T (p) // C = C R (θ) = T(p) R(θ) // C = C T(-p) = T(p) R(θ) T(-p) Hierarchical Transformations 계층적변환 (hierarchical transformation) 은한변환을다른변환에소속시키는것으로생각하면된다. 계층적변환이란한객체의변환을다른객체들에상대적인변환으로사용된다. 2 개의자동차바퀴 (wheel) 가자동차차체 (body) 에상대적인계층적변환의예를보자면 : Apply body transformation Draw body Save state Apply front wheel transformation Draw wheel Restore saved state Apply rear wheel transformation Draw wheel Hierarchical Transformations 또한, 이자동차가움직이게되면, 자동차의차체에서상대적인위치에있는바퀴두개도역시몸체와같이움직이게됨을알수있다. 이때, 두개의바퀴를자동차의몸체의변환에같이영향을받도록만들어하며, 바퀴가각자따로변환하지않도록한다.
Example: Car glloadidentity(); glcolor3f(0.0, 0.0, 1.0); gltranslatef(carpos[0], carpos[1], carpos[2]); drawbody(); glcolor3f(1.0, 1.0, 0.0); gltranslatef(-0.2, 0.0, 0.0); glrotatef(angle, 0, 0, 1); drawwheel(); Transformation Hierarchy 계층적변환 (hierarchical transformations) 은종종변환의트리 (tree) 구조로표현한다. 3 차원캐릭터를디자인하기위해강체부분 (rigid body parts) 으로만들어진계층적변환구조를사용한다. 그리고, 보다유연한 3 차원캐릭터디자인을위해서는다수의계층적변환을적절히섞어사용해야한다. 이런계층은장면그라프 (scene graph) 의기초와동일하다. glcolor3f(1.0, 0.0, 0.0); gltranslatef(0.2, 0.0, 0.0); glrotatef(angle, 0, 0, 1); drawwheel(); Example: Robot Example: Solar Display() glrotatef (theta, 0.0, 1.0, 0.0); Base(); gltranslatef (0.0, h1, 0.0); glrotatef(phi, 0.0, 0.0, 1.0); DrawLowerArm (); LowerArm UpperArm // global variables float g_elpasedtime; double g_currenttime, g_previoustime; float g_sunradius = 5.0f; float g_earthradius = 1.0f; float g_moonradius = 0.5f; float g_earthdistancefromsun = -12.0f; float g_moondistancefromearth = -2.0f; gltranslatef (0.0, h2, 0.0); glrotatef (psi, 0.0, 0.0, 1.0); DrawUpperArm(); Base void update() g_currenttime = timegettime(); g_elpasedtime = (float)((g_currenttime - g_previoustime) * 0.001); g_previoustime = g_currenttime; glutpostredisplay();
Example: Solar void display (void) static float SunSpin = 0.0f; static float EarthSpin = 0.0f; static float EarthOrbit = 0.0f; static float MoonSpin = 0.0f; static float MoonOrbit = 0.0f; if( g_orbiton == true ) SunSpin -= g_speed * (g_elpasedtime * 10.0f); EarthSpin -= g_speed * (g_elpasedtime * 100.0f); EarthOrbit -= g_speed * (g_elpasedtime * 20.0f); MoonSpin -= g_speed * (g_elpasedtime * 50.0f); MoonOrbit -= g_speed * (g_elpasedtime * 200.0f); Example: Solar // The Sun (spins by rotating it about y-axis) glrotatef( SunSpin, 0.0f, 1.0f, 0.0f ); // spin on its own axis. glcolor3f( 1.0f, 1.0f, 0.0f ); glutwiresphere( g_sunradius, 20, 20 ); // The Earth spins on its own axis and orbit the Sun. glrotatef( EarthOrbit, 0.0f, 1.0f, 0.0f ); gltranslatef( 0.0f, 0.0f, g_earthdistancefromsun ); glrotatef( EarthSpin, 0.0f, 1.0f, 0.0f ); glcolor3f( 0.0f, 1.0f, 0.0f ); glutwiresphere( g_earthradius, 10, 10 ); Example: Solar Example: Solar Using Matrix & Vector Class // The Moon spins on its own axis and orbit the Earth. glrotatef( EarthOrbit, 0.0f, 1.0f, 0.0f ); gltranslatef( 0.0f, 0.0f, g_earthdistancefromsun ); glrotatef( MoonOrbit, 0.0f, 1.0f, 0.0f ); gltranslatef( 0.0f, 0.0f, g_moondistancefromearth ); glrotatef( MoonSpin, 0.0f, 1.0f, 0.0f ); glcolor3f( 1.0f, 1.0f, 1.0f ); glutwiresphere( g_moonradius, 8, 8 ); glutswapbuffers(); #include matrix4x4.h #include vector3.h void display (void) // The Sun (spins by rotating it about y-axis) matrix4x4 msunspinrotation; matrix4x4 msunmatrix; msunspinrotation.rotate( SunSpin, 'y'); msunmatrix = msunspinrotation; // spin it on its axis. glmultmatrixf( msunmatrix.m ); glcolor4f( 1.0f, 1.0f, 0.0f, 1.0f ); glutwiresphere( g_sunradius, 20, 20 );
Example: Solar Using Matrix & Vector Class // The Earth spins on its own axis and orbit the Sun. matrix4x4 mearthtranslationtoorbit; matrix4x4 mearthspinrotation; matrix4x4 mearthorbitrotation; matrix4x4 mearthmatrix; mearthspinrotation.rotate( EarthSpin, 'y' ); mearthtranslationtoorbit.translate(vector3(0.0f, 0.0f, g_earthdistancefromsun)); mearthorbitrotation.rotate( EarthOrbit, 'y' ); mearthmatrix = mearthorbitrotation * mearthtranslationtoorbit * mearthspinrotation; glmultmatrixf( mearthmatrix.m ); glcolor4f( 0.0f, 1.0f, 0.0f, 1.0f ); glutwiresphere( g_earthradius, 10, 10 ); Example: Solar Using Matrix & Vector Class // The Moon spins on its own axis and orbit the Earth matrix4x4 mmoontranslationtoorbit; matrix4x4 mmoonspinrotation; matrix4x4 mmoonorbitrotation; matrix4x4 mmoonmatrix; mmoonspinrotation.rotate( MoonSpin, 'y' ); mmoontranslationtoorbit.translate( vector3(0.0f, 0.0f, g_moondistancefromearth) ); mmoonorbitrotation.rotate( MoonOrbit, 'y' ); mmoonmatrix = mearthorbitrotation * mearthtranslationtoorbit * mmoonorbitrotation * mmoontranslationtoorbit * mmoonspinrotation; glmultmatrixf( mmoonmatrix.m ); glcolor4f( 1.0f, 1.0f, 1.0f, 1.0f ); glutwiresphere( g_moonradius, 8, 8 ); glutswapbuffers(); 3D Geometry Functions GLUT shapes GLU quadrics Modeling a cube 3D Model Loading GLUT Shapes GLUT 는다양한기본도형드로잉함수를제공한다. 예를들어, platonic solids, simple curves, teapots 등등 GLUT 도형드로잉함수는 solid 나 wireframe 으로그릴수있다. glutsolidsphere(1.5, 16, 8) glutwiredodecahedron() 예제 glutshapes.cpp
GLUT Shapes glutsolidcube(size) glutsolidsphere(radius, slices, stacks) glutsolidcone(baseradius, height, slices, stacks) glutsolidtorus(innerradius, outerradius, sides, rings) glutsolidoctahedron() glutsoliddodecahedron() glutsolidicosahedron() glutsolidteapot(size) GLU Quadrics Quadrics 이란예를들어 x 2 + y 2 + z 2 = r 2 와같은다양한곡선이나표면을만들어내는함수이다. are various smooth surfaces described by functions like: 기본적인 GLU quadrics 는 spheres, cylinders, cone, disk 를포함하고있다. GLU quadrics 를그리려면 quadric object 을생성해서 GLU 함수에넘겨줘야한다. 그리고, GLU 에서는 quadrics 를 points, lines, 또는 polygons 등어떻게그릴지제어하는함수도제공하고있다. quadric = glunewquadric(); gluquadricdrawstyle(quadric, GLU_LINE); glusphere(quadric, 2.5, 32, 24); 예제 gluquadrics.cpp GLUT Quadrics glusphere(quadric, radius, slices, stacks) glucylinder(quadric, baseradius, topradius, height, slices, stacks) Cone using gluclinder(quadric, 0, topradius, height, slices, stacks) gludisk(quadric, innerradius, outerradius, slides, rings) glutpartialdisk(quadric, innerradius, outerradius, slides, rings, startangle, sweepangle) Modeling a Cube OpenGL 에서정점의 winding 순서 v 0, v 3, v 2, v 1 과 v 1, v 0, v 3, v 2 은같은다각형을만들어낸다. 그러나, 정점의 winding 순서 v 1, v 2, v 3, v 0 은다르다. OpenGL 에서는오른손좌표계를사용하므로, counterclockwise encirclement 로정점을정의했을때바깥쪽을향하는법선벡터 (normal) 을만들어낸다.
Modeling a Cube Modeling a Cube Vertex list 와 Index list 를사용하여 cube 를그린다. GLfloat vertex[][3] = -1.0,-1.0,-1.0, 1.0,-1.0,-1.0, 1.0, 1.0,-1.0, -1.0, 1.0,-1.0, -1.0,-1.0, 1.0, 1.0,-1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0 ; GLfloat normal[][3] = 1.0, 0.0, 0.0, // right 0.0, 1.0, 0.0, // top 0.0, 0.0, 1.0, // front -1.0, 0.0, 0.0, // left 0.0, -1.0, 0.0, // bottom 0.0, 0.0, -1.0, // back ; 7 4 3 2 6 0 1 5 (0, 0, 1) front void polygon(int n, int b, int c, int d) glbegin(gl_polygon); glnormalfv(normal[n]); glvertex3fv(vertex[a]); glvertex3fv(vertex[b]); glvertex3fv(vertex[c]); glvertex3fv(vertex[d]); glend(); void cube( ) polygon(0, 5, 1, 2, 6); // right polygon(1, 6, 2, 3, 7); // top polygon(2, 6, 7, 4, 5); // front polygon(3, 4, 7, 3, 0); // left polygon(4, 4, 0, 1, 5); // bottom polygon(5, 0, 3, 2, 1); // back 7 4 3 2 6 0 1 5 (0, 0, 1) front Model Files Wavefront OBJ Files 3 차원모델종류 Wavefront (.obj) Inventor (.iv) VRML / X3D 3D Studio (.3ds) OpenFlight (.flt) 3 차원객체모델은아래와같은정보를포함하고있다. Geometry data vertex positions, faces Colors/material properties Textures Transformations OBJ file 은일반텍스트파일로, 정점 (vertices), 다각형표면 (polygon faces), 재질 (material) 등그외다수의정보를포함하고있다. 각 line 은정점, 법선벡터, 텍스쳐등어떤정보를가진 line 인지알려주는토큰 (token) 으로시작한다. v x y z Vertex position vn x y z Vertex normal vt u v texture coordinate f v1 v2 v3.. Face (list of vertex numbers) Mtllib file.mtl File containing material descriptions Usemtl name Current material to apply to geometry