osg中有三大节点:Node,Goup,Geode
Geode作为叶节点,用于保存几何信息以便渲染。Geode节点下的Billboard类,为布告板技术,共有三种模式,视点模式,世界模式和轴模式。当设置为视点模式时,视点发生改变,物体的坐标位置也发生变化,保证物体一直面向视点。当设置为绕轴旋转时,物体围绕轴进行旋转,设置为绕世界旋转时,会绕x,y,z轴旋转。
//创建Billboard对象
osg::ref_ptr billboard1 = new osg::Billboard();
//设置旋转模式为绕视点(绕视点,绕世界轴,绕轴共有三种模式)
billboard1->setMode(osg::Billboard::POINT_ROT_EYE);
billboard1->addDrawable(geom.get());
osg::ref_ptr billboard2 = new osg::Billboard();
billboard2->setMode(osg::Billboard::AXIAL_ROT);
billboard2->setAxis(osg::Vec3(0.0f, 0.0f, 1.0f));
billboard2->addDrawable(geom.get());
osg::ref_ptr billboard3 = new osg::Billboard();
billboard3->setMode(osg::Billboard::POINT_ROT_WORLD);
billboard3->addDrawable(geom.get());
osg::ref_ptr billboard = new osg::Group();
billboard->addChild(billboard3.get());
billboard->addChild(billboard2.get());
billboard->addChild(billboard1.get());
绘制一个几何体如下:
osg::ref_ptr geom = new osg::Geometry();//定义一个几何体
//首先定义四个点
osg::ref_ptr v = new osg::Vec3Array();//定义一个几何体坐标集合
v->push_back(osg::Vec3(-1.0, 0.0, -1.0));//左下角坐标点
v->push_back(osg::Vec3(1.0, 0.0, -1.0));//右下角坐标点
v->push_back(osg::Vec3(1.0, 0.0, 1.0));//右上角坐标点
v->push_back(osg::Vec3(-1.0, 0.0, 1.0));//左上角坐标点
geom->setVertexArray(v.get());//将坐标设置到几何体节点中
//定义颜色数组
osg::ref_ptr c = new osg::Vec4Array();//定义一个颜色数组颜色
c->push_back(osg::Vec4(1.0, 0.0, 0.0, 1.0));//数组的四个参数分别为RGBA,其中A表示透明度
c->push_back(osg::Vec4(0.0, 1.0, 0.0, 1.0));
c->push_back(osg::Vec4(0.0, 0.0, 1.0, 1.0));
c->push_back(osg::Vec4(1.0, 1.0, 1.0, 1.0));
geom->setColorArray(c.get());//与几何体中进行关联
geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);//设置绑定方式为逐点绑定。
//定义法线
osg::ref_ptr n = new osg::Vec3Array();//定义了一个法线绑定到该四方体中
n->push_back(osg::Vec3(0.0, -1.0, 0.0));//法线为指向Y轴负半轴
geom->setNormalArray(n.get());//添加法线到几何体中
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);//将法线进行绑定
//设置顶点的关联方式,这里是Quad方式,总共有这么些方式:POINTS,LINES,LINE_STRIP,LINE_LOOP,TRIANGLES,TRIANGLE_STRIP,TRIANGLE_FAN,QUADS,QUAD_STRIP,POLYGON
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));
修改模型位置
//初始化位置变换节点
osg::PositionAttitudeTransform* pyramidTwoXForm = new osg::PositionAttitudeTransform();
//使用osg::Group的addChild方法,将位置变换节点添加到根节点的子节点上,并将金字塔节点作为变换节点的子节点
root->addChild(pyramidTwoXForm);
pyramidTwoXForm->addChild(pyramidGeode);
另外一种绘制几何体的方法
osg::Group* root = new osg::Group();
osg::Geode* pyramidGeode = new osg::Geode();
osg::Geometry* pyramidGeometry = new osg::Geometry();
pyramidGeode->addDrawable(pyramidGeometry);
root->addChild(pyramidGeode);
osg::Vec3Array* pyramidVertices = new osg::Vec3Array;//设置四点点坐标
pyramidVertices->push_back(osg::Vec3(0, 0, 0)); // 左前
pyramidVertices->push_back(osg::Vec3(10, 0, 0)); // 右前
pyramidVertices->push_back(osg::Vec3(10, 10, 0)); // 右后
pyramidVertices->push_back(osg::Vec3(0, 10, 0)); // 左后
pyramidVertices->push_back(osg::Vec3(5, 5, 10)); // 塔尖
pyramidGeometry->setVertexArray(pyramidVertices);
osg::DrawElementsUInt* pyramidBase = new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);//绘制地面
pyramidBase->push_back(3);
pyramidBase->push_back(2);
pyramidBase->push_back(1);
pyramidBase->push_back(0);
pyramidGeometry->addPrimitiveSet(pyramidBase);
osg::DrawElementsUInt* pyramidFaceOne = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);//绘制其中一个面
pyramidFaceOne->push_back(0);
pyramidFaceOne->push_back(1);
pyramidFaceOne->push_back(4);
pyramidGeometry->addPrimitiveSet(pyramidFaceOne);
osg::DrawElementsUInt* pyramidFaceTwo = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
pyramidFaceTwo->push_back(1);
pyramidFaceTwo->push_back(2);
pyramidFaceTwo->push_back(4);
pyramidGeometry->addPrimitiveSet(pyramidFaceTwo);
osg::DrawElementsUInt* pyramidFaceThree = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
pyramidFaceThree->push_back(2);
pyramidFaceThree->push_back(3);
pyramidFaceThree->push_back(4);
pyramidGeometry->addPrimitiveSet(pyramidFaceThree);
osg::DrawElementsUInt* pyramidFaceFour = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
pyramidFaceFour->push_back(3);
pyramidFaceFour->push_back(0);
pyramidFaceFour->push_back(4);
pyramidGeometry->addPrimitiveSet(pyramidFaceFour);//为几何体对象添加图元
// 定义一个Vec4的数组,用于保存颜色值。
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); //索引0 红色
colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); //索引1 绿色
colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); //索引2 蓝色
colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); //索引3 白色
osg::TemplateIndexArray *colorIndexArray;
colorIndexArray = new osg::TemplateIndexArray;
colorIndexArray->push_back(0); // vertex 0 assigned color array element 0
colorIndexArray->push_back(1); // vertex 1 assigned color array element 1
colorIndexArray->push_back(2); // vertex 2 assigned color array element 2
colorIndexArray->push_back(3); // vertex 3 assigned color array element 3
colorIndexArray->push_back(0); // vertex 4 assigned color array element 0
pyramidGeometry->setColorArray(colors);
//pyramidGeometry->setcolor(colorIndexArray);
pyramidGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);//为几何体对象添加颜色
osg::Vec2Array* texcoords = new osg::Vec2Array(5);//定义一个vec2数组存储纹理
(*texcoords)[0].set(0.00f, 0.0f);
(*texcoords)[1].set(0.25f, 0.0f);
(*texcoords)[2].set(0.50f, 0.0f);
(*texcoords)[3].set(0.75f, 0.0f);
(*texcoords)[4].set(0.50f, 1.0f);
pyramidGeometry->setTexCoordArray(0, texcoords);//为几何体对象绑定纹理
关于颜色,纹理,法线与坐标顶点的绑定方式,如果选择按照顶点绑定,那么osg3.0版本下会根据数组顺序按照顺序绑定,如果顶点数组元素数大于颜色数组颜色数,那么剩下的顶点绑定的颜色默认为黑色,纹理和法线的绑定方式相同。