三方库 - 三维处理/Osg

OSG(OpenSceneGraph) 是一个用于 3D 图形渲染的开源场景图形库,主要用于高性能 3D 应用程序的开发,被广泛应用于飞行模拟、游戏开发、虚拟现实(VR)、增强现实(AR)和仿真系统等领域,OSG 的设计围绕“场景图”结构,帮助开发者高效管理和渲染复杂的 3D 场景。

OSG使用C++、面向对象技术开发,基于OpenGL,封装了OpenGL中的功能,屏蔽细节、便于交互,支持Windows、Linux、macOS。

Github:

https://github.com/openscenegraph/OpenSceneGraph

一、OSG环境搭建(Windows)

1、Vcpkg包安装

vcpkg.exe install osg

vcpkg.exe install osg-qt

2、CMakeLists

find_package(OpenSceneGraph REQUIRED COMPONENTS osgDB osgUtil osgGA osgViewer osgWidget)

target_include_directories(${PROJECT_NAME} PRIVATE ${OPENSCENEGRAPH_INCLUDE_DIRS})

target_link_libraries(${PROJECT_NAME} PRIVATE ${OPENSCENEGRAPH_LIBRARIES})

二、OSG环境搭建(Linux

1、克隆源码

注意:配合OSGEARTH需要将cmake版本提升到3.20以上。

mkdir osg && cd osg

git clone https://github.com/openscenegraph/OpenSceneGraph.git

cd OpenSceneGraph

2、编译/构建

注意使用普通用户进行。

在OpenSceneGraph文件夹下打开CMakeLists.txt文件,搜索关键词OPENGL_PROFILE,寻找到 SET(OPENGL_PROFILE “GL3” CACHE STRING “OpenGL Profile to use, choose from GL1, GL2, GL3, GLES1, GLES2, GLES3”) 这一行代码,标记内容原本为GL2或其他的选项,这里一律将标记内容修改为GL3,运行以下命令进行安装。

sudo apt install ocl-icd-opencl-dev

mkdir build && cd build

cmake ../

make -j8

sudo make install

sudo vim /etc/ld.so.conf.d/osg.conf

// 输入OSG动态库路径

/usr/local/lib64

/usr/local/lib

/usr/local/lib/x86_64-linux-gnu

// 更新链接配置

sudo ldconfig

3、模型测试

下载模型数据:https://openscenegraph.github.io/OpenSceneGraphDotComBackup/OpenSceneGraph/www.openscenegraph.com/downloads/stable_releases/OpenSceneGraph-3.4.0/data/OpenSceneGraph-Data-3.4.0.zip

osgviewer cow.osg

4、CMakeLists

find_package(OpenSceneGraph REQUIRED COMPONENTS osgDB osgUtil osgGA osgViewer osgWidget)

target_include_directories(${PROJECT_NAME} PRIVATE ${OPENSCENEGRAPH_INCLUDE_DIRS})

target_link_libraries(${PROJECT_NAME} PRIVATE ${OPENSCENEGRAPH_LIBRARIES})

三、OSG文档

https://podsvirov.github.io/osg/reference/openscenegraph/annotated.html

OSG的模化设计思想将其类库按照“命名空间+类名称”命名

四、OSG核心库osg

核心osg库提供了基本的场景图类,例如 Nodes、State和 Drawables,以及数学和通用帮助程序类。

1、数据结构
  • osg::ref_ptr(引用计数)

头文件:#include <osg/ref_ptr>

osg::ref_ptr 是一个模板类,类似于标准库中的 std::shared_ptr,但是它特别为 OSG 的对象生命周期管理而设计,ref_ptr 会自动跟踪引用计数,当引用计数为 0 时,自动删除对象。

声明与使用:

#include <osg/Node>

#include <osg/ref_ptr>

int main() {

    // 创建一个 osg::Node 对象的 ref_ptr

    osg::ref_ptr<osg::Node> node = new osg::Node;

    // 使用该对象(例如将其添加到场景图中)

    node->setName("MyNode");

    // 不需要显式删除,OSG 会自动管理内存

    return 0;

}

函数返回值使用:

osg::ref_ptr<osg::Node> createNode() {

    osg::ref_ptr<osg::Node> node = new osg::Node;

    node->setName("CreatedNode");

    return node;

}

int main() {

    osg::ref_ptr<osg::Node> node = createNode();

    // node 会在使用完后自动释放内存

    return 0;

}

引用计数工作机制:

osg::ref_ptr<osg::Node> node1 = new osg::Node;

osg::ref_ptr<osg::Node> node2 = node1;  // 增加引用计数

// 当 node1 和 node2 超出作用域时,对象会自动销毁

与原始指针的转换:

osg::ref_ptr<osg::Node> node = new osg::Node;

osg::Node* rawNode = node.get();  // 获取原始指针

  • osg::Vec2(二维向量)

头文件:#include <osg/Vec2>

功能:osg::Vec2 是一个用于表示二维向量的类,包含两个 float 类型的分量:x 和 y,它通常用于表示二维坐标、纹理坐标、或其他二维向量的数学运算。

成员函数:

·  x(), y(),:获取二维向量的 x、y分量;

·  set(x, y):设置向量的 x、y分量。

示例代码:

#include <osg/Vec2>

int main() {

    // 创建一个 osg::Vec2 对象

    osg::Vec2 point(1.0f, 2.0f);

    // 访问 x 和 y 分量

    float x = point.x();

    float y = point.y();

    // 修改分量

    point.set(x + 1.0f, y + 1.0f);

    // 向量加法

    osg::Vec2 other(0.5f, 0.5f);

    osg::Vec2 sum = point + other;

    return 0;

}

  • osg::Vec2Array(二维向量数组)

#include <osg/Vec2Array>

功能:osg::Vec2Array 是一个容器类,用于存储多个 osg::Vec2 对象。通常用于表示二维顶点坐标、纹理坐标等。

成员函数:
·  push_back(const osg::Vec2 v):将一个 osg::Vec2 对象添加到数组中;

·  size():获取数组中元素的数量;

·  operator[]():按索引访问数组中的元素。

示例代码:

#include <osg/Vec2Array>

#include <osg/Geometry>

int main() {

    // 创建一个 Vec2Array 对象

    osg::ref_ptr<osg::Vec2Array> texCoords = new osg::Vec2Array;

    // 添加纹理坐标

    texCoords->push_back(osg::Vec2(0.0f, 0.0f));

    texCoords->push_back(osg::Vec2(1.0f, 0.0f));

    texCoords->push_back(osg::Vec2(0.0f, 1.0f));

    // 创建一个 Geometry 对象并设置纹理坐标

    osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;

    geometry->setTexCoordArray(0, texCoords);

    return 0;

}

  • osg::Vec3(三维向量)

头文件:#include <osg/Vec3>

功能:osg::Vec3 是一个用于表示三维向量的类,它包含三个 float 类型的分量:x、y 和 z,用来表示三维空间中的一个点或方向,支持各种数学运算,如加法、减法、点积、叉积等。

成员函数:

·  x(), y(), z():获取三维向量的 x、y、z 分量;

·  set(x, y, z):设置向量的 x、y、z 分量;

·  length():计算向量的长度(模);

·  normalize():将向量归一化;

·  dot():计算点积(Vec3 和另一个 Vec3);

·  cross():计算叉积(Vec3 和另一个 Vec3)。

示例代码:

#include <osg/Vec3>

int main() {

    // 创建一个 osg::Vec3 对象

    osg::Vec3 point(1.0f, 2.0f, 3.0f);

    // 访问 x, y, z 分量

    float x = point.x();

    float y = point.y();

    float z = point.z();

    // 修改分量

    point.set(x + 1.0f, y + 1.0f, z + 1.0f);

    // 向量加法

    osg::Vec3 other(0.5f, 0.5f, 0.5f);

    osg::Vec3 sum = point + other;

    // 向量点积

    float dotProduct = point * other;

    return 0;

}

  • osg::Vec3Array(三维向量数组)

头文件:#include <osg/Vec3Array>

功能:osg::Vec3Array 是一个容器类,用于存储多个 osg::Vec3 对象,通常用于表示一组三维点(例如多边形的顶点)。

成员函数:
·  push_back(const osg::Vec3& v):将一个 osg::Vec3 对象添加到数组中;

·  size():获取数组中元素的数量;

·  operator[]():按索引访问数组中的元素。

示例代码:

osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;

vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));

