下面的这行代码就是加载所有的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大致做的事情,就是为了兼容各个平台的差异性,一种解耦的方法。