【问题标题】:Opengl Vertices Camera orientationOpengl顶点相机方向
【发布时间】:2014-06-18 12:44:04
【问题描述】:

我正在开发一个使用顶点的 3D 项目,我从一个简单的 gluLookAt 开始,以便让第一人称相机在环境中移动,我这样使用它:

   gluLookAt(_position.x,_position.y,_position.z,
      _target.x,_target.y,_target.z,
      0,0,1);

一切正常,我正在根据鼠标的位置和角度(theta 和 phi)计算我的目标,我的项目继续使用顶点来解决性能问题,所以我不得不为这些新的相机使用相同的相机对象,为了做到这一点,我以这种方式使用了 GLM 库:

glm::mat4 Projection = glm::perspective(90.0f, 800.0f / 600.0f, 0.1f, 100.f);
glm::mat4 View = glm::lookAt(
glm::vec3(position.x,position.y,position.z),
glm::vec3(target.x,target.y,target.z), 
glm::vec3(0,0,1)  
    );

glm::mat4 Model = glm::mat4(1.0f); !
// Our ModelViewProjection : multiplication of our 3 matrices
glm::mat4 MVP = Projection * View * Model; 

GLuint MatrixID = glGetUniformLocation(this->shaderProgram, "MVP");

这是我使用的着色器:

const GLchar* default_vertexSource =
"#version 150 core\n"
"in vec2 position;"
"in vec3 color;"
"out vec3 Color;"
"uniform vec3 translation;"
"uniform mat4 rotation;"
"uniform mat4 MVP;"
"void main() {"
"   Color = color;"
"   gl_Position = MVP*rotation*vec4(position.x + translation.x, position.y + translation.y, 0.0 + translation.z, 1.0);"
"}";

发生的情况是我的对象的坐标参考与我的相机不同,它在当前 x/z 平面上绘制在其上方,而在 x/y 平面上它应该面向相机。

【问题讨论】:

  • 修改我的代码后,似乎相机很好,只是我的对象被绘制在它的顶部,我不知道为什么如果有人可以为我点亮它,那就太好了。
  • 好像我的顶点坐标参考和glLookAt不一样,我的Cube和我的相机画的一样,但不是我的顶点数组...

标签: opengl rotation vertices


【解决方案1】:

在我看来,您似乎误解了 OpenGL 中的翻译是如何工作的。

glm::lookAt 返回一个模型视图矩阵。 -> 场景中的物体如何根据相机进行平移。在 openGL 中,您不会“移动”相机,而是在移动相机周围的所有对象。 因此,如果您在 0 0 0 (您的世界相机系统的起源)中有 2 个对象,并且您的相机位于 eye(0,0,-3), center(0,0,0), up(0,1,0) 并且您想将一个对象向左移动并在对象上向右移动您需要一个矩阵堆栈来自glm

std::stack<glm::mat4> glm_ProjectionMatrix; 

在这里,您可以将相机中的模型视图作为顶部对象推送。

对于左侧的对象 movemtn,您可以使用 glm::translate,将此 mat4 作为模型视图矩阵上传到您的着色器。 (这里不渲染场景)

将顶部矩阵重置为模型视图(如果您之前复制了顶部元素,则返回 pop())或使用 glm::lookAt 重置。然后 glm::translate 在另一个方向。

在您的顶点着色器中,您现在不需要 vec3 平移或旋转。

你就说

 gl_Position = perspective * modelview *vec4(position,1);

这将根据您给定的翻译相应地更新两个对象。

如果你想移动一些对象,只需更新一个对象的模型视图矩阵。

http://www.songho.ca/opengl/gl_transform.html

希望你能理解我的回答。

OpenGL 中运动(rot 和 trans)的基础是矩阵乘法。您不需要在着色器中向模型视图中添加一些翻译 vec。 GLM 可以在你的 C++ 代码中完成所有工作

数学:

Modelview 是一个 4*4 矩阵 如果您的对象不应旋转或平移,则模型视图等于标识。

如果要旋转对象,请使用正确的 4*4 旋转矩阵对模型视图矩阵进行微调(参见齐次坐标)

如果要平移顶点,则将正确的平移乘以矩阵

假设 X = (x,y,z,w) 是你的顶点

T 是平移,R 是旋转

一个有效的操作可能看起来像这样:

模型视图 * 旋转 * 平移 *v = v'

v' 是该点在 3D 坐标系中的新位置

您可以在此处找到一些示例代码:http://incentivelabs.de/Sourcecode/ 请参阅“Teil 13”或更高版本。如果你能听懂德语,你可以在 Youtube 上使用频道名称“incentivelabs”找到我关于 OpenGL 和 C++ 的教程

编辑:

如果我想使用带有 GLM 的 C++ 移动对象/旋转对象

glm_ProjectionMatrix.top() = camera.getProjectionMat();
glUniformMatrix4fv(uniformLocations["projection"], 1, false,glm::value_ptr(glm_ProjectionMatrix.top()));
glm_ModelViewMatrix.top() = camera.getModelViewMat();

glm_ModelViewMatrix.top() = glm::translate(
glm_ModelViewMatrix.top(),
glm::vec3(0.0f, 0.0f, -Translate));

glUniformMatrix4fv(uniformLocations["modelview"], 1, false,glm::value_ptr(glm_ModelViewMatrix.top()));

在 GLSL 顶点着色器中:

gl_Position = projection  * modelview * vec4(vertexPos,1);

vertexPos 是一个属性(位置为vec3)

此代码将模型视图和投影上传后绘制的所有顶点移动到具有相同平移的着色器。

【讨论】:

  • 我知道模型视图是关于相机的,在我的代码中,我没有混合对象的平移和“相机的平移”,在我的着色器中,平移和旋转这两个词对应于对象,并且 MVP 用于相机(位置 = 相机的位置),透视图和模型视图已经由 CPU 在 MVP 中计算,我只是想应用着色器中所有顶点的平移和旋转以获得更好的性能,我想我可以把MVP 中的旋转和平移,但这不会改变任何事情吗?我还在做错什么吗?
  • 所以你想对场景中的所有顶点进行相同的平移/旋转?
  • 我已尝试根据您所说的更改我的代码,我只是使用 MVP 进行了尝试,没有对对象进行任何旋转/平移,问题仍然存在,所以似乎没有我的问题来自这一点。
  • 如果我对所有顶点都具有相同的平移/旋转并不重要,事情并没有真正起作用,但你是对的,如果我有几个顶点要显示,我可能会在稍后更改它.
  • 我解决了我的问题,它不是来自 Vertices / Opengl 矩阵,它来自于我没有正确初始化我的相机目标的事实,它认为空间的一部分是初始的所以来自 OpenGL 世界的坐标轴引用在它上面……谢谢你的解释,我还有一些代码需要优化。
猜你喜欢
  • 1970-01-01
  • 2021-10-22
  • 1970-01-01
  • 2011-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-27
相关资源
最近更新 更多