vertices->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));

vertices->push_back(osg::Vec3(0.0f, 1.0f, 0.0f));

osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;

geometry->setVertexArray(vertices);

  • osg::Vec4(四维向量)

头文件:#include <osg/Vec4>

功能:osg::Vec4 是一个用于表示四维向量的类,包含四个 float 类型的分量:x、y、z 和 w,用于表示颜色(RGBA)或四维向量。

成员函数:

·  r(), g(), b(), a():获取四维向量的 r、g、b、a 分量;

·  set(r, g, b, a):设置向量的 r、g、b、a 分量。

示例代码:

#include <osg/Vec4>

int main() {

    // 创建一个 osg::Vec4 对象(RGBA 颜色)

    osg::Vec4 color(1.0f, 0.0f, 0.0f, 1.0f);  // Red color

    // 访问 x, y, z, w 分量

    float r = color.r();

    float g = color.g();

    float b = color.b();

    float a = color.a();

    // 修改分量

    color.set(r * 0.5f, g * 0.5f, b * 0.5f, a * 0.5f);

    return 0;

}

  • osg::Vec4Array(四维向量数组)

头文件:#include <osg/Vec4Array>

功能:osg::Vec4Array 是一个容器类,用于存储多个 osg::Vec4 对象。通常用于表示一组颜色、四维坐标等。

