nanogui之更新子模块glfw3.3.2踩坑总结
nanogui源码下载:
A 、 https://github.com/wjakob/nanogui
B 、 https://github.com/dalerank/nanogui
B是fork的A,但是B有新的改进。
本文仅为参考,请以实际情况为准
本文演示环境: window10 + vs2015 up3 + cmake3.18
-----------------------------------------------------------------------
折腾
1、我想要实现界面半透明,控件不透明(透明度很差也可以)的效果。比如; 窗体时半透明的、窗体上的button, label等控件时不透明的或者透明度很差。于是想利用glfw的库函数实现窗体半透明。这里 (https://www.glfw.org/docs/3.3/group__window.html#gac31caeb3d1088831b13d2c8a156802e9) 找到了最新版glfw3.3.2中提供的库函数glfwsetwindowopacity,原型:
void glfwSetWindowOpacity ( GLFWwindow * window, float opacity )
这个函数是在3.3版本新加入的。
然而,查看nanogui使用的glfw库版本号是3.2。
为什么这样做? 为什么要调用库函数设置窗体透明效果? 答案:我现在是调用的基于OS的库函数实现的界面半透明,升级为调用glfw的库函数方便cross-platform. 而且代码更加简介。 好处多多。
2、nanogui是引用的项目glfw_objects. 这个项目在glfw3.2中是有生成的,但是升级到3.3以后,就没有这个项目了。
旧版3.2生成的项目一览:
用VS打开项目,可以清晰的看到这个项目生成的是一个静态库:
而新版3.3.2中生成的项目中没有glfw_object项目:
3、知道了上面的区别,就不能简单的替换nanogui下ext/glfw源码。否则,当执行cmake指令.的时候就会出现:
Configuring done CMake Error at CMakeLists.txt:529 (add_library): Error evaluating generator expression: $<TARGET_OBJECTS:glfw_objects> Objects of target "glfw_objects" referenced but no such target exists. CMake Error at CMakeLists.txt:529 (add_library): Error evaluating generator expression: $<TARGET_OBJECTS:glfw_objects> Objects of target "glfw_objects" referenced but no such target exists. CMake Error at CMakeLists.txt:529 (add_library): No SOURCES given to target: nanogui
cmake提示也说的很清楚: 无法找到以用的项目【glfw_objects】,该项目不存在。
回到 nanogui顶级目录下的 CMakeLists.txt ,找到出错所示的行前后代码:
if (CMAKE_GENERATOR STREQUAL Xcode) set(XCODE_DUMMY ${CMAKE_CURRENT_BINARY_DIR}/xcode_dummy.cpp) file(WRITE ${XCODE_DUMMY} "") add_library(nanogui ${NANOGUI_LIBRARY_TYPE} ${XCODE_DUMMY} $<TARGET_OBJECTS:nanogui-obj> $<TARGET_OBJECTS:glfw_objects> ) else() if (NANOGUI_GLFW_BACKEND OR NANOGUI_VULKAN_BACKEND) add_library(nanogui ${NANOGUI_LIBRARY_TYPE} $<TARGET_OBJECTS:nanogui-obj> $<TARGET_OBJECTS:glfw_objects> ) else() add_library(nanogui ${NANOGUI_LIBRARY_TYPE} $<TARGET_OBJECTS:nanogui-obj> ) endif() endif()
我这里,将【NANOGUI_GLFW_BACKEND】设置为ON。执行上面的分支到:
add_library(nanogui ${NANOGUI_LIBRARY_TYPE} $<TARGET_OBJECTS:nanogui-obj> $<TARGET_OBJECTS:glfw_objects> )
add_library将 glfw_object合并到nanogui项目。原因就是 3.3.2版本中没有生成对应的项目,造成nanogui引用项目glfw_objects失败,而且,在nanogui的CMakeLists,txt的前面,作者也说了,将glfw合并到nanogui。 原为如下 :
# Two targets have now been defined: `glfw_objects`, which will be merged into # NanoGUI at the end, and `glfw`. The `glfw` target is the library itself # (e.g., libglfw.so), but can be skipped as we do not need to link against it # (because we merge `glfw_objects` into NanoGUI). Skipping is required for # XCode, but preferable for all build systems (reduces build artifacts). # -------------------------------------------------------------------------------------- add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/ext/glfw" "ext_build/glfw")
4、个人经验: 既然glfw是个第三方库,如果能动态链接该库肯定比nanogui目前这样引用来的方便,库之间保持了相对的独立,而且维护也方便,有什么更新,只需要替换对应的头文件和动态库(和lib文件)即可。 个人很少做 非基于windows的开发,所以,可能上述情况不太适用其他平台。
更新glfw
1、下载nanogui源码,我下载的是: https://github.com/dalerank/nanogui , 要注意,一定要下载其对应的子模块,可以使用 git 指令查看其依赖的字库,或者 到 【这里】下载我之前就准备好的
2、下载glfw: https://www.glfw.org/download.html 和 https://github.com/glfw/glfw 都可以下载到。
还可以直接下载 已经编译好的Windows平台的库,我下载的是32位已经编译好的glfw库。
我这里: 使用的是VS2015up3. (c++11支持更友好)
3、解压nanogui源码,打开nanogui顶层目录下的CMakeLists.txt , 找到 523 行, 将其修改为如下:
# XCode has a serious bug where the XCode project produces an invalid target # that will not get linked if it consists only of objects from object libraries, # it will not generate any products (executables, libraries). The only work # around is to add a dummy source file to the library definition. This is an # XCode, not a CMake bug. See: https://itk.org/Bug/view.php?id=14044 if (CMAKE_GENERATOR STREQUAL Xcode) set(XCODE_DUMMY ${CMAKE_CURRENT_BINARY_DIR}/xcode_dummy.cpp) file(WRITE ${XCODE_DUMMY} "") add_library(nanogui ${NANOGUI_LIBRARY_TYPE} ${XCODE_DUMMY} $<TARGET_OBJECTS:nanogui-obj> #$<TARGET_OBJECTS:glfw> ) else() if (NANOGUI_GLFW_BACKEND OR NANOGUI_VULKAN_BACKEND) ## 下面的这行是新增的,指定库的目录 link_directories(${CMAKE_CURRENT_SOURCE_DIR}/ext/glfw/lib) add_library(nanogui ${NANOGUI_LIBRARY_TYPE} $<TARGET_OBJECTS:nanogui-obj> #$<TARGET_OBJECTS:glfw> ## 这里是需要你手动修改的 ) target_link_libraries(nanogui glfw3) ## 这里是新增的代码 else() add_library(nanogui ${NANOGUI_LIBRARY_TYPE} $<TARGET_OBJECTS:nanogui-obj> ) endif() endif()
核心:
## 下面的这行是新增的,指定库的目录 link_directories(${CMAKE_CURRENT_SOURCE_DIR}/ext/glfw/lib) add_library(nanogui ${NANOGUI_LIBRARY_TYPE} $<TARGET_OBJECTS:nanogui-obj> #$<TARGET_OBJECTS:glfw> ## 这里是需要你手动修改的 ) target_link_libraries(nanogui glfw3) ## 这里是新增代码
我将其改为了动态链接 glfw库,就这样。
4、将下载好的glfw的lib文件拷贝到xx/nanogui/ext/glfw/lib目录下,上面的CMakeLists.txt中指向了在这个目录下查找库文件(可自定义其他路径)
5、CMake执行 nanogui 目录下的 CMakeLists.txt , 生成解决方案(我这里已经打开过解决方案了):
6、将 glfw的dll文件复制到解决方案输出目录,我这里是上面图片中的debug目录(这里的批处理文件是我自己写的,删除调试文 pdb, ilk 等):
7、运行example,就可以看到和nanogui在GitHub上的示例图片,我这里就放一张。(这里,example, 是大佬提前写好的,非我自己调用glfw库实现半透明的示例)
更新
更新时间: 2020-0802 15:26
从 https://github.com/wjakob/nanogui fork了一份到自己的仓库, 并做了一下更改:
1.删除 nanogui 对 glfw 子模块的引用
2.添加glfw3.3.2源码到项目,
fork 地址: https://github.com/mohistH/nanogui
添加更新后, 生成项目, 编译输出结果: