Opengl 在三维视图中实现操纵手柄的方法

Opengl 在三维视图中实现操纵手柄的方法,opengl,3d,Opengl,3d,我正在构建一个简单的实体建模应用程序。用户需要能够在正交视图和透视视图中操作对象。例如,当屏幕上有一个框,用户点击它来选择它时,它需要在角落和中心获得“手柄”,以便用户可以将鼠标移动到这样的手柄上,并拖动它来放大或移动框 有什么策略可以做到这一点,哪一个是最好的?我可以想到两个明显的问题: 1) 将控制柄视为三维对象。例如,对于长方体,将小长方体添加到“主”长方体拐角处的场景中。问题:这在透视视图中不起作用,我需要确定框相对于当前缩放级别的大小(无论用户放大/缩小多远,控制柄都需要具有相同的大小

我正在构建一个简单的实体建模应用程序。用户需要能够在正交视图和透视视图中操作对象。例如,当屏幕上有一个框,用户点击它来选择它时,它需要在角落和中心获得“手柄”,以便用户可以将鼠标移动到这样的手柄上,并拖动它来放大或移动框

有什么策略可以做到这一点,哪一个是最好的?我可以想到两个明显的问题:

1) 将控制柄视为三维对象。例如,对于长方体,将小长方体添加到“主”长方体拐角处的场景中。问题:这在透视视图中不起作用,我需要确定框相对于当前缩放级别的大小(无论用户放大/缩小多远,控制柄都需要具有相同的大小)

2) 渲染场景后添加控制柄。渲染到屏幕外缓冲区,以某种方式确定角点的二维位置,并使用常规二维绘制技术绘制控制柄。问题:我将如何进行HIT测试?我还需要做一个两阶段的测试方法;如何在3d渲染图像上绘制2d?回到GDI

这两种方法可能都有更多的问题。有没有行业标准的方法来解决这个问题


如果有区别的话,我正在使用OpenGL。

我会将手柄视为3D对象。这提供了许多优点-更一致,它们表现良好,命中测试容易,等等

如果希望控制柄的大小保持不变,仍然可以将其视为三维对象,但必须根据到摄影机的距离适当缩放其大小。这有点麻烦,但由于通常只有几个句柄,而且这些句柄通常都是小对象,因此它的性能应该很好


然而,我实际上会说,让控制柄随着场景缩放。只要为控制柄选择使其突出的渲染样式(例如:亮橙色框等),透视效果(背景中较小的控制柄)实际上会使最终用户在许多方面更容易使用它们。很难从3D场景中获得深度感-手柄上的透视效果有助于提供更多关于手柄在屏幕中的“深度”的视觉线索。

首先,将手柄/角坐标投影到相机平面上(有效地将其转换为屏幕上的二维坐标;根据屏幕尺寸对其进行规范化。)

下面是一些启用正交/2D覆盖图形的简单代码:

void enable2D()
{

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    int wind[4];
    glGetIntegerv(GL_VIEWPORT,wind);
    glOrtho(0,wind[2],0,wind[3],-1,1);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
}


void disable2D()
{
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
}
enable2D()缓存当前modelview/投影矩阵,并将投影矩阵替换为与屏幕规格化的矩阵(即屏幕的宽度/高度),并恢复modelview的标识矩阵

进行此调用后,您可以使用屏幕/像素坐标进行glVertex2f()调用,允许您在2D中绘制!(这还允许您点击测试,因为您可以轻松获得鼠标的当前像素坐标。)

完成后,调用disable2D以恢复旧的modelview/投影矩阵:)

最困难的部分是计算命中框落在2D平面上的位置,并处理叠加(如果两个命中框投影到同一位置,单击时选择哪个?)


希望这有帮助:)

我为3d编辑软件包编写了一个带手柄的操纵器,遇到了很多同样的问题

首先,有一个开源操纵器。我在最近的搜索中找不到它,可能是因为这些东西的名字太多了——3d小部件、小发明、操纵器、万向节等等

无论如何,我这样做的方式是向场景添加一个操纵器对象,在绘制时,该对象会绘制所有控制柄。它对边界框计算和选择执行相同的操作


里德关于保持它们相同大小的想法对于存在于对象上的句柄来说很有趣,并且可能在那里起作用。对于操纵器,我发现它更像是一个3d UI元素,如果它不改变大小,它的可用性会更好。我有一个错误,大小仅根据活动视口确定,这导致在其他视口中出现可怕的大/小操纵器,非常无用。如果要将它们添加到场景中,可能需要按每个视口添加它们,或者使它们实际具有固定的大小。

我知道这个问题很老了。但万一有人需要它:


这篇文章很好,在底部有一个有趣的链接部分。

我明白你关于视角的观点,增加了视觉线索。我还不确信这对用户来说是自然的;例如,被其他对象剪裁的控制柄如何?我将检查其他一些3d建模者,看看他们是如何做到这一点的,并在我的测试应用程序中尝试这两种方法。感谢您花时间回答。一个选项是允许透视图保留,但在关闭深度测试的情况下最后渲染这些透视图。它们将始终可见(即使在其他对象的顶部)。我不会将其作为默认方式,但这是一个很好的选项,因此您可以打开/关闭是否始终显示句柄,即使是“通过”对象。我仍然需要了解深度缓冲区是如何工作的,但我认为这是可行的。我有很多尝试和错误摆在我面前:)谢谢。好吧,在这种情况下,你应该关闭对深度缓冲区的写入和测试-基本上,它总是画出你的对象(在所有其他东西之上)。它不太直观,但作为一个切换/选项很有用。在我上一次作为3D应用程序的作者时,我们使用了这种方法,效果很好。不过我不会关闭深度测试。这看起来是一种非常有用的技术,我可以在代码的许多其他地方使用,谢谢!我对OpenGL还很陌生,所以我仍然在学习一些诀窍,技巧和技巧,像这样的东西似乎很难找到。非常感谢。你能解释一下你的“操纵者”是干什么的吗?看起来不一样