【问题标题】:OpenGL Newbie - Best way to move objects about in a sceneOpenGL新手 - 在场景中移动对象的最佳方式
【发布时间】:2010-06-27 08:49:43
【问题描述】:

我是 OpenGL 和图形编程的新手,虽然我一直对这个话题很感兴趣,所以对理论有一定的了解。

我想做的是创建一个场景,其中一组对象在其中移动。具体来说,他们是球场上的机器人足球运动员。对象是:

  • 灯光、场地和球门不会改变
  • 球,这是一个单一的网格,将进行平移和旋转,但不会缩放
  • 每个球员都由身体部位组成,每个部位都被平移和旋转以产生身体相连的错觉

所以对于我的 GL 新手来说,我想将这些对象加载到场景中,然后移动它们。顶点的任何属性都不会改变,无论是它们的位置还是纹理/法线/等。只是将它们的“父”对象作为一个整体进行转换。

此外,所有球员都有相同的身体。我可以通过将模型加载到内存一次,然后每次使用不同的变换矩阵多次绘制它来进行优化吗?

我目前正在使用 OpenTK,它是 OpenGL 库之上的轻量级包装器。

所以对这个问题有帮助的答案是:

  • OpenGL 的哪些部分可以满足我的需求?我必须每帧重画所有的脸吗?只有那些会动的?我可以只更新一些转换矩阵吗?使用 OpenTK 可以使这变得多么简单?伪代码会是什么样子?或者,
  • 是否有更好的免费框架(最好是开源的)并提供这种抽象级别?

请注意,我需要任何解决方案才能在 .NET across multiple platforms 中运行。

【问题讨论】:

    标签: language-agnostic opengl graphics 3d


    【解决方案1】:

    使用所谓的顶点数组可能是优化此类场景的最可靠方法。这是一个很好的教程:

    http://www.songho.ca/opengl/gl_vertexarray.html

    一个顶点数组或更一般地说,一个 gl 数据数组保存顶点位置、法线、颜色等数据。您还可以有一个数组来保存这些缓冲区的索引,以指示绘制它们的顺序。
    然后你有一些密切相关的函数来管理这些数组,分配它们,为它们设置数据并绘制它们。只需一个 OpenGL 命令(如 glDrawElements()

    )即可执行复杂网格的渲染

    这些数组通常驻留在主机内存中,进一步的优化是使用顶点缓冲区对象,它与常规数组的概念相同,但驻留在 GPU 内存上,并且速度更快。这里有一点:

    http://www.songho.ca/opengl/gl_vbo.html

    使用缓冲区而不是旧的 glBegin() .. glEnd() 具有与 OpenGL ES 兼容的优势。在 OpenGL ES 中,数组和缓冲区是绘制东西的唯一方法。

    --- 编辑

    在场景中移动、旋转和变换它们是使用模型视图矩阵完成的,并且不需要对网格数据进行任何更改。举例说明:

    你已经初始化了:

    void initGL() {
      // create set of arrays to draw a player
      // set data in them
      // create set of arrays for ball
      // set data in them
    }
    
    void drawScene {
      glMatrixMode(GL_MODEL_VIEW);
      glLoadIdentity();
      // set up view transformation
      gluLookAt(...);
      drawPlayingField();
    
      glPushMatrix();
      glTranslate( player 1 position );
      drawPlayer();
      glPopMatrix();
    
      glPushMatrix();
      glTranslate( player 2 position );
      drawPlayer();
      glPopMatrix();
    
      glPushMatix();
      glTranslate( ball position );
      glRotate( ball rotation );
      drawBall();
      glPopMatrix();
    }
    

    【讨论】:

    • 这解释了绘制网格的基本机制,但是如何移动它们(如问题标题所示)?我可以在应用了不同转换的一帧中多次重复使用相同的网格吗?我应该使用哪个,VBO 还是 VA?
    • 感谢您的更新。这看起来不错,我有一个初步版本,每帧运行多次绘制单个 VBO。看到它融合在一起非常令人兴奋,尽管现在我需要整理照明。感谢您的帮助。
    【解决方案2】:

    既然您开始了,我建议坚持立即模式渲染并首先使其工作。如果你变得更舒服,你可以改进到顶点数组。如果你变得更舒服,VBO。最后,如果您感觉超级舒服,实例化是您的情况的最快解决方案(没有变形,只有整个对象转换)。

    除非您尝试实现像 2009 年国际足联这样的东西,否则最好坚持使用简单的方法,直到您遇到明显的效率问题。不必过早地让自己头疼。

    对于整个对象的转换,您通常会转换模型视图矩阵。

    glPushMatrix();
    // do gl transforms here and render your object
    glPopMatrix();
    

    对于加载对象,您甚至需要提出一些格式或实现一些可以加载网格格式的东西(obj 是最容易支持的格式之一)。有高级库可以简化此操作,但我建议您使用 OpenGL 以获得您将拥有的体验和控制。

    【讨论】:

      【解决方案3】:

      我希望 OpenGL API 可以通过 IDE 支持(智能感知等)轻松导航。几个小时后,很明显需要建立一些基本规则。所以我停止打字和 RTFM。

      http://www.glprogramming.com/red/

      对于在寻找 OpenGL 立足点时发现此问题的任何其他人,我可以给出最好的建议。长篇大论,但很有力量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-08
        • 2014-07-31
        • 1970-01-01
        相关资源
        最近更新 更多