iOS 版本 OSG 引擎编译
0、工作环境:
1) Xcode 6.1
2) OSX 10.10
3) iOS SDK 8.1
1、准备工作:
1)下载 OSG 3.2.1 版本:
http://pan.baidu.com/s/1hqkUTdM
2)下载 CMake 3.0.2 版本:
http://yun.baidu.com/s/1dDpeH9Z
安装 CMake 命令行工具:
Tools > Install For Command Line Use
3)下载 iOS 相关库文件:
http://yun.baidu.com/s/1dDIkY1F
放入目录 PlatformSpecifics/iOS/3rdParty 中。
2、修改 CMakeList.txt 文件:
1) 选择真机版本还是模拟器版本:
找到如下两行:
1 2 | OPTION(OSG_BUILD_PLATFORM_IPHONE "Enable IPhoneSDK Device support" OFF) OPTION(OSG_BUILD_PLATFORM_IPHONE_SIMULATOR "Enable IPhoneSDK Simulator support" OFF) |
我这里使用的是真机版本所以修改如下:
1 2 | OPTION(OSG_BUILD_PLATFORM_IPHONE "Enable IPhoneSDK Device support" ON) OPTION(OSG_BUILD_PLATFORM_IPHONE_SIMULATOR "Enable IPhoneSDK Simulator support" OFF) |
2) 修改 IPHONE SDK 版本信息:
找到如下几行:
1 2 3 | #you need to manually set the default sdk version here SET (IPHONE_SDKVER "6.0" CACHE STRING "IOS SDK-Version") SET (IPHONE_VERSION_MIN “4.2” CACHE STRING "IOS minimum os version, use 7.0 or greater to get 64bit support") |
根据自己安装的 iOS SDK 版本号来修改,我这里安装的是 iOS 8.1 SDK 所以 IPHONE_SDKVER 修改成 8.1。最小版本号修改成 7.0 是因为 7.0 以下版本默认不会生成 arm64 架构:
1 2 3 | #you need to manually set the default sdk version here SET (IPHONE_SDKVER "8.1" CACHE STRING "IOS SDK-Version") SET (IPHONE_VERSION_MIN “7.0” CACHE STRING "IOS minimum os version, use 7.0 or greater to get 64bit support") |
3、生成 Xcode 工程
1)在 OSG 根目录下创建 ios 目录:
1 | mkdir ios |
2)进入 ios 目录,根据选择 OpenGLES 2.0 还是 OpenGLES 1.1 版本分别运行如下命令(请将其中的路径修改成你自己的,关于选择 2.0 还是 1.1 版本请参考文章后的常见问题8):
情况1:使用 OpenGLES 2.0 编译:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | cmake ../ -G Xcode -DOSG_BUILD_PLATFORM_IPHONE:BOOL=ON \ -DBUILD_OSG_EXAMPLES:BOOL=OFF \ -DBUILD_OSG_APPLICATIONS:BOOL=OFF \ -DOSG_WINDOWING_SYSTEM:STRING=IOS \ -DOSG_DEFAULT_IMAGE_PLUGIN_FOR_OSX="imageio" \ -DOSG_GL1_AVAILABLE:BOOL=OFF \ -DOSG_GL2_AVAILABLE:BOOL=OFF \ -DOSG_GLES1_AVAILABLE:BOOL=OFF \ -DOSG_GLES2_AVAILABLE:BOOL=ON \ -DOSG_GL_DISPLAYLISTS_AVAILABLE:BOOL=OFF \ -DOSG_GL_FIXED_FUNCTION_AVAILABLE:BOOL=OFF \ -DOSG_GL_LIBRARY_STATIC:BOOL=OFF \ -DOSG_GL_MATRICES_AVAILABLE:BOOL=OFF \ -DOSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE:BOOL=OFF \ -DOSG_GL_VERTEX_FUNCS_AVAILABLE:BOOL=OFF \ -DCURL_INCLUDE_DIR:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/curl-ios-device/include" \ -DCURL_LIBRARY:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/curl-ios-device/lib/libcurl.a" \ -DFREETYPE_INCLUDE_DIR_freetype2:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/freetype-ios-universal/include/freetype" \ -DFREETYPE_INCLUDE_DIR_ft2build:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/freetype-ios-universal/include" \ -DFREETYPE_LIBRARY:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/freetype-ios-universal/lib/libFreeType_iphone_universal.a" \ -DTIFF_INCLUDE_DIR:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/tiff-ios-device/include" \ -DTIFF_LIBRARY:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/tiff-ios-device/lib/libtiff.a" \ -DGDAL_INCLUDE_DIR:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/gdal-ios-device/include" \ -DGDAL_LIBRARY:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/gdal-ios-device/lib/libgdal.a" \ -DDYNAMIC_OPENSCENEGRAPH:BOOL=OFF \ -DDYNAMIC_OPENTHREADS:BOOL=OFF |
情况2:使用 OpenGLES 1.1 编译:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | cmake ../ -G Xcode -DOSG_BUILD_PLATFORM_IPHONE:BOOL=ON \ -DBUILD_OSG_EXAMPLES:BOOL=OFF \ -DBUILD_OSG_APPLICATIONS:BOOL=OFF \ -DOSG_WINDOWING_SYSTEM:STRING=IOS \ -DOSG_DEFAULT_IMAGE_PLUGIN_FOR_OSX="imageio" \ -DOSG_GL1_AVAILABLE:BOOL=OFF \ -DOSG_GL2_AVAILABLE:BOOL=OFF \ -DOSG_GLES1_AVAILABLE:BOOL=ON \ -DOSG_GLES2_AVAILABLE:BOOL=OFF \ -DOSG_GL_DISPLAYLISTS_AVAILABLE:BOOL=OFF \ -DOSG_GL_FIXED_FUNCTION_AVAILABLE:BOOL=ON \ -DOSG_GL_LIBRARY_STATIC:BOOL=OFF \ -DOSG_GL_MATRICES_AVAILABLE:BOOL=ON \ -DOSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE:BOOL=ON \ -DOSG_GL_VERTEX_FUNCS_AVAILABLE:BOOL=ON \ -DCURL_INCLUDE_DIR:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/curl-ios-device/include" \ -DCURL_LIBRARY:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/curl-ios-device/lib/libcurl.a" \ -DFREETYPE_INCLUDE_DIR_freetype2:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/freetype-ios-universal/include/freetype" \ -DFREETYPE_INCLUDE_DIR_ft2build:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/freetype-ios-universal/include" \ -DFREETYPE_LIBRARY:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/freetype-ios-universal/lib/libFreeType_iphone_universal.a" \ -DTIFF_INCLUDE_DIR:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/tiff-ios-device/include" \ -DTIFF_LIBRARY:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/tiff-ios-device/lib/libtiff.a" \ -DGDAL_INCLUDE_DIR:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/gdal-ios-device/include" \ -DGDAL_LIBRARY:PATH="/Users/skylook/Documents/Develop/OSG/OSG_3.2.1/PlatformSpecifics/iOS/3rdParty/gdal-ios-device/lib/libgdal.a" \ -DDYNAMIC_OPENSCENEGRAPH:BOOL=OFF \ -DDYNAMIC_OPENTHREADS:BOOL=OFF |
4、编译生成:
打开 ios 目录的 OpenSceneGraph.xcodeproj 运行 ALL_BUILD 试验下是否顺利。
下载编译好的 SDK:
如果只是需要使用 iOS 版本 OSG 引擎,可以直接在下面 下载编译好的 SDK 即可。
常见问题:
1) 提示 LD_LIBRARY_PATH 警告:
警告如下:
1 2 3 | Your applications may not be able to find your installed libraries unless you: set your LD_LIBRARY_PATH (user specific) or update your ld.so configuration (system wide) |
解决方法:命令行运行:
1 | export LD_LIBRARY_PATH=/usr/local/lib |
参见:
http://www.cmake.org/Wiki/CMake_RPATH_handling
2) 安装 CMake Command Line Tools 提示冲突:
1 | Failed create symlink, installation may be incomplete |
手工删除 /usr/local/bin 下面如下快捷方式:
1 2 3 4 5 6 | ccmake cmake cmake-gui cmakexbuild cpack ctest |
如果提示没有权限添加,请使用如下命令:
1 | sudo open /Applications/CMake.app |
参考如下网址:[Mac] CMake 解决 Command not found 问题
3) 希望 minversion 支持 7.0 以下版本并生成 arm64 架构:
在 osg 的 cmake 工程中默认只有 IPHONE_VERSION_MIN 大于等于 7.0 版本才会生成 arm64 架构。如果需要修改成更低版本并支持 arm64 架构,请酌情修改后面的这部分内容:
1 2 3 4 5 6 7 | IF(${IPHONE_VERSION_MIN} LESS "7.0") SET(CMAKE_OSX_ARCHITECTURES "armv6;armv7" CACHE STRING "Build architectures for iOS" FORCE) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -miphoneos-version-min=${IPHONE_VERSION_MIN} -mno-thumb -pipe -no-cpp-precomp" CACHE STRING "Flags used by the compiler during all build types." FORCE) ELSE() SET(CMAKE_OSX_ARCHITECTURES "armv7;armv7s;arm64" CACHE STRING "Build architectures for iOS" FORCE) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -miphoneos-version-min=${IPHONE_VERSION_MIN} -pipe -no-cpp-precomp" CACHE STRING "Flags used by the compiler during all build types." FORCE) ENDIF() |
4) llvm-gcc-4.2 无法找到错误:
如果提示:
1 2 3 | The CMAKE_C_COMPLIER: llvm-gcc-4.2 is not a full path and was not found in PATH |
这类的错误,是因为 IPHONE_VERSION_MIN 设置过低 (< 6.0) 导致,可以修改或删除 CMakeList.txt 中的如下内容:
1 2 3 4 5 6 7 | # Force gcc <= 4.2 on iPhone IF(IPHONE_VERSION_MIN LESS "6.0") include(CMakeForceCompiler) CMAKE_FORCE_C_COMPILER(llvm-gcc-4.2 GNU) CMAKE_FORCE_CXX_COMPILER(llvm-gcc-4.2 GNU) SET(GCC_THUMB_SUPPORT NO) ENDIF() |
5) 编译出现 Use of undeclared identifier GL_BGRA_EXT 错误:
打开 osg/GL 文件:
根据你选择的 OpenGLES 版本修改相应的地方,例如我这里使用的 OpenGLES 2.0 所以找到:
1 | #include <OpenGLES/ES2/gl.h> |
在下面加上:
1 | #include <OpenGLES/ES2/glext.h> |
如果你是 OpenGLES 1.1 则找到:
1 | #include <OpenGLES/ES1/gl.h> |
在下面加上:
1 | #include <OpenGLES/ES1/glext.h> |
这部分完整代码段参考如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #if defined(OSG_GLES1_AVAILABLE) #ifdef __APPLE__ //if its apple include the target defines so we can check for IOS #include "TargetConditionals.h" #include <OpenGLES/ES1/gl.h> #include <OpenGLES/ES1/glext.h> #else #include <GLES/gl.h> #endif #elif defined(OSG_GLES2_AVAILABLE) #ifdef __APPLE__ //if its apple include the target defines so we can check for IOS #include "TargetConditionals.h" #include <OpenGLES/ES2/gl.h> #include <OpenGLES/ES2/glext.h> #else #include svn add GLES2/gl2.h> #endif #else |
6) 编译出现 '__curl_rule_01__' declared as an array with a negative size 错误:
如果在编译 osgdb_curl 的时候出现如下错误提示:
1 | curlrules.h:143:6: '__curl_rule_01__' declared as an array with a negative size |
修改方式为:打开 curlbuild.h 文件,找到如下代码:
1 2 | /* The size of `long', as computed by sizeof. */ #define CURL_SIZEOF_LONG 4 |
修改为:
1 2 3 4 5 6 | /* The size of `long', as computed by sizeof. */ #ifdef __LP64__ #define CURL_SIZEOF_LONG 8 #else #define CURL_SIZEOF_LONG 4 #endif |
7) 编译出现 Undefined symbols for architecture arm64: osgDB::readNodeFile 错误:
如果在调用 osgDB 的时候出现如下错误提示:
1 2 3 4 5 6 7 | Undefined symbols for architecture arm64: "osgDB::readNodeFile(std::string const&, osgDB::Options const*)", referenced from: -[AppDelegate application:didFinishLaunchingWithOptions:] in AppDelegate.o "osg::Shader::Shader(osg::Shader::Type, std::string const&)", referenced from: configureShaders(osg::StateSet*) in AppDelegate.o ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation) |
这很可能是你在编译 osg 引擎的 target 比调用的工程版本更高导致。虽然我们之前在 IPHONE_VERSION_MIN 中设置 6.0 或者更低的版本,但是有可能生成的 Xcode 工程还是沿用当前 SDK 的版本。如果出现这种情况一个解决方法是在生成工程后,把所有要生成的模块 target 全选,将设置中的 iOS Deployment Target 都改成 6.0,如图所示:
8) 关于选择 OpenGLES 版本的问题:
OpenGLES 2.0 有着更优秀的性能和支持自定义 shader 方法,一般情况下选择 OpenGLES 2.0 版本更好。但是也正是因为此,OpenGLES 2.0 会比较麻烦,比如想要绘制一个骨骼动画,1.1 版本只要加载文件就可以了,而 2.0 版本通常还需要自己为模型写 shader 才能正确绘制。这主要是由于 OSG 3.2.1 版本并没有提供自动生成匹配 shader 的功能。这一点会带来不少麻烦,尤其是模型并非自己制作的时候。如果你也面对这个问题,那么可以考虑暂时选用 OpenGLES 1.1 版本。