osg重启图元

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

实现效果图

这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值