scrivere .3ds o .obj loader in java
Domanda
Ho esportato un modello in Blender in un file .obj.Sono riuscito a creare un file molto semplice classe che carica vertici e indici negli array.Il mio problema è che voglio anche le coordinate della trama (vt) e le normali (vn).Quindi, ad esempio, avrei bisogno di 4 vertici * 6 facce per un semplice cubo per poter usare la trama ma ne ottengo solo 8 nel mio file .obj, così come non ho la più pallida idea di come gestire gli indici pervt poiché posso avere solo un array / buffer per gli indici ma ottengo due diversi v / vt nel file .obj.
Esiste un caricatore là fuori che restituisce solo array o simili per vertici, texture, normali e un array di indici?O esempi di come scriverne uno?Finora ho trovato solo caricatori in motori 3D completi e non è quello che voglio.
Soluzione
4 vertici * 6 facce è più del necessario.In realtà non sarà efficiente.I vertici esportati che hai sono ottimizzati con gli indici.Usando Opengl-es puoi indicare da dove ottenere i vertici (array) e quindi disegnare i vertici usando i loro indici in un altro array.Di conseguenza ottieni 8 vertici contro i 24 vertici possibili, hai bisogno di meno memoria da memorizzare.Quindi l'efficienza è 16/24 * 100%.Immagina di avere un modello con 1000 vertici.
Indice del vertice significa che in un altro array con un offset corretto GPU otterrà un vertice (size_of_vertex (3 float) * index) e un offset appropriato per le coordinate UV (size_of_UVcoord (2 float) * index)
questo codice per opengl ES 2.0 ma puoi farti un'idea:
GLES20.glUseProgram(programTextured);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);
sqTex.getVertexBuffer().position(sqTex.VERT_OFFSET);
GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(programTextured, "aPosition") 3, GLES20.GL_FLOAT, false, 5 * 4, sqTex.getVertexBuffer()); GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(programTextured, "aPosition"));
sqTex.getVertexBuffer().position(sqTex.TEXT_OFFSET);
GLES20.glVertexAttribPointer(
GLES20.glGetAttribLocation(programTextured, "aTextureCoord"), 2,
GLES20.GL_FLOAT, false, 5 * 4, sqTex.getVertexBuffer());
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, sqTex.getIndexBuffer());
e sqTEx è un'istanza di TexturedSquare:
public class TexturedSquare {
// private float[] vertices=new float[4];
float vertices[] = { -1.0f, -1.0f, 0.0f,0.0f,0.0f, // 0, Top Left //x,y,z,u,v
1.0f, -1.0f, 0.0f,0.0f,1.0f, // 1, Bottom Left
1.0f, 1.0f, 0.0f,1.0f,1.0f, // 2, Bottom Right
-1.0f, 1.0f, 0.0f,1.0f,0.0f, // 3, Top Right
};
public static int VERT_OFFSET=0;
public static int TEXT_OFFSET=3;
short[] indices = { 0, 1, 2, 2, 3, 0 };;
// Our vertex buffer.
private FloatBuffer vertexBuffer;
// Our index buffer.
private ShortBuffer indexBuffer;
public TexturedSquare()
{
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
// short is 2 bytes, therefore we multiply the number if
// vertices with 2.
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);
}
FloatBuffer getVertexBuffer(){
return vertexBuffer;
}
ShortBuffer getIndexBuffer(){
return indexBuffer;
}
}
Altri suggerimenti
Guarda un PCT (o jPCT-AE), è un'ottima libreria 3D per Java (e / o Android).Supporta il caricamento di 3ds / obj fuori dalla scatola.