我有以下功能:
void Matrix::Scale(const float xScale, const float yScale, const float zScale)
{
Matrix scaleMatrix;
scaleMatrix.m_data[M11] = xScale;
scaleMatrix.m_data[M22] = yScale;
scaleMatrix.m_data[M33] = zScale;
*this *= scaleMatrix;
}
void Matrix::Translate(const float xTranslation, const float yTranslation, const float zTranslation)
{
Matrix translationMatrix;
translationMatrix.m_data[M14] = xTranslation;
translationMatrix.m_data[M24] = yTranslation;
translationMatrix.m_data[M34] = zTranslation;
*this *= translationMatrix;
}
我不确定这两个功能的最后几行。我应该进行预乘法还是后乘法(即我现在正在做的事情)。它对这个类的使用有什么影响?我在OpenGL中使用该类,因此任何相似之处都可能有用。
修改
我的着色器代码如下所示:
void main()
{
gl_Position = vec4(v_xy, 0.0, 1.0) * v_ModelMatrix * v_ViewMatrix * v_ProjectionMatrix;
f_uv = v_uv;
}
我的矩阵乘法函数如下所示:
// Row 1
result[M11] = lhs[M11] * rhs[M11] + lhs[M12] * rhs[M21] + lhs[M13] * rhs[M31] + lhs[M14] * rhs[M41]; // Column 1
result[M12] = lhs[M11] * rhs[M12] + lhs[M12] * rhs[M22] + lhs[M13] * rhs[M32] + lhs[M14] * rhs[M42]; // Column 2
result[M13] = lhs[M11] * rhs[M13] + lhs[M12] * rhs[M23] + lhs[M13] * rhs[M33] + lhs[M14] * rhs[M43]; // Column 3
result[M14] = lhs[M11] * rhs[M14] + lhs[M12] * rhs[M24] + lhs[M13] * rhs[M34] + lhs[M14] * rhs[M44]; // Column 4
// Row 2
result[M21] = lhs[M21] * rhs[M11] + lhs[M22] * rhs[M21] + lhs[M23] * rhs[M31] + lhs[M24] * rhs[M41]; // Column 1
result[M22] = lhs[M21] * rhs[M12] + lhs[M22] * rhs[M22] + lhs[M23] * rhs[M32] + lhs[M24] * rhs[M42]; // Column 2
result[M23] = lhs[M21] * rhs[M13] + lhs[M22] * rhs[M23] + lhs[M23] * rhs[M33] + lhs[M24] * rhs[M43]; // Column 3
result[M24] = lhs[M21] * rhs[M14] + lhs[M22] * rhs[M24] + lhs[M23] * rhs[M34] + lhs[M24] * rhs[M44]; // Column 4
// Row 3
result[M31] = lhs[M31] * rhs[M11] + lhs[M32] * rhs[M21] + lhs[M33] * rhs[M31] + lhs[M34] * rhs[M41]; // Column 1
result[M32] = lhs[M31] * rhs[M12] + lhs[M32] * rhs[M22] + lhs[M33] * rhs[M32] + lhs[M34] * rhs[M42]; // Column 2
result[M33] = lhs[M31] * rhs[M13] + lhs[M32] * rhs[M23] + lhs[M33] * rhs[M33] + lhs[M34] * rhs[M43]; // Column 3
result[M34] = lhs[M31] * rhs[M14] + lhs[M32] * rhs[M24] + lhs[M33] * rhs[M34] + lhs[M34] * rhs[M44]; // Column 4
// Row 4
result[M41] = lhs[M41] * rhs[M11] + lhs[M42] * rhs[M21] + lhs[M43] * rhs[M31] + lhs[M44] * rhs[M41]; // Column 1
result[M42] = lhs[M41] * rhs[M12] + lhs[M42] * rhs[M22] + lhs[M43] * rhs[M32] + lhs[M44] * rhs[M42]; // Column 2
result[M43] = lhs[M41] * rhs[M13] + lhs[M42] * rhs[M23] + lhs[M43] * rhs[M33] + lhs[M44] * rhs[M43]; // Column 3
result[M44] = lhs[M41] * rhs[M14] + lhs[M42] * rhs[M24] + lhs[M43] * rhs[M34] + lhs[M44] * rhs[M44]; // Column 4
我的印象是,如果你对你的矩阵进行后乘(即viewMatrix = transform * viewMatrix;
),那么你的着色器代码需要按照我现在的相反顺序应用MVP?
EDIT2:
http://scratchapixel.com/lessons/3d-basic-lessons/lesson-4-geometry/conventions-again-row-major-vs-column-major-vector/上的摘要表让我感到困惑,因为我使用OpenGL后复制(表示列主要),但我的矩阵在内存中显示为行主?
答案 0 :(得分:2)
矩阵是关联的,这意味着
ABC = (AB)C = A(BC)
因此,只要您保持订单相同,首先将(AB vs BC)
实际乘以哪个矩阵并不重要。预乘与后乘是AB
与BA
的关系。
话虽如此,this question解释了如果您希望转换按照您想要的方式出现,您应该将缩放/旋转/翻译相乘的顺序。如果使用行矩阵而不是列矩阵,则可以反转顺序并转置每个元素。 Here's a slideshow给出了更好的解释(跳转到幻灯片19)。
严格地说,矩阵的列矩阵是 T * R * S ,或者是Translate * Rotate * Scale。因此,如果你从身份我开始,后乘(你正在做的)是正确的。如果您更改为预乘,则 X L 的转换将最终为 L * X ,所以为了获得 T * R * S ,您可以按顺序执行调用。
答案 1 :(得分:0)
创建一个类矩阵,以保存4x1大小矩阵的实数。保持 数组中的数字。在main中,创建两个对象,A和B. 由用户填写。创建另一个对象C. C实际上是A的总和 和B.你应该有一个函数,add,它接收两个矩阵 对象并将它们作为单独的矩阵返回。 矩阵C = add(A,B); 在屏幕上以适当的格式显示三个对象.in c ++