1. 程式人生 > 實用技巧 >nanogui之更新子模組glfw3.3.2踩坑總結

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.htmlhttps://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庫實現半透明的示例)