模型构建器end()不能正常工作" com.badlogic.gdx.utils.GdxRuntimeException:首先调用end()"

时间:2018-05-16 15:21:08

标签: libgdx kotlin

我只想尝试使用LibGDX(使用Kotlin和LibKTX)渲染基本框,但遇到了一些问题。

如果我在没有指定createBoxbegin()函数的情况下调用ModelBuilder end()函数,则不会呈现我的框。我检查了材料,相机位置,边界框,添加了光源等等,但它只是......不在那里。我认为问题在于我构建节点的方式,因为我无法找到材料的问题。

这就是我试图渲染我的方框:

class HomeView(private val baseUI: BaseUI) : KtxScreen {

    private val cam by lazy { PerspectiveCamera(67f, baseUI.aWidth, baseUI.aHeight) }
    private val boxInstance: ModelInstance
    private val modelBatch: ModelBatch
    private val modelBuilder: ModelBuilder by lazy { ModelBuilder() }
    private val vertexAttributes =
        VertexAttributes.Usage.Position.toLong() or
        VertexAttributes.Usage.Normal.toLong() or
        VertexAttributes.Usage.TextureCoordinates.toLong()
    private val greenMat by lazy { Material(ColorAttribute.createDiffuse(Color.GREEN)) }
    private val environment by lazy { Environment() }
    //------ end global

    init {
        cam.position.set(vec3(-10f, -10f, 10f))
        cam.lookAt(0f, 0f, 0f)
        cam.near = .1f
        cam.far = 10f
        cam.update()

        modelBatch = ModelBatch()

        modelBuilder.begin()
        modelBuilder.createBox(5f, 5f, 5f, greenMat, vertexAttributes)
        boxInstance = ModelInstance(modelBuilder.end())

        environment.set(ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f))
        environment.add(DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f))
    }

    override fun render(delta: Float) {
        Gdx.gl.glViewport(0, 0, baseUI.aWidth.toInt(), baseUI.aHeight.toInt())
        //this is working, screen appears grey
        clearScreen(.3f, .3f, .3f, 1f)

        modelBatch.begin(cam)
        modelBatch.render(boxInstance, environment)
        modelBatch.end()
    }

    //rest omitted
}

这是我用来添加屏幕的我的BaseUI类(我只是试图测试屏幕,这只是出于测试目的所以请忽略低效率)

class BaseUI : KtxGame<KtxScreen>(), KtxApplicationAdapter {
    val aWidth by lazy { Gdx.graphics.width.toFloat() }
    val aHeight by lazy { Gdx.graphics.height.toFloat() }

    override fun create() {
        addScreen(HomeView(this))
        setScreen<HomeView>()
    }

    override fun render() {
        super<KtxGame>.render()
    }

    //rest ommitted
}

当我运行时,我收到以下错误: Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException: Call end() first

这使得我甚至需要在创建节点之前调用modelBatch.end(),这令人困惑。我觉得我在这里做了一些非常基本的错误,因为几年前我在使用Java时尝试使用基本的3D示例。

所以,有两个问题:

  • 为什么LibGDX说我需要在使用end()创建节点之前调用ModelBuilder
  • 使用modelBuilder.begin()modelBuilder.end()实际上是使用模型构建器的最佳方式吗?我还没有看到3D示例这样做。不可否认,我发现的所有3D示例都来自2013年,所以这可能只是添加了一些内容。 LibGDX 3D部分说使用this一组不使用begin()end()函数的教程,所以我对于什么是&#34;最佳实践&#34;。

感谢您的帮助!

编辑:我尝试使用已加载的模型并且它具有相同的问题。嗯..

edit2:感谢您Xoppa帮助我找出问题所在。 LibKTX特定函数clearScreen()未按预期包含GL20.GL_COLOR_BUFFER_BIT清除函数,这是我阅读文档时的不好之处。将此添加到我的渲染功能会按预期显示绿色框:

Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT or GL20.GL_DEPTH_BUFFER_BIT)

1 个答案:

答案 0 :(得分:1)

  1. LibGDX并不是说在创建节点之前调用end(),而是已经创建了一个现有模型。因此,在创建另一个之前,您需要调用end()。

  2. 从您的代码示例中,抛出GdxRuntimeException的原因是您调用begin()然后调用createBox()。 createBox()实际上在函数中调用begin()。 (看看这里:jwt handler)因此,下一个begin()调用模型不为null并抛出异常。

  3. 对于最佳实践,如果createBox()可以满足您的请求而不仅仅是使用它。如果你需要更复杂的东西,比如createSphere(),createCapsule()不适合你,那么你需要调用begin(),part(...)和end()。

    希望这有帮助!