Happily found my answer right after posting this. Just needed to enable the depth buffer.
view.drawableDepthFormat = GLKViewDrawableDepthFormat16;
(where view is your GLKView*
)
Thank you Ray Wenderlich for the nice explanation:
drawableDepthFormat
Your OpenGL context can also optionally have another buffer associated with it called the depth buffer. This helps make sure that objects closer to the viewer show up in front of objects farther away.
The way it works by default is OpenGL stores the closest object to the viewer at each pixel in a buffer. When it goes to draw a pixel, it checks the depth buffer to see if it’s already drawn something closer to the viewer, and if so discards it. Otherwise, it adds it to the depth buffer and the color buffer.
You can set this property to choose the format of the depth buffer. The default value is GLKViewDrawableDepthFormatNone, which means that no depth buffer is enabled at all.
But if you want this feature (which you usually do for 3D games), you should choose GLKViewDrawableDepthFormat16 or GLKViewDrawableDepthFormat24. The tradeoff here is with GLKViewDrawableDepthFormat16 your app will use less resources, but you might have rendering issues when objects are very close to each other.