Android加载三维模型
这⼏天在Android项⽬中需要加载三维模型,了多种⽅法,最后决定使⽤jpct引擎。话不多说,上代码。⼀、代码解析
⾸先创建⼀个活动MainActivity,活动布局如下:
包括五个button,⼀个ImageView作为背景,⼀个GLSurfaceView显⽰模型,布局代码如下:
闭嘴爱吧
<RelativeLayout xmlns:android="schemas.android/apk/res/android"
android:id="@+id/screen"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorBg"/>
<android.opengl.GLSurfaceView
android:id="@+id/surfaceView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="180dip"
android:orientation="vertical">
<Button
android:id="@+id/btnLoadModel"
android:layout_width="match_parent"
android:layout_height="60dip"
android:text="loadModel"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dip"
android:orientation="horizontal">
<Button
android:id="@+id/btnLeft"
android:layout_width="180dip"
android:layout_height="60dip"
android:text="left"/>
<Button
android:id="@+id/btnRight"
android:layout_width="180dip"
android:layout_height="60dip"
android:text="right"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dip"
android:orientation="horizontal">
<Button
android:id="@+id/btnTop"
android:layout_width="180dip"
小狗拉稀了怎么办android:layout_height="60dip"
android:text="top"/>
<Button
android:id="@+id/btnDown"
android:layout_width="180dip"
android:layout_height="60dip"
android:text="down"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
新建RenderView.class⽤于加载模型和显⽰处理:(如果有Unity或者其他游戏引擎的开发经验的话,下⾯的代码⾮常好理解。)public class RenderView implements GLSurfaceView.Renderer{
public World myWorld;
private FrameBuffer frameBuffer;
private Object3D selectedObj;
public RenderView(Context context) {
myWorld = new World();
myWorld.setAmbientLight(25, 25, 25);
Light light = new Light(myWorld);
light.setIntensity(250, 250, 250);
light.setPosition(new SimpleVector(0, 0, -15));
Camera cam = Camera();
cam.setFOVLimits(0.1f,2.0f);
cam.setFOV(1.08f);
cam.setYFOV(1.92f);
cam.setClippingPlanes(0f,2000f);
System.out.FOV());
System.out.YFOV());
System.out.Position());
String[] ParameterNames();
for(String i:names){
System.out.println(i);
}
}
public void onSurfaceChanged(GL10 gl, int w, int h) {
if (frameBuffer != null) {
frameBuffer.dispose();
}
frameBuffer = new FrameBuffer(gl, w, h);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(1.0f,1.0f,1.0f,0.3f);
}
public void onDrawFrame(GL10 gl) {
frameBuffer.clear(Color.TRANSPARENT);
拆弹专家2潘乘风是好人还是坏人
myWorld.draw(frameBuffer);
frameBuffer.display();
}
public void addObject(Context context) {
Object3D newObject = null;
try {
createTextures(context);
Object3D[] objectsArray2 = Loader.Resources().getAssets().open("policecar.obj"), Resources()                    .getAssets().open("l"), 1f);
newObject = All(objectsArray2);
newObject.setTexture("policecar_texture");
newObject.setOrigin(new SimpleVector(0, 0, 300));
newObject.setName("policecar.obj");
} catch (IOException e) {
e.printStackTrace();
李梦颖微博
}
newObject.strip();
newObject.build();
Message msg=new Message();
msg.what=MainActivity.MSG_LOAD_MODEL_SUC;
msg.obj=newObject;
MainActivity.handler.sendMessage(msg);
高小琴怎么失的身selectedObj=newObject;
}
public void applyTranslation(float incX, float incY, float incZ) {
if (this.selectedObj != null) {
SimpleVector objOrigin = Origin();
SimpleVector currentPoition=TransformedCenter();
System.out.println(currentPoition);
anslate(incX, incY, incZ);
}
}
private void createTextures(Context context) {
Bitmap bitmap=BitmapFactory.Resources(),R.mipmap.policecar);
Texture texture = new Texture(bitmap);
if(!Instance().containsTexture("policecar_texture")){
}
}
}
myWorld是当前的场景,所有的物体都在当前场景中,FrameBuffer是显⽰缓存,selectedObj是当前选择的物体。下⾯我们来详细解释这些代码。
public RenderView(Context context) {
myWorld = new World();
myWorld.setAmbientLight(25, 25, 25);
Light light = new Light(myWorld);
light.setIntensity(250, 250, 250);
light.setPosition(new SimpleVector(0, 0, -15));
Camera cam = Camera();
cam.setFOVLimits(0.1f,2.0f);
cam.setFOV(1.08f);
外国名字cam.setYFOV(1.92f);
cam.setClippingPlanes(0f,2000f);
System.out.FOV());
System.out.YFOV());
System.out.Position());
String[] ParameterNames();
for(String i:names){
System.out.println(i);
}
}
RenderView是类的 构造函数,定义了场景中的⼀些关键要素,例如摄像机,光照等。myWorld.setAmbientLight设置全局光,Light是当前场景中的光线设置,light.setIntensity设置光照强度,light.setPosition设置光源位置,此处光源是点光源。cam是场景中的摄像机,cam.setFOVLimits设置摄像机的视场⾓范围,此处设置为0.1-2.0。摄像机的X和Y⽅向的视场⾓可以分别设置。
cam.setClippingPlanes设置相机的视距,此处为0-2000。
public void onSurfaceChanged(GL10 gl, int w, int h) {
if (frameBuffer != null) {
frameBuffer.dispose();
}
frameBuffer = new FrameBuffer(gl, w, h);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(1.0f,1.0f,1.0f,0.3f);
}
public void onDrawFrame(GL10 gl) {
frameBuffer.clear(Color.TRANSPARENT);
myWorld.draw(frameBuffer);
frameBuffer.display();
}
这⼏个函数是⽤于定义GLSurfaceView创建时和刷新时的函数,gl.glClearColor定义了SurfaceView刷新颜⾊。frameBuffer.clear定义了frameBuffer刷新颜⾊。
public void addObject(Context context) {
Object3D newObject = null;
try {
createTextures(context);
Object3D[] objectsArray2 = Loader.Resources().getAssets().open("policecar.obj"), Resources()
.getAssets().open("l"), 1f);
newObject = All(objectsArray2);
newObject.setTexture("policecar_texture");
newObject.setOrigin(new SimpleVector(0, 0, 300));
newObject.setName("policecar.obj");
} catch (IOException e) {
e.printStackTrace();
}
newObject.strip();
newObject.build();
Message msg=new Message();
msg.what=MainActivity.MSG_LOAD_MODEL_SUC;
msg.obj=newObject;
MainActivity.handler.sendMessage(msg);
selectedObj=newObject;
}
addObject⽤于向场景中添加物体,loadOBJ函数采⽤的是⼆进制流的形式加载模型数据。加载OBJ格式的模型需要三个⽂件,分别是模型.obj,模型.mtl以及模型的贴图⽂件,Obj⽂件是模型的⾯信息,mtl⽂件定义了模型贴图与⾯位置信息。
public void applyTranslation(float incX, float incY, float incZ) {
if (this.selectedObj != null) {
SimpleVector objOrigin = Origin();
SimpleVector currentPoition=TransformedCenter();
System.out.println(currentPoition);
anslate(incX, incY, incZ);
}
}