Http://bbs.9ria.com/thread-221701-1-1.html
In the previous tutorial, we have seen how to set the Libgdx render 3D scene. We've set up the camera, added some lights and rendered a green box. Now let's add a more interesting thing than a box model.
You can get from your favorite modeling application or use an existing model. I found the gdx-invaders inside the spaceship model file, you can click here to download. You can unzip the file and place it in the assets directory of the Android project. Note that it contains three files that need to be placed in the same folder:
Ship.obj: The wavefront model file we want to load
Material file used by the Ship.mtl:wavefront model file
Ship.png: Texture file
Now let's modify the Basic3dtest and replace the original square box with the model:
- public class Basic3dtest implements Applicationlistener {
- ...
- @Override
- public void Create () {
- modelbatch = new Modelbatch ();
- lights = new Lights ();
- Lights.ambientLight.set (0.4f, 0.4f, 0.4f, 1f);
- Lights.add (New DirectionalLight (). Set (0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
-
- cam = new Perspectivecamera (Gdx.graphics.getWidth (), Gdx.graphics.getHeight ());
- Cam.position.set (1f, 1f, 1f);
- Cam.lookat (0,0,0);
- cam.near = 0.1f;
- Cam.far = 300f;
- cam.update ();
-
- Modelloader loader = new Objloader ();
- model = Loader.loadmodel (Gdx.files.internal ("Data/ship.obj"));
- instance = new Modelinstance (model);
-
- camcontroller = new Camerainputcontroller (CAM);
- Gdx.input.setInputProcessor (camcontroller);
- }
- ...
- }
Copy Code
Only a little change, first, the camera is closer to the origin, because the ship is too small, then we deleted the ModelBuilder, a new modelloader, through this loader, loaded a model ship. The result is like this:
<ignore_js_op>
2013-6-27 18:15:50 Upload
Download Attachments (84.89 KB)
In doing so, there is nothing wrong with testing, but in large applications you will need to Assetmanager to manage the model files. Below, let's add:
- public class Basic3dtest implements Applicationlistener {
- public Perspectivecamera Cam;
- Public Camerainputcontroller Camcontroller;
- Public Modelbatch Modelbatch;
- public Assetmanager assets;
- Public array<modelinstance> instances = new array<modelinstance> ();
- Public Lights Lights;
- public boolean loading;
- @Override
- public void Create () {
- Modelbatch = new Modelbatch ();
- Lights = new Lights ();
- Lights.ambientLight.set (0.4f, 0.4f, 0.4f, 1f);
- Lights.add (New DirectionalLight (). Set (0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
- Cam = new Perspectivecamera (Gdx.graphics.getWidth (), Gdx.graphics.getHeight ());
- Cam.position.set (1f, 1f, 1f);
- Cam.lookat (0,0,0);
- Cam.near = 0.1f;
- Cam.far = 300f;
- Cam.update ();
- Camcontroller = new Camerainputcontroller (CAM);
- Gdx.input.setInputProcessor (Camcontroller);
- Assets = new Assetmanager ();
- Assets.load ("Data/ship.obj", Model.class);
- Loading = true;
- }
- private void doneloading () {
- Model ship = assets.get ("Data/ship.obj", Model.class);
- Modelinstance shipinstance = new modelinstance (ship);
- Instances.add (shipinstance);
- Loading = false;
- }
- @Override
- public void render () {
- if (Loading && assets.update ())
- Doneloading ();
- Camcontroller.update ();
- Gdx.gl.glViewport (0, 0, Gdx.graphics.getWidth (), Gdx.graphics.getHeight ());
- Gdx.gl.glClear (Gl10.gl_color_buffer_bit | Gl10.gl_depth_buffer_bit);
- Modelbatch.begin (CAM);
- for (Modelinstance instance:instances)
- Modelbatch.render (instance, lights);
- Modelbatch.end ();
- }
- @Override
- public void Dispose () {
- Modelbatch.dispose ();
- Instances.clear ();
- Assets.dispose ();
- }
- public Boolean needsGL20 () {
- return true;
- }
- public void Resume () {
- }
- public void Resize (int width, int height) {
- }
- public void Pause () {
- }
- }
Copy Code
The
has changed over and over, removed the model instance, created the Assetmanager, and we did not use a single Modelinstance object, but we created an array to render multiple instances, which looks more realistic. We also added a flag that marks whether the load is in progress.
Now, in the Create method, we create a asset manager and load the spaceship's model file through him. Shortly thereafter, we set the loading flag and, through it, we can tell that we need to update Assetmanager to get the resource loading state. In the Render method, we read the value of loading flag, if true, indicating that asset manager is loading the resource, we need to call Assets.update (), and if True is returned, the load ends, Call Doneloading (). Also in the Render method, we render all objects in the instance array, not just one. If the resource is not successfully loaded, the array is empty. The
New Method doneloading () Gets the ship model that we just loaded, creates a modelinstance named Shipinstance, and adds it to the instances array so that it is rendered. Finally, we need to set the load flag to false, after which assets.update () will no longer be called.
If you run this, you'll see the same picture as before. And, you'll see a black screen before you see the ship, which is caused by the asset manager loading the model asynchronously.
Our program supports multiple model instances, so let's change to the following.
- public class Basic3dtest implements Applicationlistener {
- ...
- @Override
- public void Create () {
- ...
- Cam.position.set (7f, 7f, 7f);
- ...
- }
- private void doneloading () {
- Model ship = assets.get ("Data/ship.obj", Model.class);
- for (float x = -5f; x <= 5f; x + = 2f) {
- for (float z = -5f; z <= 5f; z + = 2f) {
- Modelinstance shipinstance = new modelinstance (ship);
- ShipInstance.transform.setToTranslation (x, 0, z);
- Instances.add (shipinstance);
- }
- }
- Loading = false;
- }
- ...
- }
Copy Code
We've turned the camera away again, so we can show all the ship on the screen. You can use the mouse wheel to control the distance (zoom in, zoom out). In the Doneloading method, we create multiple instance and place it in a grid based on the X-Z axis.
<ignore_js_op>
2013-6-27 18:15:49 Upload
Download Attachments (118.78 KB)
Testing with obj (wavefront) files is good, but in real-world applications, it's not appropriate because this format doesn't have enough information to store complex models. And in Libgdx, Objloader is for testing purposes, not too much may be the function you want.
Fortunately, we have: Fbx-conv, which can convert model files generated by modeling software into LIBGDX recognizable formats. The name can be a bit misleading, FBX-CONV can convert many formats including FBX, (including obj), FBX is the preferred file format because almost all modeling programs support it.
Get Fbx-conv Running program, if you haven't, you can download the source code, or download the Windows version of, click to download (should not be up to date). Fbx-conv can generate two formats, G3DJ (JSON, for debugging) &g3db (binary, when the program is published, because it is smaller and loads faster).
The command runs as follows:
- Fbx-conv Ship.obj
Copy Code
Make sure that the other files are in the same directory, and it will generate a file named ship.g3db for you. Let's take a look at the program:
- public class Basic3dtest implements Applicationlistener {
- ...
- @Override
- public void Create () {
- ...
- Assets.load ("data/ship.g3db", Model.class);
- ...
- }
- private void doneloading () {
- Model ship = assets.get ("data/ship.g3db", Model.class);
- ...
- }
- ...
- }
Copy Code
Original address: http://blog.csdn.net/q26335804/article/details/8994401
LIBGDX New 3D API Tutorial--Loading models with LIBGDX