現代OpenGL系列教程(零)---第一個窗口

【寫在前面】

首先,要說明的是:這個系列將使用 glfw + glad 作爲基本的窗口系統和 opengl 擴展,編譯器則爲 VS2013。

其次,本篇從獲取、編譯、鏈接 glfw + glad 庫講起,然後建立 glfw 環境,並保證它能夠正確地創建 OpenGL 上下文並顯示窗口,所以已經搭建好環境的可以直接跳過本篇。


【正文開始】

1. 配置GLFW,從官網上下載:https://www.glfw.org/download.html,我這裏建議直接下載二進制版本:

解壓後得到:

接下來打開你的 VS目錄下的VC文件夾,將 glfw-3.2.1.bin.WIN32\include\ 下的 GLFW 文件夾拷貝至 VC\include\ 下,然後根據你的 VS 版本選擇相應的 lib-vc2013 (我的是2013),將其中的 glfw3.libglfw3dll.lib 拷貝至 VC\lib\ 下,而 glfw3.dll 放到C:\Windows\System32\ 下,至此,glfw 已經配置完成。

2. 配置 GLAD,glad 是運行時獲取 OpenGL 函數地址的一個擴展庫(類似於 glew ),首先還是從官網下載:https://glad.dav1d.de/,然後選擇 gl 版本爲 3.3 (後面可能爲4.x),模式選擇爲核心模式:

點擊最下方的生成按鈕,得到:

點擊 glad.zip,下載壓縮文件,然後解壓得到:

和 glfw 一樣,將 include\ 下的 glad 文件夾和 KHR文件夾 拷貝至 VC\include\ 下,將 src\glad.c 拷貝至你的工程目錄下,至此,glad 已經配置完成。

3. 新建一個項目,並鏈接 opengl 和 glfw 庫,在屬性->配置屬性->鏈接器->輸入->附加依賴項中加入 opengl32.libglfw3.lib

4. 開始創建第一個OpenGL窗口:

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>

#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")

這裏直接上代碼了,首先 #include <glad/glad.h> #include <GLFW/glfw3.h>注意:glad.h 必須在 glfw.h 之前包含(否則會重複包含)#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") 這一行不是必要的,我只是爲了關閉 Consolas 窗口。

接下來是 main 函數:

int main(int argc, char **argv)
{
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	GLFWwindow* window = glfwCreateWindow(600, 500, "OpenGL-Start", nullptr, nullptr);
	if (window == nullptr)
	{
		std::cerr << "Failed to Create GLFW Window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);

	if (!gladLoadGLLoader(GLADloadproc(glfwGetProcAddress)))
	{
		std::cerr << "Failed to Initliaze GLAD";
		glfwTerminate();
		return -1;
	}

	glfwSetWindowSizeCallback(window, [](GLFWwindow *window, int width, int height)
	{
		glViewport(0, 0, width, height);
	});

	glfwSetKeyCallback(window, [](GLFWwindow *window, int key, int scancode, int action, int mods)
	{
		if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
			glfwTerminate();
	});
	
	while (!glfwWindowShouldClose(window))
	{
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		glfwSwapBuffers(window);
		glfwPollEvents();
	}

	glfwDestroyWindow(window);
	glfwTerminate();
	return 0;
}

首先,我們在 main 函數中調用 glfwInit() 函數來初始化 glfw ,然後通過 glfwWindowHint() 函數來設置我們需要的OpenGL 版本爲 3.3,以及使用核心模式( Core )。

接下來我們使用 glfwCreateWindow() 創建一個窗口指針,(噢忘了說,glfw 所有的函數都有註釋,在其聲明的上方可以看到),創建完窗口我們就可以使用 glfwMakeContextCurrent() 通知 glfw 將我們窗口的上下文設置爲當前線程的主上下文了。

然後我們開始載入 OpenGL 的函數地址,通過 gladLoadGLLoader() 函數,它需要傳入一個函數指針,glfw 提供的函數爲glfwGetProcAddress(),這裏直接把它傳入。

再就是設置一些回調函數,glfwSetWindowSizeCallback() glfwSetKeyCallback() ,它們在窗口大小改變和有按鍵事件時調用相應的函數,我這裏在窗口大小改變時重置 OpenGL 視口,在按下 Esc 鍵時結束程序。

  • glfwWindowShouldClose() 函數在我們每次循環的開始前檢查一次GLFW是否被要求退出,如果是的話該函數返回true然後渲染循環便結束了,之後爲我們就可以關閉應用程序了。
  • glfwPollEvents() 函數檢查有沒有觸發什麼事件(比如鍵盤輸入、鼠標移動等)、更新窗口狀態,並調用對應的回調函數(可以通過回調方法手動設置)。
  • glfwSwapBuffers() 函數會交換顏色緩衝(它是一個儲存着GLFW窗口每一個像素顏色值的大緩衝),它在這一迭代中被用來繪製,並且將會作爲輸出顯示在屏幕上。

最後,銷燬窗口並結束程序,看一下效果圖(只是一個灰綠色的空窗口而已):


【結語】

其實 glfw + glad 還是稍微有點繁瑣的,所以使用起來難免有很多不方便的地方,後面我將會進行一些簡單的封裝,這樣就能減少很多不必要的工作,然後接下來還是要把注意力轉移到 render 中,畢竟那纔是真正的核心。

整個系列教程的源碼在我的 Github 上可以找到,地址是:https://github.com/mengps/OpenGL-Totural,會不定時進行更新~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章