我想在OpenGL中用鼠标位置偏移拖动一个对象。渲染管道是这样的。
gl_Position = projection * view * model * vec4(aPos, 1.0);
所以我想我应该反转(投影*视图)然后将它们相乘以获得将应用于模型矩阵的转换。
glm::mat4 CalculateDragTransform(double xOffset, double yOffset) {
double x = (2 * xOffset) / m_width;
double y = (2 * yOffset) / m_height;
glm::mat4 projection = glm::perspective(glm::radians(m_camera->GetFOV()),
(float) m_width /
(float) m_height, 0.1f,
100.0f);
glm::mat4 view = m_camera->GetViewMatrix();
glm::mat4 transform = glm::translate(glm::mat4(1.0), glm::vec3(x, y, 0));
return glm::inverse(projection * view) * transform * projection * view;
m_objects[index]->SetModelMatrix(transform * m_objects[index]->GetModelMatrix());
当我拖动它时,该对象正在跟随鼠标移动。但是如果我从其他角度看,这个物体会严重变形。那么我做错了什么?(投影*视图)应该倒置吗?
拖动前的骰子:
拖动后的骰子:
您可以从其他角度看到失真:
失真的一个更明显的例子:
更新:我设法通过仅保留位置转换来解决问题(某种)。所以我怀疑转换中左上角的 3x3 矩阵有问题。调试的时候发现第四行的前三列不是零,这是绝对错误的!但我不明白是什么原因造成的。这种现象只有在我使用 glm::perspective 作为投影矩阵时才会发生。使用 glm::ortho 也是一种无需丢弃左上角 3x3 矩阵的解决方案。
glm::mat4 view = m_camera->GetViewMatrix();
glm::mat4 transform = glm::translate(glm::mat4(1.0), glm::vec3(x, y, 0));
transform = glm::inverse(projection * view) * transform * projection * view;
float x = transform[3][0];
float y = transform[3][1];
float z = transform[3][2];
transform = glm::translate(glm::mat4(1.0f), glm::vec3(x, y, z));