all, I am trying to multiply a matrix to a vector in OpenGL, but it turn out that the rendering result I got by calling my own multiplication function(OpenGLUtility::VectorMultiMatrix4d())
is different by calling the opengl function glMultMatrixf()
. The two lines drawn on the screen is not same.
I put my code by calling two different ways as bellow. The function OpenGLUtility::VectorMultiMatrix4d() is simple, just colume-major multiplication.
Can anyone give me some advices on this? Thanks a lot.
Code1:
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
double inverse[16];
OpenGLUtility::InverseMatrix(m_mat, inverse);
double tOrigin[4] = {
g_bottom_plane.m_Origin[0],
g_bottom_plane.m_Origin[1],
g_bottom_plane.m_Origin[2],
1.0 };
OpenGLUtility::VectorMultiMatrix4d(tOrigin,inversed);
double tNormal[4] = {
g_bottom_plane.m_Normal[0],
g_bottom_plane.m_Normal[1],
g_bottom_plane.m_Normal[2],
0.0 };
OpenGLUtility::VectorMultiMatrix4d(tNormal,inversed);
glBegin(GL_LINES);
glColor3f(0.0,1.0, 0.0);
glVertex4f(tOrigin[0], tOrigin[1], tOrigin[2], tOrigin[3]);
glVertex4f( tNormal[0]*tOrigin[3] + tOrigin[0],
tNormal[1]*tOrigin[3] + tOrigin[1],
tNormal[2]*tOrigin[3] + tOrigin[2],
tOrigin[3] );
glEnd();
//
void OpenGLUtility::VectorMultiMatrix4f(float* pVector, float* pMat)
{
pVector[0] = pMat[0]*pVector[0] + pMat[4]*pVector[1] + pMat[ 8]*pVector[2] + pMat[12]*pVector[3] ;
pVector[1] = pMat[1]*pVector[0] + pMat[5]*pVector[1] + pMat[ 9]*pVector[2] + pMat[13]*pVector[3] ;
pVector[2] = pMat[2]*pVector[0] + pMat[6]*pVector[1] 开发者_开发问答+ pMat[10]*pVector[2] + pMat[14]*pVector[3] ;
pVector[3] = pMat[3]*pVector[0] + pMat[7]*pVector[1] + pMat[11]*pVector[2] + pMat[15]*pVector[3] ;
}
Code 2
float inverse[16];
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glMultMatrixf(m_mat);
OpenGLUtility::InverseMatrix(m_mat, inverse);
glMultMatrixf(inverse);
double tOrigin[4] = {
g_bottom_plane.m_Origin[0],
g_bottom_plane.m_Origin[1],
g_bottom_plane.m_Origin[2],
1.0 };
double tNormal[4] = {
g_bottom_plane.m_Normal[0],
g_bottom_plane.m_Normal[1],
g_bottom_plane.m_Normal[2],
0.0 };
glBegin(GL_LINES);
glColor3f(0.0,1.0, 0.0);
glVertex4f( tOrigin[0], tOrigin[1], tOrigin[2], tOrigin[3] );
glVertex4f( tNormal[0]*tOrigin[3] + tOrigin[0],
tNormal[1]*tOrigin[3] + tOrigin[1],
tNormal[2]*tOrigin[3] + tOrigin[2],
tOrigin[3] );
glEnd();
glMultMatrixf(m_mat);
The problem with your multiplication is that you modify your pVector
before you are done with the multiplication. You need to store it in a temporary or different variable!
Change your function to:
void OpenGLUtility::VectorMultiMatrix4f(float* pVector, float* pMat)
{
float x = pMat[0]*pVector[0] + pMat[4]*pVector[1] + pMat[ 8]*pVector[2] + pMat[12]*pVector[3] ;
float y = pMat[1]*pVector[0] + pMat[5]*pVector[1] + pMat[ 9]*pVector[2] + pMat[13]*pVector[3] ;
float z = pMat[2]*pVector[0] + pMat[6]*pVector[1] + pMat[10]*pVector[2] + pMat[14]*pVector[3] ;
float w = pMat[3]*pVector[0] + pMat[7]*pVector[1] + pMat[11]*pVector[2] + pMat[15]*pVector[3] ;
pVector[0] = x;
pVector[1] = y;
pVector[2] = z;
pVector[3] = w;
}
So. after reformatting your code, I'll comment on it: First lets have a look at code 2
float inverse[16];
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
Okay, operating on the modelview matrix, pushing the modelview matrix stack.
glMultMatrixf(m_mat);
Multiplying with a matrix m_mat
OpenGLUtility::InverseMatrix(m_mat, inverse);
Inverting it…
glMultMatrixf(inverse);
And there you multiply it back, so you've done
M * M^-1 = I
of course this only works if mat_m
was invertible at all. But if it is invertible then those two operations cancel out nothing will happen.
BTW: You're missing a closing glPopMatrix();
Then this:
glBegin(GL_LINES);
glColor3f(0.0,1.0, 0.0);
glVertex4f( tOrigin[0], tOrigin[1], tOrigin[2], tOrigin[3] );
glVertex4f( tNormal[0]*tOrigin[3] + tOrigin[0],
tNormal[1]*tOrigin[3] + tOrigin[1],
tNormal[2]*tOrigin[3] + tOrigin[2],
tOrigin[3] );
glEnd();
glMultMatrixf(m_mat);
What are you expecting that last glMultMatrix to do?
Let me guess? You somehow expect OpenGL to multiply that vector with the matrix (it does this) and returning it back to you (this is does not, at least not in this way).
Now here's some important thing for you to know: OpenGL IS NOT A MATH LIBRARY
In fact all matrix manipulation functions have been removed from OpenGL-4, so that people no longer to things with OpenGL that it's not been purposed for. If the first code works for you: Fine! This is exactly how it's supposed to be done.
However it is not entirely clear what exactly you are trying to achieve; there might be a more elegant or straigtforward way of doing it.
精彩评论