2种绘制几何体方式
osgearth提供简洁方式的AnnotationNode。CircleNodeEllipseNode FeatureNodeGeoPositionNode
ImageOverlayLableNode LocalGeometryNodePlaceNode
RectangleNode TrackNode
但有时候发现不好用,缺乏灵活性,如何是 new osgEarth::Features::Feature(new osgEarth::Symbology::Polygon,
会发现样式有很大的限制导致无法使用真正的面。
这时候有第二种方法使用原语操作geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
几何体的形状参数除了QUADS之外,还有数种方式,以用于不同的用户需求,列表如下:
和opengl对比:
osg::PrimitiveSet::POINTS对应OpenGL中的GL_POINTS绘制单独的点
osg::PrimitiveSet::LINES对应OpenGL中的GL_LINES绘制每两点连接的线
osg::PrimitiveSet::LINE_STRIP对应OpenGL中的GL_LINE_STRIP绘制依次连接各点的线
osg::PrimitiveSet::LINE_LOOP对应OpenGL中的GL_LINE_LOOP绘制依次连接各点的线,首尾相连
osg::PrimitiveSet::POLYGON对应OpenGL中的GL_POLYGON绘制依次连接各点的多边形
osg::PrimitiveSet::QUADS对应OpenGL中的GL_QUADS绘制依次连接每四点的四边形
如:1、2、3、4、5、6、7、8点 绘制结果1、2、3、4组成四边形,5、6、7、8组成四边形
osg::PrimitiveSet::QUAD_STRIP对应OpenGL中的GL_QUAD_STRIP绘制四边形
如:1、2、3、4、5、6、7、8点 绘制结果1、2、3、4组成四边形,3、4、5、6组成四边形、5、
6、7、8组成四边形
osg::PrimitiveSet::TRIANGLES对应OpenGL中的GL_TRIANGLES绘制每三点连接的三角形
如:1、2、3、4、5、6点 绘制结果1、2、3组成三角形,4、5、6组成三角形
osg::PrimitiveSet::TRIANGLE_STRIP对应OpenGL中的GL_TRIANGLE_STRIP
如:1、2、3、4、5、6点 绘制结果1、2、3组成三角形,2、3、4组成三角形,3、4、5组成三角
形4、5、6组成三角形
osg::PrimitiveSet::TRIANGLE_FAN对应OpenGL中的GL_TRIANGLE_FAN
如:1、2、3、4、5、6点 绘制结果1、2、3组成三角形,1、3、4组成三角形,1、4、5组成三角
形,1、5、6组成三角形
例子代码
enum Mode
{
POINTS = GL_POINTS,
LINES = GL_LINES,
LINE_STRIP = GL_LINE_STRIP,
LINE_LOOP = GL_LINE_LOOP,
TRIANGLES = GL_TRIANGLES,
TRIANGLE_STRIP = GL_TRIANGLE_STRIP,
TRIANGLE_FAN = GL_TRIANGLE_FAN,
QUADS = GL_QUADS,
QUAD_STRIP = GL_QUAD_STRIP,
POLYGON = GL_POLYGON,
LINES_ADJACENCY = GL_LINES_ADJACENCY,
LINE_STRIP_ADJACENCY = GL_LINE_STRIP_ADJACENCY,
TRIANGLES_ADJACENCY = GL_TRIANGLES_ADJACENCY,
TRIANGLE_STRIP_ADJACENCY = GL_TRIANGLE_STRIP_ADJACENCY,
PATCHES = GL_PATCHES
}; 四边形如下
osg::ref_ptr<osg::Node> GEOQuardTest::CreateNode()
{
osg::ref_ptr<osg::Group> _root = new osg::Group;
//创建一个叶结点对象
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
//创建一个几何体对象
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
//创建顶点数组,逆时针顺序
osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
//逆时针添加数据
v->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
v->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));
v->push_back(osg::Vec3(1.0f, 0.0f, 1.0f));
v->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
//设置顶点数据
geom->setVertexArray(v);
//创建颜色数组
osg::ref_ptr<osg::Vec4Array> vc = new osg::Vec4Array;
vc->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
vc->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
vc->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
vc->push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f));
//设置颜色数组
geom->setColorArray(vc);
//设置颜色绑定模式
geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
//创建法线数组
osg::ref_ptr<osg::Vec3Array> nc = new osg::Vec3Array;
//增加法线,几何体顶点都是是在XOZ面上,所以法线是Y轴
nc->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
//设置法线
geom->setNormalArray(nc);
//设置法线的绑定方式为全部节点
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
//添加图元,绘图基元为四边形,从第0个元素开始的四个元素,按照QUADS方式绘制四边形
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));
//添加到叶子节点中
geode->addChild(geom);
_root->addChild(geode);
return _root.get();
}
按照索引组织绘制数据,示例代码:
osg::ref_ptr<osg::Node> GEOQuardIndexTest::CreateNode()
{
osg::ref_ptr<osg::Group> _root = new osg::Group;
//创建一个叶结点对象
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
//创建一个几何体对象
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
//创建顶点数组,逆时针顺序
osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
//逆时针添加数据
v->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
v->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));
v->push_back(osg::Vec3(1.0f, 0.0f, 1.0f));
v->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
v->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
//设置顶点数据
geom->setVertexArray(v);
//创建四边形顶点索引数组,指定绘图基元为四边形
osg::ref_ptr<osg::DrawElementsUInt> quad = new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
//添加四边形的索引数据
quad->push_back(0);
quad->push_back(1);
quad->push_back(2);
quad->push_back(3);
//添加到几何体
geom->addPrimitiveSet(quad);
//创建三角形顶点索引数据,制定绘图基元为三角形
osg::ref_ptr<osg::DrawElementsUInt> tri = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
//添加数据
tri->push_back(4);
tri->push_back(0);
tri->push_back(3);
//添加到几何体
geom->addPrimitiveSet(tri);
//创建颜色数组
osg::ref_ptr<osg::Vec4Array> vc = new osg::Vec4Array;
vc->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
vc->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
vc->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
vc->push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f));
vc->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
//设置颜色数组
geom->setColorArray(vc);
//设置颜色绑定模式
geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
//创建法线数组
osg::ref_ptr<osg::Vec3Array> nc = new osg::Vec3Array;
//增加法线,几何体顶点都是是在XOZ面上,所以法线是Y轴
nc->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
//设置法线
geom->setNormalArray(nc);
//设置法线的绑定方式为全部节点
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
//添加到叶子节点中
geode->addChild(geom);
_root->addChild(geode);
return _root.get();
}
本帖最后由 liyihongcug 于 2020-4-16 10:45 编辑
补充:OSG中为了用户开发方便,已经内置了部分几何体,比如:立方体(osg::Box),椎体(osg::Cone),柱体(osg::Cylinder),球体(osg::Sphere)等。如果要渲染这些内嵌的几何体,可以将其与osg::ShapeDrawable关联来实现渲染。
在绘制这些内置几何体时候,对于趋近面,比如球体,圆柱等存在趋近面的时候,可以使用osg::TessellationHints网格化类来定义趋近面的精细程度,精细度越高细分越详细
www|qxqzx|com contents 303.html参考。
集合类
//geometry成员变量
PrimitiveSetList _primitives;
osg::ref_ptr<Array> _vertexArray; //顶点
osg::ref_ptr<Array> _normalArray; //法线
osg::ref_ptr<Array> _colorArray;//
osg::ref_ptr<Array> _secondaryColorArray;//
osg::ref_ptr<Array> _fogCoordArray;//
ArrayList _texCoordList;//纹理UV
ArrayList _vertexAttribList;//
bool _containsDeprecatedData; //
osgt文件中保存的格式:
osg::Geometry {
UniqueID 2
DataVariance STATIC
StateSet TRUE {
osg::StateSet {
UniqueID 3
DataVariance STATIC
AttributeList 1 {
osg::Material {
UniqueID 4
Ambient TRUE Front 1 1 1 1 Back 1 1 1 1
Diffuse TRUE Front 1 1 1 1 Back 1 1 1 1
Specular TRUE Front 0 0 0 1 Back 0 0 0 1
Emission TRUE Front 0 0 0 1 Back 0 0 0 1
Shininess TRUE Front 0 Back 0
}
Value OFF
}
TextureModeList 1 {
Data 1 {
GL_TEXTURE_2D ON
}
}
TextureAttributeList 1 {
Data 1 {
osg::Texture2D {
UniqueID 5
DataVariance STATIC
WRAP_S CLAMP
WRAP_T CLAMP
WRAP_R CLAMP
MIN_FILTER LINEAR
MAG_FILTER LINEAR
UnRefImageDataAfterApply TRUE
Swizzle RGBA
Image TRUE {
ClassName osg::Image
UniqueID 6
FileName "Tile_1_L23_000001001000_0.dds"
WriteHint 2 2
DataVariance STATIC
}
TextureWidth 1024
TextureHeight 1024
}
Value OFF
}
}
}
}
PrimitiveSetList 1 {
osg::DrawElementsUInt {
UniqueID 7
Mode TRIANGLES
vector 30450 {
........
}
}
}
VertexArray TRUE {
osg::Vec3Array {
UniqueID 8
Binding BIND_PER_VERTEX
vector 6681 {
........
}
}
}
TexCoordArrayList 1 {
osg::Vec2Array {
UniqueID 9
Binding BIND_PER_VERTEX
vector 6681 {
........
}
}
}
}
View Code
大致分析一下:
一个geometry包含:
一个stateset
一个primitive列表
一个顶点数组
一个纹理数组列表
stateset包含:attribute数组,纹理数组
primitive包含:绘制的图元信息:(绘制格式,顶点索引)
顶点数组包含:三维顶点位置信息
纹理数组包含:二维顶点UV信息
小tips:
osg::Geometry *geometry = geode->getDrawable(0)->asGeometry();
geometry->setDataVariance(osg::Object::DYNAMIC);
geometry->setUseVertexBufferObjects(true);
// 顶点数据
osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
// 法向量
osg::Vec3Array* normals = dynamic_cast<osg::Vec3Array*>(geometry->getNormalArray());
// 颜色
osg::Vec4Array* color = dynamic_cast<osg::Vec4Array*>(geometry->getColorArray());
(*color) = newColor;//错误哦
使用使用setVertexArray setNormalArray setColorArray
// 更新显示列表
geometry->dirtyDisplayList();
如果使用VBO来更新几何对象,需要使用Vec3Array::dirty()来将修改结果通知给VBO对象,这里使用
———————————————— 本帖最后由 liyihongcug 于 2020-4-23 16:49 编辑
实际使用 sg::PrimitiveSet::TRIANGLESFan
color绑定必须pl->setColorArray(vc);
pl->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
pl->dirtyDisplayList();
WEbgl的方式是使用primitive.更加灵活 学习了,厉害了
页:
[1]