1. 程式人生 >實用技巧 >其它 >OPENGL中GLAD的程式碼實現過程

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);
}

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.3 ,GLAD_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多個庫函式

OPENGL中GLAD的程式碼實現過程


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