成员函数:
·  push_back(const osg::Vec4& v):将一个 osg::Vec4 对象添加到数组中;

·  size():获取数组中元素的数量;

·  operator[]():按索引访问数组中的元素。

示例代码:

#include <osg/Vec4Array>

#include <osg/Geometry>

int main() {

    // 创建一个 Vec4Array 对象

    osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;

    // 添加颜色

    colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));  // Red color

    colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));  // Green color

    colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));  // Blue color

    // 创建一个 Geometry 对象并设置颜色数组

    osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;

    geometry->setColorArray(colors);

    geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);  // 每个顶点使用不同的颜色

    return 0;

}

  • osg::StateSet(渲染状态容器)

头文件:#include <osg/StateSet>

功能:osg::StateSet 是渲染状态的容器,用于管理所有渲染状态,如纹理、着色器、光照、混合模式等。

函数:

·  void setTextureAttributeAndModes(unsigned int unit, osg::StateAttribute* attribute, osg::StateAttribute::Mode mode); // 设置纹理单位和其对应的状态属性

·  void setAttributeAndModes(osg::StateAttribute* attribute, osg::StateAttribute::Mode mode); // 设置一个状态属性,并指定它的启用/禁用模式

·  void setMode(GLenum cap, osg::StateAttribute::Mode mode); // 设置 OpenGL 状态(例如启用/禁用某个渲染功能)

·  osg::StateAttribute* getAttribute(osg::StateAttribute::Type type) const; // 获取指定类型的状态属性

·  osg::ref_ptr<osg::StateSet> getOrCreateStateSet(); // 获取或创建一个与节点关联的状态集

·  void addAttribute(osg::StateAttribute* attribute); // 将一个状态属性添加到 StateSet

·  void removeAttribute(osg::StateAttribute* attribute); // 从 StateSet 中移除状态属性

  • osg::Image图像数据

头文件:#include <osg/Image>

功能:osg::Image 是 OpenSceneGraph (OSG) 中用于存储和处理图像数据的类,通常用于表示纹理图像,封装了图像的像素数据,并提供了访问图像各个像素、宽高等属性的方法。

函数:

·  unsigned int s() const; // 返回图像的宽度(水平分辨率)

·  unsigned int t() const; // 返回图像的高度(垂直分辨率)

·  unsigned int r() const; // 返回图像的深度(适用于 3D 图像)

·  unsigned int getNumComponents() const; // 返回图像的通道数(如 RGB 为 3,RGBA 为 4)

·  void setNumComponents(unsigned int numComponents); // 设置图像的通道数

·  GLenum getPixelFormat() const; // 返回图像的像素格式(如 GL_RGBA)

·  GLenum getDataType() const; // 返回图像的像素数据类型(如 GL_UNSIGNED_BYTE)

·  unsigned char* data() const; // 返回指向图像像素数据的指针

·  void setImage(unsigned int width, unsigned int height, unsigned int numComponents, GLenum dataType, unsigned char* data); // 设置图像的宽高、通道数、数据类型和像素数据

·  osg::ref_ptr<osg::Image> clone() const; // 克隆当前图像对象

·  bool isImageTranslucent() const; // 判断图像是否具有透明通道

