OpenGL:将单应变换应用于矩阵堆栈
OpenGL: Apply homographic transformation to matrix stack
我对 OpenGL 完全陌生,对 C++ 完全生疏。对于一项学校作业,我必须修改一些 C++ 起始代码来创建基本的 2D 动画。
我想把一个单位正方形变成各种梯形。我可以计算完成此操作的单应性,但我不知道如何将它们应用于矩阵堆栈。
表格的现有代码:
// Draw rectangle
glLoadIdentity();
glPushMatrix();
glScalef(HEIGHT, WIDTH, 1.0)
// C++ code to set colour
// C++ code to draw square
glPopMatrix()
按预期使用所选颜色绘制一个按高度和宽度缩放的矩形。
其中一个同形异义词是:
1.0 0.0 0.0
0.0 9.0/4.0 3.0/4.0
0.0 1.0/12.0 1.0/4.0
它将点:(1, 1), (-1, 1), (-1, -1), (1, -1) 转换为 (3, 9), (-3, 9) , (-6, -9), (6, -9) 分别.
我按列优先顺序将其表示为:
float homographyBody[9] = {1.0, 0.0, 0.0, 0.0, 9.0/4.0, 1.0/12.0, 0.0, 3.0/4.0, 1.0/4.0}
但是,代入:
glMultMatrixf(homographyBody)
用于:
glScalef(HEIGHT, WIDTH, 1.0)
没有达到预期的效果。
除了从靠近原点的点向上和向右延伸的长楔形之外,乘法和缩放的组合似乎无法渲染任何东西。
我怀疑我只是对一些基本概念一无所知。任何建议表示赞赏。
glMultMatrix()
需要一个 4x4 矩阵作为参数。另外,正如您已经注意到的,OpenGL 以列主顺序存储矩阵。
要完成这项工作,您必须将矩阵扩展到 4x4。您需要一个 4x4 矩阵来转换以齐次坐标表示的 3D 点,就像您原来的 3x3 矩阵以齐次坐标转换 2D 点一样。
对于您的 3x3 矩阵,转换应用为:
[ a00 a01 a02 ] [ x ] [ a00 * x + a01 * y + a02 ]
[ a10 a11 a12 ] * [ y ] = [ a10 * x + a11 * y + a12 ]
[ a20 a21 a22 ] [ 1 ] [ a20 * x + a21 * y + a22 ]
据此,除以 w
(结果向量的第 3 个分量)后,您得到的结果点为:
x' = (a00 * x + a01 * y + a02) / (a20 * x + a21 * y + a22)
y' = (a10 * x + a11 * y + a12) / (a20 * x + a21 * y + a22)
将其扩展到 4x4 矩阵,我们并不真正关心 z
坐标:
[ a00 a01 0.0 a02 ] [ x ] [ a00 * x + a01 * y + a02 ]
[ a10 a11 0.0 a12 ] * [ y ] = [ a10 * x + a11 * y + a12 ]
[ 0.0 0.0 1.0 0.0 ] [ z ] [ z ]
[ a20 a21 0.0 a22 ] [ 1 ] [ a20 * x + a21 * y + a22 ]
除以 w
(现在是结果向量的第 4 个分量)后,您得到与之前相同的点。
对于您的示例,这是:
float homographyBody[16] = {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 9.0f/4.0f, 0.0f, 1.0f/12.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 3.0f/4.0f, 0.0f, 1.0f/4.0f
};
我对 OpenGL 完全陌生,对 C++ 完全生疏。对于一项学校作业,我必须修改一些 C++ 起始代码来创建基本的 2D 动画。
我想把一个单位正方形变成各种梯形。我可以计算完成此操作的单应性,但我不知道如何将它们应用于矩阵堆栈。
表格的现有代码:
// Draw rectangle
glLoadIdentity();
glPushMatrix();
glScalef(HEIGHT, WIDTH, 1.0)
// C++ code to set colour
// C++ code to draw square
glPopMatrix()
按预期使用所选颜色绘制一个按高度和宽度缩放的矩形。
其中一个同形异义词是:
1.0 0.0 0.0
0.0 9.0/4.0 3.0/4.0
0.0 1.0/12.0 1.0/4.0
它将点:(1, 1), (-1, 1), (-1, -1), (1, -1) 转换为 (3, 9), (-3, 9) , (-6, -9), (6, -9) 分别.
我按列优先顺序将其表示为:
float homographyBody[9] = {1.0, 0.0, 0.0, 0.0, 9.0/4.0, 1.0/12.0, 0.0, 3.0/4.0, 1.0/4.0}
但是,代入:
glMultMatrixf(homographyBody)
用于:
glScalef(HEIGHT, WIDTH, 1.0)
没有达到预期的效果。
除了从靠近原点的点向上和向右延伸的长楔形之外,乘法和缩放的组合似乎无法渲染任何东西。
我怀疑我只是对一些基本概念一无所知。任何建议表示赞赏。
glMultMatrix()
需要一个 4x4 矩阵作为参数。另外,正如您已经注意到的,OpenGL 以列主顺序存储矩阵。
要完成这项工作,您必须将矩阵扩展到 4x4。您需要一个 4x4 矩阵来转换以齐次坐标表示的 3D 点,就像您原来的 3x3 矩阵以齐次坐标转换 2D 点一样。
对于您的 3x3 矩阵,转换应用为:
[ a00 a01 a02 ] [ x ] [ a00 * x + a01 * y + a02 ]
[ a10 a11 a12 ] * [ y ] = [ a10 * x + a11 * y + a12 ]
[ a20 a21 a22 ] [ 1 ] [ a20 * x + a21 * y + a22 ]
据此,除以 w
(结果向量的第 3 个分量)后,您得到的结果点为:
x' = (a00 * x + a01 * y + a02) / (a20 * x + a21 * y + a22)
y' = (a10 * x + a11 * y + a12) / (a20 * x + a21 * y + a22)
将其扩展到 4x4 矩阵,我们并不真正关心 z
坐标:
[ a00 a01 0.0 a02 ] [ x ] [ a00 * x + a01 * y + a02 ]
[ a10 a11 0.0 a12 ] * [ y ] = [ a10 * x + a11 * y + a12 ]
[ 0.0 0.0 1.0 0.0 ] [ z ] [ z ]
[ a20 a21 0.0 a22 ] [ 1 ] [ a20 * x + a21 * y + a22 ]
除以 w
(现在是结果向量的第 4 个分量)后,您得到与之前相同的点。
对于您的示例,这是:
float homographyBody[16] = {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 9.0f/4.0f, 0.0f, 1.0f/12.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 3.0f/4.0f, 0.0f, 1.0f/4.0f
};