2011-11-30 90 views
2

如何使用模板缓冲区在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 

回答

1

你应该综合第二步还有,你在

//只渲染“内部”提到剪影 - 我们希望重叠

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

这意味着,您应该将您在RENDER_QUEUE_1中设置的遮罩应用于渲染的场景,就像您在gl调用时所做的一样。主要呈现发生在食人魔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(); 
} 
+1

哇,四年后有人回答! – brunobg