Разница между матрицей умножения с помощью функции Opengl (glMultMatrixf ()) и моей собственной функцией - PullRequest
0 голосов
/ 25 февраля 2011

все, я пытаюсь умножить матрицу на вектор в OpenGL, но оказывается, что результат рендеринга, который я получил, вызвав свое умножение function(OpenGLUtility::VectorMultiMatrix4d()), отличается от вызова функции opengl glMultMatrixf(). Две линии, нарисованные на экране, не совпадают.

Я поставил свой код, назвав его двумя разными способами. Функция OpenGLUtility :: VectorMultiMatrix4d () проста, просто умножение на столбцы.

Может кто-нибудь дать мне несколько советов по этому поводу? Большое спасибо.


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] ;
}

Код 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);

Ответы [ 2 ]

1 голос
/ 25 февраля 2011

Итак. после переформатирования вашего кода я прокомментирую его: сначала давайте посмотрим на код 2

float inverse[16];

glMatrixMode(GL_MODELVIEW);
glPushMatrix();

Хорошо, работаем с матрицей вида модели, выталкиваем стек матрицы вида модели.

glMultMatrixf(m_mat);

Умножение с матрицей m_mat

OpenGLUtility::InverseMatrix(m_mat, inverse);

Инвертирование ...

glMultMatrixf(inverse);

И там вы умножаете это обратно, так что вы сделали

М * М ^ -1 = I

конечно, это работает, только если mat_m вообще обратимо. Но если оно обратимо, то эти две операции отменяются, ничего не произойдет.

Кстати: вам не хватает закрытия glPopMatrix();

Тогда это:

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

Что вы ожидаете от последнего glMultMatrix?

Дай угадаю? Вы как-то ожидаете, что OpenGL умножит этот вектор на матрицу (он это делает) и вернет его вам (это делает не , по крайней мере, не таким образом).

Теперь вот что вам важно знать: OpenGL НЕ МАТЕМАТИЧЕСКАЯ БИБЛИОТЕКА

Фактически все функции манипуляции с матрицами были удалены из OpenGL-4, так что люди больше не занимаются вещами с OpenGL, для которых он не предназначен. Если у вас работает первый код: Отлично! Именно так и должно быть.

Однако не совсем ясно, чего именно вы пытаетесь достичь; мог бы быть более изящный или прямой способ сделать это.

1 голос
/ 25 февраля 2011

Проблема с вашим умножением заключается в том, что вы модифицируете pVector до того, как закончите умножение.Вам необходимо сохранить его во временной или другой переменной!

Измените свою функцию на:

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;
}
...