Osg 开发二:OpenSceneGraph 场景树节点及布告板技术
文章目录一 OSG 场景树节点二 OSG 中的父节点与子节点三 Billboard 结点四 布告板示例1 开发环境2 环境设置3 Billboard 工程其他一 OSG 场景树节点场景图形采用一种自顶向下的、分层的树状数据结构来组织空间数据集以提升渲染的效率。例如一个房子里面有窗、门和家具等如下图所示场景树的顶部是一个根节点从根节点向下延伸各个组节点中均包含了几何信息和用于控制其外观的渲染状态信息。根节点和各个组节点均可以有0个或多个子成员。场景树的最底部是叶子结点构成场景中物体的实际几何信息。综上OSG 程序使用组节点来组织和排列场景中的几何体。二 OSG 中的父节点与子节点OSG 主要包含 NodeGeode叶节点和 Group 组节点。OSG 中大部分节点都继承自 Group少数继承自 Node 和 Geode但 Geode 和 Group 均继承自 Node 结点。它们的继承关系如下图所示三 Billboard 结点osg::Geode 是 OSG 中的叶节点用于保存几何信息以便渲染提供了 addDrawable() 函数来关联应用程序中需要渲染的几何体信息。Billboard 节点继承自 Geode 节点有以下三种模式enumMode{POINT_ROT_EYE,//绕视点POINT_ROT_WORLD,//绕世界坐标AXIAL_ROT//绕轴}Billboard 是一种布告板技术原理是将图形绘制在朝向视点的多边形表面根据视点的观察方向来确定多边形的方向随着观察角度的变化多边形的方向也随之变换。布告板技术主要有面向世界的布告板和轴向布告板。其中面向轴向的布告板包括面向视平面的布告板和面向视点的布告板。如下图所示轴向布告板技术中经过纹理贴图的多边形通常不直接朝向视点而是允许多边形围绕某个固定世界空间轴旋转但调整多边形使其在此范围内尽可能朝向视点。四 布告板示例1 开发环境操作系统Windows10及以上MSVC 2022(Release 64)2 环境设置1包含文件和库文件目录# 添加头文件include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)# 库文件find_library(OSG_LIB NAMES osg PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)find_library(OPEN_THREADS_LIB NAMES OpenThreads PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)find_library(OSGDB_LIB NAMES osgDB PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)find_library(OSGFX_LIB NAMES osgFX PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)find_library(OSGGA_LIB NAMES osgGA PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)find_library(OsgManipulator_LIB NAMES osgManipulator PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)find_library(OsgParticle_LIB NAMES osgParticle PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)find_library(OsgShadow_LIB NAMES osgShadow PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)find_library(OsgSim_LIB NAMES osgSim PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)find_library(OsgTerrain_LIB NAMES osgTerrain PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)find_library(OsgText_LIB NAMES osgText PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)find_library(OsgUtil_LIB NAMES osgUtil PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)find_library(OsgViewer_LIB NAMES osgViewer PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)if(OSG_LIB)message(STATUSFound library: ${OSG_LIB})target_link_libraries(${target_name}PRIVATE ${OSG_LIB}${OPEN_THREADS_LIB}${OSGDB_LIB}${OSGFX_LIB}${OSGGA_LIB}${OsgManipulator_LIB}${OsgParticle_LIB}${OsgShadow_LIB}${OsgSim_LIB}${OsgTerrain_LIB}${OsgText_LIB}${OsgUtil_LIB}${OsgViewer_LIB})else()message(STATUSCould not find required library)endif()2将osg动态库.dll拷贝到可执行文件所在目录3 Billboard 工程1工程代码经测试将OSG窗口嵌入 Qt 中不能显示布告板的三维效果。因此本文采用Visual Studio工程主要代码如下。//创建布告板节点osg::ref_ptrosg::NodecreateBillboardTree(osg::ref_ptrosg::Imageimage){//创建四边形osg::ref_ptrosg::Geometrygeometrynew osg::Geometry();//设置顶点osg::ref_ptrosg::Vec3Arrayvnew osg::Vec3Array();v-push_back(osg::Vec3(-0.5f,0.0f,-0.5f));v-push_back(osg::Vec3(0.5f,0.0f,-0.5f));v-push_back(osg::Vec3(0.5f,0.0f,0.5f));v-push_back(osg::Vec3(-0.5f,0.0f,0.5f));geometry-setVertexArray(v.get());//设置法线osg::ref_ptrosg::Vec3Arraynormalnew osg::Vec3Array();normal-push_back(osg::Vec3(1.0f,0.0f,0.0f)^osg::Vec3(0.0f,0.0f,1.0f));geometry-setNormalArray(normal.get());geometry-setNormalBinding(osg::Geometry::BIND_OVERALL);//设置纹理坐标osg::ref_ptrosg::Vec2Arrayvtnew osg::Vec2Array();vt-push_back(osg::Vec2(0.0f,0.0f));vt-push_back(osg::Vec2(1.0f,0.0f));vt-push_back(osg::Vec2(1.0f,1.0f));vt-push_back(osg::Vec2(0.0f,1.0f));geometry-setTexCoordArray(0,vt.get());//绘制四边形geometry-addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));if(image.get()){//状态属性对象osg::ref_ptrosg::StateSetstatesetnew osg::StateSet();//创建一个Texture2D属性对象osg::ref_ptrosg::Texture2Dtexturenew osg::Texture2D();//关联imagetexture-setImage(image.get());//关联texture2D纹理对象第三个参数默认为ONstateset-setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);//启用混合stateset-setMode(GL_BLEND,osg::StateAttribute::ON);//关闭光照stateset-setMode(GL_LIGHTING,osg::StateAttribute::OFF);geometry-setStateSet(stateset.get());}//创建billboard对象一osg::ref_ptrosg::Billboardbillboard1new osg::Billboard();//设置旋转模式为绕视点billboard1-setMode(osg::Billboard::POINT_ROT_EYE);//添加drawable并设置其位置默认位置为osg::Vec3(0.0f,0.0f,0.0f)billboard1-addDrawable(geometry.get(),osg::Vec3(5.0f,0.0f,0.0f));osg::ref_ptrosg::Billboardbillboard2new osg::Billboard();//设置旋转模式为绕轴转因此还需要设置旋转轴billboard2-setMode(osg::Billboard::AXIAL_ROT);//设置旋转轴billboard2-setAxis(osg::Vec3(0.0f,0.0f,1.0f));billboard2-addDrawable(geometry.get(),osg::Vec3(10.0f,0.0f,0.0f));osg::ref_ptrosg::Groupbillboardnew osg::Group();billboard-addChild(billboard1.get());billboard-addChild(billboard2.get());returnbillboard.get();}2测试结果其他官方店https://2td9n4muhvgusvzepfo0a3cyfue8cph.taobao.com/