2

I'm reading official Android OpenGL ES 2.0 tutorial, and I noticed something. The code in the tutorial multiplies rotation matrix into the view-projection matrix like this:

Matrix.multiplyMM(mMVPMatrix, 0, mRotationMatrix, 0, mMVPMatrix, 0);

But, the documentation for this method specifies that the result matrix, and either of operands should not overlap, or the result is undefined:

Multiply two 4x4 matrices together and store the result in a third 4x4 matrix. In matrix notation: result = lhs x rhs. Due to the way matrix multiplication works, the result matrix will have the same effect as first multiplying by the rhs matrix, then multiplying by the lhs matrix. This is the opposite of what you might expect. The same float array may be passed for result, lhs, and/or rhs. However, the result element values are undefined if the result elements overlap either the lhs or rhs elements.

So, if we use offsets, we can store result, lhs and rhs in the same array, but they should not overlap. But, in the call from the tutorial, result and the rhs overlap, and offset of zero is used.

Am I reading something wrong, or is Googles tutorial wrong?

Davor
  • 1,387
  • 16
  • 33
  • Unlike other calls like glRotateM, glTranslateM etc, Matrix.multiplyMM will not append changes, instead it will first set the resultant matrix to identity and then make the changes as specified by LHSxRHS – Patt Mehta Jan 21 '13 at 20:12
  • Yes, but what happens when result and RHS are one and the same array? If the result was first set to identity, so would RHS, as it is the same memory, and the result would be equal to LHS, but that doesn't happen. I'm guessing that it is possible that result gets assigned new float[16] before the multiplication begins? But than document would be wrong in implying that this causes undefined behavior. – Davor Jan 21 '13 at 21:08
  • 1
    Actually, you are correct, I cannot say whether the documentation is correct or not, but it ruined a complete month when I was working to achieve this - http://www.pixdip.com/opengles/transform.php, just because that unnecsry stuff was mentioned in the documentation, it kept distracting me away from debugging in other intelligent ways, at the end I found out that there were floating point errors caused by sdk - http://stackoverflow.com/questions/11965593/appropriate-multiplication-of-matrices-for-rotation-translation – Patt Mehta Jan 21 '13 at 22:26
  • 2
    Duplicate: http://stackoverflow.com/questions/11925647/is-googles-android-opengl-tutorial-teaching-incorrect-linear-algebra (yes google's page is wrong) – Tim Jan 23 '13 at 21:59
  • Should have posted that as answer. Thanks anyway :D – Davor Jan 24 '13 at 11:06
  • 1
    This is a standard mistake I've seen students make teaching a computer graphics course for years. MM is `for i for j for k r[i,j] += a[i,k]*b[k,j]` with the loops in any order. In all cases if the result shares space with an operand, that operand can have elements overwritten before they're needed. To make life easier for users, a library would put the result in fresh storage and copy at the end, but some libraries (like this one) put speed ahead of programmer convenience. A got'cha ready to happen. – Gene Jan 30 '13 at 20:07

0 Answers0