Trung tâm Tin học – ĐH KHTN
Hình động 3D
Chắc các bạn cũng biết là Android là hệ điều hành có hỗ trợ dạng 3D và sau đây mình
sẽ trình bày code để tạo ra 1 Kim tự tháp 3D và cho nó tự quay vòng vòng.
1/ Các bạn tạo 1 Project như sau:
Project name: open_gl
Build Target: Android 2.3.3
Application name: Open_gl
Package name: com.dac. open_gl
Create Activity: Open_gl
2/ Tiếp theo các bạn tạo 1 class Pyramid.java trong package và viết code như sau:
package com.dac.open_gl;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import javax.microedition.khronos.opengles.GL10;
public class Pyramid {
public Pyramid() {
int one = 0x10000;
int vertices[] = {
-one, -one, -one,
-one, one, -one,
one, one, -one,
one, -one, -one,
0, 0, one
};
int colors[] = {
one, 0, one, one,
one, 0, one, one,
one, 0, one, one,
one, 0, one, one,
one, one, one, one
};
byte indices[] = {
0, 1, 2, 0, 2, 3,
0, 3, 4,
0, 4, 1,
1, 4, 2,
2, 4, 3
Lập trình Android – Page 1
Trung tâm Tin học – ĐH KHTN
};
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asIntBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);
ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
cbb.order(ByteOrder.nativeOrder());
mColorBuffer = cbb.asIntBuffer();
mColorBuffer.put(colors);
mColorBuffer.position(0);
mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
mIndexBuffer.put(indices);
mIndexBuffer.position(0);
}
public void draw(GL10 gl) {
gl.glFrontFace(GL10.GL_CW);
gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, 18, GL10.GL_UNSIGNED_BYTE,
mIndexBuffer);
}
private IntBuffer mVertexBuffer;
private IntBuffer mColorBuffer;
private ByteBuffer mIndexBuffer;
}
3/ Các bạn tạo tiếp 1 class PyramidRenderer.java để xử lý cho Kim tự tháp xoay:
package com.dac.open_gl;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView;
public class PyramidRenderer implements GLSurfaceView.Renderer {
public PyramidRenderer(boolean useTranslucentBackground) {
mTranslucentBackground = useTranslucentBackground;
mPyramid = new Pyramid();
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(mCenter[0], mCenter[1], mCenter[2]);
gl.glRotatef(mAngle, 0, 1, 0);
gl.glRotatef(mAngle*0.25f, 1, 0, 0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
mPyramid.draw(gl);
mAngle += mAngleDelta;
mCenter[0] += mVel[0];
mCenter[1] += mVel[1];
Lập trình Android – Page 2
Trung tâm Tin học – ĐH KHTN
if(Math.abs(mCenter[0])>4.0f) {
mVel[0] = -mVel[0];
mAngleDelta=(float) (5*(0.5-Math.random()));
}
if(Math.abs(mCenter[1])>6.0f) {
mVel[1] = -mVel[1];
mAngleDelta=(float) (5*(0.5-Math.random()));
}
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
float ratio = (float) width / height;
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 20);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glDisable(GL10.GL_DITHER);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
GL10.GL_FASTEST);
if (mTranslucentBackground) {
gl.glClearColor(0,0,0,0);
} else {
gl.glClearColor(1,1,1,1);
}
gl.glEnable(GL10.GL_CULL_FACE);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_DEPTH_TEST);
}
private boolean mTranslucentBackground;
private Pyramid mPyramid;
private float mAngle, mAngleDelta=0;
private float mCenter[]={0,0,-10};
private float mVel[]={0.025f, 0.03535227f, 0f};
}
4/ Cuối cùng các bạn code trong file Open_gl.java như sau:
package com.dac.open_gl;
import android.app.Activity;
import android.os.Bundle;
import android.opengl.GLSurfaceView;
public class Open_gl extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mGLSurfaceView = new GLSurfaceView(this);
mGLSurfaceView.setRenderer(new PyramidRenderer(true));
Lập trình Android – Page 3
Trung tâm Tin học – ĐH KHTN
setContentView(mGLSurfaceView);
}
@Override
protected void onResume() {
super.onResume();
mGLSurfaceView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mGLSurfaceView.onPause();
}
private GLSurfaceView mGLSurfaceView;
}
Và các bạn chỉ còn việc debug Project sẽ được 1 Kim tự tháp quay vòng vòng (gần
giống như màn hình chờ của window)
Lập trình Android – Page 4