LIBGDX Carga Modelos3D

De MediaWiki
Revisión del 17:26 17 feb 2016 de Wiki (discusión | contribuciones) (→‎Carga Modelos obj)
(dif) ← Revisión anterior | Revisión actual (dif) | Revisión siguiente → (dif)
Ir a la navegación Ir a la búsqueda

UNIDADE 4: Carga de Modelos 3D


Deseñando os nosos modelos 3D

Loxicamente os nosos modelos 3D non vai ser creados 'manualmente', se non utilizando programas gráficos.

Algún deles:

Moi completo pero tamén bastante complexo.
Bastante máis sinxelo.

Nos imos usar o wings3d aínda que os alumnos podedes utilizar calquera que manexedes.


A continuación tedes un enlace con tres vídeos (e o códec de vídeo por se non o visualizades) de como se manexa o Wings3D e como podemos crear un obxecto 3D e asinarlle unha textura.


Enlace a vídeos explicativos Wings3D



Conversión de formatos en 3D

En canto os formatos gráficos que podemos cargar están, entre outros:


Para pasar dun formato a outro podemos utilizar unha ferramenta: fbx-conv.

Podemos ver o código fonte en: https://github.com/libgdx/fbx-conv

Podemos descargar a versión compilada en: http://libgdx.badlogicgames.com/fbx-conv/

Información na wiki: https://github.com/libgdx/fbx-conv


O proceso para pasar dun obj a un g3db sería:

  • Descargar a versión compilada do enlace anterior.
  • Descomprimide e abride unha consola.
  • Vos situades onde se atopan os executables e escolledes a versión correspondente ó voso S.O.:
    • fbx-conv-win32.exe: Windows
    • fbx-conv-lin64: Linux
    • fbx-conv-mac: Mac




  • A orde para pasar por exemplo de obj a g3db seria:
1 fbx-conv-win32.exe modelo_entrada.obj modelo_saida.g3db


NOTA: Sempre que queiramos acelerar a carga dos modelos deberemos de pasalos a binario.

Carga de Modelos 3D

Nota: O que imos ver aquí é unha forma de cargar os Mesh cun formato obj. Dito formato non leva información de cor en cada vértice como vimos nos anteriores puntos, e polo tanto o ShaderProgram non ten que recoller o parámetro de cor.

Polo tanto os arquivos vertex.vrt e fragment.frag quedarían da seguinte maneira:

Arquivo vertext.vert

 1     attribute vec3 a_position;
 2     attribute vec2 a_texCoord0;
 3     varying vec2 v_textCoord;
 4     uniform mat4 u_worldView;
 5     void main()
 6     {
 7       gl_Position =  u_worldView *vec4(a_position,1);
 8 
 9       v_textCoord = a_texCoord0;
10     }


Arquivo fragment.frag

 1     #ifdef GL_ES
 2       precision mediump float;
 3     #endif
 4     varying vec2 v_textCoord;
 5     uniform sampler2D u_texture;
 6     void main()
 7     {
 8       vec4 texColor = texture2D(u_texture, v_textCoord);
 9       gl_FragColor = texColor;
10     }


Para cargar e manexar os modelos dunha forma máis sinxela mirade o punto: Programación avanzada 3D. De todas formas recomendo a lectura desta parte para entender os principios básicos.

Carga Modelos obj

Para cargar un modelo obj temos que facer uso da clase ModelLoader.

O proceso sería:

  • Crear unha instancia de dita clase:
1 		ModelLoader loader = new ObjLoader();
1         Model model = loader.loadModel(Gdx.files.internal("modelos/ship.obj"));

Dito método espera recibir como parámetro o arquivo obj.

Este método devolve un obxecto da clase Model.

Para nos un Model ven ser como un Mesh, o que sucede é que nun model poden ser cargados moitos Mesh de vez, polo que para ter unha referencia a un concreto faremos o seguinte:

  • Cargamos o Mesh:
1 	private Mesh meshNave;
2         .............
3         meshNave = model.meshes.get(0);

