【发布时间】:2019-05-22 16:52:28
【问题描述】:
我正在尝试实现选择轮廓功能。这就是我现在所做的。
如您所见,当鼠标悬停并在所选对象周围绘制轮廓时,对象被正确选择。
我现在想做的就是用这种方式勾勒出物体的可见边缘
左图是我现在拥有的,右图是我想要实现的。
这是我现在使用的程序。
void paintGL()
{
/* ... */
int w = geometry().width();
int h = geometry().height();
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilMask(0xFF);
setClearColor(Qt::GlobalColor::darkGray);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glStencilMask(0x00);
DrawGeometry();
if (HoveredSphere != RgbFromColorToString(Qt::GlobalColor::black))
{
glBindFramebuffer(GL_FRAMEBUFFER, addFBO(FBOIndex::OUTLINE));
{
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilMask(0xFF);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
DrawOutline(HoveredSphere, 1.0f - 0.025f);
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
glBindFramebuffer(GL_READ_FRAMEBUFFER, addFBO(FBOIndex::OUTLINE));
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, defaultFramebufferObject());
{
// copy stencil buffer
GLbitfield mask = GL_STENCIL_BUFFER_BIT;
glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, mask, GL_NEAREST);
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
glStencilMask(0x00);
glDepthFunc(GL_LEQUAL);
DrawOutline(HoveredSphere, 1.0f);
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
}
update();
}
其中DrawGeometry 绘制所有对象,DrawOutline 绘制选定对象,该对象按作为第二个参数传递的因子缩放。
感谢您的任何建议。
【问题讨论】:
-
我能想到的两种方法:一种方法是预先计算形状重叠的“环”,然后使用 GL_LINES 或类似方法绘制该环。另一种方法是首先将图像渲染到帧缓冲区,其中突出显示的形状获得特殊值,然后使用 Sobel 运算符对其进行后处理。
-
@MichaelMahn 谢谢!我喜欢环的想法,我想尝试实现它,但我有一些疑问。第一次表演。最终场景有 1000 个球体,我应该计算每个可能的交叉点。这是我在加载模型时可以离线执行 1 次的事情。第二环近似。 GL_LINES 只能给出一个圆的近似值,而我将球体描述为冒名顶替者(使用光线追踪),获得“完美”球体。我应该找到一种方法来描绘一个“完美”的戒指。我不太喜欢 sobel-idea,因为我不知道用这种方法是否能得到正确的结果。
-
@Arctic Pi 是的,如果你能离线做一次,戒指的事情肯定会更好。如果您的球体移动并且您必须每帧执行一次,则必须考虑性能。如果我没有误解您的问题,Sobel 运算符也应该可以工作。您可以使用已有的模板缓冲区,如果片段由突出显示的球体渲染,并且至少有一个相邻片段不是,则该片段必须使用轮廓颜色。
-
@MichaelMahn 非常感谢您的回答。你给了我一个关于如何实现目标的想法,我做到了。今天下午,我将在问题的答案中向您展示结果。我仍然需要改进,为此我会在我的回答中要求您提供提示。再次感谢!
标签: c++ opengl graphics highlight outlining