关于c ++:OpenGL – 让对象跟随鼠标

OpenGL - have object follow mouse

我想在OpenGL的屏幕上让一个对象跟随我的鼠标。(我也在使用glew、glfw和glm)。我想到的最好办法是:

使用glfwgetcursorpos获取窗口内的坐标。

窗口是用创建的

1
window = glfwCreateWindow( 1024, 768,"Test", NULL, NULL);

得到坐标的代码是

1
2
double xpos, ypos;
glfwGetCursorPos(window, &xpos, &ypos);

接下来,我使用glm unproject获取"对象空间"中的坐标。

1
2
3
glm::vec4 viewport = glm::vec4(0.0f, 0.0f, 1024.0f, 768.0f);
glm::vec3 pos = glm::vec3(xpos, ypos, 0.0f);
glm::vec3 un = glm::unProject(pos, View*Model, Projection, viewport);

我已经看到两个潜在的问题。视区很好,因为初始的x,y,左下角的坐标确实是0,0,它实际上是一个1024*768的窗口。但是,我创建的位置向量似乎不正确。Z坐标可能不应为零。然而,glfwgetcursorpos返回二维坐标,我不知道如何从那里转到三维窗口坐标,特别是因为我不确定窗口坐标的第三维度是什么意思(因为计算机屏幕是二维的)。那么,我不确定我是否正确地使用了未经处理的对象。假设视图、模型、投影矩阵都正常。如果我在窗口坐标中传递了正确的位置向量,unproject调用会给我对象坐标中的坐标吗?我想是的,但是文件不清楚。

最后,对于我要跟随鼠标移动的对象的每个顶点,我只需将x坐标增加un[0]、y坐标增加un[1]和z坐标增加un[2]。但是,由于未投影的位置向量很可能是错误的,所以这不会产生好的效果;对象确实会随着鼠标的移动而移动,但偏移量相当大(也就是说,移动鼠标太多不会移动对象太多,而且Z坐标非常大)。实际上,我发现无论鼠标在哪里,z坐标un[2]总是相同的值,可能是因为我传递给unproject的位置矢量对于z总是0.0的值。但是,改变位置矢量中的最后一个坐标并不能解决对象移动比鼠标慢得多的事实。


我认为你的主要问题实际上是z坐标。当您考虑屏幕上的一个点时,这将不仅指定对象空间中的一个点,而且指定一条直线。当你使用投影时,你可以从眼睛位置画一条线到任何物体空间点,这样一条线上的每一点都会投影到同一个屏幕空间点。

当z=0时,你得到的实际上是近平面上的点。现在它将取决于对象离相机的距离,如上图所示。

sketch of unprojecting with a frustum

你得到的是坐标中相对于物体空间原点的A点。如果只从深度缓冲区的鼠标光标下的像素读取z值,则可以返回点B。

但是,我认为A点和B点都不能真正帮助你。你需要更多的约束。例如,可以指定不更改对象的距离,鼠标指向的像素应为对象中心(或对象空间中的任何其他参考点)应出现的点。然后,你可以计算光线上你要移动的点。但是,还不清楚您真正想要实现什么样的移动。

附带说明:手动调整顶点坐标不是一个好主意。GPU可以做得更好。您应该只是操纵模型矩阵来移动对象。在这种方案中,不需要将点或光线投影到对象空间,而是投影到世界空间,并使用该空间更新对象的模型矩阵,这是很有用的。