No noso caso só temos un Mesh no obj.


Exemplo:

Imos ver un exemplo completo, engadindo un modelo dunha nave e movéndoa cara a cámara, facendo que a cámara siga a nave cando a pase.


Preparación: Crear unha clase de nome UD4_6_CargaModelos3D, que derive da clase Game e sexa chamada pola clase principal das diferentes versións (desktop, android,...).


Crea un cartafol de nome modelos dentro do cartafol assets da versión Android.

Leva ó cartafol assets/modelos os arquivos ship.mtl, ship.obj e ship.png que se atopan no seguinte arquivo comprimido:

Media:Ship.zip


Creamos unha clase Elementos3D que garde a información de calquera elemento 3D. É igual á clase Cubo que utilizamos no exercicio anterior:

Código da clase Elementos3D
Obxectivo: Definir unha clase que garde o que necesitamos dun obxecto 3d.

 1 import com.badlogic.gdx.math.Matrix4;
 2 import com.badlogic.gdx.math.Vector3;
 3 
 4 public class Elemento3D {
 5 	
 6 	public Matrix4 matriz;
 7 	public Vector3 posicion;
 8 	public float escala;
 9 	public Vector3 velocidade;
10 	private Vector3 temp;
11 	
12 	public Elemento3D(Vector3 pos, float escala,Vector3 velocidade){
13 		matriz = new Matrix4();
14 		posicion = pos;
15 		this.escala=escala;
16 		this.velocidade = velocidade;
17 		
18 		temp = new Vector3();
19 		
20 	}
21 	
22 	public void update(float delta){
23 		
24 		temp.set(velocidade);
25 		posicion.add(temp.scl(delta));
26 		
27 
28 		matriz.idt();
29 		matriz.translate(posicion);
30 		matriz.scl(escala);
31 		
32 		
33 	}
34 
35 }


