I am trying to obtain the rotation matrix and translation matrix in a 3x4 matrix form using pyopengl in python. I found out from this link here that the rotation and translation matrix can be obtained from:
model = glGetDoublev(GL_MODELVIEW_MATRIX)
I know that this is actually the modelview matrix and not the model matrix but I read in some post that this only work if I call glLoadIdentity() before getting the modelview matrix for eg.:
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
model = glGetDoublev(GL_MODELVIEW_MATRIX)
This is my sample code:
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()
This is the output of the above code:
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]]
The problem is the matrix obtained looks weird. The last row should be [0,0,0,1] but instead I got some values in it. I actually ran similar code in c++ opengl and the last row was always [0,0,0,1] but not for pyopengl.
My goal is to only obtain rotation and translation matrix in 3x4 matrix form and my question is can I just take the first 3 rows as is and ignore the last row despite it having values? eg.:
Matrix 2:
[[ 0.49999997 0.22414388 -0.83651632 0. ]
[ 0. 0.96592581 0.25881904 0. ]
[ 0.86602545 -0.12940951 0.48296288 0. ]
even if doing this, it looks wrong because I translate it using glTranslatef(0.0, -4, -10) but the translation column (the 4th column on the right) is showing [0,0,0].
Any help would be greatly appreciated.
The fixed function pipeline operations (glRotatef
, glTranslatef
, ...) create matrices in column-major order. Because of that your output is transposed.
See 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', isC' = 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.