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

24
Chỉ dẫn lập trình game 3D trên Android (P2) Bài hôm nay tôi sẽ hướng dẫn các bạn biên dịch native code trong ứng dụng Android. JNI là viết tắt của Java Native Interface. Sử dụng JNI chúng ta có thể gọi các hàm được viết trong những ngôn ngữ khác từ Java. Trước hết bạn tạo một Android project tạo một activity MainActivity: ? 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 package com.vndev.jni.activities; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import jni.Natives; import android.app.Activity; import android.os.Bundle; public class MainActivity extends Activity { private static final String LIB = "libch02.so"; private static final String LIB_PATH = "/data/data/com.vndev.jni.activities/files/" + LIB; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); try { // Install lib System.out.println("Installing LIB: " + LIB);

Transcript of Chỉ dẫn lập trình game 3D trên Android

Page 1: Chỉ dẫn lập trình game 3D trên Android

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

Bài hôm nay tôi sẽ hướng dẫn các bạn biên dịch native code trong ứng dụng Android.JNI là viết tắt của Java Native Interface. Sử dụng JNI chúng ta có thể gọi các hàm được viết trong những ngôn ngữ khác từ Java.Trước hết bạn tạo một Android project tạo một activity MainActivity:

?1234567891011121314151617181920212223242526272829303132333435363738

package com.vndev.jni.activities; import java.io.IOException;import java.io.InputStream;import java.io.OutputStream; import jni.Natives; import android.app.Activity;import android.os.Bundle; public class MainActivity extends Activity {    private static final String LIB = "libch02.so";    private static final String LIB_PATH = "/data/data/com.vndev.jni.activities/files/" + LIB;     /** Called when the activity is first created. */

     @Override

     public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);

         setContentView(R.layout.main);

         try {             // Install lib

             System.out.println("Installing LIB: " + LIB);             // Copy lib from assests folder to files folder:

             // /data/data/PKG_NAME/files

             writeToStream(getAssets().open(LIB), openFileOutput(LIB, 0));

             // Load Lib

             System.load(LIB_PATH);

 

Page 2: Chỉ dẫn lập trình game 3D trên Android

39404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384

            // Run it

             String[] argv = { "MyLib", "arg1", "arg2" };             Natives.LibMain(argv);

         } catch (Exception e) {             e.printStackTrace();

         }

     }

       /**

      * Write to a stream

      *

      * @param in

      * @param out

      * @throws IOException

      */

     public static void writeToStream(InputStream in, OutputStream out)             throws IOException {         byte[] bytes = new byte[2048];         for (int c = in.read(bytes); c != -1; c = in.read(bytes)) {             out.write(bytes, 0, c);

         }

         in.close();

         out.close();

     }

 }

Page 3: Chỉ dẫn lập trình game 3D trên Android

858687888990

Trong activity này ta sẽ load thư viện từ C vào bằng cách gọi:

?1System.load(LIB_PATH);

Activity này gọi một phương thức trong lớp Natives:?1Natives.LibMain(argv);

Phương thức này được khai báo:?1public static native int LibMain(String[] argv);

Phương thức này có từ khóa native, nó sẽ gọi phương thức LibMain trong thư viên được load ở trên.Toàn bộ nội dung class Natives sẽ như sau:?12345678910111213141516171819

package jni; public class Natives {    /**     * Native Main Doom Loop     * @param argv     * @return     */    public static native int LibMain(String[] argv);         /**     * This fires on messages from the C layer     * @param text     */    @SuppressWarnings("unused")    private static void OnMessage(String text, int level) {        System.out.println("OnMessage text:" + text + " level=" + level);    }}

Để tạo file header cho lớp này ta sử dụng javah trong java như sau?1Javah -jni Natives

Page 4: Chỉ dẫn lập trình game 3D trên Android

Khi đó ta có file header như sau?12345678910111213141516171819202122232425262728293031323334353637383940414243

