首先我想提一下,我发现我认为是完全相同的问题,不幸的是没有答案,在这里: Java Using OpenGL Stencil to create Outline
我将在下面发布我的代码,但首先是问题所在:从这个捕获**,您可以看到整个框架结构正在显示,而不是球体周围的单线。我想摆脱里面的所有这些线条!
** 显然我无法添加图片:请参阅此链接 - 想象一个球体,四边形的所有边缘在 3 像素大线中可见。
http://srbwks36224-03.engin.umich.edu/kdi/images/gs_sphere_with_frame.jpg
这是给出该结果的代码:
// First render the sphere:
// inside "show" is all the code to display a textured sphere
// looking like earth
sphe->show();
// Now get ready for stencil buffer drawing pass:
// 1. Clear and initialize it
// 2. Activate stencil buffer
// 3. On the first rendering pass, we want to "SUCCEED ALWAYS"
// and write a "1" into the stencil buffer accordingly
// 4. We don't need to actually render the object, hence disabling RGB mask
glClearStencil(0); //Edit: swapped this line and below
glClear(GL_STENCIL_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_NEVER, 0x1, 0x1); //Edit: GL_ALWAYS
glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP); //Edit: GL_KEEP, GL_KEEP, GL_REPLACE
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE); // As per Andon's comment
sphe->show();
// At this point, I expect to have "1" on the entire
// area covered by the sphere, so...
// 1. Stencil test should fail for anything, but 0 value
// RM: commented is another option that should work too I believe
// 2. The stencil op instruction at the point is somewhat irrelevant
// (if my understanding is correct), because we won't do anything
// else with the stencil buffer after that.
// 3. Re-enable RGB mask, because we want to draw this time
// 4. Switch to LINE drawing instead of FILL and
// 5. set a bigger line width, so it will exceed the model boundaries.
// We do want this, otherwise the line would not show
// 6. Don't mind the "uniform" setting instruction, this is so
// that my shader knows it should draw in plain color
// 7. Draw the sphere's frame
// 8. The principle, as I understand it is that all the lines should
// find themselves matched to a "1" in the stencil buffer and therefore
// be ignored for rendering. Only lines on the edges of the model should
// have half their width not failing the stencil test.
glStencilFunc(GL_EQUAL, 0x0, 0x1);
//glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
glLineWidth(3);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
psa::shader::setUniform("outlining", 1);
sphe->show();
psa::shader::setUniform("outlining", 0);
现在只是为了证明一点,我厌倦了使用模板缓冲区做一些不同的事情 - 我只是想确保我的代码中的所有内容都到位,以便它工作。
** 不幸的是,我再次无法显示我得到的结果的屏幕截图:场景就像这样
http://mathworld.wolfram.com/images/eps-gif/SphereSphereInterGraphic_700.gif
但较小的球体是不可见的(RGB 蒙版已停用),并且可以通过孔看到世界背景(而不是更大的球体内部 - 面部剔除已停用)。
这就是代码……有趣的是,我可以更改很多东西,例如激活/停用 STENCIL_TEST,将操作更改为 GL_KEEP,甚至将第二个 stencilFunc 更改为“NOT EQUAL 0”……结果总是一样的!我想我在这里缺少一些基本的东西。
void testStencil()
{
// 1. Write a 1 in the Stencil buffer for
// every pixels of the first sphere:
// All colors disabled, we don't need to see that sphere
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 0x1, 0x1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE); // Edit: added this
{
sphe->W = mat4::trans(psa::vec4(1.0, 1.0, 1.0)) * mat4::scale(0.9);
sphe->show();
}
// 2. Draw the second sphere with the following rule:
// fail the stencil test for every pixels with a 1.
// This means that any pixel from first sphere will
// not be draw as part of the second sphere.
glStencilFunc(GL_EQUAL, 0x0, 0x1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE); // Edit: added this
{
sphe->W = mat4::trans(psa::vec4(1.2, 1.2, 1.2)) * mat4::scale(1.1);
sphe->show();
}
}
瞧!如果有人能指出我正确的方向,我将不胜感激。我还将确保将您的答案参考我找到的其他帖子。