0

次の射影行列があると仮定します(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

私のコードは、Apples openGLES1/2 Example とこのサイト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日間デバッグしていますが、何が欠けているのかわかりました...何かアイデアはありますか?

4

2 に答える 2

2

コードから判断するのは少し難しいですが、行列に行順または列順を使用するつもりですか? 行順の方が一般的ですが、列順の変換マトリックスを作成しています。平行移動行列には、一番下の行に沿ってではなく、右上隅から一番右の列に沿って走る平行移動 3-ベクトルがあります。

行順の行列では、行は連続したブロックであるため、最初の 4 つの数値が一番上の行になります。列順の行列では、列は連続したブロックであるため、最初の 4 つの数値が最初の列になります。

私があなたのコードを正しく読んでいる場合、あなたの multiMatrix 関数は、行順を使用して、スタンディング クラス マトリックスに対してパラメーター マトリックスを右乗算しているように見えます。マトリックスが行順である場合、これは変換に適しているため、作成している変換マトリックスを転置する必要があります。

于 2011-02-04T16:47:51.473 に答える
2

私はいつもこの優れた実装を参考にしています。コードは簡単に理解でき、機能します。

彼らの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;
},
于 2011-02-05T01:31:11.183 に答える