Thursday, December 2, 2010

Chỉ dẫn lập trình game 3D trên Android (P3)

Hôm nay tôi sẽ chỉ các bạn lập trình OpenGL trong Android, cách sử dụng OpenGL trong cả 2 ngôn ngữ Java và C. Điều này rất quan trọng trong việc tái sử dụng mã nguồn trong Java và C cũng như sử dụng được các tính năng tốt nhất mà mỗi ngôn ngữ cung cấp.
Bất kỳ một nhà phát triển game nào cũng cần phải biết OpenGL là kim chỉ nam cho nhưng nhà phát triển game chuyên nghiệp. Bạn khó có thể tìm thấy một game mạnh mẽ nào mà không sử dụng API của OpenGl, bởi vì nó có khả năng tận dụng và tăng tốc phần cứng hơn hầu hết tất cả các phần mềm renderer khác.
OpenGL có thể là một môn học đáng sợ cho người mới bắt đầu (that's true for me :D). Nhưng bạn cũng không thể thành thạo OpenGL tới mức biết được làm thế nào để nó có thể vẽ các phần tử đó với OpenGL API. Bạn chỉ cần sự ham học hỏi, mong muốn tìm hiểu một công cụ mạnh mẽ để xây dựng các ứng dụng đồ họa như game.
Trong giới hạn của bài này tôi không thể chỉ bạn tất cả về OpenGL mà tôi chỉ đưa ra ví dụ sử dụng chúng trong ứng dụng Android, dựa vào đó và các API của OpenGL bạn có thể tùy biến theo ý của bạn.
Tham khảo thêm về OpenGL tại:
http://www.opengl.org/sdk/docs/man/
http://www.falloutsoftware.com/tutorials/gl/gl0.htm
http://mathworld.wolfram.com/OrthographicProjection.html
http://nehe.gamedev.net/

Về thiết bị thì khỏi bàn, hiện nay Android ngày càng trở nên mạnh mẽ cho việc phát triển các ứng dụng đồ họa.
Để tận dụng tối đa hiệu năng của CPU, Google đã đưa OpenGL Embedded System (OpenGL-ES) vào trong hệ điều hành Android.
OpenGL-ES cung cấp một loạt các API làm cho game có hiệu năng sử lý cao, tăng tốc phần cứng. Đây là các Java API, để xây dựng lại chúng từ C là một công việc rất phức tạp. Tôi sẽ chỉ các bạn cách thức làm việc trên cả Java và C.
Bắt đầu bằng một số khái niệm cơ bản về OpenGL

1, Đỉnh: là một điểm trong không gian 3D trong OpenGl có thể chỉ là 2 tọa độ (x, y) hoặc nhiều tọa độ như (x, y, z, w) ở đó w là tùy chọn và mặc định nó có giá trị là 1.0, tương tự trục z cũng là tùy chọn và giá trị mặc định của nó là 0. Tất các các đối tượng được vẽ bởi các đỉnh hay chính là các điểm, do đó kho nói tới điểm cũng chính là 1 đỉnh.
2, Tam giác: được tạo nên bởi 3 điểm, trong OpenGL chúng ta có thể dùng 3 đỉnh để tạo nên 1 tam giác.
3, Đa giác: được tạo nên bởi nhiều hơn 2 điểm, tam giác cũng là 1 đa giác.

Nào trước hết chúng ta bắt đầu chúng với Java:
Tạo một Android project mới, với activity là Vortex và một số các lớp sau:
package vn.vndev.android.opengl;

import android.app.Activity;
import android.os.Bundle;

/**
 * 
 * @author TanNM
 *
 */
public class Vortex extends Activity {
 private static final String LOG_TAG = Vortex.class.getSimpleName();
 private VortexView vortexView;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  // Hien thi toan man hinh
  this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
  getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.FLAG_FULLSCREEN);
  vortexView = new VortexView(this);
  setContentView(vortexView);
 }
}
package vn.vndev.android.opengl;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.view.MotionEvent;

/**
 * 
 * @author TanNM
 *
 */
public class VortexView extends GLSurfaceView {
 private static final String LOG_TAG = VortexView.class.getSimpleName();
 private VortexRenderer renderer;

 /**
  * 
  * @param context
  */
 public VortexView(Context context) {
  super(context);
  renderer = new VortexRenderer();
  setRenderer(renderer);
 }

 public boolean onTouchEvent(final MotionEvent event) {
  queueEvent(new Runnable() {
   public void run() {
    renderer.setColor(event.getX() / getWidth(), event.getY() / getHeight(), 1.0f);
   }
  });
  return true;
 }
}
package vn.vndev.android.opengl;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLSurfaceView;

/**
 * 
 * @author TanNM
 *
 */
public class VortexRenderer implements GLSurfaceView.Renderer {
 private static final String LOG_TAG = VortexRenderer.class.getSimpleName();

 private float red = 0.7f;
 private float green = 0.5f;
 private float blue = 0.8f;

 @Override
 public void onSurfaceCreated(GL10 gl, EGLConfig config) {
  gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
 }

 @Override
 public void onSurfaceChanged(GL10 gl, int w, int h) {
  gl.glViewport(0, 0, w, h);
  float ratio = (float) w / h;
  gl.glMatrixMode(GL10.GL_PROJECTION);
  gl.glLoadIdentity();
  gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
 }

 @Override
 public void onDrawFrame(GL10 gl) {
  gl.glClearColor(red, green, blue, 1.0f);
  gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
 }

 public void setColor(float r, float g, float b) {
  red = r;
  green = g;
  blue = b;
 }
}
Ok giờ bạn hãy chạy thử ứng dụng và click lên các vị trí khác nhau của màn hình. Thấy j nhỉ?

6 comments:

  1. thấy không chạy :|

    ReplyDelete
  2. Lỗi gì thế bạn? Bạn đã biết cách chạy chưa? Mình chạy bt mà.

    ReplyDelete
    Replies
    1. Mình chạy nhưng bị lỗi Unfortunately, Vortex has stop. Bạn hướng dẫn cách chạy đc ko

      Delete
  3. Thanks bác!
    Bài viết rất hay!

    Bác chịu khó thêm mấy cái comment cho các hàm thì tốt quá!

    ReplyDelete
  4. em bi loi vi khong tim thay Window: this.requestWindowFeature(Window.FEATURE_NO_TITLE);

    ReplyDelete
    Replies
    1. Ban them may dong import nay vao nhe:

      import android.view.Window;
      import android.view.WindowManager;

      Delete