查看: 1828|回复: 0

利用osg的双面模板缓冲技术实现剖切面填充问题

[复制链接]

该用户从未签到

发表于 2022-2-23 10:16:46 | 显示全部楼层 |阅读模式
用下面这段代码,对多个封闭实体构成的模型 m_vecBufferNode,用一个矩形面m_vecSurFillGeom[i]去切割模型,实现剖面的封闭。现在的问题是,剖面填充时,剖面范围是正确的的,但不能正确显示出每个剖面填充的颜色。图1-4是错误的剖面填充效果。想得到图5这样正确的填充效果(这是硬切出来的效果),请教各位,问题出在哪里?

//更新剖面填充面
void s3dDynamicCut::UpdateFillSur(osg::ref_ptr<osg::Vec3Array>& clipSurfPnts, double clipParam[4])
{
        int iTranNodeNum = m_vecBufferNode.size();

        osg::ref_ptr<osg::ClipPlane> curClipPlane = new osg::ClipPlane;
        curClipPlane->setClipPlane(clipParam[0], clipParam[1], clipParam[2], clipParam[3]);

        //清楚模板缓冲
        if (m_sceneCamera != NULL)
        {
                unsigned int clearMask = m_sceneCamera->getClearMask();
                m_sceneCamera->setClearMask(clearMask | GL_STENCIL_BUFFER_BIT);
                m_sceneCamera->setClearStencil(0);
        }
        //模型绘制模板
        osg::ref_ptr<osg::StencilTwoSided> cutBufferStencil1 = new osg::StencilTwoSided();
        cutBufferStencil1->setFunction(StencilTwoSided::BACK, osg::StencilTwoSided::ALWAYS, 0, 0xFF);
        cutBufferStencil1->setOperation(StencilTwoSided::BACK, osg::StencilTwoSided::INCR_WRAP, osg::StencilTwoSided::INCR_WRAP, osg::StencilTwoSided::INCR_WRAP);
        cutBufferStencil1->setFunction(StencilTwoSided::FRONT, osg::StencilTwoSided::ALWAYS, 0, 0xFF);
        cutBufferStencil1->setOperation(StencilTwoSided::FRONT, osg::StencilTwoSided:ECR_WRAP, osg::StencilTwoSided::DECR_WRAP, osg::StencilTwoSided::DECR_WRAP);

        //剖面填充计算模板
        osg::ref_ptr<osg::StencilTwoSided> cutBufferStencil2 = new osg::StencilTwoSided();
        cutBufferStencil2->setFunction(osg::StencilTwoSided::BACK, osg::StencilTwoSided::NOTEQUAL, 0, 0xFF);
        cutBufferStencil2->setOperation(StencilTwoSided::BACK, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::REPLACE);
        cutBufferStencil2->setFunction(osg::StencilTwoSided::FRONT, osg::StencilTwoSided::NOTEQUAL, 0, 0xFF);
        cutBufferStencil2->setOperation(StencilTwoSided::FRONT, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::REPLACE);

        //循环处理各个实体模型进行切割和剖面绘制
        for (int i = 0; i < iTranNodeNum; i++)
        {
                //1.设置模型节点的裁剪面,切割模型,保留一边
                m_vecBufferNode[i]-->getOrCreateStateSet()->setAttributeAndModes(curClipPlane, osg::StateAttribute::ON);
                m_vecBufferNode[i]->getOrCreateStateSet()->setRenderBinDetails(-10, "RenderBin");
                m_vecBufferNode[i]->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
                m_vecBufferNode[i]->getOrCreateStateSet()->setAttribute(colorMaskTmp, osg::StateAttribute::ON);

                //2. 先求出模型节点的模板缓冲(切面或盖子的地方为非0)               
                m_vecBufferNode[i]->getOrCreateStateSet()->setAttributeAndModes(cutBufferStencil1, osg::StateAttribute::ON);

                //3. 按照模型节点的颜色对剖面进行填充
                m_vecSurFillGeom[i]->setVertexArray(clipSurfPnts);        //设置剖面几何边界
                osgUtil::SmoothingVisitor::smooth(*m_vecSurFillGeom[i]);//计算剖面法向
                m_vecSurFillGeom[i]->getOrCreateStateSet()->setAttributeAndModes(cutBufferStencil2, osg::StateAttribute::ON);                //进行剖面填充
        }
动态剖切截图.png
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表