Recientemente publiqué un tutorial sobre cómo crear un nivel de juego en blender en tres partes, pero en realidad nunca ilustré cómo un motor de juego usaría ese nivel. Un usuario en /r/gamedev hizo exactamente esta pregunta, así que pensé en hacer una publicación rápida que mostrara cómo se puede cargar dicho contenido en un motor de juego, en este caso LibGDX. Este código se extrae directamente de mi serie de tutoriales LibGDX, al igual que más información sobre cómo exportar su modelo desde Blender.
Aquí está el proceso…
Primero, y esto es específico de LibGDX… hay un límite de tamaño de datos de int corto (32k) para la cantidad de índices que puede tener. Esto significa que, por defecto, el paisaje que hemos generado es demasiado denso para usarlo en LibGDX. Simplemente apliqué el modificador diezmar al objeto plano para que mi cara contara hasta 8600.
Ahora exporte la escena como un archivo FBX. La configuración predeterminada debería funcionar bien. A continuación, necesita el FBX-Conv para su plataforma, que puede ser descargado aquí.
Con el archivo FBX y el fbx-conv.exe adecuado extraídos en la misma carpeta, ejecute el comando:
fbx-conv.exe -f -o nivel G3DJ.fbx
Obviamente, cambie el nombre del exe y el nombre del nivel para que coincida con el suyo. Esto generará un archivo g3dj, cópielo en la carpeta de activos de su proyecto LibGDX. También debe copiar las texturas Skybox y Ground que utilizó en este proyecto en la carpeta de activos. Si estos archivos están incrustados en su archivo .Blend, puede exportarlos usando el comando Archivo->Datos externos->Desempaquetar todo en archivos o puede guardar manualmente los archivos externamente en el Editor de imágenes UV.

Ahora, con todos estos archivos copiados en su carpeta de activos, escriba el siguiente código:
package com.gamefromscratch.levelloader; import com.badlogic.gdx.ApplicationListener; import com.badlogic.gdx.Files.FileType; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.PerspectiveCamera; import com.badlogic.gdx.graphics.g3d.Environment; import com.badlogic.gdx.graphics.g3d.Model; import com.badlogic.gdx.graphics.g3d.ModelBatch; import com.badlogic.gdx.graphics.g3d.ModelInstance; import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute; import com.badlogic.gdx.graphics.g3d.loader.G3dModelLoader; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.utils.JsonReader; import com.badlogic.gdx.utils.UBJsonReader; import com.badlogic.gdx.graphics.g3d.utils.AnimationController; import com.badlogic.gdx.graphics.g3d.utils.AnimationController.AnimationDesc; import com.badlogic.gdx.graphics.g3d.utils.AnimationController.AnimationListener; public class LevelLoader implements ApplicationListener { private PerspectiveCamera camera; private ModelBatch modelBatch; private Model model; private ModelInstance modelInstance; private Environment environment; @Override public void create() { camera = new PerspectiveCamera( 90, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); camera.position.set(0f,0f,300f); camera.lookAt(0f,0f,1f); camera.near = 0.1f; camera.far = 5000.0f; modelBatch = new ModelBatch(); JsonReader jsonReader = new JsonReader(); G3dModelLoader modelLoader = new G3dModelLoader(jsonReader); model = modelLoader.loadModel(Gdx.files.getFileHandle("level.g3dj", FileType.Internal)); modelInstance = new ModelInstance(model); environment = new Environment(); environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.8f, 0.8f, 0.8f, 1.0f)); } @Override public void dispose() { modelBatch.dispose(); model.dispose(); } @Override public void render() { Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); Gdx.gl.glClearColor(1, 1, 1, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); camera.rotateAround(Vector3.Zero, new Vector3(0,1,0),1f); camera.update(); modelBatch.begin(camera); modelBatch.render(modelInstance, environment); modelBatch.end(); } @Override public void resize(int width, int height) { } @Override public void pause() { } @Override public void resume() { } }
Y cuando ejecutas este código:
