Opengl es Matrixmultiplication-glTranslate的自己实现?错误矩阵

Opengl es Matrixmultiplication-glTranslate的自己实现?错误矩阵,opengl-es,matrix,matrix-multiplication,opengl-es-2.0,Opengl Es,Matrix,Matrix Multiplication,Opengl Es 2.0,假设我有以下投影矩阵(使用gluPerspective(40,1.0,0.2200.0);在单位矩阵上计算): 并且想要做一个glTranslatef(0.0,0.0,-10.0)命令。使用openGL ES 1.1函数,我收到(我认为这似乎是正确的): 但如果我使用自己的实现(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

假设我有以下投影矩阵(使用
gluPerspective(40,1.0,0.2200.0);
在单位矩阵上计算):

并且想要做一个
glTranslatef(0.0,0.0,-10.0)命令。使用openGL ES 1.1函数,我收到(我认为这似乎是正确的):

但如果我使用自己的实现(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
我的代码与苹果openGLES1/2示例和本网站非常相似:

void Matrix::translate(GLfloat xTranslate、GLfloat yTranslate、GLfloat zTranslate){
GLfloat矩阵[16];
矩阵[0]=矩阵[5]=矩阵[10]=矩阵[15]=1.0;
矩阵[1]=矩阵[2]=矩阵[3]=矩阵[4]=0.0;
矩阵[6]=矩阵[7]=矩阵[8]=矩阵[9]=0.0;
矩阵[11]=0.0;
矩阵[12]=xTranslate;
矩阵[13]=钇Translate;
矩阵[14]=zTranslate;
多重矩阵(矩阵);
}
无效矩阵::多重矩阵(常量GLfloat*a){
GLfloat*矩阵;
glb[16];
matrix=currentMatrix();//获取作为GLfloat的ProjectionMatrix*
复制矩阵(矩阵,b);
矩阵[0]=a[0]*b[0]+a[4]*b[1]+a[8]*b[2]+a[12]*b[3];
矩阵[1]=a[1]*b[0]+a[5]*b[1]+a[9]*b[2]+a[13]*b[3];
矩阵[2]=a[2]*b[0]+a[6]*b[1]+a[10]*b[2]+a[14]*b[3];
矩阵[3]=a[3]*b[0]+a[7]*b[1]+a[11]*b[2]+a[15]*b[3];
矩阵[4]=a[0]*b[4]+a[4]*b[5]+a[8]*b[6]+a[12]*b[7];
矩阵[5]=a[1]*b[4]+a[5]*b[5]+a[9]*b[6]+a[13]*b[7];
矩阵[6]=a[2]*b[4]+a[6]*b[5]+a[10]*b[6]+a[14]*b[7];
矩阵[7]=a[3]*b[4]+a[7]*b[5]+a[11]*b[6]+a[15]*b[7];
矩阵[8]=a[0]*b[8]+a[4]*b[9]+a[8]*b[10]+a[12]*b[11];
矩阵[9]=a[1]*b[8]+a[5]*b[9]+a[9]*b[10]+a[13]*b[11];
矩阵[10]=a[2]*b[8]+a[6]*b[9]+a[10]*b[10]+a[14]*b[11];
矩阵[11]=a[3]*b[8]+a[7]*b[9]+a[11]*b[10]+a[15]*b[11];
矩阵[12]=a[0]*b[12]+a[4]*b[13]+a[8]*b[14]+a[12]*b[15];
矩阵[13]=a[1]*b[12]+a[5]*b[13]+a[9]*b[14]+a[13]*b[15];
矩阵[14]=a[2]*b[12]+a[6]*b[13]+a[10]*b[14]+a[14]*b[15];
矩阵[15]=a[3]*b[12]+a[7]*b[13]+a[11]*b[14]+a[15]*b[15];
}
无效矩阵::复制矩阵(常量GLfloat*源,GLfloat*目标){

对于(int i=0;i从您的代码中有点难以分辨,但您是否打算对矩阵使用行顺序或列顺序?行顺序更常见,但您创建的是列顺序转换矩阵。转换矩阵的平移3向量从右上角向下,而不是沿着botto我是罗

在按行排序的矩阵中,行是连续的块,因此前四个数字是顶行。在按列排序的矩阵中,列是连续的块,因此前四个数字是第一列


如果我正确地阅读了您的代码,那么您的multiMatrix函数似乎正确地使用行顺序将参数矩阵与标准类矩阵相乘。如果矩阵是行顺序的,则这对于translate是正确的,因此您需要转置正在创建的转换矩阵。

很难从您的代码中分辨出来您的代码,但您是否打算对矩阵使用行顺序或列顺序?行顺序更常见,但您正在创建列顺序转换矩阵。转换矩阵的转换3向量从右上角向下延伸到最右边的列,而不是沿着最下面的行

在按行排序的矩阵中,行是连续的块,因此前四个数字是顶行。在按列排序的矩阵中,列是连续的块,因此前四个数字是第一列

如果我正确地阅读了您的代码,那么您的multiMatrix函数似乎正确地使用行顺序将参数矩阵与标准类矩阵相乘。如果矩阵是行顺序的,则这对于translate是正确的,因此您需要转置您正在创建的翻译矩阵。

我经常提到的代码这很容易理解,而且很有效

他们的
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;
},
我总是参考。代码很容易理解,而且很有效

他们的
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;
},
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];   
    }
}
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;
},