【问题标题】:How do I render 3d objects with 2d GUI (nifty-gui) correctly?如何使用 2d GUI (nifty-gui) 正确渲染 3d 对象?
【发布时间】:2012-11-28 22:58:36
【问题描述】:

我有这个代码:https://github.com/magicgoose/lwjgl-nifty-test-project 当我只渲染 GUI 时,它会像预期的那样工作。当我尝试渲染三角形(在透视投影中)然后渲染 GUI 时,一切都失败了,甚至 GUI 也无法正确渲染——我只得到黑色背景上的字母。 (如果我取消注释就会发生这种情况 draw_something() 方法中的draw_something() 语句)

private def draw_something() {
    glTranslatef(0, 0, -20)
    glBegin(GL_TRIANGLES)
    glVertex3f(0.0f, 1.0f, 0.0f)
    glVertex3f(-1.0f, -1.0f, 0.0f)
    glVertex3f(1.0f, -1.0f, 0.0f)
    glEnd()
}

我做错了什么? 我尝试在背景上搜索带有漂亮 gui 和 3d 图形的工作示例,但没有运气。

更新 1

我已经根据 datenwolf 的回答更改了代码,现在 GUI 渲染正常,但我只能在几毫秒内看到白色三角形(实际上它可能在一个帧中?),似乎 3d 设置正在“损坏”...仅当我渲染 GUI 时才会发生这种情况,如果我注释行 gui.render(false),白色三角形会留在屏幕上。

更新 2

我为 3d 部分添加了一些动作(请参阅存储库中的更新),现在我可以看到三角形几乎不可见(看起来像 z 战斗)。

【问题讨论】:

  • 你在显示函数开头的glClear调用中添加了GL_DEPTH_BUFFER_BIT吗?
  • 因为我不知道 NiftyGUI 在哪个 z 级别上绘制了它的东西:您是否尝试使用 glOrtho 而不是 gluOrtho2D 并为 near 和 fast 参数使用不同的值(最后两个)? gluOrtho2D 相当于调用glOrtho,近 = 0 远 = 1。
  • @bluenote10 现在试试这个。似乎它只影响 Nifty GUI 本身:如果它的 z 级别超出范围,它不会绘制,但是如果我尝试在 @987654333 中调用 gui.render(false),三角形会被任何 zNearzFar 值损坏@。这似乎是合乎逻辑的,因为display_ready2d(...) 中有glDisable(GL_DEPTH_TEST)。顺便说一句,测试表明 NiftyGUI 在 z=0 处绘制。 (或接近于零)

标签: scala opengl 3d lwjgl nifty-gui


【解决方案1】:

您必须在正交投影和透视投影之间切换。为此准备了两个函数:display_ready2d(设置正射投影矩阵)和display_ready3d(设置透视投影)。

不幸的是,display_ready3d 函数在应用更改之前不会重置矩阵堆栈。您必须在调用 gluPerspective 之前添加 glLoadIdentity。此外,您不应该清除这些函数中的帧缓冲区,因为您希望能够在矩阵设置之间切换。所以改成这样:

private def display_ready3d(fov: Float, aspect: Float) {
    glMatrixMode(GL_PROJECTION)
            glLoadIdentity();
    gluPerspective(fov, aspect, 0.01f, 100.0f)

    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

    glEnable(GL_DEPTH_TEST)
}

display_ready2d 在绘制 GUI 之前和 display_ready3d 在 draw_something 之前。此外,您必须将清除命令放在那里,这也需要覆盖深度缓冲区;透明色的 alpha 值也应为 1(除非您创建了透明窗口)。

def display(width: Int, height: Int, AR: Float, gui: Nifty) {
            glViewport(0, 0, width, height)
            glClearDepth(1.)
            glClearColor(0., 0., 0., 1.)
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    display_ready3d(90, width/height)
    draw_something()

    display_ready2d(width, height)
    gui.render(false)

    glFlush()
    Display.update()
}

【讨论】:

  • 感谢您的大开眼界。现在还有另一个问题,请参阅更新的问题。
  • @SargeBorsch 另一个问题需要单独发布问题,而不是更新原始问题。
  • @beaker 这仍然与“如何使用 2d GUI 正确渲染 3d 对象?”有关,不是吗?
  • @SargeBorsch 你可能是对的。在更仔细地查看了您的更新和代码之后,我可能说得太快了。当然,无论如何我都会服从 datenwolf。
  • 我找到了最终解决方案,将其发布为答案。
【解决方案2】:

我在我的一个项目中使用以下代码来实现这一点。 datenwolf 解决方案的主要区别在于,您不必在每次从 GUI 模式切换回时设置 3D 透视图。在我的情况下,我有一个相当复杂的 3D 透视设置,因此,依靠这种推/弹出矩阵方法更方便。

如果您在 3D 模式下启用了闪电,您可能还需要考虑为 GUI 模式关闭闪电,以确保 GUI 颜色不受灯光影响。

def enableOrthoView(winW: Int, winH: Int) {   
  glMatrixMode(GL_PROJECTION)                 // Select projection
  glPushMatrix()                              // Push the matrix
  glLoadIdentity()                            // Reset the matrix
  glOrtho(0, winW, winH, 0, -1, 1)            // Select ortho mode
  glMatrixMode(GL_MODELVIEW)                  // Select Modelview matrix
  glPushMatrix()                              // Push the Matrix
  glLoadIdentity()                            // Reset the Matrix
  glDisable(GL_DEPTH_TEST)                    // Cure z-fighting
  glDisable(GL_LIGHTING)                      // Ensure unaffected colors
}

def disableOrthoView() {
  glMatrixMode(GL_PROJECTION)                 // Select projection
  glPopMatrix()                               // Pop the matrix
  glMatrixMode(GL_MODELVIEW)                  // Select Modelview
  glPopMatrix()                               // Pop the matrix
  glEnable(GL_DEPTH_TEST)    
  glEnable(GL_LIGHTING)
}

【讨论】:

    【解决方案3】:

    我找到了 3D 图形闪烁/消失问题的根源。在OpenGL中,如果你在不提供纹理的情况下绘制几何图形,则必须禁用纹理,所以我写了

    glDisable(GL_TEXTURE_2D)

    display_ready3d(...) 的末尾,现在一切都在做它必须做的事情。我在这里阅读另一个相关问题的答案时意外地意识到了这个失败:https://gamedev.stackexchange.com/questions/44437/lwjgl-mixing-2d-and-3d 还要感谢datenwolfbluenote10,您的帮助非常宝贵。

    【讨论】:

      猜你喜欢
      • 2016-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-14
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 2017-01-30
      相关资源
      最近更新 更多