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

Posted

技术标签:

【中文标题】使用 GLM 功能放大 OpenGL 中的当前鼠标位置【英文标题】:Zoom in on current mouse position in OpenGL using GLM functionality 【发布时间】:2013-02-03 12:36:58 【问题描述】:

我对放大 OpenGL 中当前鼠标位置的任务感到绝望。我已经尝试了很多不同的东西并阅读了其他关于此的帖子,但我无法根据我的具体问题调整可能的解决方案。所以据我了解,您必须获取鼠标光标的当前窗口坐标,然后将它们取消投影以获取世界坐标,最后转换为这些世界坐标。

为了找到当前的鼠标位置,每次点击鼠标右键时,我都会在我的 GLUT 鼠标回调函数中使用以下代码。

if(button == 2)

    mouse_current_x = x;
    mouse_current_y = y;
...

接下来,在设置 ModelView 和 Projection 矩阵之前,我在显示函数中取消投影当前鼠标位置,这似乎也可以正常工作:

// 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 方向(小车)平移来实现缩放:

// 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方向平移 使用上面发布的代码可以正常缩放到中心。现在我想放大到某个任意位置,问题是如何实现这一点。 您想在不旋转相机的情况下放大 0,0,0 以外的方向吗?那么您必须将相机跳到新位置,以便它仍然看着相同的“z”方向。更自然的变焦将是相机保持其世界位置但改变它正在查看的点。这需要轮换。您可以阅读有关偏航、俯仰、旋转的信息。 我不太确定这是什么意思...可以通过 glm::lookAt() 函数自动实现这种旋转吗?否则我怎么知道必要的旋转角度? 你可以看几篇文章celestialcoding.com/opengl-147/…和toymaker.info/Games/html/camera.html 【参考方案1】:

也许这不适用于您的情况。但对我来说,这似乎是处理这个问题的最好方法。使用 glulookat() 查看您已经找到的鼠标单击的 xyz 位置。然后把gluPerspective()改成更小的视角来实现实际的缩放。

【讨论】:

其实我并不想通过改变视角来实现缩放,所以这并不能真正回答我的问题。 @Schnigges:那么您的问题命名不正确。 “缩放”的意思是“改变视野”。如果你想通过移动相机来“缩放”,那就不再是“缩放”了;那是移动相机 感谢您的更正,但我认为您可以将相机移动解释为变焦。这就是为什么我说“我通过在 z 方向平移来实现缩放(小车)”。 但假设我会使用 gluLookat 或 glm::lookAt 来执行此操作...我必须如何缩放这些函数的查看参数向量?如果我只使用来自 unProject 函数的 worldCoordinates 向量,结果是什么都没有渲染。 我建议一开始你想象物体的相互作用。相机是一个有世界位置的物体,看、上和右/左向量形成一个新的空间,世界被渲染。其坐标系的向量被归一化。它们只是方向。要缩放,您将相机位置移向您正在缩放的​​点,例如一个对象。缩放在您正在查看的方向。一旦你想象它,小数学将有助于打包它。

以上是关于使用 GLM 功能放大 OpenGL 中的当前鼠标位置的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL C++ 鼠标光线拾取 glm:unproject

放大鼠标的算法(OpenGL)

GLM opengl 裁剪问题 - Game Engine c++

使用鼠标拖动的 OpenGL 平移点

openGL按鼠标中键实现放大缩小

glm::unProject 将鼠标位置转换为 3 个坐标