`
NickWar
  • 浏览: 72185 次
  • 来自: 南京
文章分类
社区版块
存档分类

OSG 编程

 
阅读更多

OpenSceneGraph Programming



OSG 编程

对象管理

  • 使用new osg::Class创建osg对象,不用使用delete,是OSG编程的特色.
  • OSG内部使用含有引用计数智能指针 (OSG::Referenced)
  • 通过OSG API传递的OSG对象会将权限赋给OSG, 场景(graph)拥有所有通过addChild()方法加载的对象
  • osg::ref_ptr
    如果一个程序在通过API传递OSG对象之后,仍需要继续跟踪这个对象 则必须使用 osg::ref_ptr 来增加其引用计数(防止此对象被意外删除).

对象引用计数

有一个容易犯的错误:在构造函数中使用this传递自身到ref_ptr中,这是因为C++在进行赋值操作时,先检测右值再检测左值

构造函数在model增加引用计数之前就被执行了,所以此时新建的对象未被分配到引用计数

当构造函数传递this后,此对象被过早的删除,

osg::ref_ptr<Model> mode; = new Model();

void
EnableAlphaBlending( osg::ref_ptr<Model> model );

Model::Model( void )
{
    EnableAlphaBlending( this );  // oops!
}

矩阵,变换

矩阵的旋转操作,可建立一个旋转矩阵,然后进行矩阵乘法运算

例如,动态旋转一个飞机模型,每帧旋转1度

首先根据单位矩阵计算一个1度的转置矩阵,

然后每帧与变换的矩阵相乘。

如果你不需要改变旋转的角度(每帧1度),转置矩阵可以一直保持不变

class
{
   osg::ref_ptr<osg::MatrixTransform> mTransform;       // 每帧旋转一次
   osg::ref_ptr<osg::Matrix>          mRotationMatrix;  // 矩阵相乘的系数
};

// 建立一个转换矩阵:
mRotationMatrix.makeRotate( degree, osg::Vec3f( 1.0f, 0.0f, 0.0f ) );  // X轴

// 每帧进行一次转换 (matrix of OSG::MatrixTransform):
...
osg::Matrix m = mTransform->getMatrix();
m = mRotationMatrix * m;
mTransform->setMatrix( m );

矩阵运算,旋转轴

矩阵的旋转可以在对象空间或指定空间进行

绕远路:找一本代数课本然后学学什么是左乘和右乘

走捷径:直接运行程序,如果旋转角度是反的,就调换一下系数

m = mRotationMatrix * m; // 绕本地轴

m = m * mRotationMatrix; // 绕固定轴

混合

OSG中的混合与OpenGL相似,OSG为透明体添加了透明渲染属性(transparent bin,一般由其他渲染元传递进来).

// 启用混合,设置透明.
stateSet->setMode( GL_BLEND, osg::StateAttribute::ON );
stateSet->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );

// 启用深度检测,使不透明的多边形遮挡它后面的透明物体
stateSet->setMode( GL_DEPTH_TEST, osg::StateAttribute::ON );

// 相反地,禁用写入深度缓存,
// 使透明多边形背后的物体可以显示出来
// OSG先绘制透明多边形,然后绘制不透明的多边形
osg::Depth* depth = new osg::Depth;
depth->setWriteMask( false );
stateSet->setAttributeAndModes( depth, osg::StateAttribute::ON );

// 禁用 conflicting modes.
stateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF );

公告板

osg::AutoTransform是 osg::Billboard的替代品,AutoTransform 在视角接近它时不会发生旋转

读取压缩的3D文件

-- OSG 2.9 可以读取压缩的3D文件(.gz格式等). --

One way is to pass a C++ stream to osg::ReaderWriter::readNode( istreamstream& ). The C++ stream is the buffer for the decompressed file.

// Read gzip-compressed file into a C++ string.
string buf;
ReadGzipFile( buf, filename );

// Convert C++ string to a C++ stream.
istringstream ss( buf );

// Pass the C++ stringstream, containing the decompressed file, to OSG.
osg::ref_ptr<osgDB::ReaderWriter> readerWriter = /
   osgDB::Registry::instance()->getReaderWriterForExtension( modelFileSuffix );
osgDB::ReaderWriter::ReadResult res = readerWriter->readNode( ss );

OSG编程杂记

  • drawable, geode:
Geometry不是一个节点(Node)继承自Drawable
从字面上也可以大致看出来,Geode 是一个包含Drawable的节点(Node),

Drawable --> Geometry
Node --> Geode

geode->addDrawable( geometry );
  • modes vs. attributes:
  • OSG 模式(modes) 与OpenGL的模式(modes)直接关联,如着色,混合等
    属性(Attributes)是模式的参数,如阴影模型和混合方程
    OSG定义了一系列的属性类,这些类继承自StateAttribute,如BlendFunc等
    mode是StateSet的一部分,所以可以这样使用:
    osg::StateSet::setMode()
    为了简单起见,使用方法setAttributeAndModes()可以同时设置模式(mode)和属性(attribute)
    如下:
    osg::BlendFunc* bf = new osg::BlendFunc();
    state->setAttributeAndModes( bf, osg::StateAttribute::ON );
    state->setAttributeAndModes( bf );  // 默认设置为ON
    
  • 状态继承
  • 一个子对象的状态继承自其父对象
    osg::StateAttribute::OVERRIDE 如果你将一个渲染属性和模式设置为
    OVERRIDE,那么所有的子节点都将继承这一属性或模式,子节点对它
    们更改将会无效。
    osg::StateAttribute::PROTECTED 这种形式可以视为OVERRIDE 的一
    个例外。凡是设置为PROTECTED 的渲染属性或模式,均不会受到父节
    点的影响。
    默认情况下,子节点的STATESET渲染模式为OVERRIDE [Martz].
    
       A
      / /
     B   C
    
    A 颜色设置为Blue
    B 颜色设置为Red
    C 不改变颜色
    那么c的颜色会是什么样?
    C的颜色是Red!
    是不是有点惊讶?
    因为OSG会保留最后执行的glColor()函数的效果(此函数在设置B的时候被调用)
    从B-->A的"回访"不会保存或弹出OpenGL状态
    这并不是OSG所独有的(这是其他场景图库的通用做法);
    
  • 停用节点:
  • node->setNodeMask(0)
    
    这可以有效的禁用不太明显的类如Cameras等
    
  • 访问者模式
  • OSG使用访问者模式,并apply()相当于访问者模式中的visit()方法
    从NodeVisitor 派生出来的对象,要重写apply()方法
    
    class Visitor : public osg::NodeVisitor
    {
        virtual void apply( osg::Node& node )  // visit() method
        {
            ...
              // Keep searching.
              traverse( node );
        }
    };
    
  • 屏幕截图,记录和图像:
  • osg::Image* shot = new osg::Image();
    shot->allocateImage(width, height, 24, GL_RGB, GL_UNSIGNED_BYTE);
    camera->attach(osg::Camera::COLOR_BUFFER, shot);
    osgDB::writeImageFile(*shot,"image_file.png");
    
    若要获取屏幕截图,需要使用Viewer渲染一个帧(frame)
  • Direct rendering:
  • OSG 提供几种方式用于直接调用OpenGL:
    
    1.osg::Operation -osg::Window 的回调函数
    2.osg::Camera::DrawCallback
    3.继承osg::Drawable
    
    前两种方式以frame为单位进行渲染
    第三种方式(osg::Drawable)以节node为单位进行渲染
    
    对于节点渲染(osg::Drawable),一个极好的例子是osgteapot.
    
    class Teapot : public osg::Drawable
    {
        virtual void drawImplementation( osg::RenderInfo& ) const;
    
        // 我们需要为数据建立一个包容盒,这样场景才能知道
        // 对象的位置,这对初始化时确定相机位置和
        // 执行拣选(culling)十分重要
        virtual osg::BoundingBox computeBound() const;
    };
    
  • 渲染元:
  • [Martz]
    "主题: Re: [osg-users] 渲染序列
    osgUtil::CullVisitor 从可见的Drawable对象创建渲染元(RenderBins)
    然后处理每一个RenderBin。所以,查看CullVisitor和RenderBin的代码
    然后在看看osg::Geometry::apply等,了解Geometry是如何传递给OpenGL的。
    你可以使用GLIntercept等工具来捕获OpenGL命令,这样可以让你看到OSG是如何渲染场景的"
    
    [Osfield]
    "在将多个Drawable,Stateset和RenderBin/RenderStage以及一个状态图放入渲染后端时,
    OSG 中的状态排序(state sorting)是作为拣选过程的一部分来完成的,一个渲染元(RenderBin )排序完成时,
    其状态值(state)为sorted,这个过程是通过一个STL的映射容器完成的,此容器保存指针与StateSet的映射"
    
  • 禁用光照:
  • osg::StateAttribute::OVERRIDE 渲染模式下可以禁用光照,但PROTECTED下不行,如下: mSwitchNode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OVERRIDE | osg::StateAttribute::OFF );

    • 多光源:
    osg::Light 是一个状态属性(state attribute);
    osg::LightSource 是一个组(Group)
    一个LightSource只能包含一个osg::Light
    所以,要使用多光源,需要建立由一个由LightSource组成的线性链表
    然后将渲染对象(geometry)放置到此链表的末端
    
       root
        |
        V
    lightSource 0
        |
        V
    lightSource 1
        |
        V
      geodes
    
  • 处理ESC键:
  • viewer->setKeyEventSetsDone( 0 );
    
  • 相机:
  • Cameras 定义3D的模型视图矩阵(modelview matrix),2D的视点和渲染对象。
    Cameras 包含在一个图形窗口的图形上下文中
    
    Cameras 可以作为节点(node)放入一个场景图中(原始方式)
    或添加到osg::Viewer中(新方式)
    
    操作机(Manipulator)可以控制Camera
    Manipulator可以高效的定义一个模型视图矩阵(modelview matrix)
    使用Manipulator::getInverseMatrix()可以提取一个模型视图矩阵
    
    一个Camera定义需要渲染的目标
    对于2D窗口中不同视角,OSG通过添加多个Camera来对每一个视角进行单独渲染
    纹理渲染(RTT)也是由osg::Camera完成的,
    将一个纹理设置为camera的"渲染目标"(render target)即可.
    
    在绘制视图前/后调用的回调函数(Callbacks),可以通过osg::Camera来注册.
    
  • 在视图中启用窗口模式:
  • viewer.setUpViewInWindow( 0, 0, 1024, 768 );



    原文地址:http://www.palomino3d.com/pal_com/openscenegraph/

    分享到:
    评论

    相关推荐

      OSG快速入门指导_osg_osg编程_

      OSG编程基础 - **节点创建与操作**: 使用`osg::Node`基类创建自定义节点,或通过`osg::Geode`添加几何数据。 - **几何体构建**: 使用`osg::Geometry`类创建几何体,通过`osg::DrawArrays`或`osg::DrawElements`...

      OSG编程入门指南(英文)

      **OSG编程入门指南概述** OpenSceneGraph(OSG)是一种高性能的3D图形库,专为实时可视化和科学模拟而设计。它基于OpenGL标准,提供了丰富的功能集,包括场景图管理、高级渲染技术、动画支持以及交互式应用开发工具...

      OSG编程入门指南 OSG编程入门指南

      ### OSG编程入门指南知识点详解 #### 一、OpenSceneGraph简介 OpenSceneGraph(简称OSG)是一种高性能、跨平台的开源场景图应用程序接口(API),被广泛应用于三维图形应用开发领域。它提供了一套丰富的工具和库,...

      OSG快速入门指导.pdf

      ### 三、OSG编程基础 1. **安装与配置**:首先,你需要下载并安装OSG库,然后设置编译环境和链接库,以便在项目中使用OSG。 2. **创建场景图**:通过继承`osg::Node`类,你可以创建自定义的节点类型。节点间的关系...

      osg 编程指南

      osg 编程指南

      OSG三维渲染引擎编程指南电子版

      该书是OSG三维渲染引擎编程指南电子版高清电子版,可以为OSG的学习带来很大帮助。

      OSG的书籍,三维渲染引擎编程指南,肖鹏等

      《OpenSceneGraph三维渲染引擎编程指南》是由肖鹏等人编著的一本专业书籍,主要针对OSG(OpenSceneGraph)这一强大的开源三维图形渲染引擎进行深入讲解。这本书旨在帮助读者理解和掌握如何使用OSG进行三维场景的构建...

      OSG三维渲染引擎编程指南+OSG-Cookbook(英文)+OSG程序设计教程+OSG三维渲染引擎设计与实践

      这个压缩包包含了四本关于OSG编程的重要参考资料,涵盖了从基础到高级的各个方面,适合对OSG感兴趣的开发者深入学习。 1. **《OSG三维渲染引擎编程指南》**:这本书可能是入门OSG的首选资料,它详细介绍了如何使用...

      OSG程序设计教程.zip_OSG程序设计_osg 地_osg例子_osg回调_osg的一些例子代码

      这些代码是学习OSG编程的最佳起点,因为它们将理论与实践结合在一起。 4. **osg回调** OSG中的回调机制允许你在特定事件发生时执行自定义代码。例如,你可以设置一个回调函数在每次帧更新时被调用,以动态改变场景...

      OSG程序设计教程

      为了帮助更多初学者更好地理解和学习OSG编程技术,作者决定编写此书。值得注意的是,作者原本并未打算写书,而是计划由另一位名叫Array的朋友来完成这项任务。然而,由于种种原因,Array未能如期完成书籍,促使作者...

      osg.zip_OSG程序设计_Quick_osg_osg开发教程

      这是一本深入介绍OSG编程的书籍,涵盖了OSG的基础概念、数据结构、场景图构建、渲染机制、动画处理、事件处理等方面的知识。通过阅读此书,你可以了解到如何创建基本的OSG程序,理解场景图的工作原理,以及如何利用...

      OSG程序设计教程(附书源码)

      《OSG程序设计教程》是一本深入探讨OpenSceneGraph (OSG) 的专业教程,它为读者提供了详尽的OSG编程知识。OpenSceneGraph是一个高性能的3D图形库,广泛应用于游戏开发、虚拟现实、科学可视化等领域。本书旨在帮助...

      OSG编程资料

      Open Scene Graphic (OSG) 是一个强大的开源图形库,专门用于构建复杂的3D应用程序和可视化系统。这个库提供了丰富的功能,包括场景管理、图形渲染、动画支持以及与多种硬件和软件接口的集成。由于其开源性质,OSG ...

      OpenSceneGraph三维渲染引擎编程指南

      OpenSceneGraph(OSG)是一个开源的高性能三维图形渲染引擎,它基于工业标准OpenGL,并...它为对OpenGL和OSG编程感兴趣的读者提供了详尽的技术指导,帮助读者深入掌握OSG的使用,并提升在三维图形编程方面的专业技能。

      osg示例程序简介——快速查看示例

      同时,它也鼓励用户动手实践,通过运行和修改示例程序,进一步提升自己的OSG编程技能。 总的来说,"osg示例程序简介"是学习和掌握OpenSceneGraph不可或缺的资源,它以实例驱动的方式,引导学习者逐步探索3D图形编程...

      osg海军教程+源代码

      "海军教程源码"这部分则提供了实践的机会,你可以通过查看和运行这些源代码来加深对OSG编程的理解。源代码可能包含了各种示例程序,如基本的几何形状绘制、用户交互、视图变换等。通过分析和修改代码,你可以更好地...

      OSG三维渲染引擎编程指南代码

      《OSG三维渲染引擎编程指南代码》是一份针对初学者的宝贵资源,旨在帮助学习者掌握OpenSceneGraph(OSG)这一强大的三维渲染引擎。OpenSceneGraph是一个开源的C++库,广泛应用于科学可视化、虚拟现实、游戏开发等...

      osg_second.rar_osg

      在压缩包文件`osg_second`中,可能包含了各种OSG编程实例,比如简单的几何体渲染、模型加载、光照和纹理应用、动画实现等。通过这些实例,初学者可以逐步理解OSG的工作原理,并学习如何在实际项目中应用这些技术。

    Global site tag (gtag.js) - Google Analytics