·  void flipVertical(); // 将图像垂直翻转

  • osg::Texture2D(纹理数据)

头文件:#include <osg/Texture2D>

功能:osg::Texture2D 用于表示 2D 纹理图像,通常在 3D 场景中用于贴图,它包含纹理图像、纹理过滤方式、环绕模式等参数,可以通过 setImage 方法将一个 osg::Image 对象应用为纹理,也可以设置各种纹理参数来控制纹理如何在渲染时进行处理(例如,过滤方式、环绕方式等)。

函数:

·  void setImage(osg::Image* image); // 设置纹理图像

·  osg::Image* getImage() const; // 获取纹理图像

·  void setFilter(osg::Texture::FilterMode minFilter, osg::Texture::FilterMode magFilter); // 设置纹理的过滤方式

·  void setWrap(osg::Texture::WrapMode wrapS, osg::Texture::WrapMode wrapT); // 设置纹理的环绕方式

·  void setWrap(osg::Texture::WrapMode wrapS, osg::Texture::WrapMode wrapT, osg::Texture::WrapMode wrapR); // 设置 3D 纹理的环绕方式

·  void setInternalFormat(GLenum format); // 设置纹理的内部格式

·  GLenum getInternalFormat() const; // 获取纹理的内部格式

·  void setBorderColor(const osg::Vec4& borderColor); // 设置纹理的边框颜色

·  const osg::Vec4& getBorderColor() const; // 获取纹理的边框颜色

·  void setTextureWidth(unsigned int width); // 设置纹理的宽度

·  unsigned int getTextureWidth() const; // 获取纹理的宽度

·  void setTextureHeight(unsigned int height); // 设置纹理的高度

·  unsigned int getTextureHeight() const; // 获取纹理的高度

·  void setTextureDepth(unsigned int depth); // 设置纹理的深度

·  unsigned int getTextureDepth() const; // 获取纹理的深度

·  void setTarget(GLenum target); // 设置纹理的目标类型(例如,GL_TEXTURE_2D)

·  GLenum getTarget() const; // 获取纹理的目标类型

·  void setMaxAnisotropy(float maxAnisotropy); // 设置纹理的最大各向异性

·  float getMaxAnisotropy() const; // 获取纹理的最大各向异性

·  void apply(osg::StateSet& stateSet) const; // 将纹理应用到给定的状态集

2、场景图(Scene Graph)
  • osg::Geode(几何节点)

头文件:#include <osg/Geode>

功能:osg::Geode 是 OpenSceneGraph 中一个非常重要的类,通常用于包含几何体(osg::Drawable)集合,它用于构建一个渲染节点,几何体数据(如 osg::Geometry)可以被添加到 Geode 中,形成可渲染的图形。

函数:

·  void addDrawable(osg::Drawable* drawable); // 将几何体(osg::Drawable)添加到 Geode 中

·  unsigned int getNumDrawables() const; // 返回 Geode 中包含的几何体(osg::Drawable)的数量

·  osg::Drawable* getDrawable(unsigned int index) const; // 获取 Geode 中指定索引的几何体(osg::Drawable)

·  void removeDrawable(osg::Drawable* drawable); // 从 Geode 中移除指定的几何体

·  void setStateSet(osg::StateSet* stateSet); // 设置 Geode 的状态集(StateSet)

·  osg::StateSet* getOrCreateStateSet(); // 获取或创建 Geode 的状态集(StateSet)

·  void traverse(osg::NodeVisitor& nv); // 遍历 Geode 中的所有几何体,通常用于场景图遍历

3、几何体和着色器(osg::Geometry)

头文件:#include <osg/Geometry>

功能:osg::Geometry 类是 OpenSceneGraph (OSG) 中用于表示几何体的核心类之一,负责存储顶点数据、颜色、法线、纹理坐标等信息,供图形渲染引擎渲染使用,通过 osg::Geometry 类,可以定义模型的顶点、面、颜色、纹理映射等,并将其传递给图形管线进行绘制。

  • 构造函数

·  Geometry(): 默认构造函数,创建一个空的几何体;

·  Geometry(const Geometry& geometry, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY): 复制构造函数。

  • 设置顶点数据(setVertexArray)

void setVertexArray(osg::ref_ptr<osg::Vec3Array> vertices): 设置顶点坐标数组,vertices 是一个 osg::Vec3Array 类型的对象,存储模型的顶点坐标。

