使用pyopengl获取模型矩阵

obtaining model matrix using pyopengl

我正在尝试使用 python 中的 pyopengl 以 3x4 矩阵形式获取旋转矩阵和 t运行slation 矩阵。我从这个 link here 中发现旋转和 t运行slation 矩阵可以从以下位置获得:

model = glGetDoublev(GL_MODELVIEW_MATRIX)

我知道这实际上是模型视图矩阵,而不是模型矩阵,但我在一些 post 中读到,只有在获取模型视图矩阵之前调用 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 矩阵形式的旋转和 t运行slation 矩阵,我的问题是我是否可以只使用前 3 行并忽略最后一行,尽管它有值?例如:

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

即使这样做,它看起来也不对,因为我 t运行 使用 glT运行slatef(0.0, -4, -10) 但 t运行slation 列(右侧第 4 列)显示 [0,0,0].

如有任何帮助,我们将不胜感激。

固定函数管道操作(glRotatefglTranslatef、...)按 column-major 顺序创建矩阵。因此,您的输出被转置。

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

LoadMatrix takes a pointer to a 4 × 4 matrix stored in column-major order as 16 consecutive floating-point values ...

(This differs from the standard row-major C ordering for matrix elements. If the standard ordering is used, all of the subsequent transformation equations are transposed, and the columns representing vectors become rows.)
The specified matrix replaces the current matrix with the one pointed to. MultMatrix takes the same type argument as LoadMatrix, but multiplies the current matrix by the one pointed to and replaces the current matrix with the product. If C is the current matrix and M is the matrix pointed to by MultMatrix’s argument, then the resulting current matrix, C', is

C'  = C · M

....

There are a variety of other commands that manipulate matrices. Rotate, Translate, Scale, Frustum, and Ortho manipulate the current matrix. Each computes a matrix and then invokes MultMatrix with this matrix.