Overview OSG Building a Scene Graph 2008 년여름 박경신 Rendering States StateSet Attribute & Modes Texture Mapping Light Materials File I/O NodeKits Text 2 Rendering State OSG는대부분의 OpenGL 함수파이프라인렌더링상태를 ( 예, 알파, 블렌딩, 클리핑, 색마스크, 컬링, 안개, 깊이, 스텐실, 래스터링, 등 ) 지원한다. OSG는 osg::stateset에서렌더링상태를지정하고 scene graph의어떤노드에 attach 할수있다. OSG 가 scene graph 를 traverse 하면서 StateSet 은 OpenGL state attribute 를관리한다. 그래서우리프로그램이다른 subgraph 에서다른상태를지정할수있도록한다. OSG 가각 subgraph 를 traverse 하면서렌더링상태를저장 (store) 하고복구 (restore) 할수있다. Rendering State OSG 는렌더링상태를 attributes (fog color and blend functions, ) 과 modes 로정리하고있다. Modes 는 glenable() 과 gldisable() 로 OpenGL state feature 를지정한것과거의일대일대응이다. State value 을지정하려면, 지정해야하는 Node 나 Drawable 의상태에서 StateSet 를얻어와야한다. StateSet 를불러서 state modes 와 attributes 를지정한다. Node 나 Drawable 로부터 StateSet 를얻으려면, // obj is either a Node or a Drawble osg::stateset *state = obj->getorcreatestateset(); 3 4
Rendering State Setting Attributes getorcreatestateset() 함수는 obj s StateSet 포인터를반환한다. 만약 obj 가 StateSet 이없다면, 새로운 StateSet 을생성해서 attach 한다. Attribute 를지정하려면, Attribute 을바꿔야하는클래스를 instantiate 한다. 이클래스에 attribute 값을지정하고, osg::stateset::setattribute 를사용하여 StateSet 에 attach 한다. // Obtain the StateSet from the geom osg::stateset *state = geom->getorcreatestateset(); // Create and add the CullFace attribute Osg::CullFace *cf = new osg::cullface(osg::cullface::back); state->setattribute(cf); 5 Rendering State Setting a Mode osg::stateset::setmode() 를사용하여 mode 를 enable 또 disable 한다. // Obtain the StateSet osg::stateset *state = geom->getorcreatestateset(); // Enable fog in this StateSet // The first parameter to setmode() is any GLenum that is valid // in a call to glenable() or gldisable() // The second parameter can be osg::stateattribute::on or // osg::stateattribute::off state->setmode(gl_fog, osg::stateattribute::on); 6 Rendering State Setting Attribute & Mode osg::stateset::setattributeandmodes() 를사용하여 attribute 과 mode 를동시에지정할수있다. // Create the BlendFunc attribute osg::blendfunc *bf = new osg::blendfunc(); // Attach the BlendFunc attribute and enable blending // The second parameter to setattributeandmodes() enables or // disabled the first parameter s attribute s corresponding mode state->setattributeandmodes(bf); Rendering State State Inheritance 노드에상태가지정되면, 그상태가그노드와그노드의 children 에게적용된다. child node 가같은상태에다른값을지정하고자한다면, 그 child 상태값을 parent state 에서 override 해야한다. 즉, default behavior 는 child 노드에서바꾸지않는한 parent state 를 inherit 한다. 7 8
Rendering State State Inheritance OSG 는 scene graph 의어느지점에서 attribute 와 mode 에대한 state inheritance behavior 를개별적으로고칠수있도록해준다. setattribute(), setmode(), and setattributeandmodes() 함수의 second parameter 에 bitwise OR 를해서다음중하나와같이지정할수있다. osg::stateattribute::override attribute 이나 mode 를 OVERRIDE 로지정하면, 모든 children 이자신의 state 를바꾸던아니던상관없이 attribute 와 mode 를상속한다. osg::stateattribute::protected Attribute 이나 mode 를 overriding 으로부터보호하려면 PROTECTED 를사용한다. 이것은 parent state 가 child state 를절대 override 하지않는다. osg::stateattribute::inherit 이것은 child state 를무조건 parent 로부터상속받도록한다. 그결과, child state 을지우로 parent state 를사용하게한다. 9 Rendering State State Inheritance // Obtain the root node s StateSet osg::stateset *state = root->getorcreatestateset(); // Create a PolygonMode attribute osg::polygonmode *pm = new osg::polygonmode( osg::polygonmode::front_and_back, osg::polygonmode::line); // Force wireframe rendering state->setattributeandmodes(pm, osg::stateattribute::on osg::stateattribute::override); 10 Texture Mapping Texture Coordinates OSG 는 OpenGL texture mapping 을지원한다. Texture mapping 을사용하고자한다면, 반드시다음과같이지정해야한다. Geometry 에 textuere coordinates 이있어야한다. Texture attribute 개체를생성하고, texture image 데이터를저장한다. SetState 에 texture attrubute 과 mode 를지정한다. 11 OSG 의 geometry 개체에 texture coordinates 을지정한다. 여러개의텍스쳐를하나의 geometry 에지정하려면여러개의텍스쳐좌표 (texture coordinates) 배열을 geometry 에 attach 한다. // create a geometry object osg::ref_ptr<osg::geometry> geom = new osg::geometry; // create a Vec2Array of texture coordinates for texture unit 0 // and attach it to the geom osg::ref_ptr<osg::vec2array> tc = new osg::vec2array; geom->settexcoordarray(0, tc.get()); tc->push_back(osg::vec2(0.f, 0.f)); tc->push_back(osg::vec2(1.f, 0.f)); tc->push_back(osg::vec2(1.f, 1.f)); tc->push_back(osg::vec2(0.f, 1.f)); 12
Loading Images 기본적인 2D Texture Mapping 을만들려면 osg::texture2d 와 osg::image 클래스를사용한다. osg::stateset* state = node->getorcreatestateset(); // load the texture image osg::ref_ptr<osg::image> image = osgdb::readimagefile( sun.tif ); // attach the image in a Texture2D object osg::ref_ptr<osg::texture2d> tex = new osg::texture2d; tex->setimage(image.get()); // after creating the OpenGL texture object, // release the internal ref_ptr<image> (delete the Image) tex->setunrefimagedataafterapply(true); 13 Texture State osg::stateset::settextureattribute() 은 texture attribute 을지정한다. // create a texture3d attribute osg::ref_ptr<osg::texture2d> tex = new osg::texture2d;. // attach the texture attribute for texture unit 0 state->settextureattribute(0, tex.get()); osg::stateset::settexturemode() 사용하여 texture mode 를지정한다. // disable 2D texture mapping for texture unit 1 state->settexturemode(1, GL_TEXTURE_2D, osg::stateattribute::off); // attach 2D texture attribute and enable GL_TEXTURE_2D both on // texture unit 0 state->settextureattributeandmodes(0, tex.get()); 14 Lighting OSG 는 OpenGL lighting (material properties, light properties, lighting models) 을지원한다. OpenGL 과같이, OSG 는 light source 나 shadows 를렌더링하지않는다. Lighting 을사용하고자한다면, 반드시다음과같이지정해야한다. Geometry 에는 normal 이있어야한다. Lighting 을 enable ( 활성화 ) 시키고, lighting state 을지정한다. Light source properties 를지정하고, 그것을 scene graph 에 attach 하여넣는다. Surface material properties 를지정한다. Lighting Normals OpenGL 같이 normals 은반드시 unit vector 이어야한다. 그러나, scale 변환은 normals 의길이를변형시킨다. Normal을 unit vector로지정하는가장효과적인해법은 StateSet 에서 normal rescaling을활성화하는것이다. osg::stateset *state = geode->getorcreatestateset(); state->setmode(gl_rescale_normal, osg::stateattribute::on); 이것은 uniform scaling 에의해영향을받으면 normals 을 unit vector 로복원시켜주는기능이다. 15 16
Lighting Normals 전체 scene graph 에전역적으로 normalization 을활성화하려면다음과같이한다. osg::stateset *state = geode->getorcreatestateset(); state->setmodel(gl_normalize, osg::stateattribute::on); NOTE: normal rescaling 보다렌더링효과를떨어뜨린다. Lighting State Light 과 light source 를활성화 (enable) 한다. osgviewer 는 root node 의 state set 에 light 을지정한다. 다음은 lighting enable 하고 root 노드의 StateSet 에 2 개 light sources (GL_LIGHT0 & GL_LIGHT1) 지정하는예제이다. osg::stateset *state = root->getorcreatestateset(); state->setmode(gl_lighting, osg::stateattribute::on); state->setmode(gl_light0, osg::stateattribute::on); state->setmode(gl_light1, osg::stateattribute::on); 17 18 Light Sources OSG 는동시에 8 개의 light source (GL_LIGHT0 ~ GL_LIGHT7) 를지정할수있다. OpenGL implementation 에따라좀더추가적으로 light source 를지정할수도있다. Scene graph 에 light source 를추가하려면 osg::light 개체를생성하고 light source parameters 를정의한다. osg::lightsource 를 Light 에추가한다. Scene graph 에 LightSource 를추가한다. LightSource 는하나의 light definition 을가진 leaf node 로전체신그라프에영향을미친다. LightSource 는 group 노드의파생노드이므로, light 에 geometry 를붙히는것도가능하다 그렇게해서 light 을표시할수있다. Light Sources OpenGL light source 에 light 을연결짓기위해 light 의숫자를지정한다. Default 상태에 light number 는 0 이다. 다음예제는 GL_LIGHT2 에 light 개체를연결한것을보여준다. // Create a Light object to control GL_LIGHT2 s parameters osg::ref_ptr<osg::light> light = new osg::light; light->setlightnum(2); 19 20
Light Sources Light 클래스는 OpenGL 의 gllight() 에서볼수있는기능들을제공한다. Light 클래스함수로 light 의 ambient, diffuse, specular 색을지정할수있다 ; point light, directional light, spot lights 을지정할수있다 ; light 의거리에따라밝기감쇠 (lihgt attenuation) 을지정할수있다. // create a white spot light source osg::ref_ptr<osg::light> light = new osg::light; light->setambient(osg::vec4(.1f,.1f,.1f, 1.f)); light->setdiffuse(osg::vec4(.8f,.8f,.8f, 1.f)); light->setspecular(osg::vec4(.8f,.8f,.8f, 1.f)); light->setposition(osg::vec3(0.f, 0.f, 0.f)); light->setdirection(osg::vec3(1.f, 0.f, 0.f)); light->setspotcutoff(25.f); 21 Light Sources OSG 는 LightSource 노드에변환행렬을적용해서 light 의위치를변환할수있다. 일반적으로 LightSource 를 MatrixTransform 의 child 로 attach 하고 MatrixTransform 으로 light 의위치를제어한다. // Create the Light and set its properties osg::ref_ptr<osg::light> light = new osg::light; // Create a MatrixTransform to position the Light osg::ref_ptr<osg::matrixtransform> mt = new osg::matrixtransform; osg::matrix m; m.maketranslate(osg::vec3(-3.f, 2.f, 5.f)); mt->setmatrix(m); 22 Light Sources // Add the Light to a LightSource. Add the LightSource and // MatrixTransform to the scene graph osg::ref_ptr<osg::lightsource> ls = new osg::lightsource; parent->addchild(mt.get()); mt->addchild(ls.get()); ls->setlight(light.get()); By default, OSG 는 LightSource 에현재변환행렬에의하여 light 위치를변환한다. 다음예제는 LightSource 변환을무시하고 light 위치를절대값에의거하여적용되도록하는예이다. Light Material Properties osg::materialstateattribute 은 OpenGL 의 glmaterial() 또는 glcolormaterial() 기능을제공한다. Ambient, diffuse, specular, emissive material colors Specular exponent (or shininess) Material properties 를지정하려면 Material 개체를생성한다. Colors 와그외의파라메타를지정한다. Scene graph 에 StateSet 을 attach 한다. osg::ref_ptr<osg::lightsource> ls = new osg::lightsource; ls->setreferenceframe(osg::lightsource::absolute_rf); 23 24
Light Material Properties Material properties 를지정하는예제 Shininess (specular exponent) 는반드시 1.0 ~ 128.0 사이값을사용하도록한다. osg::stateset *state = node->getorcreatestateset(); osg::ref_prt<osg::material> mat = new osg::material; mat->setdiffuse(osg::material::front, osg::vec4(.2f,.9f,.9f, 1.f)); mat->setspecular(osg::material::front, osg::vec4(1.f, 1.f, 1.f, 1.f)); mat->setshininess(osg::material::front, 96.f); state->setattribute(mat.get()); FileIO Reading Files osgdb::readnodefile 는 3 차원모델파일을읽어들여서 Node 개체로반환한다. osgdb::readimagefile 은 2 차원이미지파일을읽어들여서 Image 개체로반환한다. osgdb::registry::getdatafilepathlist() 함수를사용하여데이터파일디렉토리를추가한다. Write a Scene into a File osgdb::writenodefile 는 Node 데이터를 3 차원모델파일로저장한다. osgdb::writeimagefile 는 Image 데이터를 2 차원이미지파일로저장한다. 25 Text Output with OSG osgtext NodeKit OSG 는 core OSG 를확장인 nodekits 를제공하고있다. osgtext nodekit 를사용한 texture mapped text 를그릴수있다. osgtext Components osgtext namespace 를정의한다. 이 namespace에서, 폰트로딩이나텍스트스트링렌더링등관련된클래스를제공한다. osgtext::text 클래스가이중에서주요콤포넌트이다. osgtext::font 클래스는 font filename으로폰트를생성해준다. Font는 FreeType plugin을사용하여 font file을로딩한다. Using osgtext osgtext/font 와 osgtext/text header files 이필요하다. osgtext 를사용하기위해서, 다음 3 스텝을진행해야한다. 같은폰트를사용해서여러개의텍스트스트링을그리기위해서는, 모든텍스트개체들과공유하는하나의 Font 개체를생성한다. 그리는텍스트스트링하나마다, Text 개체를생성한다. 텍스트의정렬 (alignment), 방향 (orientation), 위치 (position), 크기 (size) 등의옵션을지정한다. 스텝 1 에서생성한폰트개체에새로운폰트개체를지정한다. adddrawable() 을사용해서 Geode 에텍스트개체를추가한다. 여러개의텍스트개체를하나의 Geode 에추가하거나또는여러개의 Geode 개체를생성할수있다. Scene graph 에 Geode 개체를 child node 로추가한다. 27 28
Using osgtext 다음은 Font object 을 Courier New TrueType font file 인 cour.ttf 를생성하는예를보여주고있다. osg::ref_ptr<osgtext::font> font = osgtext::readfontfile( fonts/cour.ttf ); osgtext::osgreadfontfile 는폰트파일을로딩하기위해 FreeType OSG plugin 를사용한다. osgreadfontfile() 은 OSG_FILE_PATH 에지정되어있는디렉토리에플랫폼에맞는여러폰트를찾는다. readfromfile() 이지정한파일을못찾거나파일이폰트가아니면, NULL 을반환한다. Using osgtext 다음과같이 Text object 를생성하고, 폰트를지정하고, 텍스트출력을지정한다. osg::ref_ptr<osgtext::text> text = new osgtext::text; text->setfont(font.get()); text->settext( Display this message. ); settext 함수는 osgtext::string 를받는다. osgtext::text 는텍스트의크기 (size), 모양 (appearance), 방향 (orientation), 위치 (position) 를제어하는여러가지함수를제공하고있다. 29 30 Text Position Text 는 cull 과 draw traversal 중에텍스트개체의좌표위치를변환시킨다. By default, 텍스트개체의위치는텍스트개체 (object) 좌표의중심에있다. Text::setPosition 를사용하여텍스트개체의위치를변환한다. // Draw the text at (10., 0., 1.) text->setposition(osg::vec3(10.f, 0.f, 1.f)); Text Orientation 텍스트방향은 3 차원공간에서렌더링괴는텍스트의전면의방향을결정한다. Text::setAxisAlignment() 를사용하여텍스트의방향을지정한다. Billboard-style 텍스트를생성하려면 Text::Screen 을사용한다. text->setaxisalignment(osgtext::text::screen); 이와다른방법으로는, 텍스트를 an axis-aligned plane 에놓는다 ( 텍스트의기본방향은 Text::XY_PLANE 에있으며텍스트는 xy plane 에서 +z 로바라보는곳에위치하고있다 ). text->setaxisalignment(osgtext::text::xy_plane); 31 32
Text AxisAlignment Text Alignment 워드프로세서의 text alignment 나스프레드쉬트의 cell alignment 와비슷하다. 렌더링텍스트의수직수평정렬을결정한다. Default 는 Text::LEFT_BASE_LINE 이다. 텍스트 alignment 을바꾸려면, Text::setAlignment() 를사용한다. text->setalignment(osgtext::text::center_top); 33 34 Text Alignment Text Size Default character height 는 32 object coordinate units 이다. Character width 는폰트에따라다양하다. Default character height 를바꾸려면, Text::setCharacterSize() 를부른다. // change the height to one object coordinate unit text->setcharactersize(1.0f); Text::setCharacterSizeMode() 를사용하여 text 를 object coordinate 대신 screen coordinate 에서 character height 을지정할수있다. text->setcharactersizemode(osgtext::text::screen_coords); 35 36
Text Resolution 응용프로그램에서는폰트텍스쳐맵이사용되서희미하게보이는캐릭터가생기지않도록 glyph resolution 를다양하게해야한다. By default, osgtext 는 glyph 마다 32x32 texels 를할당한다. Text::setFontResolution() 를사용하여 text resolution 을바꿀수있다. text->setfontresolution(128, 128); Text Color Text::setColor() 를사용해서텍스트색을바꾼다. osg::vec4 에 rgba 색값으로 setcolor() 에파라메터로지정한다. // Set the text color to blue text->setcolor(osg::vec4(0.f, 0.f, 1.f, 1.f)); 폰트 resolution 증가는 hardware resource 요구를증가시킨다. 37 38