Using the Blender Generated Game Level in LibGDX

I recently published a tutorial on creating a game level in Blender over three parts, but I never actually illustrated how such a level would be used by a game engine.  A user on /r/gamedev asked exactly this question, so I figured I would throw together a quick post showing how such content could be loaded into a game engine, in this case LibGDX.  This code is lifted directly from my LibGDX tutorial series, as is further information on how to export your model from Blender.

Here is the process…

First, and this is LibGDX specific… there is a data size limit of short int (32k) for the number of indices you can have.  This means by default the landscape we have generated is too dense for use in LibGDX.  I simply applied the decimate modifier to the plane object to get my face count down to 8,600.

image

Now export the scene as an FBX file.  Default settings should work fine.  Next you need the FBX-Conv for your platform, which can be downloaded here.

With the FBX file and the proper fbx-conv.exe extracted to the same folder, run the command:

fbx-conv.exe -f -o G3DJ level.fbx

Obviously change the exe name and level name to match your own.  This will generate a g3dj file, copy it to the assets folder of your LibGDX project.  You also need to copy in the Skybox and Ground textures you used in this project to the assets folder.  If these files are embedded in your .Blend file, you can export them using the command File->External Data->Unpack All Into Files or you can manually save the files externally in UV Image Editor.

image

Now with all of these files copied into your assets folder, write the following code:

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() {
	}
}

And when you run this code:

resizedLevelGif

Scroll to Top