适用于Android的OpenGL ES工具
在哪里可以找到在OpenGL ES中设计复杂对象的所有工具适用于Android的OpenGL ES工具,android,opengl-es,Android,Opengl Es,在哪里可以找到在OpenGL ES中设计复杂对象的所有工具 像正方形、立方体、球体等,您可以使用blender和libgdx库。 我试过libgdx,它很棒,但从来都不适合3d。 从blender for libgdx开始的教程:只需对对象建模并将其导出到OBJ文件,然后就可以将OBJ文件加载到场景中 下面是我编写的代码,用于加载我从Maya导出的OBJ文件。 请注意,这更像是实验性代码,所以它不是干净的,但我测试了它,工作得非常完美 Vector3D类保存X、Y和Z变量,Face类保存UVW、
像正方形、立方体、球体等,您可以使用blender和libgdx库。 我试过libgdx,它很棒,但从来都不适合3d。
从blender for libgdx开始的教程:只需对对象建模并将其导出到OBJ文件,然后就可以将OBJ文件加载到场景中 下面是我编写的代码,用于加载我从Maya导出的OBJ文件。 请注意,这更像是实验性代码,所以它不是干净的,但我测试了它,工作得非常完美 Vector3D类保存X、Y和Z变量,Face类保存UVW、顶点和顶点法线的阵列列表 你必须通过调用gldrawerelements来绘制你的对象。 希望这个能帮上忙()
公共类模型{
//常数
私有静态最终整数浮点大小字节=4;
私有静态final int SHORT_SIZE_BYTES=2;
私有浮动缓冲区_vb;
私人浮动缓冲区(nb);
专用短缓冲区;
专用浮动缓冲区(tcb);
私人短期债券指数;
私人浮动[]tempV;
私人浮动[]临时;
私有浮动[]tempVn;
私有数组列表顶点;
私人ArrayList Vertexture;
私有数组列表顶点法线;
私人ArrayList面孔;
私人帐户;
私有ArrayList组对象;
//安卓的东西!
私人语境;
私有int modelID;
公共模型(int modelID,上下文活动)
{
this.vertices=新的ArrayList();
this.vertexture=新的ArrayList();
this.vertexNormal=新的ArrayList();
this.faces=new ArrayList();
this.groupObjects=new ArrayList();
this.modelID=modelID;
这个上下文=活动;
loadFile();
}
私有int加载文件()
{
InputStream InputStream=context.getResources().openRawResource(modelID);
BufferedReader in=新的BufferedReader(新的InputStreamReader(inputStream));
试一试{
loadOBJ(in);
Log.d(“加载文件”,“文件加载成功=======================”;
}捕获(IOE异常){
e、 printStackTrace();
}
试一试{
in.close();
}捕获(IOE异常){
e、 printStackTrace();
}
返回1;
}
私有void loadOBJ(BufferedReader in)引发IOException
{
Log.d(“正在加载文件”、“正在启动!=========================”;
GroupObject defaultObject=新的GroupObject();
GroupObject currentObject=defaultObject;
this.groupObjects.add(defaultObject);
String Line;//存储我们读过的任何一行!
String[]Blocks;//在拆分后存储字符串片段!!
String CommandBlock;//存储命令块,如:v、vt、vn、g等。。。
而((Line=in.readLine())!=null)
{
块=行。拆分(“”);
CommandBlock=块[0];
//Log.d(“命令块”,“命令块+”------------“+CommandBlock+”------------“);
if(CommandBlock.equals(“g”))
{
如果(块[1]=“默认”)
currentObject=defaultObject;
其他的
{
GroupObject GroupObject=新的GroupObject();
setObjectName(块[1]);
currentObject=groupObject;
groupObjects.add(groupObject);
}
}
if(CommandBlock.equals(“v”))
{
Vector3D顶点=新的Vector3D(Float.parseFloat(块[1])、Float.parseFloat(块[2])、Float.parseFloat(块[3]);
this.vertexs.add(顶点);
//Log.d(“顶点数据”、“顶点+VERTEX.getX()+”、“+VERTEX.getY()+”、“+VERTEX.getZ());
}
if(CommandBlock.equals(“vt”))
{
Vector3D Vertextextex=新的Vector3D(Float.parseFloat(块[1]),Float.parseFloat(块[2]),0.0f);
this.vertexture.add(vertextextex);
//Log.d(“纹理数据”、“+vertexTex.getX()+”、“+vertextextex.getY()+”、“+vertexTex.getZ());
}
if(CommandBlock.equals(“vn”))
{
Vector3D vertexNorm=新的Vector3D(Float.parseFloat(块[1])、Float.parseFloat(块[2])、Float.parseFloat(块[3]);
this.vertexNormal.add(vertexNorm);
//Log.d(“正常数据”、“+vertexNorm.getX()+”、“+vertexNorm.getY()+”、“+vertexNorm.getZ());
}
if(CommandBlock.equals(“f”))
{
面=新面();
面。添加(面);
字符串[]面参数;
对于(int i=1;ipublic 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;
}
}