使用GLM功能在OpenGL中放大当前鼠标位置

3
我对在OpenGL中放大当前鼠标位置的任务感到绝望。我尝试了很多不同的方法并阅读了其他帖子,但我无法将可能的解决方案适应于我的特定问题。因此,据我所理解的,您必须获取鼠标光标的当前窗口坐标,然后将其反投影以获取世界坐标,最后将其翻译为这些世界坐标。
为了找到当前的鼠标位置,我在我的GLUT鼠标回调函数中使用以下代码,每次右键单击时都会触发。
if(button == 2)
{
    mouse_current_x = x;
    mouse_current_y = y;
...

接下来,在我的显示函数中,我会对当前鼠标位置进行反投影,然后设置模型视图和投影矩阵,这似乎也完美地工作:

// Unproject Window Coordinates
float mouse_current_z;
glReadPixels(mouse_current_x, mouse_current_y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &mouse_current_z);
glm::vec3 windowCoordinates = glm::vec3(mouse_current_x, mouse_current_y, mouse_current_z);
glm::vec4 viewport = glm::vec4(0.0f, 0.0f, (float)width, (float)height);
glm::vec3 worldCoordinates = glm::unProject(windowCoordinates, modelViewMatrix, projectionMatrix, viewport);
printf("(%f, %f, %f)\n", worldCoordinates.x, worldCoordinates.y, worldCoordinates.z);

现在开始翻译。目前,我正在绘制一个具有尺寸(dimensionX、dimensionY、dimensionZ)的立方体,并将其平移到该立方体的中心点,因此我的缩放也发生在中心点。我通过在z方向上进行平移(dolly)来实现缩放:

// Set ModelViewMatrix
modelViewMatrix = glm::mat4(1.0); // Start with the identity as the transformation matrix
modelViewMatrix = glm::translate(modelViewMatrix, glm::vec3(0.0, 0.0, -translate_z)); // Zoom in or out by translating in z-direction based on user input 
modelViewMatrix = glm::rotate(modelViewMatrix, rotate_x, glm::vec3(1.0f, 0.0f, 0.0f)); // Rotate the whole szene in x-direction based on user input
modelViewMatrix = glm::rotate(modelViewMatrix,  rotate_y, glm::vec3(0.0f, 1.0f, 0.0f)); // Rotate the whole szene in y-direction based on user input
modelViewMatrix = glm::rotate(modelViewMatrix, -90.0f, glm::vec3(1.0f, 0.0f, 0.0f)); // Rotate the camera by 90 degrees in negative x-direction to get a frontal look on the szene
modelViewMatrix = glm::translate(modelViewMatrix, glm::vec3(-dimensionX/2.0f, -dimensionY/2.0f, -dimensionZ/2.0f)); // Translate the origin to be the center of the cube
glBindBuffer(GL_UNIFORM_BUFFER, globalMatricesUBO);
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(modelViewMatrix));
glBindBuffer(GL_UNIFORM_BUFFER, 0);

我试图通过将翻译转换为worldCoordinates向量来将其放置在立方体的中心,但这并没有起作用。我还尝试按宽度或高度缩放向量。 这里是否有一些重要的步骤我错过了?


我认为,在将物体平移到立方体中心后,您应该回到原点,然后再进行z轴方向的平移。 - Deepak
以上发布的代码可以使缩放到中心正常工作。现在我想缩放到任意位置,问题是如何实现。 - Schnigges
你想在不旋转相机的情况下朝着不同于0,0,0的方向进行缩放吗?那么你需要将相机跳到新位置,以便它仍然朝着相同的“z”方向观察。更自然的缩放是让相机保持其世界位置,但改变它所看的点。这需要旋转。你可以了解一下偏航、俯仰和旋转。 - user2026095
我不太确定这是什么意思... glm::lookAt() 函数能否自动实现此旋转?否则,我如何知道所需的旋转角度? - Schnigges
您可以查看以下几篇文章:http://celestialcoding.com/opengl-147/opengl-ground-up-tutorial-6-mouse-based-camera-rotation/?PHPSESSID=mjtq65vsm6oic63icbg28p7od3 和 http://www.toymaker.info/Games/html/camera.html。 - user2026095
想知道你是否得到了那个问题的答案,如果有的话,能否发布一下? - LBes
1个回答

0
也许这种方法在你的情况下不适用。但对我来说,这似乎是处理这个问题的最佳方式。使用glulookat()查看已经找到的鼠标点击的xyz位置。然后改变gluPerspective()为一个更小的视角来实现实际缩放。

实际上,我不想通过改变透视来实现缩放,所以那并没有真正回答我的问题。 - Schnigges
@Schnigges:那么你的问题命名不当。“缩放”意味着“改变视野”。如果你想通过移动相机来“缩放”,那就不再是“缩放”了;那是移动相机 - Nicol Bolas
谢谢您的纠正,但我认为您可以将这种相机运动解释为缩放。这就是为什么我说“通过在z方向上平移来实现缩放”。 - Schnigges
但是假设我使用gluLookat或glm :: lookAt来完成这个任务...我需要如何缩放这些函数的lookat参数向量?如果我只是使用从unProject函数得到的worldCoordinates向量,结果就是什么都没有被渲染。 - Schnigges
我建议一开始先想象对象之间的交互。相机是具有世界位置的对象,而观察方向、上下和左右向量形成了一个新的空间,从中对世界进行渲染。它的坐标系向量被归一化。它们只是方向。要缩放,您需要将相机位置移向您要缩放的点(例如一个对象)。缩放是在您所看的方向上进行的。一旦你想象出来,一些简单的数学计算可以帮助你整理思路。 - user2026095

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接