当前位置: 首页 > news >正文

OpenSceneGraph (OSG) 开发入门

一、环境搭建

1. 安装OSG

Windows
  1. 下载预编译包:从OSG官方网站下载

  2. 设置环境变量:

    • 添加OSG_ROOT指向安装目录

    • %OSG_ROOT%\bin添加到PATH

Linux (Ubuntu)
sudo apt-get install openscenegraph libopenscenegraph-dev openscenegraph-examples
macOS (使用Homebrew)
brew install open-scene-graph

2. 验证安装

osgversion  # 查看版本
osgviewer cow.osgt  # 测试示例模型

二、第一个OSG程序

1. 基本程序结构

#include <osgViewer/Viewer>
#include <osgDB/ReadFile>

int main() {
    // 创建Viewer
    osgViewer::Viewer viewer;
    
    // 加载模型
    osg::Node* node = osgDB::readNodeFile("cow.osgt");
    
    // 设置场景数据
    viewer.setSceneData(node);
    
    // 运行查看器
    return viewer.run();
}

2. 编译命令

Linux/macOS
g++ hello_osg.cpp -losgViewer -losgDB -o hello_osg
Windows (Visual Studio)
  1. 新建C++项目

  2. 配置包含目录:$(OSG_ROOT)\include

  3. 配置库目录:$(OSG_ROOT)\lib

  4. 添加依赖库:osgViewer.lib;osgDB.lib;OpenThreads.lib

三、核心概念

1. 场景图结构

场景根(Group)
├─ 变换节点(MatrixTransform)
│  └─ 几何节点(Geode)
│     └─ 几何体(Geometry)
└─ 细节层次节点(LOD)
   ├─ 高细节模型
   └─ 低细节模型

2. 基本组件

组件说明
osg::Node场景图中所有节点的基类
osg::Group可包含子节点的组节点
osg::Geode几何体节点(叶子节点)
osg::Geometry存储几何数据(顶点、法线等)
osgViewer::Viewer3D场景查看器

四、创建自定义场景

1. 创建简单几何体

osg::Geode* createQuad() {
    osg::ref_ptr<osg::Geode> geode = new osg::Geode;
    osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
    
    // 设置顶点
    osg::Vec3Array* vertices = new osg::Vec3Array;
    vertices->push_back(osg::Vec3(-1,0,-1));
    vertices->push_back(osg::Vec3(1,0,-1));
    vertices->push_back(osg::Vec3(1,0,1));
    vertices->push_back(osg::Vec3(-1,0,1));
    geom->setVertexArray(vertices);
    
    // 设置颜色
    osg::Vec4Array* colors = new osg::Vec4Array;
    colors->push_back(osg::Vec4(1,0,0,1)); // 红
    colors->push_back(osg::Vec4(0,1,0,1)); // 绿
    colors->push_back(osg::Vec4(0,0,1,1)); // 蓝
    colors->push_back(osg::Vec4(1,1,0,1)); // 黄
    geom->setColorArray(colors);
    geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
    
    // 添加图元
    geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));
    
    geode->addDrawable(geom);
    return geode.release();
}

2. 构建场景图

osg::Group* createScene() {
    osg::ref_ptr<osg::Group> root = new osg::Group;
    
    // 添加多个几何体
    root->addChild(createQuad());
    
    // 添加变换节点
    osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform;
    transform->setMatrix(osg::Matrix::translate(2,0,0));
    transform->addChild(createCube());
    root->addChild(transform);
    
    return root.release();
}

五、交互与动画

1. 键盘事件处理

class KeyboardHandler : public osgGA::GUIEventHandler {
public:
    bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) {
        if (ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN) {
            switch (ea.getKey()) {
                case 'a': 
                    // 处理A键按下
                    return true;
                case osgGA::GUIEventAdapter::KEY_Left:
                    // 处理左箭头
                    return true;
            }
        }
        return false;
    }
};

// 添加到查看器
viewer.addEventHandler(new KeyboardHandler());

2. 简单动画

