我之前寫過兩篇Filament編譯文檔,就在我的網站上,可以到如下地址找到:
http://beavermagic.com/doc.html
現在又在做安卓有關開發和編譯的問題,尤其是涉及到C++原生代碼編譯so文件,然後安卓端引入打包成apk,這一套流程Filament都有。另外,它還有Vulkan後端,並配合OpenGL後端可以切換,它還是個PBR渲染引擎,和我目前在做的工作可謂非常吻合。因此,我又要學習Filament了,尤其是編譯這一塊,是我目前主要需要打通的工作點。
更多的不寫了,前面兩篇文檔記錄很詳盡,幾十頁內容,從編譯tools,到aar,到出apk包,以及jni、jar、so和a文件,dll和lib文件都有介紹。這裏我補充介紹編譯的問題,以便以後查看。
現在最新的發行版是1.4.5,下載該版本源碼,準備編譯。解壓縮後命名爲Filament,這就是後面會用到的根目錄。然後先準備編譯Visual Studio的工程,就是在根目錄建立out目錄,然後out目錄下建立cmake-windows-release目錄。然後進入cmake-windows-release,執行:
cmake ..\.. -G "Visual Studio 16 2019" -A x64 -DCMAKE_BUILD_TYPE=Release -DFILAMENT_SUPPORTS_VULKAN=ON -DFILAMENT_ENABLE_JAVA=ON
注意是用Visual Studio x64 Native Tools Command Prompt執行,不是cmd或者powershell的命令行。而且不是用clang,因爲他們逐步轉換到vs,放棄clang編譯了。開啓Java支持是爲了JNI的,配置沒問題即可生成TNT解決方案文件,用VS打開即可。然後選全部編譯,沒有問題,可以編譯一百多項目。選擇material_sandbox作爲啓動項目,設置命令參數:
-a vulkan ..\..\..\assets\models\monkey\monkey.obj
即可渲染出來猴子的模型,可以在我之前的文檔中看到效果,這裏不貼了。
然後是編譯安卓,首先編譯桌面版工具,out目錄下新建cmake-release,執行:
cmake ..\.. -G Ninja -DFILAMENT_SUPPORTS_VULKAN=ON -DCMAKE_INSTALL_PREFIX=..\release\filament -DCMAKE_BUILD_TYPE=Release
然後創建out/release/filament目錄,接着編譯安裝:
ninja install
然後創建out/cmake-android-release-aarch64目錄,進入該目錄執行:
cmake ..\.. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=..\android-release\filament -DCMAKE_TOOLCHAIN_FILE=..\..\build\toolchain-aarch64-linux-android.cmake -DFILAMENT_SUPPORTS_VULKAN=ON
這裏需要新建out/android-release/filament,然後執行
ninja install
這裏可能直接就成功了,也可能會在組合靜態庫的時候出錯。我的另一臺電腦就出現了問題,因爲cmd中調用sh腳本的時候無法獲取參數,雖然sh文件打開方式選了git bash。所以就將命令單獨放在git窗口中執行了。命令比較長,如下:
C:/Users/dingw/Desktop/workspace/Cpp/Filament/build/linux/combine-static-libs.sh C:/Users/dingw/AppData/Local/Android/Sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android-ar.exe C:/Users/dingw/Desktop/workspace/Cpp/Filament/out/cmake-android-release-aarch64/libs/filamat/libfilamat_combined.a C:/Users/dingw/Desktop/workspace/Cpp/Filament/out/cmake-android-release-aarch64/third_party/glslang/tnt/OGLCompilersDLL/libOGLCompiler.a C:/Users/dingw/Desktop/workspace/Cpp/Filament/out/cmake-android-release-aarch64/third_party/glslang/tnt/glslang/OSDependent/Unix/libOSDependent.a C:/Users/dingw/Desktop/workspace/Cpp/Filament/out/cmake-android-release-aarch64/third_party/glslang/tnt/SPIRV/libSPIRV.a C:/Users/dingw/Desktop/workspace/Cpp/Filament/out/cmake-android-release-aarch64/third_party/spirv-tools/source/libSPIRV-Tools.a C:/Users/dingw/Desktop/workspace/Cpp/Filament/out/cmake-android-release-aarch64/third_party/spirv-tools/source/opt/libSPIRV-Tools-opt.a C:/Users/dingw/Desktop/workspace/Cpp/Filament/out/cmake-android-release-aarch64/third_party/glslang/tnt/SPIRV/libSPVRemapper.a C:/Users/dingw/Desktop/workspace/Cpp/Filament/out/cmake-android-release-aarch64/libs/filamat/libfilamat.a C:/Users/dingw/Desktop/workspace/Cpp/Filament/out/cmake-android-release-aarch64/third_party/glslang/tnt/glslang/libglslang.a C:/Users/dingw/Desktop/workspace/Cpp/Filament/out/cmake-android-release-aarch64/third_party/spirv-cross/tnt/libspirv-cross-core.a C:/Users/dingw/Desktop/workspace/Cpp/Filament/out/cmake-android-release-aarch64/third_party/spirv-cross/tnt/libspirv-cross-glsl.a C:/Users/dingw/Desktop/workspace/Cpp/Filament/out/cmake-android-release-aarch64/third_party/spirv-cross/tnt/libspirv-cross-msl.a
然後繼續install就可以了,會在android-release/filament下得到許多頭文件和.a文件。
這樣安卓的生成就完成了,注意我只用了arm64-v8a。然後需要生成aar,就進入根目錄的android目錄,用cmd命令行執行,注意是cmd,powershell不行,會報錯filament not found in root project,用cmd在該目錄下執行:
gradlew -Pfilament_dist_dir=..\out\android-release\filament -Pextra_cmake_args=-DFILAMENT_SUPPORTS_VULKAN=ON assembleRelease
這樣就得到了aar文件,生成完畢。對於filament的幾個build.gradle,如果報錯缺少v7的a文件等錯誤,可以用ndk指定僅使用v8的,參考如下:
defaultConfig {
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
externalNativeBuild {
cmake {
arguments.add("-DANDROID_PIE=ON")
arguments.add("-DANDROID_PLATFORM=android-${versions.targetSdk}".toString())
arguments.add("-DANDROID_STL=c++_static")
arguments.add("-DFILAMENT_DIST_DIR=${filamentPath}".toString())
cppFlags.add("-std=c++14")
if (project.hasProperty('extra_cmake_args')) {
arguments.add(extra_cmake_args)
}
}
}
ndk {
abiFilters 'arm64-v8a'
}
}