我用轮廓渲染四边形。我通过将所需大小的四边形渲染为黑色,然后渲染"内部" quad比第一个小。我还希望这个概述的四边形是透明的。
我当前的尝试呈现如此:
http://i39.tinypic.com/2eq993s.png
然而我遇到的问题是,因为我基本上将两个四边形渲染在一起,所以黑色" main" quad融合到较小的"内部"四。我不希望这种情况发生,因为我希望混合只混合背景和内部"四色。
除了为轮廓渲染单独的四边形/三角形之外,有一种方法(理想情况下不使用着色器,因为我使用固定管道)使混合忽略/不渲染" main"混合"内部"四
相关代码:
混合模式:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable( GL_BLEND );
渲染方框:
struct vertex
{
GLfloat x,y;
};
void draw_box()
{
glPushMatrix();
glTranslatef( -3.0f, 1.12f, 1.0f );
// Draw a huge black quad
const vertex vertices2[] =
{
{ -1.0f, -1.0f },
{ 0.0f, 0.0f },
{ -1.0f, 0.0f },
{ -1.0f, -1.0f },
{ 0.0f, 0.0f },
{ 0.0f, -1.0f },
};
glVertexPointer(2, GL_FLOAT, 0, vertices2);
glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
glDrawArrays(GL_TRIANGLES, 0, 6);
// Draw a smaller grey quad
const GLfloat space = 0.04f;
const vertex vertices3[] =
{
{ -1.0f+space, -1.0f+space },
{ 0.0f-space, 0.0f-space },
{ -1.0f+space, 0.0f-space },
{ -1.0f+space, -1.0f+space },
{ 0.0f-space, 0.0f-space },
{ 0.0f-space, -1.0f+space },
};
glVertexPointer(2, GL_FLOAT, 0, vertices3);
glColor4f(0.5f, 0.5f, 0.5f, 0.5f);
glDrawArrays(GL_TRIANGLES, 0, 6);
glPopMatrix();
}
答案 0 :(得分:3)
这样做的最好方法可能就是将边框分成四个梯形四边形,但是既然你明确提到你不想沿着这条路走下去,那么你可以选择其他几个选项。
下一个最好的方法可能是使用深度缓冲区:glEnable(GL_DEPTH_TEST)
。首先绘制内部四边形(启用混合)。然后绘制外部四边形,但使用坐标使其深度大于第一个四边形(它“更远”)。如果在绘制边框四边形时启用深度测试,则对于您已绘制的四边形将失败,因为这些像素的深度值较小。请注意,使用此方法时,如果在渲染这些四边形后面的内容时写入深度缓冲区,则可能会遇到一些问题,其中部分背景被认为比新四边形更接近。您可以通过将深度测试配置为始终成功来解决内部四边形问题,即使测试失败也是如此:glDepthFunc(GL_ALWAYS)
。然而,这对外部四边形没有帮助。在这种情况下,下一个方法可能会有所帮助:
您可以以类似于深度缓冲区的方式使用模板缓冲区。渲染内部四边形时,将模板值(或至少一个位)设置为特定值:
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 1, GLuint(-1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
然后,当您绘制外部四边形时,仅在片段没有该值时才配置模板测试成功:
glStencilFunc(GL_NOT_EQUAL, 1, 1);
基本上,这与上面的版本使用深度缓冲区相同,但使用模板缓冲区。您可能需要查看glStencilFunc和glStencilOp的文档。
可能还有其他方法可以实现此行为,但我能想到的所有其他解决方案都涉及使用您指定的自定义着色器,这是不可接受的。就个人而言,我只是将边界分成4个四边形。当然,它比其他方法多3个四边形,但它不需要任何额外的OpenGL功能或状态变化。