escribiendo .3ds o .obj loader en java
Pregunta
Iv'e exportó un modelo en Blender a un archivo .obj.Iv'e logró crear un muy simple clase que carga vértices e índices en matrices.Mi problema es que quiero las coordenadas de textura (vt) y normales (vn) también.Entonces, por ejemplo, necesitaría 4 vértices * 6 caras para que un cubo simple pueda usar textura, pero solo obtengo 8 en mi archivo .obj, y no tengo ni idea de cómo manejar los índices paravt ya que solo puedo tener una matriz / búfer para índices, pero obtengo dos v / vt diferentes en el archivo .obj.
¿Existe algún cargador que solo devuelva matrices o similares para vértices, texturas, normales y una matriz de índices?¿O ejemplos de cómo escribir uno?Hasta ahora solo he encontrado cargadores en motores 3D completos y eso no es lo que quiero.
Solución
4 vértices * 6 caras es más de lo que necesitas.En realidad, no será eficaz.Los vértices exportados que tienes están optimizados con índices.Usando Opengl-es puede apuntar desde dónde obtener vértices (matriz) y luego dibujar vértices usando sus índices en otra matriz.Como resultado, obtiene 8 vértices frente a los posibles 24 vértices, necesita menos memoria para almacenar.Entonces la eficiencia es 16/24 * 100%.Imagina que tendrás un modelo con 1000 vértices.
El índice de vértice significa que en otra matriz con una GPU de compensación adecuada obtendrá un vértice (size_of_vertex (3 flotantes) * índice) y una compensación adecuada para las coordenadas UV (size_of_UVcoord (2 flotantes) * índice)
este código para opengl ES 2.0 pero puede hacerse una 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());
y sqTEx es una instancia de 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;
}
}
Otros consejos
Mire un PCT (o jPCT-AE), es una excelente biblioteca 3D para Java (y / o Android).Admite la carga de 3ds / obj desde el primer momento.