【问题标题】:OpenGL ES orbit camera around object围绕物体的OpenGL ES轨道相机
【发布时间】:2013-11-28 05:40:10
【问题描述】:

我想在 OpenGL 中围绕对象旋转相机。不太会发生。这是我的代码:

对象是标准立方体。

- (void)update {

    float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);

    float radius = 10.0f;
    float startAngle = -3 * M_PI/4.0;

     float newX = 0.0f + radius *cos(phi)*sin(theta);
     float newY = 0.0f + radius *sin(phi)*sin(theta);
     float newZ = 0.0f + radius *cos(theta);

    GLKMatrix4 projectionMatrix = GLKMatrix4MakeLookAt(newX, 0.0, newZ 
                                                       0.0, 0.0, 0.0,
                                                       0.0, 1.0, 0.0);


    self.effect.transform.projectionMatrix = projectionMatrix;

    GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 0.0f);
   self.effect.transform.modelviewMatrix = modelViewMatrix;



}



-(void) viewPanned:(UIPanGestureRecognizer *) sender

{

    CGPoint curTouch = [sender locationInView:self.view];

    if ([sender state] == UIGestureRecognizerStateBegan){
        oldX = curTouch.x;
        oldY = curTouch.y;

    }


    theta += (curTouch.x-oldX)*0.001f;
    phi   += (curTouch.y-oldY)*0.001f;

    oldX = curTouch.x;
    oldY = curTouch.y;
}

【问题讨论】:

  • 我没有看到从(由theta/phi 旋转)眼睛坐标转换为剪辑坐标的投影矩阵。这可能是您问题的一部分……除此之外,它可能有助于澄清“没有发生”。
  • GLKMatrix4 projectionMatrix = GLKMatrix4MakeLookAt(newX, 0.0, newZ 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);这是一个投影矩阵?还是我错过了什么?在这种情况下也没有完全发生意味着白屏,那里什么也没有。

标签: ios opengl-es opengl-3 glkit


【解决方案1】:

您的 ModelView 和 Projection 矩阵设置不正确 - 在这两者之间您有一个模型视图转换,但没有从眼睛空间到剪辑空间的投影。

要理解为什么,学习坐标空间、变换以及它们在 3D 图形编程中的常见作用是有帮助的...那里有很多很好的教程(like this one——它适用于桌面 GL,并使用 C++ GLM 库,对于 iOS,您最好使用 GLKit 数学,但概念是相同的),但这里有一个快速概述。


在传统的图形管道中(由GLKBaseEffect 建模),您可能关心四个坐标空间:

  • 模型空间是定义您的顶点数据的任意坐标系。例如,如果您正在绘制一个具有很多四四方方形状的场景,您可以只定义一个单位立方体以原点为中心,并使用变换将其拉伸、移动和旋转到场景中的不同位置。

  • 世界空间是您设计场景的任意坐标系。例如,如果您使用该立方体绘制城市景观,您可以将原点放在街角并在 X 和 Z 方向平移立方体以制作建筑物。

  • 眼睛(或相机或视图)坐标空间是根据您查看场景的方式定义的。前两个空间可以用任何方便的方式定义,但是有了这个空间开始映射到屏幕的规则。在眼睛空间中,X 轴向右增加,Y 轴向上增加,Z 轴指向你身后——即相机看向负 Z 方向。

  • 剪辑 空间是橡胶与道路的交汇处——它是 OpenGL (ES) 选择要绘制的内容以及它在屏幕上的位置的地方。因此,它的定义非常严格:立方体中所有三个轴上从-1.0 延伸到1.0 的任何东西都会出现在屏幕上。 (立方体之外的任何东西都会被“剪裁”。)与眼睛空间一样,+X 是正确的,+Y 是向上的,+Z 是更靠近观察者。

顶点处理最多使用三个转换(通常串联在一起)来获取您的顶点数据(在模型空间中指定)一直到剪辑空间,以便 OpenGL (ES) 可以绘制它。每个转换都由一个 4x4 矩阵指定(GLKBaseEffect 是一个GLKMatrix4),它本身可能是多个转换的串联。

  • Model 矩阵从模型空间转换为世界空间。那个城市景观的例子?对于每栋建筑,您在一个方向上缩放立方体以制作摩天大楼,然后在 X 和 Z 方向上平移它以将其放置在世界中——这就是模型变换。

  • View 矩阵从 World 空间转换为 Eye 空间。您可以从平移和旋转构建视图矩阵(毕竟,移动相机与向相反方向移动世界相同),但大多数 3D 数学库都为您提供了方便,例如 GLKMatrix4MakeLookAt,让您可以指定视图变换a)相机的位置,b)你正在看的点,c)哪个方向应该是“向上”。

  • Projection 矩阵从 Eye 空间转换为 Clip 空间。通常,您使用透视投影 (GLKMatrix4MakePerspective),它根据视角、纵横比以及远近限制来定义您可以看到的内容。 (换句话说,您可以看到的区域适合从您的眼睛向外延伸到无穷大的金字塔内部,我们从该金字塔切出一个部分,或 frustrum,以定义实际获得的深度范围画在屏幕上。)

要将顶点数据渲染到屏幕上,它必须经过所有三个转换——通常它们相乘以创建一个 ModelViewProjection 矩阵,然后将其提供给 GPU 用于转换每个顶点位置。光照计算通常在眼睛空间中完成,因此您通常会单独向 GPU 提供一个 ModelView 矩阵(或者更确切地说,它的逆转置,用于转换表面法线)。

当您使用GLKBaseEffect 时,您提供了一个 ModelView 矩阵和一个 Projection 矩阵,它会根据需要将它们相乘或反转。


还在这里吗? :)

你得到的是从模型空间到眼睛空间的转换。 (在像您这样的简单场景中,模型空间和世界空间通常是相同的。)您没有到剪辑空间的投影变换,因此 OpenGL ES 将您的眼睛空间解释为就好像它应该是剪辑空间一样。根据您的顶点坐标,您的所有几何图形可能都在 -1 到 1 立方体之外,因此您什么都看不到。

到目前为止,您所做的所有转换都应该相乘并作为 ModelView 矩阵提供给GLKBaseEffect。然后,使用您已经计算的纵横比创建透视投影 (GLKMatrix4MakePerspective),并将其作为投影矩阵提供给 GLKBaseEffect

【讨论】:

  • 谢谢,我想我现在明白了。将开始实施。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多