天天看點

Mac OpenGL的坑OpenGL使用Bug

OpenGL使用Bug

系統:MacOS 10.13.6

openGL 版本: 4.1 ATI-1.68.21

opengl 函數管理庫:glew2.1.0

opengl 視窗庫:glfw3.3

IDE:CLion 2018.1

編譯時openGL 相關函數找不到

報錯日志:

Undefined symbols for architecture x86_64:
  "_glClear", referenced from:
      _main in main.cpp.o
  "_glClearColor", referenced from:
      _main in main.cpp.o
  "_glGetString", referenced from:
      _main in main.cpp.o
  "_glViewport", referenced from:
      framebuffer_size_callback(GLFWwindow*, int, int) in main.cpp.o
           

報錯的原因是代碼中所有涉及到opengl函數調用的地方,都不被x86_64架構系統識别,這點在日志中寫的很明白。

原因和解決方案:

學習的時候,代碼參考網絡部落格,CMakeLists.txt檔案如下:

cmake_minimum_required(VERSION 3.10)
project(OpenGL)

# 添加頭檔案
set(CMAKE_CXX_STANDARD 11)
set(GLFW_H /usr/local/Cellar/glfw/3.3/include/GLFW)
set(GLEW_H /usr/local/Cellar/glew/2.1.0/include/GL)
include_directories(${GLFW_H} ${GLEW_H})

# 添加目标連結
set(GLFW_LINK /usr/local/Cellar/glfw/3.3/lib/libglfw.3.3.dylib)
set(GLEW_LINK /usr/local/Cellar/glew/2.1.0/lib/libGLEW.2.1.0.dylib)
link_libraries(${OPENGL} ${GLFW_LINK} ${GLEW_LINK})

# 執行編譯指令
set(SOURCE_FILES main.cpp)
add_executable(OpenGL ${SOURCE_FILES})
           

其中

${OPENGL}

原本應該将系統的OpenGL相關庫連結到項目中的,但這個寫法可能在目前環境不支援。将這種寫法換成

"-framework OpenGL"

即可。

替換後,完整的CMakeLists.txt檔案如下:

cmake_minimum_required(VERSION 3.10)
project(OpenGL)

# 添加頭檔案
set(CMAKE_CXX_STANDARD 11)
set(GLFW_H /usr/local/Cellar/glfw/3.3/include/GLFW)
set(GLEW_H /usr/local/Cellar/glew/2.1.0/include/GL)
include_directories(${GLFW_H} ${GLEW_H})

# 添加目标連結
set(GLFW_LINK /usr/local/Cellar/glfw/3.3/lib/libglfw.3.3.dylib)
set(GLEW_LINK /usr/local/Cellar/glew/2.1.0/lib/libGLEW.2.1.0.dylib)
link_libraries("-framework OpenGL" ${GLFW_LINK} ${GLEW_LINK})

# 執行編譯指令
set(SOURCE_FILES main.cpp)
add_executable(OpenGL ${SOURCE_FILES})
           

運作時EXC_BAD_ACCESS

報錯日志:

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [0]

VM Regions Near 0:
--> 
    __TEXT                 00000001026c2000-00000001026c5000 [   12K] r-x/rwx SM=COW  
 [/Users/**/CLionProjects/OpenGL/cmake-build-debug/OpenGL]

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   ???                           	000000000000000000 0 + 0
1   OpenGL                        	0x00000001026c3d71 main + 465 (main.cpp:55)
2   libdyld.dylib                 	0x00007fff7efbd015 start + 1
           

main.cpp:55 這行的代碼是:

unsigned int VBO;
glGenBuffers(1, &VBO); // main.cpp:55
           

原因和解決方案:

出現問題的客觀原因是:在跟随教程你好,三角形練習時,教程中的代碼并不完成适用于目前場景,可能是系統方面的原因。直接原因:教程的代碼中,沒有執行

glewInit()

函數,造成随後調用的OpenGL函數無法正确的找到對應函數,進而導緻段錯誤。

來看看GLEW的官方解釋:

The OpenGL Extension Wrangler Library (GLEW) is a cross-platform open-source C/C++ extension loading library. GLEW provides efficient run-time mechanisms for determining which OpenGL extensions are supported on the target platform. OpenGL core and extension functionality is exposed in a single header file. GLEW has been tested on a variety of operating systems, including Windows, Linux, Mac OS X, FreeBSD, Irix, and Solaris.

OpenGL的使用,最基本的兩個步驟是:

  1. 初始化OpenGL上下文:上下文環境用于記錄所有OpenGL相關的狀态,位于作業系統的某一個程序中,每個程序可以擁有多個上下文,每個上下文可以描述系統中的一個視窗。簡單的說,就是在目前作業系統中建立一個視窗。
  2. 定位所有需要使用的OpenGL函數:因為OpenGL隻是一個标準,具體的實作由顯示卡驅動廠商實作,但OpenGL驅動版本居多,無法在編譯時制定。這個工作就隻能轉移到運作時,由開發者指定了。GLEW的作用就是在運作時,擷取顯示卡驅動支援的函數,儲存在對應的函數指針中供運作時調用。

是以,對應上述兩個步驟,我們應該分别執行:

  1. glfwInit

    :以建立上下文。
  2. glewInit

    :以加載系統OpenGL函數。

是以,本次未捕獲異常隻需要在執行任何OpenGL函數調用之前,調用

glewInit

即可。

繼續閱讀