0

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

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 个顶点。

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

4

3 回答 3

1

我目前看到两种方法来做到这一点。

  1. 如果您的“界面”完全是 2D 并直接映射到屏幕 - 您可以只使用屏幕坐标进行绘图。只需设置正确的正交矩阵,您的点击坐标将与 2D 元素坐标相同 - 简单范围比较(x < click_x < x+width)。请参阅 gluOrtho2D、glOrtho 手册(请注意,最新的 GL 配置文件中不提供 glOrtho 和其他矩阵函数)。

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

于 2013-10-03T03:44:11.943 回答
0

我从来没有在这里得到有用的答案,但我确实在第二天就弄清楚了。我的框是使用从 -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 处绘制我的盒子所需要做的所有事情,然后我可以在每次点击时简单地检查我的盒子的边界。

于 2013-11-12T17:07:56.133 回答
-1

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

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

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

于 2013-10-03T04:07:27.537 回答