OpenGLES 3.0 需要連結到 下面庫 : 1 OpenGLES3.0 庫 libGLESv2.lib 和 EGL 庫 libEGL.lib 我們會在 android-ndk-r10c下的 platforms/android-21/arch-arm/usr/lib下找到這兩個 libEGL.so 和 libGLEv3.so
2 OpenGLES3.0 應用程式也需要 包含 相關的 ES3.0 和 EGL 頭檔案 #include <EGL/egl.h> #include <GLES3/gl3.h> 也可以包含 gl2ext.h 頭檔案,已包含一些opengl es的擴充性能
OpenGL ES3.0 寫一個 三角形的demo: 内容: 1 用EGL建立on-screen 渲染surface 2 加載vertex/fragment shaders 3 建立shader 工程 ,編譯shaders,并連結到shader 工程 4 設定viewport 5 重置 color buffer 6 渲染簡單的形狀 7 使顔色buffer的 内容在EGL window surface上可見
Android.mk: Android 通過mk 檔案來 導入外部c/c++庫,并輸出so共享庫,以供Android platform調用。是以, Android ndk程式設計需要從 Android.mk入手
一般, 在mk檔案中 以LOCAL開頭的名字都是 ndk編譯系統的 宏名,在編譯時,會識别這些名字:
參考: http://blog.csdn.net/smfwuxiao/article/details/8530742
1 定義 目前路徑 即 LOCAL_PATH LOCAL_PATH := $(call my-dir) 這個就是 目前Android工程 的Android.mk 所在的根目錄 2 定義編譯導出的共享庫的名字 LOCAL_MODULE := name
3 定義c/c++宏 LOCAL_CFLAGS += -DANDROID 形如LOCAL_CFLAGS : = -D*想入這種形式 表明 要在全局(即所有的c/c++檔案裡)定義 *的 宏
4 列舉出對應于同一子產品的,要編譯的源檔案(注意不是頭檔案) LOCAL_SRC_FILES := *.c / **.c ...
5 包含源檔案要用到的 頭檔案的路徑,它是Android 工程目錄jni根目錄的相對路徑 LOCAL_C_INCLUDES : = $(your-path)
6 告訴連結器在加載共享庫的時候必須連結 系統.so共享庫 LOCAL_LDLIBS : = **
7 指定應該連結到目前子產品的靜态庫(可指定多個)。 目前子產品是動态庫時,才有意義 LOCAL_STATIC_LIBRARIES : = **
8 用于指向 一個特殊的Makefile,這個Makefile負責不同的功能 8.1 include $(CLEAR_VARS)表示 清除 LOCAL_XXX的變量,除了 LOCAL_PATH 8.2 include $(BUILD_SHARED_LIBRARY) 表示将LOCAL_XXX等變量中 定義的資訊收集起來, 确定要編譯的檔案,如何編譯。 如果要編譯靜态庫: BUILD_STATIC_LIBRARY
9 引入外部庫 $(call import-module, name); name是ndk/sources根目錄下的某個路徑,一般我們把要導入的庫,都會放在這個路徑下
編寫工程: 目的: 1 鍛煉Android NDK 程式設計能力 純C/C++編寫,由于不需要編寫java,是以我們必須找到activity底層啟動的入口, 這也是在鍛煉Android NDK 程式設計能力 2 學習能移植不同平台的opengl es 在學習OpenGL ES3.0 的知識點的同時,寫一些demo,在寫demo的同時,把一些公用的東西整理出一個工具集,供以後開發使用 實作步驟: 1 在Manifest.xml 參考: http://www.cnblogs.com/pilang/archive/2011/04/20/2022932.html
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.openglesbook.HelloTriangle">
<application
android:label="HelloTriangle"
android:hasCode="false">
<activity android:name="android.app.NativeActivity"
android:label="HelloTriangle"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:launchMode="singleTask"
android:configChanges="orientation|keyboardHidden">
<meta-data android:name="android.app.lib_name"
android:value="Hello_Triangle" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-feature android:glEsVersion="0x00030000"/>
<uses-sdk android:minSdkVersion="18"/>
</manifest>
相關說明: 詳細說明請參看 參考 1.1 因為我們嘗試隻用 c/c++來開發應用程式, 是以将android:hasCode 設定為false,意思是不包含任何的JAVA的代碼(除了内置元件類,比如Activity類)
1.2 <activity android:name="android.app.NativeActivity"... NativeActivity是 實作Android 純c/c++程式設計的關鍵,它是我們app啟動的界面, 它裡面有一個 靜态字元串 META_DATA_LIB_NAME, 它定義了 元件需要從meta-data 中加載的共享so庫。 正如 <meta-data android:name="android.app.lib_name" android:value="Hello_Triangle"/>中指的, Hello_Triangle就是NativeActivity要加載的so檔案。
1.3 我們下面就編寫輸出Hello_Triangle.so的 c/c++檔案
2 入口函數及執行順序 關于 純C++的 Android NDK開發 可以參考: http://blog.csdn.net/gengshenghong/article/details/8656862 2.1 native_app_glue native_app_glue 是Android 運作的一個子產品, 它位于 ndk根目錄下 Sources/android/目錄下,
mk檔案 定義了 将 native_app_glue作為靜态庫的語句:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS)
LOCAL_MODULE:= android_native_app_glue
LOCAL_SRC_FILES:= android_native_app_glue.c
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_EXPORT_LDLIBS := -llog
include $(BUILD_STATIC_LIBRARY)
LOCAL_EXPORT_C_INCLUDES 是将 目前路徑下的頭檔案,導到 我們工程的 mk根目錄下, 它與LOCAL_C_INCLUDES功能是一樣的都會 将 頭檔案 弄到 根目錄下
android_native_glue.c 有一個程式入口函數:
static void* android_app_entry(void *param)
{
struct android_app *android_app = (struct android_app*)param;
......
android_main(android_app);
.....
}
可以看到android_app_entry 調用了 android_main,android_main 接收 android_app結構體參數
2.2 struct android_app 它定義在 android_native_app_glue.h 頭檔案裡 是以,我們如果需要使用android_app的資訊,必須包含此頭檔案
我們需要關心的資訊有: struct android_app{ void *userData; // 指向它内部狀态的對象 ...... ANativeActivity *activity; // app運作的activity .... ANativeWindow *window; // app可以畫上去的視窗 }
2.3 android_main 函數 它是我們自己建立的一個 main函數,在這個函數裡面,我們可以完成 建立視窗,并運作opengl程式的功能。它就相當于Java層的GLSurfaceView。
3 純C/C++ 建立Android 視窗 參考: http://jingyan.baidu.com/article/a501d80cf394dfec630f5e85.html?qq-pf-to=pcqq.c2c 這篇文章比較給力,我就不羅嗦了。
建立完視窗後,後面會在這個視窗上 用OpenGLl來繪圖。