mycug 发表于 2022-2-23 10:16:46

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

用下面这段代码,对多个封闭实体构成的模型 m_vecBufferNode,用一个矩形面m_vecSurFillGeom去切割模型,实现剖面的封闭。现在的问题是,剖面填充时,剖面范围是正确的的,但不能正确显示出每个剖面填充的颜色。图1-4是错误的剖面填充效果。想得到图5这样正确的填充效果(这是硬切出来的效果),请教各位,问题出在哪里?

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

        osg::ref_ptr<osg::ClipPlane> curClipPlane = new osg::ClipPlane;
        curClipPlane->setClipPlane(clipParam, clipParam, clipParam, clipParam);

        //清楚模板缓冲
        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::DECR_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-->getOrCreateStateSet()->setAttributeAndModes(curClipPlane, osg::StateAttribute::ON);
                m_vecBufferNode->getOrCreateStateSet()->setRenderBinDetails(-10, "RenderBin");
                m_vecBufferNode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
                m_vecBufferNode->getOrCreateStateSet()->setAttribute(colorMaskTmp, osg::StateAttribute::ON);

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

                //3. 按照模型节点的颜色对剖面进行填充
                m_vecSurFillGeom->setVertexArray(clipSurfPnts);        //设置剖面几何边界
                osgUtil::SmoothingVisitor::smooth(*m_vecSurFillGeom);//计算剖面法向
                m_vecSurFillGeom->getOrCreateStateSet()->setAttributeAndModes(cutBufferStencil2, osg::StateAttribute::ON);                //进行剖面填充
        }
页: [1]
查看完整版本: 利用osg的双面模板缓冲技术实现剖切面填充问题