class AnimationCallback : public osg::NodeCallback {
public:
    void operator()(osg::Node* node, osg::NodeVisitor* nv) {
        osg::MatrixTransform* mt = dynamic_cast<osg::MatrixTransform*>(node);
        if (mt) {
            double time = osg::Timer::instance()->time_s();
            mt->setMatrix(osg::Matrix::translate(0, 0, sin(time)*2));
        }
        traverse(node, nv);
    }
};

// 应用到变换节点
transform->setUpdateCallback(new AnimationCallback());

六、进阶主题

1. 着色器编程

osg::StateSet* addShader(osg::Node* node) {
    osg::ref_ptr<osg::Program> program = new osg::Program;
    program->addShader(osgDB::readShaderFile(osg::Shader::VERTEX, "shader.vert"));
    program->addShader(osgDB::readShaderFile(osg::Shader::FRAGMENT, "shader.frag"));
    
    osg::StateSet* stateset = node->getOrCreateStateSet();
    stateset->setAttributeAndModes(program, osg::StateAttribute::ON);
    
    return stateset;
}

2. 粒子系统

osg::Node* createFireEffect() {
    osgParticle::ParticleSystem* ps = new osgParticle::ParticleSystem;
    // 配置粒子系统...
    
    osgParticle::ModularEmitter* emitter = new osgParticle::ModularEmitter;
    emitter->setParticleSystem(ps);
    // 配置发射器...
    
    osg::Group* root = new osg::Group;
    root->addChild(emitter);
    root->addChild(new osgParticle::ParticleSystemUpdater(ps));
    
    return root;
}

七、调试与优化

1. 性能分析工具

  • osgstats:查看场景统计信息

  • osgviewer --stats:运行时显示性能数据

2. 优化技巧

  • 使用osgUtil::Optimizer优化场景

  • 合理使用LOD(细节层次)节点

  • 合并几何体减少绘制调用

八、学习资源

  1. 官方文档:http://www.openscenegraph.org/documentation

  2. 书籍:OpenSceneGraph 3.0 Beginner's Guide

  3. 示例代码$OSG_ROOT/share/OpenSceneGraph/bin中的示例程序

相关文章:

  • LeetCode 热题 100 堆
  • 快速通过简单代码了解装饰模式
  • 在Unity中,如果物体上的脚本丢失,可以通过编写一个自定义编辑器脚本来查找并删除这些丢失的组件
  • DeepSeek 教我 C++ (7) :常见的一些未定义UB
  • 基于论文的大模型应用:基于SmartETL的arXiv论文数据接入与预处理(一)
  • 嵌入式硬件篇---TOF陀螺仪SPI液晶屏
  • Xorg内存管理机制深度解析
  • P1025 [NOIP 2001 提高组] 数的划分(DFS)
  • 【Linux】:HTTP协议
  • Spring RestTemplate修仙指南:从HTTP萌新到请求大能的终极奥义
  • 【VS Code】为什么vscode已经关闭,http://localhost:5173/还可以打开或项目还在运行,端口被占用
  • 软件工程面试题(三十二)
  • 如何计算卷积的复杂度、卷积层的参数量
  • 基于springboot+vue的漫画天堂网
  • frp内网穿透零基础详细教程
  • 03.31-04.06 论文速递 聚焦具身智能、复杂场景渲染、电影级对话生成等五大前沿领域
  • 如何解决uniapp打包安卓只出现功能栏而无数据的问题
  • 优雅实现级联选择器:CascadeSelect 类设计与实现
  • 第4课:列表渲染与条件渲染
  • Diffusion Policy Visuomotor Policy Learning via Action Diffusion官方项目解读(二)(2)
  • 七台河哈尔滨网站建设/谷歌商店官网下载
  • wordpress和iss/优化关键词排名推广
  • 导入表格做地图中热力网站/软文发布
  • 网站建设上市公司/推广团队在哪里找
  • 佛山网站建设设计公司/怎样给自己的网站做优化
  • 网站推广中的评估指标有哪些/网站运营推广的方法有哪些