So I am trying to draw and rotate a cube using GLKit on an iPad. My problem is that as the cube rotates it seems as the aspect ratio changes with it, squeezing it as it rotates. What I mean can be seen in the three images that follow where the cube is rotating counterclockwise for 90 degrees. Although at the beginning(first image) the ratio width/height of the cube is approx. 1/2 which I have set by
GLKMatrix4 scaleMatrix=GLKMatrix4MakeScale(0.5, 1., 0.3);
as it turns it gets "squeezed" to end up after a pi/2 turn,with the side that was the base (before the turn) to be double the height(third image). I believe my mistake is in the arguments I pass to GLKMatrix4MakePerspective
but as I am not very comfortable with all the calls to openGL methods and what each does I put also some parts of my code that I believe could have some connection to that, after the images.
- (void)draw{
//just a quaternion that rotates the cube
GLKQuaternion glkq=GLKQuaternionMake(_quat.x,_quat.y,_quat.z,_quat.w);
GLKMatrix4 rotationMatrix=GLKMatrix4MakeWithQuaternion (glkq);
GLKMatrix4 scaleMatrix=GLKMatrix4MakeScale(0.5, 1., 0.3);
GLKMatrix4 translateMatrix = GLKMatrix4MakeTranslation(0.,0.,0.);
GLKMatrix4 modelMatrix =GLKMatrix4Multiply(translateMatrix,
GLKMatrix4Multiply(scaleMatrix,rotationMatrix));
GLKMatrix4 viewMatrix = GLKMatrix4MakeLookAt(0, 0, 5, 0, 0, 0, 0, 1 , 0);
effect.transform.modelviewMatrix = GLKMatrix4Multiply(viewMatrix, modelMatrix);
effect.transform.projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(45.0f), 3./4., 3, -5);
[effect prepareToDraw];
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, triangleVertices);
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, 0, triangleColors);
glDrawArrays(GL_TRIANGLES, 0, 36);
glDisableVertexAttribArray(GLKVertexAttribPosition);
glDisableVertexAttribArray(GLKVertexAttribColor);
}
I am not sure if you maybe need some other parts of the code to tell me what I doing wrong here...
Matrix multiplication as a series of geometric transformations works from right to left and is not commutative. That is, given a rotation matrix R
and scale matrix S
, the product S x R
means "rotate by R
and then scale by S
", which is a different result from "scale by S
and then rotate by R
" (as given by the product R x S
).
You're scaling after rotating: instead of squishing a cube into a rectangular prism and then rotating it, you're rotating a cube and then squishing the resulting image. Reverse your multiplication of scaleMatrix
and rotationMatrix
and you should see the result you expect.
(Also, your translateMatrix
specifies a translation of zero, so multiplying it into the model view matrix does nothing. If it was nonzero, though, in what order should you multiply it into your model view matrix?)