參考自LearnOpenGL CN,現将配置過程記錄如下
在我們畫出出色的效果之前,首先要做的就是建立一個OpenGL上下文(Context)和一個用于顯示的視窗。然而,這些操作在每個系統上都是不一樣的,OpenGL有目的地從這些操作抽象(Abstract)出去。這意味着我們不得不自己處理建立視窗,定義OpenGL上下文以及處理使用者輸入。
幸運的是,有一些庫已經提供了我們所需的功能,其中一部分是特别針對OpenGL的。這些庫節省了我們書寫作業系統相關代碼的時間,提供給我們一個視窗和上下文用來渲染。最流行的幾個庫有GLUT,SDL,SFML和GLFW。在教程裡我們将使用GLFW。
GLFW
GLFW是一個專門針對OpenGL的C語言庫,它提供了一些渲染物體所需的最低限度的接口。它允許使用者建立OpenGL上下文,定義視窗參數以及處理使用者輸入,這正是我們需要的。
下載下傳GLFW
首先進入官網下載下傳源代碼包,然後解壓使用CMake生成VS2017的工程。
CMake
CMake是一個工程檔案生成工具。使用者可以使用預定義好的CMake腳本,根據自己的選擇(像是Visual Studio, Code::Blocks, Eclipse)生成不同IDE的工程檔案來進行編譯。在這裡進行下載下傳Win32安裝程式。
CMake需要一個源代碼目錄和一個存放編譯結果的目标檔案目錄。源代碼目錄我們選擇GLFW的源代碼的根目錄,然後我們建立一個 build 檔案夾,選中作為目标目錄。點選Configure配置之後,可以再次點選Configure和Generate生成。
編譯
在build檔案夾裡找到GLFW.sln檔案,打開并生成解決方案,在build/src/Debug中會出現glfw3.lib檔案。現在我們建立一個空的檔案夾,并在裡面建立Include和Libs檔案夾,存放OpenGL工程用到的第三方庫和頭檔案,這樣友善整理所有的第三方庫。将"../glfw-3.3\build\src\Debug"下的glfw3.lib複制到你的Libs檔案夾中,“..\glfw-3.3\include”下的GLFW下檔案夾複制到你的Include檔案夾中。然而這要求你每次建立一個工程時都需要告訴IDE/編譯器在哪能找到這些目錄。
GLAD
GLAD是一個開源的庫。打開GLAD的線上服務,将語言(Language)設定為C/C++,在API選項中,選擇3.3以上的OpenGL(gl)版本(我們的教程中将使用3.3版本,但更新的版本也能正常工作)。之後将模式(Profile)設定為Core,并且保證生成加載器(Generate a loader)的選項是選中的。現在可以先(暫時)忽略拓展(Extensions)中的内容。都選擇完之後,點選生成(Generate)按鈕來生成庫檔案。
GLAD現在應該提供給你了一個zip壓縮檔案,包含兩個頭檔案目錄,和一個glad.c檔案。将兩個頭檔案目錄(glad和KHR)複制到你的Include檔案夾中,并添加glad.c檔案到你的工程源檔案中。
第一個工程
打開Visual Studio,選擇Visual C++,然後選擇Empty Project(空項目),建立一個新的項目。
連結
打開Project Properties(工程屬性,在解決方案視窗裡右鍵項目),然後選擇VC++ Directories(VC++ 目錄)頁籤(如下圖)。在下面的兩欄添加建立的第三方庫檔案夾:
最後需要在Linker(連結器)頁籤裡的Input(輸入)頁籤裡添加glfw3.lib這個檔案:
代碼
建立一個
.cpp
檔案,然後把下面的代碼粘貼到該檔案的最前面,Ctrl+F5開始執行,就能看到一個灰色的視窗。
#include "glad/glad.h"
#include "GLFW/glfw3.h"
#include "iostream"
//settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);
void clearWindowByColor(GLFWwindow *window);
int main()
{
/* 初始化 */
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//主版本号(Major)=3
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//次版本号(Minor)=3
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//GLFW使用核心模式
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);//mac端設定
/* 建立窗體對象 */
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);//★
/* 注冊視窗大小改變回調函數 */
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
/* 初始化GLAD */
//調用任何OpenGL的函數之前我們需要初始化GLAD
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
/* 渲染循環 */
while (!glfwWindowShouldClose(window))
{
clearWindowByColor(window);
/* 輸入 */
processInput(window);
/* 渲染指令 */
/* 檢查并調用事件、交換緩沖 */
glfwSwapBuffers(window);
glfwPollEvents();
}
/* 正确釋放/删除之前的配置設定的所有資源 */
glfwTerminate();
return 0;
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
/* 設定視口大小*/
glViewport(0, 0, width, height);//前兩個參數控制視窗左下角的位置
}
void processInput(GLFWwindow *window)
{
/* 按ESC關閉視窗 */
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
void clearWindowByColor(GLFWwindow *window)
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}