因為實習有點忙,所以一直沒顧的上寫這篇文章,乘著放假趕緊和大家分享NDK的相關知識,NDK國內的資料還比較少,我就到了Google的群組裡面問了好多人,最終還是讓我寫出來了。其實並不是很難只是對Opengl ES的API不熟罷了。好了廢話不多說。
如果你對NDK開發的基本概念不是很瞭解,可以先看看我這篇文章:http://blog.csdn.net/ldj299/archive/2011/02/12/6181456.aspx
這是在Activity中的重要代碼:
package com.ldj.hellondk;<br />import android.app.Activity;<br />import android.opengl.GLSurfaceView;<br />import android.os.Bundle;<br />public class HelloNDK extends Activity {<br /> public void onCreate(Bundle savedInstanceState) {<br /> super.onCreate(savedInstanceState);<br /> GLSurfaceView surface = new GLSurfaceView(this);<br /> surface.setRenderer(new NdkGLRenderer());<br /> setContentView(surface);<br /> }<br />static {<br /> //載入本地共用庫<br /> System.loadLibrary("NdkGLRenderer");<br /> }<br />}
這裡面主要是建立一個GLSurfaceView對象且綁定渲染,並且載入了本地共用庫。
接下來看NdkGLRenderer這個渲染類:
package com.ldj.hellondk;<br />import javax.microedition.khronos.egl.EGLConfig;<br />import javax.microedition.khronos.opengles.GL10;<br />import android.opengl.GLSurfaceView.Renderer;<br />public class NdkGLRenderer implements Renderer {<br />/*<br /> * 聲明了三個本地方法並且在Java中調用<br /> *<br /> */<br />native private void onNdkSurfaceCreated ();<br />native private void onNdkSurfaceChanged (int width, int height);<br />native private void onNdkDrawFrame ();</p><p>public void onDrawFrame(GL10 gl) {<br />onNdkDrawFrame ();<br />}<br />public void onSurfaceChanged(GL10 gl, int width, int height) {<br />onNdkSurfaceChanged (width, height);<br />}<br />public void onSurfaceCreated(GL10 gl, EGLConfig config) {<br />onNdkSurfaceCreated ();<br />}<br />}
接下來就是這三個本地方法的實現了,hello-ndk.c:
#include <jni.h><br />#include <GLES/gl.h><br />unsigned int vbo[2];<br />float positions[12] = {1,-1,0, 1,1,0, -1,-1,0, -1,1,0};<br />short indices [4] = {0,1,2,3};<br />void Java_com_ldj_hellondk_NdkGLRenderer_onNdkSurfaceCreated (JNIEnv* env, jobject obj)<br />{<br /> //產生兩個緩衝區對象<br /> glGenBuffers (2, vbo);<br /> //綁定第一個緩衝對象<br /> glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);<br /> //建立和初始化第一個緩衝區對象的資料<br /> glBufferData (GL_ARRAY_BUFFER, 4*12, positions, GL_STATIC_DRAW);<br /> //綁定第二個緩衝對象<br /> glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, vbo[1]);<br /> //建立和初始化第二個緩衝區對象的資料<br /> glBufferData (GL_ELEMENT_ARRAY_BUFFER, 2*4, indices, GL_STATIC_DRAW);<br />}<br />void Java_com_ldj_hellondk_NdkGLRenderer_onNdkSurfaceChanged (JNIEnv* env, jobject obj, jint width, jint height)<br />{<br /> //圖形最終顯示到螢幕的地區的位置、長和寬<br /> glViewport (0,0,width,height);<br /> //指定矩陣<br /> glMatrixMode (GL_PROJECTION);<br /> //將當前的矩陣設定為glMatrixMode指定的矩陣<br /> glLoadIdentity ();<br /> glOrthof (-2, 2, -2, 2, -2, 2);<br />}</p><p>void Java_com_ldj_hellondk_NdkGLRenderer_onNdkDrawFrame (JNIEnv* env, jobject obj)<br />{<br /> //啟用頂點設定功能,之後必須要關閉功能<br /> glEnableClientState (GL_VERTEX_ARRAY);<br /> //清屏<br /> glClearColor (0,0,1,1);<br /> glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br /> glMatrixMode (GL_MODELVIEW);<br /> glLoadIdentity ();<br /> glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);<br /> //定義頂點座標<br /> glVertexPointer (3, GL_FLOAT, 0, 0);<br /> glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, vbo[1]);<br /> //按照參數給定的值繪製圖形<br /> glDrawElements (GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0);<br /> //關閉頂點設定功能<br /> glDisableClientState(GL_VERTEX_ARRAY);<br />}
代碼中的注釋應該是比較詳細的,和用Java來實現此功能的代碼其實還是差不多的,
最後在Android.mk中告訴NDK需要編譯哪些檔案,產生哪些模組。
本文的來源程式:http://download.csdn.net/source/3154085
利用ndk-build命令編譯jni裡的檔案,然後運行程式你就回得到如下:
好了今天就到這裡,謝謝!