使用pyopengl获取模型矩阵

时间:2018-03-11 22:14:05

标签: python opengl pyopengl coordinate-transformation

我试图在python中使用pyopengl以3x4矩阵形式获得旋转矩阵和平移矩阵。我从这个链接here中发现旋转和平移矩阵可以从以下地址获得:

model = glGetDoublev(GL_MODELVIEW_MATRIX)

我知道这实际上是模型视图矩阵,而不是模型矩阵,但我在一些帖子中读到,只有在获取模型视图矩阵之前调用glLoadIdentity()时,这才有效:

glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
model = glGetDoublev(GL_MODELVIEW_MATRIX)

这是我的示例代码:

meshes = pywavefront.Wavefront("sample.obj") #3D model file goes here

#Get current directory
directory = os.getcwd() + "/result/" + filename 

#Create directory if does not exist
try:
    os.makedirs(directory)
except OSError as e:
    if e.errno != errno.EEXIST:
        raise

counter = 1
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
gl.glPushMatrix()
glLoadIdentity()
model1 = glGetDoublev(GL_MODELVIEW_MATRIX)
print("Matrix 1: ")
print(model1) #should print identity matrix

glRotatef(15, 1, 0, 0)
glTranslatef(0.0, -4, -10)
glRotatef(60, 0, 1, 0)
model2 = glGetDoublev(GL_MODELVIEW_MATRIX)
print("Matrix 2: ")
print(model2)
meshes.draw()
pygame.image.save(screen, directory+"/"+filename+"_"+str(counter)+".jpg")
counter += 1
gl.glPopMatrix()

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
gl.glPushMatrix()
glLoadIdentity()
model3 = glGetDoublev(GL_MODELVIEW_MATRIX)
print("Matrix 3: ")
print(model3) #should print identity matrix

glRotatef(15, 1, 0, 0)
glTranslatef(0.0, -2.2, -10)
glRotatef(90, 0, 1, 0)
model4 = glGetDoublev(GL_MODELVIEW_MATRIX)
print("Matrix 4: ")
print(model4)
meshes.draw()
pygame.image.save(screen, directory+"/"+filename+"_"+str(counter)+".jpg")
counter += 1
gl.glPopMatrix()

这是上述代码的输出:

Matrix 1: 
[[ 1.  0.  0.  0.]
 [ 0.  1.  0.  0.]
 [ 0.  0.  1.  0.]
 [ 0.  0.  0.  1.]]
Matrix 2: 
[[  0.49999997   0.22414388  -0.83651632   0.        ]
 [  0.           0.96592581   0.25881904   0.        ]
 [  0.86602545  -0.12940951   0.48296288   0.        ]
 [  0.          -1.2755127  -10.6945343    1.        ]]
Matrix 3: 
[[ 1.  0.  0.  0.]
 [ 0.  1.  0.  0.]
 [ 0.  0.  1.  0.]
 [ 0.  0.  0.  1.]]
Matrix 4: 
[[ -4.37113883e-08   2.58819044e-01  -9.65925813e-01  -0.00000000e+00]
 [  0.00000000e+00   9.65925813e-01   2.58819044e-01   0.00000000e+00]
 [  1.00000000e+00   1.13133396e-08  -4.22219593e-08   0.00000000e+00]
 [  0.00000000e+00   4.63153839e-01  -1.02286596e+01   1.00000000e+00]]

问题是获得的矩阵看起来很奇怪。最后一行应该是[0,0,0,1],但我得到了一些值。我实际上在c ++ opengl中运行了类似的代码,最后一行总是[0,0,0,1],但不是pyopengl。

我的目标是只获得3x4矩阵形式的旋转和平移矩阵,我的问题是我可以直接取前三行并忽略最后一行,尽管它有值吗?例如:

Matrix 2: 
[[  0.49999997   0.22414388  -0.83651632   0.        ]
[  0.           0.96592581   0.25881904   0.        ]
[  0.86602545  -0.12940951   0.48296288   0.        ]

即使这样做,它看起来也不对,因为我使用glTranslatef(0.0,-4,-10)翻译它,但翻译栏(右边的第4列)显示[0,0,0]。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

固定功能管道操作(glRotatefglTranslatef,...)按列主要顺序创建矩阵。因此你的输出是转置的。

请参阅OpenGL 2.1 (API Specification); 2.11.2 Matrices; page 43

  

LoadMatrix 将指向存储在 column-major 顺序中的4×4矩阵作为16个连续浮点值...

     

(这与矩阵元素的标准行主要C顺序不同。如果使用标准排序,则所有后续变换方程都被转置,表示向量的列变为行。)
  指定的矩阵用指向的矩阵替换当前矩阵。 MultMatrix 采用与 LoadMatrix 相同的类型参数,但将当前矩阵乘以指向的矩阵,并将当前矩阵替换为产品。如果C是当前矩阵并且M是 MultMatrix 的参数指向的矩阵,那么得到的当前矩阵C'是

C'  = C · M
     

...

     

有许多其他命令可以操纵矩阵。 <强>旋转下,   翻译缩放 Frustum Ortho 操纵当前矩阵。每个都计算一个矩阵,然后用这个矩阵调用 MultMatrix