示例代码:

osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;

vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));

vertices->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));

geometry->setVertexArray(vertices);

  • 设置颜色数据(setColorArray)

void setColorArray(osg::ref_ptr<osg::Vec4Array> colors): 设置顶点颜色数组,colors 是一个 osg::Vec4Array 类型的对象,存储每个顶点的颜色。

示例代码:

osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;

colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));  // 红色

geometry->setColorArray(colors);

  • 设置纹理坐标(setTexCoordArray)

void setTexCoordArray(int unit, osg::ref_ptr<osg::Vec2Array> texCoords): 设置纹理坐标数组,texCoords 是一个 osg::Vec2Array 类型的对象,unit 是纹理单元(通常为 0)。

示例代码:

osg::ref_ptr<osg::Vec2Array> texCoords = new osg::Vec2Array;

texCoords->push_back(osg::Vec2(0.0f, 0.0f));  // 纹理坐标 (0,0)

geometry->setTexCoordArray(0, texCoords);

  • 设置法线数据(setNormalArray/setNormalBinding)

法线:垂直与一个平面的向量,根据法线计算该面为朝向光源/背向光源;

(计算法线向量和从平面上一个点到光源方向向量的点乘,cos值在角度[-90°, +90°]范围内的时候是正值,并且越接近±90°值越接近0,只要cos值大于0,就证明这个面被光照到)

void setNormalArray(osg::ref_ptr<osg::Vec3Array> normals): 设置法线数组,normals 是一个 osg::Vec3Array 类型的对象,存储每个顶点的法线向量。

void setNormalBinding(NormalBinding binding): 设置法线的绑定方式;

        osg::Geometry::BIND_OFF:没有绑定;

        osg::Geometry::BIND_PER_VERTEX:每个顶点使用不同的法线;

        osg::Geometry::BIND_PER_PRIMITIVE:每个面使用相同的法线。

示例代码:

osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array;

normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));  // Z轴法线

geometry->setNormalArray(normals);

geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);

  • 设置几何体拓补(addPrimitiveSet)

void addPrimitiveSet(osg::ref_ptr<osg::DrawArrays> primitiveSet): 添加绘制原始数组,这个函数用来指定如何通过顶点来绘制几何体,例如,使用 osg::DrawArrays 来绘制三角形、线段等;

·  osg::PrimitiveSet::POINTS - 绘制独立的点,每个顶点作为一个点来绘制

·  osg::PrimitiveSet::LINES - 绘制一系列线段,每两个顶点定义一条线段

·  osg::PrimitiveSet::LINE_STRIP - 绘制一条折线,连接一系列顶点,形成连续的线条

·  osg::PrimitiveSet::LINE_LOOP - 绘制一个闭合的折线,连接顶点并形成闭环

·  osg::PrimitiveSet::TRIANGLES - 绘制三角形,每三个顶点定义一个三角形

·  osg::PrimitiveSet::TRIANGLE_STRIP - 绘制三角形带,每个新顶点与前两个顶点共同形成一个三角形

·  osg::PrimitiveSet::TRIANGLE_FAN - 绘制三角形扇形,第一个顶点作为中心,与后续顶点一起形成三角形

·  osg::PrimitiveSet::QUADS - 绘制四边形,每四个顶点定义一个四边形

·  osg::PrimitiveSet::QUAD_STRIP - 绘制四边形带,每两个新顶点与前两个顶点共同形成一个四边形

·  osg::PrimitiveSet::POLYGON - 绘制多边形,顶点按顺序连接形成闭合的多边形

·  osg::PrimitiveSet::LINES_ADJACENCY - 绘制带有邻接线段的线段

·  osg::PrimitiveSet::LINE_STRIP_ADJACENCY - 绘制带有邻接折线的折线

·  osg::PrimitiveSet::TRIANGLES_ADJACENCY - 绘制带有邻接三角形的三角形

·  osg::PrimitiveSet::TRIANGLE_STRIP_ADJACENCY - 绘制带有邻接三角形带的三角形带。

示例代码:

osg::ref_ptr<osg::DrawArrays> drawArrays = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, 3);