Agora imos ver o código de carga da nave.

  1 import com.badlogic.gdx.Game;
  2 import com.badlogic.gdx.Gdx;
  3 import com.badlogic.gdx.assets.loaders.ModelLoader;
  4 import com.badlogic.gdx.files.FileHandle;
  5 import com.badlogic.gdx.graphics.GL20;
  6 import com.badlogic.gdx.graphics.Mesh;
  7 import com.badlogic.gdx.graphics.PerspectiveCamera;
  8 import com.badlogic.gdx.graphics.Texture;
  9 import com.badlogic.gdx.graphics.g3d.Model;
 10 import com.badlogic.gdx.graphics.g3d.loader.ObjLoader;
 11 import com.badlogic.gdx.graphics.glutils.ShaderProgram;
 12 import com.badlogic.gdx.math.Vector3;
 13 
 14 /**
 15  * Cargando modelos 3D
 16  * @author ANGEL
 17  */
 18 
 19 public class UD4_6_CargaModelos3D extends Game {
 20 
 21 	private Mesh meshNave;
 22 	private Elemento3D nave;
 23 	private ShaderProgram shaderProgram;
 24 
 25 	private Texture textura;
 26 	private PerspectiveCamera camara3d;
 27 	
 28 
 29 	
 30 	@Override
 31 	public void create() {
 32 		// TODO Auto-generated method stub
 33 
 34 		shaderProgram = new ShaderProgram(Gdx.files.internal("vertex.vert"), Gdx.files.internal("fragment.frag"));
 35 		if (shaderProgram.isCompiled() == false) {
 36 			Gdx.app.log("ShaderError", shaderProgram.getLog());
 37 			System.exit(0);
 38 		}
 39 	
 40 
 41 		ModelLoader loader = new ObjLoader();
 42                 Model model = loader.loadModel(Gdx.files.internal("modelos/ship.obj"));
 43                 meshNave = model.meshes.get(0);
 44         
 45 		FileHandle imageFileHandle = Gdx.files.internal("modelos/ship.png");
 46 		textura = new Texture(imageFileHandle);
 47 		
 48 		camara3d = new PerspectiveCamera();
 49 		nave = new Elemento3D(new Vector3(0,-1f,-20f), 2f, new Vector3(0.1f,0.1f,2f));
 50 		
 51 	}
 52 	
 53 	
 54 	@Override
 55 	public void render() {
 56 
 57 		Gdx.gl20.glClearColor(0f, 0f, 0f, 1f);
 58 		Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT|GL20.GL_DEPTH_BUFFER_BIT);
 59 
 60 		Gdx.gl20.glEnable(GL20.GL_DEPTH_TEST);
 61                 Gdx.gl20.glEnable(GL20.GL_TEXTURE_2D);		
 62 
 63 		nave.update(Gdx.graphics.getDeltaTime());
 64 		
 65 		camara3d.lookAt(nave.posicion);
 66 		camara3d.update();
 67 		
 68 		shaderProgram.begin();
 69 		textura.bind(0);
 70 		shaderProgram.setUniformi("u_texture", 0);
 71 		shaderProgram.setUniformMatrix("u_worldView", camara3d.combined.cpy().mul(nave.matriz));
 72 		meshNave.render(shaderProgram, GL20.GL_TRIANGLES);
 73 			
 74 			
 75 
 76 		shaderProgram.end();
 77 		
 78                 Gdx.gl20.glDisable(GL20.GL_TEXTURE_2D);
 79 		Gdx.gl20.glDisable(GL20.GL_DEPTH_TEST);
 80 
 81 	}
 82 	
 83 	@Override
 84 	public void resize (int width,int height){
 85 		// Definimos os parámetros da cámara
 86 		float aspectRatio = (float) width / (float) height; 
 87 		camara3d.viewportWidth=aspectRatio*1f;
 88 		camara3d.viewportHeight=1f;
 89 		camara3d.far=1000f;
 90 		camara3d.near=0.1f;
 91 		camara3d.lookAt(0,0,0);
 92 		camara3d.position.set(0f,0f,5f);
 93 		camara3d.update();
 94 	}
 95 	
 96 	@Override
 97 	public void dispose(){
 98 		shaderProgram.dispose();
 99 		meshNave.dispose();
100 
101 	}
102 
103 }
  • Liña 21: Definimos o obxecto Mesh que vai representar a nave.
  • Liñas 41-43: Cargamos o obj utilizando a clase ModelLoader.
  • Liña 49: Instanciamos a nave pasándolle uns datos concretos.
  • Liñas 65-66: Facemos que a cámara mire cara a nave. LEMBRAR CHAMAR AO UPDATE.
  • Liña 72: Renderizamos a nave.
  • Liña 99: Liberamos a memoria.



TAREFA 4.5 A FACER: Esta parte está asociada á realización dunha tarefa.


Carga Modelos g3db

Para cargar estes modelos debemos facer uso da clase AssetManager.

Como isto é optativo na parte 2D non fai falla que o provedes.


Para cargar un modelo g3db previamente obtido coa ferramenta fbx-conv debemos facer o seguinte:

  • Crear un obxecto da clase AssetManager (que xa podemos ter creado se utilizamos esta forma de carga dos gráficos do xogo):
1         AssetManager assetManager = new AssetManager();


  • Chamamos ó método load para cargar o modelo e esperamos a que remate de cargar.
1         assetManager.load("modelos/ship.g3db", Model.class);
2         
3         assetManager.finishLoading();
  • Obtemos o obxecto da clase Model como fixemos no caso anterior:
1         Model model = assetManager.get("modelos/ship.g3db", Model.class);
  • Cargamos o Mesh que se atopa no Model (só temos un).
1         meshNave = model.meshes.get(0);



O código completo:

1         AssetManager assetManager = new AssetManager();
2         assetManager.load("modelos/ship.g3db", Model.class);
3         
4         assetManager.finishLoading();
5         
6         Model model = assetManager.get("modelos/ship.g3db", Model.class);
7         meshNave = model.meshes.get(0);

Modelos 3D xa feitos

Temos diferentes sitios web onde obter modelos 3D.



-- Ángel D. Fernández González -- (2015).