具有纬度/经度OpenGL的线框球体

时间:2014-10-05 21:32:00

标签: java opengl

我尝试使用具有纬度和经度线的openGL创建线框球体。目前我遇到了一个问题,我认为我只是忽略了一些帮助,可以通过创建球体来快速纠正。我的代码是在创建显示的类中的以下内容:

double rho = 1;
gl.glBegin(GL2.GL_LINE_LOOP);
for (int i = 0; i< 360; i++){
     theta = i/180 * Math.PI;
     for (int j = 0; j< 360; j++){
           double phi = j/180 * Math.PI;
           double x = rho * Math.sin(phi) * Math.cos(theta);
           double y = rho * Math.sin(phi) * Math.sin(theta);
           double z = rho * Math.sin(phi);
           gl.glVertex3d(x, y, z);
     }
     gl.glEnd();
}

从这段代码中,我目前没有得到任何显示内容。我错过了什么?

1 个答案:

答案 0 :(得分:2)

此代码中存在许多问题:

  1. 正如评论中已经指出的那样,glBegin()glEnd()是不平衡的。 glBegin()需要在第一个循环中。
  2. 第二个角度应仅从0到180循环,而不是360.这是基于球面坐标的定义。
  3. 在分部i/180j/180中,两个值都是int类型,因此操作是整数除法。使用这些值时,这些除法的结果将始终为0或1。
  4. z坐标的计算需要使用cos(phi)而不是sin(phi)
  5. 没错,只是建议:

    1. 无需使用双精度值。无论如何,OpenGL将使用单精度。
    2. 正如评论中所提到的,代码使用的是在现代版本的OpenGL中不推荐使用的旧版功能。
    3. 坚持使用立即模式绘图,修复这些问题应该会导致工作(未经测试)代码:

      float radius = 1.0f;
      for (int i = 0; i <= 360; i++) {
          gl.glBegin(GL2.GL_LINE_LOOP);
          float theta = i * (Math.PI / 180.0f);
          for (int j = 0; j <= 180; j++) {
              float phi = j * (Math.PI / 180.0f);
              float x = radius * Math.sin(phi) * Math.cos(theta);
              float y = radius * Math.sin(phi) * Math.sin(theta);
              float z = radius * Math.cos(phi);
              gl.glVertex3f(x, y, z);
          }
          gl.glEnd();
      }
      

      这将为您提供经度线。纬度线的代码非常相似,交换了两个循环。

      关于弃用/遗留功能的讨论,这里有一点涉及。所以只是一个非常快速的总结:

      您在这里使用的通常称为“立即模式绘图”。这是OpenGL在原始版本中的工作方式。大约20年前引入了更有效的指定顶点数据的方法。最初是Vertex Arrays,然后是Vertex Buffer Objects(VBO)。后来引入了顶点数组对象(VAO),使状态设置更有效。

      使用2009年推出的OpenGL 3.2,定义了两个“配置文件”:

      • 核心配置文件:删除已弃用的旧版功能,包括立即模式绘制。
      • 兼容性配置文件:仍然支持所有功能以保持向后兼容性。

      如果你编写新代码,特别是如果你刚刚开始学习,那么没有充分的理由去学习遗留功能。使用核心配置文件时,初始阈值略高(主要是因为它要求您在GLSL中编写自己的着色器),但这非常值得。当前版本的OpenGL ES也更接近核心配置文件,并且没有任何这些遗留特性。