geometry->addPrimitiveSet(drawArrays);

  • 绑定纹理(setTextureAttributeAndModes

getOrCreateStateSet() 方法用于获取与 geom(即几何体)相关联的 osg::StateSet 对象,如果 geom 没有 StateSet,它会自动创建一个。

StateSet 用于管理渲染状态,例如纹理、着色器、混合模式等。

setTextureAttributeAndModes() 方法用于将纹理设置到 StateSet 中。

示例代码:

osg::Texture2D* texture = new osg::Texture2D;

texture->setImage(pImage);

osg::StateSet* stateset = geom->getOrCreateStateSet();

stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);

五、OSG读写库osgDB

负责与文件系统交互,进行模型、纹理和其他数据的加载、保存及管理。

  • 读取图像数据(readRefImageFile

头文件:#include <osgDB/ReadFile>

osgDB::readRefImageFile 是 OpenSceneGraph (OSG) 中的一个函数,用于从文件读取图像数据并返回一个引用计数的图像对象(osg::Image),该函数可以自动根据文件扩展名选择合适的图像格式加载图像,支持常见的图像格式如 BMP、PNG、JPEG、TIFF 等。

示例代码:

osg::ref_ptr<osg::Image>pImage = osgDB::readRefImageFile(filename);

if (pImage) {

    osg::Texture2D* texture = new osg::Texture2D;

    texture->setImage(pImage);

    osg::StateSet* stateset = geom->getOrCreateStateSet();

    stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);

}

六、OSG查看器osgViewer::Viewer

头文件:#include <osgViewer/Viewer>

功能:osgViewer::Viewer 是 OpenSceneGraph 提供的一个视图渲染器,帮助用户启动、设置和控制图形窗口、场景和渲染循环,提供设置视图、相机、渲染模式等功能,用于创建一个简单的 OpenGL 渲染应用。

函数:

·  int run(); // 启动视图渲染循环

·  void setSceneData(osg::Node* scene); // 设置场景图数据

·  osg::ref_ptr<osg::View> getView() const; // 获取当前视图

·  void setCamera(osg::ref_ptr<osg::Camera> camera); // 设置渲染所用的相机

·  osg::ref_ptr<osg::Camera> getCamera() const; // 获取当前使用的相机

·  void setLightingMode(osg::View::LightingMode mode); // 设置光照模式

·  void setMultiThreaded(bool multiThreaded); // 启用或禁用多线程渲染

·  void setDrawFPS(bool drawFPS); // 是否在窗口显示帧率

·  bool getDrawFPS() const; // 获取是否显示帧率的设置

·  void setUpViewInWindow(int x, int y, int width, int height); // 设置窗口位置和大小

·  void setReleaseContextAtEndOfFrameHint(bool hint); // 控制 OpenGL 上下文在帧结束时是否释放

·  void setCameraManipulator(osgGA::CameraManipulator* manipulator); // 设置自定义相机操作器

七、OSG示例代码

  • 立方骰子

#include <osg/Group>

#include <osg/Geode>

#include <osg/MatrixTransform>

#include <osg/Texture2D>

#include <osgViewer/Viewer>

#include <osgDB/ReadFile>

#include <osgDB/WriteFile>

#include <osg/ref_ptr>

// 创建四边形面

//      pt1--------pt2

//      |           |

//      |           |

//      pt4-------pt3

osg::ref_ptr<osg::Geometry> createFace(osg::Vec3& pt1, osg::Vec3& pt2, osg::Vec3& pt3, osg::Vec3& pt4, std::string& filename)

{

    // 几何对象

    osg::ref_ptr<osg::Geometry> geom = new osg::Geometry();

    // 顶点数组

    osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array(6);

    (*vertices)[0] = pt1;

    (*vertices)[1] = pt2;

    (*vertices)[2] = pt3;

    (*vertices)[3] = pt3;

    (*vertices)[4] = pt4;

    (*vertices)[5] = pt1;

    geom->setVertexArray(vertices);

    // 纹理坐标数组

    osg::ref_ptr<osg::Vec2Array> texcoords = new osg::Vec2Array(6);

    (*texcoords)[0].set(0.0f, 1.0f);

    (*texcoords)[1].set(1.0f, 1.0f);

    (*texcoords)[2].set(1.0f, 0.0f);

    (*texcoords)[3].set(1.0f, 0.0f);

    (*texcoords)[4].set(0.0f, 0.0f);

    (*texcoords)[5].set(0.0f, 1.0f);

    geom->setTexCoordArray(0, texcoords);

    // 法线

    osg::Vec3 normal = (pt1 - pt2) ^ (pt3 - pt2);

    normal.normalize();

    osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array(1);

    (*normals)[0] = normal;

    geom->setNormalArray(normals, osg::Array::BIND_OVERALL);

    // 颜色数组

    osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);

    (*colors)[0].set(1.0f, 1.0f, 1.0f, 1.0f);

    geom->setColorArray(colors, osg::Array::BIND_OVERALL);

    // 绘制指令

    geom->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, 6));

    // 加载纹理

    osg::ref_ptr<osg::Image>pImage = osgDB::readRefImageFile(filename);

    if (pImage) {

        osg::Texture2D* texture = new osg::Texture2D;

        texture->setImage(pImage);

        osg::StateSet* stateset = geom->getOrCreateStateSet();

        stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);

    }

    return geom;

}

