我正在尝试以等距摄像机角度绘制多个立方体。这是绘制一个的代码。 (在iOS上使用GLKit的OpenGL ES 2.0)。
float startZ = -4.0f;
// position
GLKMatrix4 modelViewMatrix = GLKMatrix4Identity;
modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, location.x, location.y, location.z + startZ);
// isometric camera angle
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(45), 1.0, 0, 0);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(45), 0.0, 1.0, 0);
self.effect.transform.modelviewMatrix = modelViewMatrix;
[self.effect prepareToDraw];
glDrawArrays(GL_TRIANGLES, 0, 36);
问题在于它首先进行平移,然后进行旋转,这意味着有多个方框,它们不会排列(它们看起来像一串钻石。每个都处于适当位置并旋转,因此角落重叠)。
我已经尝试切换顺序,因此轮换在转换之前,但它们根本没有出现。我的顶点数组绑定到以原点为中心的单位立方体。
我真的不明白如何将相机与物体分开控制。我把投影矩阵搞砸了一会儿而没有得到它。据我所知,相机应该由modelViewMatrix控制,对吧? (“查看”部分)。
答案 0 :(得分:1)
您的“相机”变换(模型视图)似乎是正确的,但看起来您正在使用透视投影 - 如果您想要等距,则需要更改投影矩阵。
看起来您在绘制时将相机旋转应用于每个对象。相反,如果您的用例如此简单,则模拟一个2深的矩阵堆栈,因此您只需拥有相机矩阵和每个立方体的矩阵。
请注意,对于渲染的每个立方体,相机矩阵将保持不变,但是模型视图矩阵会将立方体的单个变换矩阵和相机矩阵合并到单个模型视图矩阵中。这相当于旧的矩阵堆栈方法glPushMatrix
和glPopMatrix
(在GLES 2.0中不可用)。如果您需要更复杂的对象层次结构(其中多维数据集在其“局部”坐标空间中具有子对象),那么您应该实现自己的完整矩阵堆栈,而不是上面讨论的2-deep等价物。
答案 1 :(得分:0)
供参考,这是一篇帮助我理解它的文章。这有点肮脏,但做得很直观。
http://db-in.com/blog/2011/04/cameras-on-opengl-es-2-x/
我最终保留了透视投影,因为我不想要真正的等距。关键是要按正确的顺序进行,因为移动相机与移动物体相反。请参阅评论和文章。工作代码:
// the one you want to happen first is multiplied LAST
// camRotate * camScale * camTranslate * objTranslate * objScale * objRotate;
// TODO cache the camera matrix
// the camera angle remains the same for all objects
GLKMatrix4 camRotate = GLKMatrix4MakeRotation(GLKMathDegreesToRadians(45), 1, 0, 0);
camRotate = GLKMatrix4Rotate(camRotate, GLKMathDegreesToRadians(45), 0, 1, 0);
GLKMatrix4 camTranslate = GLKMatrix4MakeTranslation(4, -5, -4.0);
GLKMatrix4 objTranslate = GLKMatrix4MakeTranslation(location.x, location.y, location.z);
GLKMatrix4 modelViewMatrix = GLKMatrix4Multiply(camRotate, camTranslate);
modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, objTranslate);
self.effect.transform.modelviewMatrix = modelViewMatrix;
[self.effect prepareToDraw];
glDrawArrays(GL_TRIANGLES, 0, 36);