【问题标题】:How to use a stencil buffer mask in ogre?如何在食人魔中使用模板缓冲区掩码?
【发布时间】:2011-11-30 18:51:11
【问题描述】:

如何使用模板缓冲区在 OGRE 中创建蒙版?

也就是说,一些对象应该首先渲染到模板缓冲区并生成一个掩码(比如0是背景,0xFF是前景);然后渲染场景本身,使用模板缓冲区作为掩码,因此仅渲染 0xFF 的像素。

我想我应该使用 RenderQueueListener,但我无法让它工作。这是我现在正在做的事情:

void StencilOpQueueListener::renderQueueStarted(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& skipThisInvocation) {
   if (queueGroupId == Ogre::RENDER_QUEUE_1) {
      Ogre::RenderSystem *rs = Ogre::Root::getSingleton().getRenderSystem();
      rs->clearFrameBuffer(Ogre::FBT_STENCIL, Ogre::ColourValue::Black, 1.0, 0xFF);
      rs->setStencilCheckEnabled(true);
      rs->_setColourBufferWriteEnabled(false, false, false, false);
      rs->setStencilBufferParams(
         Ogre::CMPF_ALWAYS_PASS, // compare
         0x1, // refvalue
         0xFFFFFFFF, // mask
         Ogre::SOP_REPLACE, Ogre::SOP_REPLACE, // stencil fail, depth fail
         Ogre::SOP_REPLACE, // stencil pass + depth pass
         false); // two-sided operation? no
   }
}

void StencilOpQueueListener::renderQueueEnded(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& repeatThisInvocation)  {
   if (queueGroupId == Ogre::RENDER_QUEUE_1)  {
      Ogre::RenderSystem *rs = Ogre::Root::getSingleton().getRenderSystem();
      rs->setStencilCheckEnabled(false);
      rs->setStencilBufferParams();
   }
}

我将应该渲染到模板缓冲区的实体设置为:

   entity->setRenderQueueGroup(RENDER_QUEUE_1);

我做错了什么?在 Ogre 中如何做到这一点的任何例子?谢谢!

作为参考,这是我在纯 OpenGL 中的做法:

/* Enable stencil test and leave it enabled throughout */
glClearStencil(0xFF);
glClearColor(1, 1, 1, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);
glStencilFunc(GL_ALWAYS, 0x1, 0xFFFFFFFF);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);

// render into the stencil buffer. This should render only the selector objects
renderStencil();

// restore the rendering
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);

// only render "inside" the silhouette -- we want the overlap
glStencilFunc(GL_EQUAL, 0x1, 0xFFFFFFFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

render(); // now we render objects against that mask

【问题讨论】:

    标签: ogre3d ogre


    【解决方案1】:

    你也应该综合你在

    中提到的第二步

    // 只渲染轮廓的“内部”——我们想要重叠

    glStencilFunc(GL_EQUAL, 0x1, 0xFFFFFFFF); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

    这意味着,您应该将在 RENDER_QUEUE_1 中设置的遮罩应用于渲染场景,就像在 gl 调用的情况下一样。默认情况下,主渲染发生在 Ogre 的 RENDER_QUEUE_MAIN 中,因此您应该将其添加到您的 renderQueueStarted 方法中:

    if (queueGroupId == Ogre::RENDER_QUEUE_MAIN)
    {
        Ogre::RenderSystem * rs = Ogre::Root::getSingleton().getRenderSystem();
        rs->_setColourBufferWriteEnabled(true, true, true, true);
        rs->setStencilCheckEnabled(true);
        rs->setStencilBufferParams(Ogre::CMPF_EQUAL,0x1,0xFFFFFFFF,
            Ogre::SOP_KEEP,Ogre::SOP_KEEP,Ogre::SOP_KEEP,false);     
    }
    

    另外,仅在主渲染完成后关闭 renderQueueEnded 中的模板:

    if ( queueGroupId == Ogre::RENDER_QUEUE_MAIN )
    {
        Ogre::RenderSystem *rs = Ogre::Root::getSingleton().getRenderSystem();
        rs->setStencilCheckEnabled(false);
        rs->setStencilBufferParams();
    }
    

    【讨论】:

    • 哇,四年后有人回答了!
    猜你喜欢
    • 1970-01-01
    • 2018-03-30
    • 2012-07-08
    • 2011-09-05
    • 1970-01-01
    • 2020-03-16
    • 2012-03-13
    • 1970-01-01
    • 2016-05-03
    相关资源
    最近更新 更多