OPENGL中GLAD的代码实现过程

下面的这行代码就是加载所有的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);
}

2.看下GLFW是怎么加载Opengl32.dll的

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.3GLAD_GL_VERSION_1_0 至 GLAD_GL_VERSION_3_3的值都是1,后面这个为了后面动态加载每个版本的函数做准备。

 

3.依据版本号动态加载相应的函数

动态加载各个版本的函数

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大致做的事情,就是为了兼容各个平台的差异性,一种解耦的方法。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值