// 创建立方体

osg::ref_ptr<osg::Geode> createCube()

{

    osg::ref_ptr<osg::Geode> pGeode = new osg::Geode();

    {

        osg::Vec3 pt1(-1, -1, -1);

        osg::Vec3 pt2(1, -1, -1);

        osg::Vec3 pt3(1, 1, -1);

        osg::Vec3 pt4(-1, 1, -1);

        std::string imageFile = "./Images/6.png";

        osg::ref_ptr<osg::Geometry>pGeoBottom = createFace(pt1, pt2, pt3, pt4, imageFile);

        if (pGeoBottom) {

            pGeode->addChild(pGeoBottom);

        }

    }

    {

        osg::Vec3 pt1(-1, 1, 1);

        osg::Vec3 pt2(1, 1, 1);

        osg::Vec3 pt3(1, -1, 1);

        osg::Vec3 pt4(-1, -1, 1);

        std::string imageFile = "./Images/5.png";

        osg::ref_ptr<osg::Geometry>pGeoTop = createFace(pt1, pt2, pt3, pt4, imageFile);

        if (pGeoTop) {

            pGeode->addChild(pGeoTop);

        }

    }

    {

        osg::Vec3 pt1(-1, -1, 1);

        osg::Vec3 pt2(1, -1, 1);

        osg::Vec3 pt3(1, -1, -1);

        osg::Vec3 pt4(-1, -1, -1);

        std::string imageFile = "./Images/1.png";

        osg::ref_ptr<osg::Geometry>pGeoFront = createFace(pt1, pt2, pt3, pt4, imageFile);

        if (pGeoFront) {

            pGeode->addChild(pGeoFront);

        }

    }

    {

        osg::Vec3 pt1(1, 1, 1);

        osg::Vec3 pt2(-1, 1, 1);

        osg::Vec3 pt3(-1, 1, -1);

        osg::Vec3 pt4(1, 1, -1);

        std::string imageFile = "./Images/3.png";

        osg::ref_ptr<osg::Geometry>pGeoBack = createFace(pt1, pt2, pt3, pt4, imageFile);

        if (pGeoBack) {

            pGeode->addChild(pGeoBack);

        }

    }

    {

        osg::Vec3 pt1(-1, 1, 1);

        osg::Vec3 pt2(-1, -1, 1);

        osg::Vec3 pt3(-1, -1, -1);

        osg::Vec3 pt4(-1, 1, -1);

        std::string imageFile = "./Images/4.png";

        osg::ref_ptr<osg::Geometry>pGeoLeft = createFace(pt1, pt2, pt3, pt4, imageFile);

        if (pGeoLeft) {

            pGeode->addChild(pGeoLeft);

        }

    }

    {

        osg::Vec3 pt1(1, -1, 1);

        osg::Vec3 pt2(1, 1, 1);

        osg::Vec3 pt3(1, 1, -1);

        osg::Vec3 pt4(1, -1, -1);

        std::string imageFile = "./Images/2.png";

        osg::ref_ptr<osg::Geometry>pGeoRight = createFace(pt1, pt2, pt3, pt4, imageFile);

        if (pGeoRight) {

            pGeode->addChild(pGeoRight);

        }

    }

    return pGeode;

}

int main(int argc, char** argv)

{

    osg::ref_ptr<osg::Geode> pGeode = createCube();

    osgViewer::Viewer viewer;

    viewer.setSceneData(pGeode);

    return viewer.run();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值