osg重启图元
OpenGL重启图元
opengl中相关的重启图元函数
- glEnable(GL_PRIMITIVE_RESTART)
- glPrimitiveRestartIndex(GLuint index)
- OpenGL3.1以上版本
当需要绘制大量相同类型的图元,例如GL_TRIANGLE_STRIP,GL_QUAD_STRIP,使用glDrawElement函数时,需要在特定索引位置重启图元,这个特定索引位置的值一般取值为索引数据类型的最大值,如无符号短整形设置为0xffff。
OSG重启图元
OSG中封装相应的重启图元命令
- 开启状态GL_PRIMITIVE_RESTART
- 使用状态属性osg::PrimitiveRestartIndex
- 重启索引值不能设定为数据类型的最大值,并且重启索引位置必须有对应的顶点值,否则在顶点遍历计算时取此索引值会因为不在顶点数组内存而挂掉
OSG重启图元实现
//画球的网格
#if 1
int verNums = 15 + 3*((int)_radarStyle->getSphereFrameEMax() - (int)_radarStyle->getSphereFrameEMin())/90;//根据角度大小调整密度
const float azIncr = (azMax - azMin)/verNums;
const float elevIncr = (elevMax - elevMin)/verNums;
osg::Vec3Array* varr = new osg::Vec3Array(verNums*verNums+1);
for(int i=0; i<verNums; i++)
{
float az = azMin + (i*azIncr);
for (int j=0; j<verNums; j++)
{
float elev = elevMin + (j*elevIncr);
// QuadStrip Edge formed at az
// ----------------------------
// Work out the sphere normal
float x = cos(elev)*sin(az);
float y = cos(elev)*cos(az);
float z = sin(elev);
(*varr)[i*verNums + j].set(4990*x, 4990*y, 4990*z);
}
}
//restart vertex index can't be 0xffff, take max index value;
(*varr)[verNums*verNums].set(0.0, 0.0, 0.0);
osg::DrawElementsUInt* indices = new osg::DrawElementsUInt(osg::PrimitiveSet::QUAD_STRIP, 2*verNums*verNums+verNums-1);
int restartIndex = 0;
//first quad strip
for (int j=0;j<verNums;j++)
{
(*indices)[j*2] = j;
(*indices)[j*2+1] = verNums+j;
}
for (int i = 1; i < verNums-1; i++)
{
restartIndex += 2*verNums;
(*indices)[restartIndex] = verNums*verNums;
restartIndex++;
for (int j=0;j<verNums;j++)
{
(*indices)[restartIndex + j*2] = verNums*i + j;
(*indices)[restartIndex + j*2+1] = verNums*i + verNums+j;
}
}
//close last
restartIndex += 2*verNums;
(*indices)[restartIndex] = verNums*verNums;
restartIndex++;
for (int j=0;j<verNums;j++)
{
(*indices)[restartIndex + j*2] = verNums * (verNums-1) + j;
(*indices)[restartIndex + j*2+1] = j;
}
osg::Vec4Array* colours = new osg::Vec4Array(1);
(*colours)[0] = _radarStyle->getSphereSideColor();
osg::Geometry* geom=new osg::Geometry;
geom->setVertexArray(varr);
geom->setColorArray(colours, osg::Array::BIND_OVERALL);
geom->addPrimitiveSet(indices);
geom->setUseVertexBufferObjects(true);
{
osg::StateSet* stateset=new osg::StateSet();
osg::PolygonMode* pm = new osg::PolygonMode(osg::PolygonMode::Face::FRONT_AND_BACK,osg::PolygonMode::Mode::LINE);
stateset->setAttributeAndModes(pm,osg::StateAttribute::ON);
stateset->setAttributeAndModes(new osg::LineWidth(3.0f), osg::StateAttribute::ON);
stateset->setMode(GL_PRIMITIVE_RESTART, osg::StateAttribute::ON);
stateset->setAttributeAndModes(new osg::PrimitiveRestartIndex(verNums*verNums), osg::StateAttribute::ON);
geom->setStateSet(stateset);
}
osg::Geode* geode = new osg::Geode;
geode->addDrawable(geom);
radarSphere->addChild(geode);
#endif