studio - Cómo cargar y mostrar un archivo.obj en Android con OpenGL-ES 2
opengl apk no root (2)
Estoy tratando de cargar un archivo .obj en mi aplicación de Android y mostrarlo con OpenGL 2.
Puede encontrar el archivo aquí: EDITAR: eliminé el archivo , puede usar cualquier archivo .obj que contenga los valores que se mencionan a continuación para realizar pruebas.
Hay muchas preguntas similares sobre stackoverflow pero no encontré una solución simple que no requiera una gran biblioteca.
El archivo solo contiene los siguientes tipos de valor:
- sol
- v
- Vermont
- vn
- F
Intenté libgdx, que funcionó bien, pero es un poco excesivo para lo que necesito.
Probé el oObjLoader https://github.com/seanrowens/oObjLoader sin el LWJGL. El análisis parece funcionar, pero ¿cómo puedo mostrar los valores en una escena simple?
El siguiente paso es adjuntar una imagen como una textura al objeto. Pero por ahora me gustaría mostrar el archivo tal como está.
Estoy abierto a diferentes soluciones como la conversión previa del archivo, ya que solo será esta una vez dentro de la aplicación.
¡Gracias!
Actualización de estado La carga y visualización básicas ahora funcionan, como se muestra en mi propia respuesta.
Como puede analizar los archivos obj, consultar esta post puede ayudarlo mucho.
Hay una manera más fácil, use el objloader objloader . Usa XWalkView para agregar la página web en tu aplicación de Android. XWalkView es algo así como webview, aquí la vista de trabajo puede no funcionar para renderizar escenas complejas, mientras que XWalkView tiene. Si no hace que la página web sea remota, puede hacerlo local.
Terminé escribiendo un nuevo analizador, se puede usar así para construir FloatBuffers para usar en su Renderizador:
ObjLoader objLoader = new ObjLoader(context, "Mug.obj");
numFaces = objLoader.numFaces;
// Initialize the buffers.
positions = ByteBuffer.allocateDirect(objLoader.positions.length * mBytesPerFloat)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
positions.put(objLoader.positions).position(0);
normals = ByteBuffer.allocateDirect(objLoader.normals.length * mBytesPerFloat)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
normals.put(objLoader.normals).position(0);
textureCoordinates = ByteBuffer.allocateDirect(objLoader.textureCoordinates.length * mBytesPerFloat)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
textureCoordinates.put(objLoader.textureCoordinates).position(0);
y aquí está el analizador:
public final class ObjLoader {
public final int numFaces;
public final float[] normals;
public final float[] textureCoordinates;
public final float[] positions;
public ObjLoader(Context context, String file) {
Vector<Float> vertices = new Vector<>();
Vector<Float> normals = new Vector<>();
Vector<Float> textures = new Vector<>();
Vector<String> faces = new Vector<>();
BufferedReader reader = null;
try {
InputStreamReader in = new InputStreamReader(context.getAssets().open(file));
reader = new BufferedReader(in);
// read file until EOF
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split(" ");
switch (parts[0]) {
case "v":
// vertices
vertices.add(Float.valueOf(parts[1]));
vertices.add(Float.valueOf(parts[2]));
vertices.add(Float.valueOf(parts[3]));
break;
case "vt":
// textures
textures.add(Float.valueOf(parts[1]));
textures.add(Float.valueOf(parts[2]));
break;
case "vn":
// normals
normals.add(Float.valueOf(parts[1]));
normals.add(Float.valueOf(parts[2]));
normals.add(Float.valueOf(parts[3]));
break;
case "f":
// faces: vertex/texture/normal
faces.add(parts[1]);
faces.add(parts[2]);
faces.add(parts[3]);
break;
}
}
} catch (IOException e) {
// cannot load or read file
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
//log the exception
}
}
}
numFaces = faces.size();
this.normals = new float[numFaces * 3];
textureCoordinates = new float[numFaces * 2];
positions = new float[numFaces * 3];
int positionIndex = 0;
int normalIndex = 0;
int textureIndex = 0;
for (String face : faces) {
String[] parts = face.split("/");
int index = 3 * (Short.valueOf(parts[0]) - 1);
positions[positionIndex++] = vertices.get(index++);
positions[positionIndex++] = vertices.get(index++);
positions[positionIndex++] = vertices.get(index);
index = 2 * (Short.valueOf(parts[1]) - 1);
textureCoordinates[normalIndex++] = textures.get(index++);
// NOTE: Bitmap gets y-inverted
textureCoordinates[normalIndex++] = 1 - textures.get(index);
index = 3 * (Short.valueOf(parts[2]) - 1);
this.normals[textureIndex++] = normals.get(index++);
this.normals[textureIndex++] = normals.get(index++);
this.normals[textureIndex++] = normals.get(index);
}
}
}