【问题标题】:Clicking on a Quad and getting screen coords in opengl单击 Quad 并在 opengl 中获取屏幕坐标
【发布时间】:2013-10-03 01:08:00
【问题描述】:

假设我像这样制作一个四边形:

float botBaseY = -0.5;
glBegin(GL_QUADS); // Box
    glVertex2f(-.05, botBaseY + -.05);
    glVertex2f(-.05, botBaseY + .05);
    glVertex2f(.05, botBaseY + .05);
    glVertex2f(.05, botBaseY + -.05);
glEnd();

好的,现在说我想确定用户是否在该四边形内部单击。 那么当你点击时,你会收到屏幕坐标,所以如果你的主窗口是 600x600 像素,那么您的点击将产生小于 600 的 x 和 y 值。 但我将点击(375,400)与使用创建的四边形进行比较 从 -1.0 到 1.0 的值来定义 4 个顶点。

如何确定用户是否在四边形内部单击?

【问题讨论】:

  • 你在考虑这个问题。当您单击某处时,您已经有了屏幕坐标。你想要做的只是检测点击的点是否在四边形内(它覆盖了标准化设备空间的一小部分,如果它是屏幕对齐的,那就更容易了)。您应该能够使用视口转换的逆来做到这一点。

标签: opengl opengl-1.x


【解决方案1】:

我目前看到了两种方法。

  1. 如果您的“界面”完全是 2D 并直接映射到屏幕 - 您可以只使用屏幕坐标进行绘图。只需设置正确的正交矩阵,您的点击坐标将与 2D 元素坐标相同 - 简单的范围比较(x

  2. 如果第一个变体不适合您的情况 - 您需要将 2D 坐标映射到查看空间并将结果点用作光线方向。然后跟踪该射线与您要单击的元素平面的交点。看看http://www.toymaker.info/Games/html/picking.html - d3d 没关系,数学总是一样的)。然后,当您在您感兴趣的平面上获取结果点击点时 - 它再次只是范围比较(尽管如果您的平面不平行于屏幕会有点棘手 - 但我认为它仍然不是同样的问题)。

【讨论】:

    【解决方案2】:

    我从来没有在这里得到有用的答案,但我确实在第二天弄明白了。我的框是使用从 -1 到 1 的坐标绘制的。但我的点击有大屏幕坐标,例如 200,300。我需要知道如何将 -1 到 1 转换为屏幕坐标,或者如何仅绘制兼容坐标。

    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0, 400, 0, 400);
    glBegin(GL_QUADS); // Box
        glVertex2f(xOffset + topBaseX + -15, topBaseY + -15);// bottom left vert
        glVertex2f(xOffset + topBaseX + -15, topBaseY + 15); // top left vert
        glVertex2f(xOffset + topBaseX + 15, topBaseY + 15);// top right vert
        glVertex2f(xOffset + topBaseX + 15, topBaseY + -15);// bottom right vert
    glEnd();
    glLoadIdentity();
    

    这就是我在大约 200,300 处绘制我的框所需要做的所有事情,然后我可以在每次点击时简单地检查我的框的边界。

    【讨论】:

      【解决方案3】:

      最简单、最准确(但不一定最有效)的方式:

      再次渲染场景(到屏幕外缓冲区),目标对象为白色,其他所有对象为黑色。如果光标下的像素是白色的,则目标被单击。如果您希望能够点击某些透明材质,只需跳过渲染这些对象即可。

      为了提高效率,您可以关闭混合并为每个对象使用唯一的颜色(可能是索引)。并使用新的 OpenGL 功能在正常渲染期间填充选取器颜色平面,而不是进行额外的传递。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-29
        • 1970-01-01
        • 2011-11-21
        • 2017-12-11
        • 1970-01-01
        • 2015-06-29
        • 1970-01-01
        • 2012-02-02
        相关资源
        最近更新 更多