OPENGL中GLAD的程式碼實現過程
技術標籤:OpenGL
下面的這行程式碼就是載入所有的OpenGL功能函式,這個任務由glad來負責完成:
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
一、先看下GLAD是怎麼樣和Opengl32.dll建立聯絡的
1.glfwGetProcAddress的實現:
GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
{
.....return window->context.getProcAddress(procname);
}
glfwCreateWindow() -> _glfwPlatformCreateWindow() -> _glfwInitWGL() 這樣的呼叫關係:
_glfwInitWGL()函式位於GLFW原始碼wgl_context.c檔案中
GLFWbool _glfwInitWGL(void)
{
......_glfw.wgl.instance = LoadLibraryA("opengl32.dll");
if (!_glfw.wgl.instance)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to load opengl32.dll");
return GLFW_FALSE;
}_glfw.wgl.GetProcAddress = (PFN_wglGetProcAddress)
GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress");......
}
二、gladLoadGLLoader函式
1.先進入gladLoadGLLoader()函式中:
int gladLoadGLLoader(GLADloadproc load) {
GLVersion.major = 0; GLVersion.minor = 0;
glGetString = (PFNGLGETSTRINGPROC)load("glGetString"); //動態載入glGetString 函式
if(glGetString == NULL) return 0;
if(glGetString(GL_VERSION) == NULL) return 0;
find_coreGL();
load_GL_VERSION_1_0(load);
load_GL_VERSION_1_1(load);......
}
2.再進入find_coreGL()中:
static void find_coreGL(void) {
......
/* PR #18 */
#ifdef _MSC_VER
sscanf_s(version, "%d.%d", &major, &minor);
#else
sscanf(version, "%d.%d", &major, &minor);
#endif
GLVersion.major = major; GLVersion.minor = minor; //得到主版本號:例如"3.3.0 - Build 10.18.10.4252"
max_loaded_major = major; max_loaded_minor = minor;
GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1;
GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1;
GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1;
GLAD_GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1;
GLAD_GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1;
GLAD_GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1;
GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2;
......
}
int GLAD_GL_VERSION_1_0;
int GLAD_GL_VERSION_1_1;
int GLAD_GL_VERSION_1_2;
......
int GLAD_GL_VERSION_4_4;
int GLAD_GL_VERSION_4_5;
這些都是int型的標識,為1:表示當前的Openg32 庫大於且需相容的版本,為0:表示還沒有到這個版本
這裡版本是3.3 ,GLAD_GL_VERSION_1_0 至GLAD_GL_VERSION_3_3的值都是1,後面這個為了後面動態載入每個版本的函式做準備。
動態載入各個版本的函式
load_GL_VERSION_1_0(load);
load_GL_VERSION_1_1(load);
load_GL_VERSION_1_2(load);
load_GL_VERSION_1_3(load);
load_GL_VERSION_1_4(load);
load_GL_VERSION_1_5(load);
......
例如:
static void load_GL_VERSION_1_0(GLADloadproc load) {
if(!GLAD_GL_VERSION_1_0) return; //這裡是判斷Opengl32的庫版本是否大於它,大於就載入後面的庫函式
glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace");
glad_glFrontFace = (PFNGLFRONTFACEPROC)load("glFrontFace");
glad_glHint = (PFNGLHINTPROC)load("glHint");
glad_glLineWidth = (PFNGLLINEWIDTHPROC)load("glLineWidth");
glad_glPointSize = (PFNGLPOINTSIZEPROC)load("glPointSize");......
}
總結
可以看到windows下的Opengl32.dll共匯出300多個庫函式

以上就是GLAD大致做的事情,就是為了相容各個平臺的差異性,一種解耦的方法。
