回答
只是你的模型對象,並將它們導出到OBJ文件,然後就可以OBJ文件簡單地加載到你的場景。
這裏是我寫的代碼,用於加載我從OBJ文件中導出的代碼,它們是從Maya中導出的。 請注意,這更像是實驗性代碼,所以它不乾淨,但我測試了它並完美地工作。
Vector3D類保存X,Y和Z變量,Face類保存UVW,Vertices和Vertex Normals的ArrayList。
而你必須通過調用glDrawElements btw來繪製你的對象。 希望這個人會幫助=)
public class Model {
// Constants
private static final int FLOAT_SIZE_BYTES = 4;
private static final int SHORT_SIZE_BYTES = 2;
private FloatBuffer _vb;
private FloatBuffer _nb;
private ShortBuffer _ib;
private FloatBuffer _tcb;
private short[] indices;
private float[] tempV;
private float[] tempVt;
private float[] tempVn;
private ArrayList<Vector3D> vertices;
private ArrayList<Vector3D> vertexTexture;
private ArrayList<Vector3D> vertexNormal;
private ArrayList<Face> faces;
private int vertexCount;
private ArrayList<GroupObject> groupObjects;
//Android Stuff!
private Context context;
private int modelID;
public Model(int modelID, Context activity)
{
this.vertices = new ArrayList<Vector3D>();
this.vertexTexture = new ArrayList<Vector3D>();
this.vertexNormal = new ArrayList<Vector3D>();
this.faces = new ArrayList<Face>();
this.groupObjects = new ArrayList<GroupObject>();
this.modelID = modelID;
this.context = activity;
loadFile();
}
private int loadFile()
{
InputStream inputStream = context.getResources().openRawResource(modelID);
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
try {
loadOBJ(in);
Log.d("LOADING FILE", "FILE LOADED SUCESSFULLY====================");
} catch (IOException e) {
e.printStackTrace();
}
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
return 1;
}
private void loadOBJ(BufferedReader in) throws IOException
{
Log.d("LOADING FILE", "STARTING!====================");
GroupObject defaultObject = new GroupObject();
GroupObject currentObject = defaultObject;
this.groupObjects.add(defaultObject);
String Line; // Stores ever line we read!
String[] Blocks; // Stores string fragments after the split!!
String CommandBlock; // Stores Command Blocks such as: v, vt, vn, g, etc...
while((Line = in.readLine()) != null)
{
Blocks = Line.split(" ");
CommandBlock = Blocks[0];
// Log.d("COMMAND BLOCK" , "---------- " + CommandBlock + " ----------");
if(CommandBlock.equals("g"))
{
if(Blocks[1] == "default")
currentObject = defaultObject;
else
{
GroupObject groupObject = new GroupObject();
groupObject.setObjectName(Blocks[1]);
currentObject = groupObject;
groupObjects.add(groupObject);
}
}
if(CommandBlock.equals("v"))
{
Vector3D vertex = new Vector3D(Float.parseFloat(Blocks[1]), Float.parseFloat(Blocks[2]), Float.parseFloat(Blocks[3]));
this.vertices.add(vertex);
// Log.d("VERTEX DATA", " " + vertex.getX() + ", " + vertex.getY() + ", " + vertex.getZ());
}
if(CommandBlock.equals("vt"))
{
Vector3D vertexTex = new Vector3D(Float.parseFloat(Blocks[1]), Float.parseFloat(Blocks[2]), 0.0f);
this.vertexTexture.add(vertexTex);
// Log.d("TEXTURE DATA", " " + vertexTex.getX() + ", " + vertexTex.getY() + ", " + vertexTex.getZ());
}
if(CommandBlock.equals("vn"))
{
Vector3D vertexNorm = new Vector3D(Float.parseFloat(Blocks[1]), Float.parseFloat(Blocks[2]), Float.parseFloat(Blocks[3]));
this.vertexNormal.add(vertexNorm);
// Log.d("NORMAL DATA", " " + vertexNorm.getX() + ", " + vertexNorm.getY() + ", " + vertexNorm.getZ());
}
if(CommandBlock.equals("f"))
{
Face face = new Face();
faces.add(face);
String[] faceParams;
for(int i = 1; i < Blocks.length ; i++)
{
faceParams = Blocks[i].split("/");
face.getVertices().add(this.vertices.get(Integer.parseInt(faceParams[0]) - 1));
if(faceParams[1] == ""){}
else
{
face.getUvws().add(this.vertexTexture.get(Integer.parseInt(faceParams[1]) - 1));
face.getNormals().add(this.vertexNormal.get(Integer.parseInt(faceParams[2]) - 1));
}
}
}
}
// fillInBuffers();
fillInBuffersWithNormals();
Log.d("OBJ OBJECT DATA", "V = " + vertices.size() + " VN = " + vertexTexture.size() + " VT = " + vertexNormal.size());
}
private void fillInBuffers() {
int facesSize = faces.size();
vertexCount = facesSize * 3;
tempV = new float[facesSize * 3 * 3];
tempVt = new float[facesSize * 2 * 3];
indices = new short[facesSize * 3];
for(int i = 0; i < facesSize; i++)
{
Face face = faces.get(i);
tempV[i * 9] = face.getVertices().get(0).getX();
tempV[i * 9 + 1] = face.getVertices().get(0).getY();
tempV[i * 9 + 2] = face.getVertices().get(0).getZ();
tempV[i * 9 + 3] = face.getVertices().get(1).getX();
tempV[i * 9 + 4] = face.getVertices().get(1).getY();
tempV[i * 9 + 5] = face.getVertices().get(1).getZ();
tempV[i * 9 + 6] = face.getVertices().get(2).getX();
tempV[i * 9 + 7] = face.getVertices().get(2).getY();
tempV[i * 9 + 8] = face.getVertices().get(2).getZ();
tempVt[i * 6] = face.getUvws().get(0).getX();
tempVt[i * 6 + 1] = face.getUvws().get(0).getY();
tempVt[i * 6 + 2] = face.getUvws().get(1).getX();
tempVt[i * 6 + 3] = face.getUvws().get(1).getY();
tempVt[i * 6 + 4] = face.getUvws().get(2).getX();
tempVt[i * 6 + 5] = face.getUvws().get(2).getY();
indices[i * 3] = (short) (i * 3);
indices[i * 3 + 1] = (short) (i * 3 + 1);
indices[i * 3 + 2] = (short) (i * 3 + 2);
}
_vb = ByteBuffer.allocateDirect(tempV.length
* FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
_vb.put(tempV);
_vb.position(0);
_tcb = ByteBuffer.allocateDirect(tempVt.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
_tcb.put(tempVt);
_tcb.position(0);
_ib = ByteBuffer.allocateDirect(indices.length
* SHORT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asShortBuffer();
_ib.put(indices);
_ib.position(0);
}
private void fillInBuffersWithNormals() {
int facesSize = faces.size();
vertexCount = facesSize * 3;
tempV = new float[facesSize * 3 * 3];
tempVt = new float[facesSize * 2 * 3];
tempVn = new float[facesSize * 3 * 3];
indices = new short[facesSize * 3];
for(int i = 0; i < facesSize; i++)
{
Face face = faces.get(i);
tempV[i * 9] = face.getVertices().get(0).getX();
tempV[i * 9 + 1] = face.getVertices().get(0).getY();
tempV[i * 9 + 2] = face.getVertices().get(0).getZ();
tempV[i * 9 + 3] = face.getVertices().get(1).getX();
tempV[i * 9 + 4] = face.getVertices().get(1).getY();
tempV[i * 9 + 5] = face.getVertices().get(1).getZ();
tempV[i * 9 + 6] = face.getVertices().get(2).getX();
tempV[i * 9 + 7] = face.getVertices().get(2).getY();
tempV[i * 9 + 8] = face.getVertices().get(2).getZ();
tempVn[i * 9] = face.getNormals().get(0).getX();
tempVn[i * 9 + 1] = face.getNormals().get(0).getY();
tempVn[i * 9 + 2] = face.getNormals().get(0).getZ();
tempVn[i * 9 + 3] = face.getNormals().get(1).getX();
tempVn[i * 9 + 4] = face.getNormals().get(1).getY();
tempVn[i * 9 + 5] = face.getNormals().get(1).getZ();
tempVn[i * 9 + 6] = face.getNormals().get(2).getX();
tempVn[i * 9 + 7] = face.getNormals().get(2).getY();
tempVn[i * 9 + 8] = face.getNormals().get(2).getZ();
tempVt[i * 6] = face.getUvws().get(0).getX();
tempVt[i * 6 + 1] = face.getUvws().get(0).getY();
tempVt[i * 6 + 2] = face.getUvws().get(1).getX();
tempVt[i * 6 + 3] = face.getUvws().get(1).getY();
tempVt[i * 6 + 4] = face.getUvws().get(2).getX();
tempVt[i * 6 + 5] = face.getUvws().get(2).getY();
indices[i * 3] = (short) (i * 3);
indices[i * 3 + 1] = (short) (i * 3 + 1);
indices[i * 3 + 2] = (short) (i * 3 + 2);
}
_vb = ByteBuffer.allocateDirect(tempV.length
* FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
_vb.put(tempV);
_vb.position(0);
_tcb = ByteBuffer.allocateDirect(tempVt.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
_tcb.put(tempVt);
_tcb.position(0);
_nb = ByteBuffer.allocateDirect(tempVn.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
_nb.put(tempVn);
_nb.position(0);
_ib = ByteBuffer.allocateDirect(indices.length
* SHORT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asShortBuffer();
_ib.put(indices);
_ib.position(0);
}
public FloatBuffer getVertices()
{
return _vb;
}
public FloatBuffer getTexCoords()
{
return _tcb;
}
public ShortBuffer getIndices()
{
return _ib;
}
public FloatBuffer getNormals() {
return _nb;
}
}
如果這個回答你的問題,請投票支持它;)
+1提醒新人接受和投票功能。 –
謝謝你的代碼,它確實有幫助,但問題是,我想繪製複雜的對象,像汽車一樣繪製複雜的對象只會使用頂點。我在想,如果他們是我們可以讓事情變得更容易的工具。你提供的代碼只加載一個已經創建的對象。請relply – karim
如果您想製作(或建模)複雜的對象,您必須學習如何建模3D對象。你有免費的Blender,並且互聯網上有大量關於如何使用它和爲複雜的3D對象建模的教程。像Maya和3DS Max等其他軟件也可以完成這項工作,但您需要爲它們購買許可證。當然,一旦你完成建模,你需要將模型導出到OBJ格式,以便我發佈的代碼工作;) – mrcomplicated
你可以用攪拌器和libgdx庫。 我嘗試過libgdx,這很棒,但從來沒有用過3d。 教程,開始用攪拌機中libgdx:http://code.google.com/p/libgdx/wiki/BlenderModels
- 1. OpenGL ES的工具?
- 2. 是否有適用於Android OpenGL ES的多邊形三角測量工具?
- 3. 適用於Windows Mobile的OpenGL ES 2.0 SDK
- 4. GL_TEXTURE_EXTERNAL_OES不適用於OpenGL ES 3.0 NDK
- 5. 適用於Android的OpenGL ES 2.0 - gl_FragCoord和gl_FragColor
- 6. 適用於iOS和Android的OpenGL ES差異
- 7. 適用於OpenGL ES的3D模型格式Android
- 8. Android上用於openGL ES的豐富庫
- 9. OpenGl ES,android FPS
- 10. iOS OpenGL ES與Android OpenGL ES兼容?
- 11. 在OpenGL ES的Android
- 12. Android上的OpenGL ES
- 13. 適用於Android的良好ORM工具?
- 14. 適用於Android的取證工具
- 15. OpenGL ES for Android,造型傢俱
- 16. 關於opengl es 2.0驅動的irrlicht android
- 17. 基於Android OpenGL ES Line的圈子
- 18. 適合這項工作的正確工具:CoreAnimation,Cocoa Animation或OpenGL ES?
- 19. 適用於iPhone的OpenGL ES混合不起作用
- 20. gluUnProject Android OpenGL ES 1.1用法
- 21. Android OpenGL ES Line antialiase
- 22. Shader for Android OpenGL ES
- 23. Android OpenGL ES和2D
- 24. OpenGl ES 2D Android redraw
- 25. OpenGL ES 1.1 Android Cubemapping
- 26. android opengl es draw scale
- 27. Android OpenGL ES教程
- 28. Android的OpenGL ES的法線
- 29. 的OpenGL ES的Android混亂
- 30. OpenGL ES 2.0照明不適用於iOS應用程序
您可以使用OpenGL ES的下面的例子中http://blog.jayway.com/2009/12/03 /的OpenGL-ES-教程換機器人部分-I /。 –
嘿,Mr先生,您是否已經爲您提供上述代碼的那個課程調用瞭如何以及如何調用?無論如何,您可以發佈包含示例項目的zip文件嗎?感謝 –