使用OpenGL中的AntiAliasing进行颜色选择?

时间:2011-05-25 10:13:10

标签: opengl antialiasing color-picker multisampling

我在OpenGL中遇到颜色选择和抗锯齿问题。当AA被激活时,glReadPixels的结果在对象边缘和对象交叉点上显然是错误的。例如:

我在框#32(RGBA:32,0,0,0)附近渲染框#28(RGBA:28,0,0,0)。使用AA,由于AA算法,我可以得到错误的ReadPixel值(例如30),其中立方体和三角形重叠,或者框边缘的值为14。

我需要能够选择~4万个物体(这是一个拼图游戏)。能够按形状选择对象至关重要。

我试图用glDisable(GL_MULTISAMPLE)禁用AA,但它不适用于某些AA模式(我读它取决于AA实现 - SS,MS,CS ..)

那么,我如何选择基础对象?

  1. 临时禁用AA的方式?
  2. 使用不同的缓冲区甚至渲染上下文?
  3. 还有其他建议吗?

2 个答案:

答案 0 :(得分:7)

为什么不使用FBO作为选择缓冲区?

答案 1 :(得分:1)

我使用这个黑客:不仅选择一个像素,而选择拾取点周围的所有3x3 = 9个像素。如果他们都一样,我们是安全的。否则,它必须处于边缘,我们可以跳过它。

int renderer::pick_(int x, int y)
{
    static_assert(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__,
            "only works on little-endian architecture");
    static_assert(sizeof(int) == 4,
            "only works on architecture that has int size of 4");

    // sort of edge detection. selection only happens at non-edge
    // since the edge may cause anti-aliasing glitch
    int ids[3*3];
    glReadPixels(x-1, y-1, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, ids);
    for (auto& id: ids) id &= 0x00FFFFFF;       // mask out alpha
    if (ids[0] == 0x00FFFFFF) return -1;        // pure white for background

    // prevent anti-aliasing glitch
    bool same = true;
    for (auto id: ids) same = (same && id == ids[0]);
    if (same) return ids[0];

    return -2;                                  // edge
}