I'm trying to port over some OpenGL code from an Android project to iOS. I've done a little bit of iOS programming before so i'm familiar with the syntax of Objective-C but I can't seem to figure out how these GLKMatrixStacks work. Here is some Java code that I am trying to port with an example of how I need to use the stack.
public void drawLeftHip()
{
float[] temp = new float[16];
System.arraycopy(mModelMatrix, 0, temp, 0, mModelMatrix.length);
stack.push(temp);
//Global transformations here
Matrix.translateM(mModelMatrix, 0, -1.0f, -.75f, 0.0f);
Matrix.rotateM(mModelMatrix, 0, lThighAngle, 1.0f, 0.0f, 0.0f);
//draw children
drawLeftThigh();
//left hip
Matrix.scaleM(mModelMatrix, 0, .25f, .25f, .25f);
drawPackedTriangleBuffer(mSphereData, mSphereVertexCount, mModelMatrix, mColorBlack); //draw the triangle with the given model matrix
mModelMatrix = stack.pop();
}
I basically make a copy of mModelMatrix (a 4x4 matrix) and push it on the stack, do my global transformations, draw children, do local transformations, and finally pop the stack.
I've tried using a NSMutableArray for the purpose of a stack but I can't use it because I need to use GLKMatrix4 which is not if type (id).
GLKMatrix4
represents a 4x4 matrix. It's just a union encapsulating a 16-elementfloat
array, so it's analogous to thefloat[16]
array in your example. If you work withGLKBaseEffect
you're already using these for your ModelView and Projection matrices. (If you're rolling your own shaders, using the GLKit matrix/vector types and corresponding math utilities is a good idea anyway, since they're optimized to provide good performance on iOS devices.)To follow the pattern of your example:
Use
GLKMatrixStackCreate
to create a stack, thenGLKMatrixStackLoad
to copy your current ModelView matrix onto the stack. This function automatically copies the matrix so you don't need to create a copy yourself as in your example.Use
GLKMatrix4Translate
,GLKMatrix4Rotate
, etc to transform your ModelView matrix before drawing with it. (Don't forget to upload the changed matrices to your shader's uniform variables, or if usingGLKBaseEffect
update itstransform
property and tell it toprepareToDraw
, before drawing.)Finally, use one of the
GLKMatrixStackGet
functions to retrieve the saved matrix from the stack.This pattern doesn't actually make use of the stack, though -- it just saves and loads a single matrix. You can extend the pattern by using
GLMatrixStackPush
to save additional matrices andGLKMatrixStackPop
to restore to a prior state. (The pop function doesn't return the top matrix before disposing of it, so use aGLKMatrixStackGet
function if you want to retrieve it first.) This pattern still doesn't make optimal use of the stack, though -- a better way is to keep all your matrix operations in the stack. Here's a quick (untested) example:Read the documentation on
GLKMatrixStack
for more info.