假设我有以下投影矩阵(在身份矩阵上使用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示例和此网站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天,现在知道我错过了什么......有什么想法吗?
答案 0 :(得分:2)
从代码中判断一下有点困难,但是您打算在矩阵中使用行顺序还是列顺序?行顺序会更常见,但您正在创建列顺序转换矩阵。翻译矩阵的翻译3向量从右上角向下最右列,而不是沿着底行。
在行有序矩阵中,行是连续的块,因此前四个数字是顶行。在列有序矩阵中,列是连续的块,因此前四个数字是第一列。
如果我正确地读取你的代码,那么看起来你的multiMatrix函数是正确的 - 使用行顺序将参数矩阵与常设类矩阵相乘。如果矩阵是按行排序的,那么对于翻译来说这是正确的,因此您需要转置正在创建的转换矩阵。
答案 1 :(得分:2)
我总是提到this excellent implementation。代码很容易理解,它只是起作用。
他们的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;
},