我之前写过两篇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'
}
}