3

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

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

我有大约 400 万件我需要能够挑选的物品(这是一个拼图游戏)。能够按形状选择对象至关重要。

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

那么,我该如何选择一个底层对象呢?

  1. 暂时禁用AA的方法?
  2. 使用不同的缓冲区甚至渲染上下文?
  3. 还有什么建议吗?
4

2 回答 2

7

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

于 2011-05-25T11:30:40.007 回答
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
}
于 2015-04-12T09:51:15.980 回答