/* DO NOT EDIT THIS FILE - it is machine generated */

 #include <jni.h>

 /* Header for class jni_Natives */

   #ifndef _Included_jni_Natives

 #define _Included_jni_Natives

 #ifdef __cplusplus

 extern "C" { #endif

 /*

  * Class:     jni_Natives

  * Method:    LibMain

  * Signature: ([Ljava/lang/String;)I

  */

 JNIEXPORT jint JNICALL Java_jni_Natives_LibMain

   (JNIEnv *, jclass, jobjectArray);

   //implements method call by java native

   #ifdef __cplusplus

 }

 #endif

 #endif

 </jni.h>

Page 5: Chỉ dẫn lập trình game 3D trên Android

44454647

Giờ bạn cần tạo một file C khác dựa vào khai báo trên cài đặt phương thức này trong C và biên dịch chúng, chạy để thấy kết quả.

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

Page 6: Chỉ dẫn lập trình game 3D trên Android

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:?12345678910111213141516171819202122232425

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); }}

?1234567891011121314

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;  /**

Page 7: Chỉ dẫn lập trình game 3D trên Android

1516171819202122232425262728293031323334

  *   * @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; }}

?12345678910111213141516171819202122232425

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);

Page 8: Chỉ dẫn lập trình game 3D trên Android

2627282930313233343536373839404142434445

  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ỉ?

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

Chúc các bạn một ngày tốt lành, hôm qua đi đá bóng về đau chân quá ko làm việc được nên ngồi viết bài tiếp vậy!Hôm trước ứng bài demo chạy tốt chứ? Hôm nay tôi sẽ giải thích sơ qua một chút về ứng dụng đó.1, Trước hết là lớp GLSurfaceView:Bắt đầu được hỗ trợ trên Android từ phiên bản 1.5.Lớp này hỗ trợ bạn kết nối vào OpenGL từ view bằng cách quản lý một bề mặt và ghép chúng vào hệ thống view của Android. Nó quản lý một EGL display, cho phép OpenGL thực hiện render vào một bề mặt.Tạo khả năng giúp OpenGL ES làm việc với vòng đời của Activity.Tạo khả năng lựa chọn định dạng frame buffer pixel một cách thích hợp.Quản lý các thread rendering riêng biệt cho phép tạo các chuyển động mượt mà :D.Cung cấp tools debugging một cách đơn giản cho tracing các lời gọi API OpenGL ES và kiểm tra lỗi.

Bạn muốn tiến xa hơn trong OpenGL thì đây là nơi mà bạn cần phải bắt đầu.Để sử dụng GLSurfaceView bạn chỉ cần gọi phương thức:?1public void  setRenderer(GLSurfaceView.Renderer renderer);

Page 9: Chỉ dẫn lập trình game 3D trên Android

có trong GLSurfaceView. Để tùy biến các thuộc tính của GLSurfaceView thì trước khi gọi phương thức setRenderer bạn có thể gọi một số các phương thức khác như:?12345

setDebugFlags(int);setEGLConfigChooser(boolean);setEGLConfigChooser(EGLConfigChooser);setEGLConfigChooser(int, int, int, int, int, int);setGLWrapper(GLWrapper);

Mặc định GLSurfaceView sẽ tạo một bề mặt với định dạng mặc định là PixelFormat.RGB_565. Nếu bạn cần một bề mặt trong suốt bạn có thể gọi phương thức getHolder().setFormat(PixelFormat.TRANSLUCENT).Một GLSurfaceView phải được thông báo khi Activity là paused và resumed. GLSurfaceView clients cần phải gọi phương thức onPause() khi activity pauses và gọi onResume() khi activity resumes. Lời gọi cho phép GLSurfaceView thực hiện pause hay resume các thread rendering, và nó cũng cho phép GLSurfaceView release hay khởi tạo lại các đối tượng OpenGL display.

2, GLSurfaceView.Renderer:Là một render interface.Render sẽ được gọi trên một thread riêng biệt vì thế hiệu năng rendering sẽ tách rời UI thread. Nhưng các render cần giao tiếp với các UI thread bởi vì UI thread là nơi nhận được các sự kiện input. Các render có thể giao tiếp bằng bất kỳ kỹ thuật java chuẩn nào cho giao tiếp cross-thread, hoặc đơn giản hơn là sử dụng phương thức queueEvent(Runnable).Khi bạn implementation render này bạn cần khai báo các phương thức sau:?123456789

// Gọi khi một bề mặt được khởi tạo hay khởi tạo lạipublic void onSurfaceCreated(GL10 gl, EGLConfig config)  // Gọi để vẽ frame hiện tại.// Phương thức này sẽ chịu trách nhiệm vẽ frame hiện tại.public void onDrawFrame(GL10 gl) // Gọi khi bề mặt thay đổi kích thướcpublic void onSurfaceChanged(GL10 gl, int width, int height)

onSurfaceCreated: Đây là nơi tốt để bạn cài đặt một điều gì đó mà bạn không thường xuyên thay đổi trong vòng đời của rendering.onDrawFrame: Đây là nơi sự kiện vẽ thực sự diễn ra.onSurfaceChanged: Nếu thiết bị của bạn cho phép chuyển giữa màn hình nằm ngang hay nằm dọc, bạn sẽ có lời gọi tới phương thức này khi sự chuyển đổi đó diễn ra. Bạn có thể thiết lập lại các tỷ lệ mới ở đây

Bạn có thể download mã nguồn của bài trước và bài này tại đây

Page 10: Chỉ dẫn lập trình game 3D trên Android

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

Đang chờ deploy cái web viết tiếp loạt bài về OpenGL vậy.Bài hôm nay tôi sẽ giới thiệu cho các bạn cách vẽ một hình đa giác cách xoay chúng như thế nào. Bài trước các bạn đã được học về GLSurfaceView và hãy chắc chắn rằng bạn đã đọc nó vì nó rất quan trọng cho bài hôm nay.Loạt bài trước tôi cũng đã giới thiệu với các bạn một số khái niệm về đỉnh, tam giác, đa giác. Hôm nay trước khi vào vẽ đa giác tôi sẽ giới thiệu cho các bạn thêm một số khái niệm khác.1, Cạnh: Cạnh là một đường thẳng nối 2 đỉnh với nhau. Chúng là đường viền của mặt và đa giác. Trong không gian 3D một cạnh có thể là một đường giao nhau của 2 mặt, do đó khi cạnh này chuyển đổi sẽ dẫn đến sự thay đổi theo của các đỉnh, các mặt kết nối với chúng.Trong OpenGL ES bạn không định nghĩa các cạnh, thay vào đó bạn định nghĩa các mặt bởi các đỉnh khi đó ta sẽ có các cạnh.Nếu bạn muốn sửa, thay đổi mộ cạnh bạn có thể thay đổi 2 đỉnh tạo nên cạnh đó.2, Mặt:Một cách tổng quát, mặt trong toán học là đa tạp n-1 chiều trong không gian n chiều. Trong tô pô, một mặt hai chiều được gọi là mặt đơn giản nếu nó đồng phôi với một hình vuông trên mặt phẳng hai chiều.Ví dụ: mặt bán cầu là một mặt đơn giản, còn toàn bộ mặt cầu lại không phải là một mặt đơn giản.Trong không gian ba chiều, mặt được mặc định là đa tạp hai chiều, là tập hợp những điểm trong hệ tọa độ Đề các ba chiều Oxyz thỏa phương trình: z = f(x,y).Trong OpenGL ES ta hiểu rằng có thể chia mặt tới mức nhỏ nhất khi đó một mặt chỉ là một tam giác, chúng được tạo lên bởi 3 đỉnh, một chuyển đổi của mặt sẽ ảnh hưởng tới các đỉnh, cạnh liên kết với nó.Khi uốn khúc trên bề mặt của bạn điều này rất quan trọng để thực hiện các điều khiển đúng hướng của nó. Khi đó bạn phải điều khiển những gì sẽ sảy ra với mặt phía trước và cả mặt phía sau nữa. Tại sao điều này lại rất quan trọng bởi vì hiệu năng của ứng dụng sẽ tăng lên khi bạn không phải vẽ cả 2 mặt mà chỉ thực hiện vẽ mặt phía trước. Đó là ý tưởng tốt sử dụng sự uốn khúc cho tất cả các dự án của bạn. Bạn có thể định nghĩa phía trên của bề mặt bằng cách.gl.glFrontFace(GL10.GL_CCW); // OpenGL docsgl.glEnable(GL10.GL_CULL_FACE); // OpenGL docsgl.glCullFace(GL10.GL_BACK); // OpenGL docs

3, Render:Thời gian để bạn đưa một cái j đó ra ngoài màn hình, có 2 phương thức để bạn làm điều này, 2 phương thức đó là:public abstract void glDrawArrays(int mode, int first, int count); // OpenGL docsvàpublic abstract void glDrawElements(int mode, int count, int type, Buffer indices); // OpenGL docs

Một số render cơ bản nhất:

Page 11: Chỉ dẫn lập trình game 3D trên Android

GL_POINTS: Render một điểm ra màn hình.GL_LINE_STRIP: Render một dãy các phân đoạn đường thẳng nối liền nhau, nhưng không nối điểm đầu và điểm cuối.GL_LINE_LOOP: Giống như GL_LINE_STRIP nhưng không nối điểm đầu và điểm cuối.GL_LINES: Render một đường thẳng.GL_TRIANGLES: Render một tam giác.GL_TRIANGLE_STRIP: Render một loạt các tam giác theo thứ tự VD: Ta có các đỉnh v0, v1, v2, v3, v4, v5 khi đó các tam giác được render là (v0, v1, v2) sau đó là (v2, v1, v3) (lưu ý thứ tự), tiếp theo là (v2, v3, v4) ...

GL_TRIANGLE_FAN: Render một loạt các tam giác giống như GL_TRIANGLE_STRIP nhưng các tam giác được vẽ giống như một hình quạt dựa vào một gốc.

Giờ chúng ta sẽ vẽ thử một tam giác:Bạn vẫn còn project hôm trước chứ, ta sẽ thay đổi một chút để có thể render ra được một tam giác.Ta chỉ cần sửa lại lớp VortexRenderer lại như sau:

package vn.vndev.android.opengl;

import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import java.nio.ShortBuffer;

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

import android.opengl.GLSurfaceView;

/** * * @author TanNM

Page 12: Chỉ dẫn lập trình game 3D trên Android

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

private float red = 0f; private float green = 0f; private float blue = 0f;

// a raw buffer to hold indices allowing a reuse of points. private ShortBuffer indexBuffer;

// a raw buffer to hold the vertices private FloatBuffer vertexBuffer;

private short[] indicesArray = { 0, 1, 2 }; private int nrOfVertices = 3;

private float angle;

@Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // preparation gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); initTriangle(); }

@Override public void onSurfaceChanged(GL10 gl, int w, int h) { gl.glViewport(0, 0, w, h); }

public void setAngle(float angle) { this.angle = angle; }

@Override public void onDrawFrame(GL10 gl) { // define the color we want to be displayed as the "clipping wall" gl.glClearColor(red, green, blue, 1.0f);

// clear the color buffer to show the ClearColor we called above... gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

// set rotation gl.glRotatef(angle, 0f, 1f, 0f);

gl.glColor4f(0.2f, 0.5f, 0.2f, 0.5f); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); gl.glDrawElements(GL10.GL_TRIANGLES, nrOfVertices, GL10.GL_UNSIGNED_SHORT, indexBuffer); }

private void initTriangle() { // float has 4 bytes ByteBuffer vbb = ByteBuffer.allocateDirect(nrOfVertices * 3 * 4);

Page 13: Chỉ dẫn lập trình game 3D trên Android

vbb.order(ByteOrder.nativeOrder()); vertexBuffer = vbb.asFloatBuffer();

// short has 4 bytes ByteBuffer ibb = ByteBuffer.allocateDirect(nrOfVertices * 2); ibb.order(ByteOrder.nativeOrder()); indexBuffer = ibb.asShortBuffer();

float[] coords = { -0.5f, -0.5f, 0f, // (x1, y1, z1) 0.5f, -0.5f, 0f, // (x2, y2, z2) 0f, 0.5f, 0f // (x3, y3, z3) }; vertexBuffer.put(coords); indexBuffer.put(indicesArray); vertexBuffer.position(0); indexBuffer.position(0); }

public void setColor(float r, float g, float b) { red = r; green = g; blue = b; }}

Để hình tam giác của ta quay với tốc độ tùy vào vị chí mà ta click ta set thêm góc giống nhưrenderer.setAngle((event.getX() + event.getY()) / 20);

trong phương thức public boolean onTouchEvent(final MotionEvent event)

của lớp VortexView

Bạn có thể download mã nguồn của ứng dụng về chạy thử.

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

Xin lỗi các bạn về sự chậm chễ này, dạo này bận quá nên ko có time để post bài nữa. Nhưng mình sẽ tiếp tục loạt bài viết này khi rảnh.Bài trước mình đã giới thiệu về Java Native Interface. Nhưng hình như các bạn không thể thực hành được bài này.Và có những email gửi về cho mình nhờ chỉ dẫn cách chạy JNI như thế nào, các bạn đó chạy ví dụ của google mà không được.Hôm nay tôi sẽ chỉ các bạn cách chạy native như thế nào.

Như các bạn đã biết lập trình game chúng ta cần tận dụng sức mạnh của phần cứng và Java Native Interface là một cách tuyệt vời để thực hiện nó.Vậy Java Native Interface làm gì?Có thể các bạn đã biết thực ra Java Native Interface cho phép chúng ta gọi hàm từ thư viện C/C++ khi đó ta có thể giao tiếp nhiều hơn với phần cứng.Ok, vậy ta có thể hình dung ta cần j rồi, hiểu về C/C++ (Hiểu sâu nhé :D). Một trình biên dịch trên Window (Những ai dùng Linux thì chuyên gia rồi chắc mình không phải hướng

Page 14: Chỉ dẫn lập trình game 3D trên Android

dẫn nữa, và mình cũng khuyên các bạn nên chuyển qua Linux (Ubuntu) mà dùng).Ở đây mình dùng http://www.cygwin.com/. Bạn phải download Android NDK về nhé http://developer.android.com/sdk/ndk/index.htmlEclipse chắc bạn có rồi :D.

Bắt đầu nhé:Cài đặt cygwin nhé.Giải nén Android NDK nhé.Bây giờ ta sẽ chạy một ví dụ của google viết sẵn để hiểu cách làm việc của nó.Trong thư mục Android NDK bạn vừa giải nén ra có thư mục sample bạn nhìn thấy một số ví dụ ở đây.Trên eclipse, bạn tạo một project android mới từ source này, ở đây chúng ta chọn hello-jni nhé.

Giờ chúng ta đã có project trên eclipse rồi.Trên command của windown (cmd), bạn cd tới thư mục của project trên ...\samples\hello-jniChạy command:?1android update project -p . -s

Nhớ rằng trước đó đã path cho android trong thư mục ...android-sdk-windows\tools và ...android-sdk-windows\platform-toolsVà path của ...cygwin\bin nữa nhé.

Giờ chúng ta bắt đầu build native code sử dụng command ndk-build.

Hãy chắc chắn rằng bạn đang ở ...\samples\hello-jni như vậy bạn sẽ không phải gõ đường dẫn này nhiều nữa.Trên command của window bạn chạy ash (Hãy chắc chắn rằng bạn đã set path cho ...cygwin\bin).Lúc này bạn đang chạy SHELL trên môi trường GNU/Linux chứ không phải command như ở window nữa.Chạy command su Của mình là su tannmKhi đó bạn sẽ nhìn thấy đường dẫn của bạn giống như:

TanNM@TanNM-PC /cygdrive/e/STUDY/android/android-ndk-r5b/samples/hello-jni

Ngon rồi đấy!Tiếp theo bạn hãy chạy lệnh:/cygdrive/e/STUDY/android/android-ndk-r5b/ndk-build

Khi đó output sẽ giống như:Gdbserver : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserverGdbsetup : libs/armeabi/gdb.setup

Page 15: Chỉ dẫn lập trình game 3D trên Android

Compile thumb : hello-jni <= hello-jni.c SharedLibrary : libhello-jni.so Install : libhello-jni.so => libs/armeabi/libhello-jni.so

Quay lại eclipse refresh lại project và chạy.

OK chứ?