c++ - GLM 中的模型矩阵

标签 c++ opengl glm-math

我从自己的矩阵/vector 运算迁移到 GLM,但我不明白一件事。

OpenGL 中的模型矩阵 - model_matrix = scale_matrix * rotate_matrix * translate_matrix,因此我们首先平移,然后旋转,最后缩放。 但是后来我尝试在 GLM 中这样做,只有当我使用乘法的逆序(翻译 * 旋转 * 缩放)时,它才会在正确的位置显示四边形,但对于 MVP 矩阵(投影 * View * 模型)它应该工作。

示例代码

using namespace glm;
mat4 projection = ortho(0.0f, 1.0f, 0.0f, 1.0f);
mat4 translate = translate(mat4(1.0f), vec3(0.5f, 0.5f, 0.0f));
mat4 rotate = rotate(mat4(1.0f), 90.0f, vec3(0.0f, 0.0f, 1.0f));
mat4 scale = scale(mat4(1.0f), vec3(0.5f, 0.5f, 1.0f));
mat4 m = translate * scale * rotate;// must be scale * rotate * translate
mat4 mvp = projection * mat4(1.0f)/*view matrix*/ * m;
glUseProgram(shader->prog);
glUniformMatrix4fv(shader->uniforms[0]/*um_mvp*/, 1, GL_FALSE, value_ptr(mvp));
...

顶点着色器

attribute vec3 av_pos;
attribute vec2 av_tex;

uniform mat4 um_mvp;

varying vec2 vv_tex;

void main()
{
 vv_tex = av_tex;
 gl_Position = um_mvp * vec4(av_pos, 1.0); 
} 

最佳答案

so we first translate then rotate and at last scale.

...嗯,恰恰相反。

你的“完整”矩阵看起来像这样(为简单起见将旋转放在一边):

proj * view * translate * scale

,对吧?嗯,这是正确的:这意味着你的点 X 将以这种方式转换:

proj * view * translate * scale * X

,这意味着您将首先应用缩放,然后是平移,然后是相对于相机的定位,然后是投影。这是完美的。

您的问题似乎是“先缩放再翻译”的问题。想象一下 X 轴上的平移为 10,比例为 2。您将矩阵应用到一艘船上。

  • You scale your ship. You have now a big ship, but still at the origin
  • You translate your ship. It's now still as big, but at 10 units of the origin.

If you do the opposite :

  • You translate your ship. Its center is now at 10 units of the origin
  • You scale your ship. Every coordinate is multiplied by 2 relative to the origin, which is far away... So you end up with a big ship, but centered at 2*10 = 20. Which you don't want.

这有意义吗?

(来源:opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/)

关于c++ - GLM 中的模型矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12838375/

相关文章:

c++ - 从 cpp 方法调用 objective-c 方法

c++ - 对物体施加重力

opengl - 如何在 glShaderSource 中将字符串作为 GLchar** (char**) 参数传递?

c++ - 使用扫掠 AABB 交叉算法解决碰撞法线

c++ - 通过 glUniform 将 GLM 的 vector 类型传递给 OpenGL

C++ 函数返回 bool 未执行

c++ - 两个程序具有相同的代码: floating point overflow

C++停止CAsyncSocket将单个大数据包拆分为多个小数据包

c - 同时使用纹理和照明

c++ - 在按键期间不会不断调用 GLFW 中的 glfwSetKeyCallback()