Матричное умножение - собственная реализация glTranslate?Неправильная матрица - PullRequest
0 голосов
/ 04 февраля 2011

Предполагая, что у меня есть следующая матрица проекции (она рассчитывается с использованием gluPerspective(40, 1.0, 0.2, 200.0); на единичной матрице):

2.75, 0.00, 0.00, 0.00, 
0.00, 2.75, 0.00, 0.00, 
0.00, 0.00, -1.00, -1.00, 
-0.00, -0.00, -0.40, -0.00

и хотите выполнить команду glTranslatef(0.0, 0.0, -10.0); для этой матрицы. С функцией openGL ES 1.1 я получаю (что мне кажется правильным):

2.75, 0.00, 0.00, 0.00, 
0.00, 2.75, 0.00, 0.00, 
0.00, 0.00, -1.00, -1.00, 
0.00, 0.00, 9.62, 10.00 

Но если я использую свою собственную реализацию (openGL ES 2.0), я получаю странное поведение:

2.75, 0.00, 0.00, 0.00, 
0.00, 2.75, 0.00, 0.00, 
0.00, 0.00, 9.00, -1.00, 
0.00, 0.00, -0.40, 0.00

Мой код очень похож на Apple, пример openGLES1 / 2 и этот сайт http://iphonedevelopment.blogspot.com/2009/06/opengl-es-from-ground-up-part-7_04.html:

void Matrix::translate(GLfloat xTranslate, GLfloat yTranslate, GLfloat zTranslate){
    GLfloat matrix[16];

    matrix[0] = matrix[5] =  matrix[10] = matrix[15] = 1.0;
    matrix[1] = matrix[2] = matrix[3] = matrix[4] = 0.0;
    matrix[6] = matrix[7] = matrix[8] = matrix[9] = 0.0;    
    matrix[11] = 0.0;
    matrix[12] = xTranslate;
    matrix[13] = yTranslate;
    matrix[14] = zTranslate;

    multiMatrix(matrix);
}
void Matrix::multiMatrix(const GLfloat* a){
    GLfloat* matrix;
    GLfloat b[16];
    matrix = currentMatrix(); //gets the ProjectionMatrix as GLfloat*
    copyMatrix(matrix, b);
    matrix[0]  = a[0] * b[0]  + a[4] * b[1]  + a[8] * b[2]   + a[12] * b[3];
    matrix[1]  = a[1] * b[0]  + a[5] * b[1]  + a[9] * b[2]   + a[13] * b[3];
    matrix[2]  = a[2] * b[0]  + a[6] * b[1]  + a[10] * b[2]  + a[14] * b[3];
    matrix[3]  = a[3] * b[0]  + a[7] * b[1]  + a[11] * b[2]  + a[15] * b[3];

    matrix[4]  = a[0] * b[4]  + a[4] * b[5]  + a[8] * b[6]   + a[12] * b[7];
    matrix[5]  = a[1] * b[4]  + a[5] * b[5]  + a[9] * b[6]   + a[13] * b[7];
    matrix[6]  = a[2] * b[4]  + a[6] * b[5]  + a[10] * b[6]  + a[14] * b[7];
    matrix[7]  = a[3] * b[4]  + a[7] * b[5]  + a[11] * b[6]  + a[15] * b[7];

    matrix[8]  = a[0] * b[8]  + a[4] * b[9]  + a[8] * b[10]  + a[12] * b[11];
    matrix[9]  = a[1] * b[8]  + a[5] * b[9]  + a[9] * b[10]  + a[13] * b[11];
    matrix[10] = a[2] * b[8]  + a[6] * b[9]  + a[10] * b[10] + a[14] * b[11];
    matrix[11] = a[3] * b[8]  + a[7] * b[9]  + a[11] * b[10] + a[15] * b[11];

    matrix[12] = a[0] * b[12] + a[4] * b[13] + a[8] * b[14]  + a[12] * b[15];
    matrix[13] = a[1] * b[12] + a[5] * b[13] + a[9] * b[14]  + a[13] * b[15];
    matrix[14] = a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14] * b[15];
    matrix[15] = a[3] * b[12] + a[7] * b[13] + a[11] * b[14] + a[15] * b[15];

}
void Matrix::copyMatrix(const GLfloat* source, GLfloat* destination){
    for(int i=0; i<16; i++){
        destination[i] = source[i];   
    }
}

Я отлаживаю это уже 2 дня и теперь имею представление, что мне не хватает ... Есть идеи?

Ответы [ 2 ]

2 голосов
/ 05 февраля 2011

Я всегда ссылаюсь на это отличная реализация . Код легко следовать, и он просто работает.

Их translate метод вставлен здесь:

translate: function (tx, ty, tz) {
    this.elements[3*4+0] += this.elements[0*4+0] * tx + this.elements[1*4+0] * ty + this.elements[2*4+0] * tz;
    this.elements[3*4+1] += this.elements[0*4+1] * tx + this.elements[1*4+1] * ty + this.elements[2*4+1] * tz;
    this.elements[3*4+2] += this.elements[0*4+2] * tx + this.elements[1*4+2] * ty + this.elements[2*4+2] * tz;
    this.elements[3*4+3] += this.elements[0*4+3] * tx + this.elements[1*4+3] * ty + this.elements[2*4+3] * tz;

    return this;
},
2 голосов
/ 04 февраля 2011

Сложно сказать по вашему коду, но собираетесь ли вы использовать порядок строк или столбцов для ваших матриц?Порядок строк будет более распространенным, но вы создаете матрицу перевода порядка столбцов.Матрица перевода имеет вектор перевода 3, идущий вниз по крайнему правому столбцу из верхнего правого угла, а не вдоль нижней строки.

В матрице с упорядоченной строкой строки представляют собой смежные блоки, поэтому первыйчетыре числа - верхний ряд.В упорядоченной по столбцам матрице столбцы являются смежными блоками, поэтому первые четыре числа являются первым столбцом.

Если я правильно читаю ваш код, то похоже, что ваша функция multiMatrix умножает параметр вправоматрица против матрицы постоянного класса, используя порядок строк.Это было бы правильно для перевода, если бы матрица была упорядочена по строкам, поэтому вам нужно транспонировать создаваемую вами матрицу перевода.

...