2015-02-08 139 views
0

我对OpenGL完全陌生,在C++中完全生锈。对于学校作业,我必须修改一些C++入门代码来创建基本的2D动画。OpenGL:将单应矩阵转换应用于矩阵堆栈

我想将单位正方形变成各种梯形。我可以计算完成这个的单应性,但我不知道如何将它们应用到矩阵堆栈。

存在的形式的代码:

// 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) 

没有收到预期的效果。

没有乘法和缩放的组合似乎能够呈现除了从靠近原点的点延伸到右边的长楔形以外的任何其他物体。

我怀疑我简直对一些基本概念一无所知。任何建议表示赞赏。

回答

2

glMultMatrix()需要一个4x4矩阵作为参数。另外,正如您已经注意到的那样,OpenGL按列主要顺序存储矩阵。

要做到这一点,您必须将矩阵扩展到4x4。您需要一个4x4矩阵来转换以均匀坐标表示的3D点,就像您的原始3x3矩阵在均匀坐标中转换2D点一样。靠,你得到所产生的点为w(结果矢量的第三分量)

[ 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 ] 

由此看来,分割后:

x' = (a00 * x + a01 * y + a02)/(a20 * x + a21 * y + a22) 
y' = (a10 * x + a11 * y + a12)/(a20 * x + a21 * y + a22) 

为了您的3x3矩阵,转化应用为

扩展这一个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 
}; 
+0

感谢。是的,额外的“=”是一个错字。我的单应矩阵是标准形式,但是我的float数组将其转换为列主要的顺序,如OP所述。我无法理解从这些命令中的任何一个到您为4x4表示提供的映射。你能解释这个映射吗? – Schemer 2015-02-08 03:56:22

+1

@Schemer我加了一些解释。 – 2015-02-08 04:21:27

+0

非常感谢您解释这一点。在我发布到SO之前,Google搜索答案是一次冒险和一半。我已经应用了您的扩展矩阵,现在正在渲染单应性。 – Schemer 2015-02-08 04:35:12