ModelBuilder end () не работает должным образом "com.badlogic.gdx.utils.GdxRuntimeException: сначала вызовите end ()" - PullRequest
0 голосов
/ 16 мая 2018

Я просто пытаюсь получить базовую коробку с помощью LibGDX (используя Kotlin & LibKTX), но сталкиваюсь с некоторыми проблемами.

Если я вызываю функцию ModelBuilder createBox без указанной begin()и 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(), прежде чем я даже создаю узлы, что сбивает с толку.Я чувствую, что я делаю что-то очень простое здесь неправильно, так как я смог вернуть базовые 3D-примеры обратно, когда я пытался сделать это с Java несколько лет назад.

Итак, два вопроса:

  • Почему LibGDX говорит, что мне нужно вызвать end(), прежде чем я создаю узлы с ModelBuilder?
  • . Использование modelBuilder.begin() и modelBuilder.end() на самом деле лучший способ использоватьModelBuilder?Я еще не видел 3D пример сделать это.По общему признанию, все трехмерные примеры, которые я нашел, были с 2013 года, так что это может быть просто добавлено.В разделе LibGDX 3D говорится, что это набор учебных пособий, в которых не используются функции begin() и end(), поэтому я немного запутался в том, что такое "наилучшая практика".

Спасибо за любую помощь!

edit: Я пробовал это с загруженной моделью, и у нее та же проблема.Хм ..

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 голосов
/ 16 мая 2018
  1. LibGDX не говорит о вызове end () перед созданием узла, но о том, что уже существует существующая модель, которая была создана. Поэтому перед созданием другого вам нужно вызвать end ().

  2. Из вашего примера кода выдается исключение GdxRuntimeException в том, что вы вызываете begin (), а затем createBox (). createBox () фактически вызывает begin () в функции. (посмотрите здесь: https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g3d/utils/ModelBuilder.java) Следовательно, при следующем вызове begin () модель не равна нулю, и генерируется исключение.

Для передового опыта, если createBox () может удовлетворить ваш запрос, чем просто использовать это. Если вам нужно что-то более сложное, например, createSphere (), createCapsule () не работают для вас, вам нужно вызвать begin (), part (...) и end ().

Надеюсь, это поможет!

...