【OSG学习笔记】Day 6: Day 6: 几何体(Geometry)的创建与自定义
今天学习下几何体的创建,也就是Geometry 。
学习之前我们先来回想一下右手坐标系:
OSG 是右手坐标系,坐标轴定义如下:
- X 轴:向右(屏幕右侧)
- Y 轴:向前(垂直于屏幕向里)
- Z 轴:向上(垂直屏幕向上)
所以如果我们想直观的看到效果需要定义X、Z轴来实现几何体。
Geometry
在OSG中有个osg::Geometry
类来操作几何体。
osg::Geometry
是 OpenSceneGraph(OSG)中一个非常重要的类,它用于表示和管理 3D 几何数据,是构建复杂 3D 场景的基础元素之一。
主要功能
-
存储几何数据:可以存储顶点、法线、纹理坐标、颜色等几何数据,这些数据定义了 3D 物体的形状、外观和朝向等属性。
-
渲染控制:通过设置不同的渲染模式(如点、线、三角形等),控制几何数据的渲染方式。
-
状态管理:可以关联材质、纹理等状态属性,从而为几何对象赋予特定的外观效果。
关键组成部分
- 顶点数组(Vertex Array):存储几何图形的顶点坐标,确定了物体的形状。
- 法线数组(Normal Array):定义每个顶点的法线方向,用于光照计算,决定物体表面的明暗效果。
- 纹理坐标数组(Texture Coordinate Array):为每个顶点指定纹理坐标,用于将纹理映射到物体表面。
- 颜色数组(Color Array):存储每个顶点的颜色信息,可用于实现顶点着色效果。
- 图元集(PrimitiveSet):指定如何将顶点组合成图元(如点、线、三角形等)进行渲染
对比项 | osg::Geometry | osg::Geode | osg::Group |
---|---|---|---|
类型 | 可绘制对象类 | 场景图节点类 | 场景图节点类 |
作用 | 表示和管理 3D 几何数据,定义物体形状、外观和朝向等属性 | 作为可绘制对象的容器,将具体渲染内容集成到场景中 | 组织和管理子节点,构建复杂的场景图结构 |
存储内容 | 顶点、法线、纹理坐标、颜色等几何数据,以及图元集 | 一个或多个 osg::Drawable 对象,如 osg::Geometry 、osg::ShapeDrawable 等 | 一个或多个子节点,这些子节点可以是 osg::Geode 或其他 osg::Group 节点 |
使用场景 | 需要创建自定义几何形状,如三角形、立方体、球体等,并进行精细渲染控制时 | 需要将多个可绘制对象组合在一起,作为整体进行管理和渲染时 | 构建复杂的场景层次结构,对不同场景元素进行分组管理,或实现场景的动态更新和变换时 |
代码实现
ok,基础知识看差不多了,下面来看下代码实现。
开始构建前,我们先了解下构建流程:
- 创建节点和几何对象:创建了一个 osg::Geode 节点和一个 osg::Geometry 对象。
- 设置顶点数组:创建了一个包含三个顶点的顶点数组,并将其设置给 Geometry 对象。
- 设置颜色数组:创建了一个颜色数组,并将其设置为整体绑定模式,即整个三角形使用相同的颜色。
- 设置图元集:使用 osg::DrawArrays 创建一个三角形图元集,并添加到 Geometry 对象中。
- 添加到场景并渲染:将 Geometry 对象添加到 Geode 节点中,然后将 Geode 节点设置为场景数据,最后运行 Viewer 进行渲染。
geometry.cpp
#include <osg/Geometry>
#include <osg/Geode>
#include <osgViewer/Viewer>
#include <osg/LineWidth>
#include <osg/Point>// 创建三角形几何体
osg::Geometry* createTriangle()
{osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;// 顶点数组 (XYZ坐标)osg::Vec3Array* vertices = new osg::Vec3Array;vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f)); // 顶点1vertices->push_back(osg::Vec3(2.0f, 0.0f, 0.0f)); // 顶点2vertices->push_back(osg::Vec3(1.0f, 0.0f, 2.0f)); // 顶点3geom->setVertexArray(vertices);// 颜色数组 (RGBA)osg::Vec4Array* colors = new osg::Vec4Array;colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); // 红色geom->setColorArray(colors);geom->setColorBinding(osg::Geometry::BIND_OVERALL);// 设置图元类型为三角形geom->addPrimitiveSet(new osg::DrawArrays