Windows 下OpenGL的基本安装与配置(基于Visual Studio 2019 与 MinGW)
MinGW的安裝
1.首先我們下載相應的MinGW安裝文件, 可以通過下載相對應的架構和相應的環境的壓縮文件或者在線安裝。在這里我選擇的是在線安裝的安裝程序。
如果你下載的是壓縮包的形式(.7z), 請將它解壓縮到你想安裝的位置, 然后設置相應的環境變量。
若果你選擇在線安裝, 則直接點擊安裝程序(.msi), 點擊“Next”, 按照下圖的選項配置, 點擊“Next”, 之后選擇你的安裝路徑, 點擊“Next”, 等待下載相關的文件, 完成安裝。
安裝OpenGL
按下“Win + R”, 輸入“dxdiag”, 點擊左上角的“呈現”, 查看當前顯卡的版本, 下載對應的驅動。如果你電腦的“C:\Windows\System32\”下已經有“opengl32.dll和glu32.dll”, 那么你可以跳過這一步。
OpenGL下載地址
CMake
在下載對應的GLFW源代碼后,首先對其進行解壓縮。 我們需要使用CMake工具來生成對應的庫文件, 首先我們需要下載CMake, Cmake下載地址。下載相應的安裝文件(.msi 大概25MB左右), 運行它安裝CMake。
我們直接點擊“Next”, 接受相應的許可協議, 點擊Next。
在這里推薦選擇第二項, 以便之后的使用。
選擇安裝路徑
點擊“Install”開始安裝
等待安裝完成, 至此, CMake的安裝結束。
FreeGLUT
FreeGLUT是OpenGL Utility Toolkit(GLUT)庫的開源替代方案。GLUT(以及FreeGLUT)允許用戶在廣泛的平臺上創建和管理包含OpenGL上下文的窗口,還可以讀取鼠標,鍵盤和操縱桿功能。FreeGLUT旨在完全替代GLUT,并且僅有幾處區別。
由于GLUT陷入停滯,因此FreeGLUT正在開發中,以改進該工具包。它根據MIT許可證發布。
執行之后, 如果你已經安裝了OpenGL, 那么不出錯的話你應當能夠在你的FreeGLUT文件夾下看到對應的Makefile文件。
如果最后你看到了這樣的內容, 那么恭喜你, 你已經把FreeGLUT安裝到你的MinGW中了, 它已經自動把需要的include文件、lib文件以及bin文件復制到你的MinGW中了(在 freeglut 3.0.0以上的版本中, 可能不會安裝"glut.h"庫文件)。最后, 讓我們來測試一下。
編寫一個FreeGLUT的C程序example.c, 源代碼如下:
/** GL01Hello.cpp: Test OpenGL C/C++ Setup*/ #include <windows.h> // For MS Windows #include <GL/freeglut.h> // GLUT, includes glu.h and gl.h/* Handler for window-repaint event. Call back when the window first appears andwhenever the window needs to be re-painted. */ void display() {glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaqueglClear(GL_COLOR_BUFFER_BIT); // Clear the color buffer// Draw a Red 1x1 Square centered at originglBegin(GL_QUADS); // Each set of 4 vertices form a quadglColor3f(1.0f, 0.0f, 0.0f); // RedglVertex2f(-0.5f, -0.5f); // x, yglVertex2f( 0.5f, -0.5f);glVertex2f( 0.5f, 0.5f);glVertex2f(-0.5f, 0.5f);glEnd();glFlush(); // Render now }/* Main function: GLUT runs as a console application starting at main() */ int main(int argc, char** argv) {glutInit(&argc, argv); // Initialize GLUTglutCreateWindow("OpenGL Setup Test"); // Create a window with the given titleglutInitWindowSize(320, 320); // Set the window's initial width & heightglutInitWindowPosition(50, 50); // Position the window's initial top-left cornerglutDisplayFunc(display); // Register display callback handler for window re-paintglutMainLoop(); // Enter the infinitely event-processing loopreturn 0; }執行一下指令
gcc -c -o example.o example.c gcc -o example.exe example.o -lfreeglut -lopengl32 -Wl,--subsystem,windows運行生成的example.exe文件, 你應該可以看到以下界面:
如果你看到以下這種錯誤, 那么你可能需要將“x86_64-w64-mingw32\bin”目錄下的“libfreeglut.dll”文件復制到MinGW安裝目錄下的"bin"目錄下。
GLEW
GLFW
GLFW是一個專門針對OpenGL的C語言庫,它提供了一些渲染物體所需的最低限度的接口。它允許用戶創建OpenGL上下文,定義窗口參數以及處理用戶輸入。我們需要先下載它GLFW官網下載,它對應的源代碼。當然你可以選擇直接下載對應的已經編譯好的庫文件, 下載源代碼來構建庫文件是為了更好的適合每個人的電腦。
使用CMake的GUI界面可以很簡單的完成生成Makefile的任務, 但是我們在這里使用命令行的方式來執行, 一是為了更具普遍性, 二是為了之后的安裝。
不出意外的話, 你看到的應該是以下的界面
恭喜你, 你已經完成了GLFW的安裝, 你應當能在你的MinGW目錄下的“include”文件夾下看到相關的頭文件。
編寫一個簡單的OpenGL程序 HelloOpenGL.cpp
// CPP program to render a triangle using Shaders #include <GL/glew.h> #include <GL/glut.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glext.h>#include <iostream> #include <string>using namespace std;string vertexShader = R"(#version 430in vec3 pos;void main(){gl_Position = vec4(pos, 1);} )";string fragmentShader = R"(#version 430void main() {gl_FragColor = vec4(1, 1, 1, 1); // white color} )";// Compile and create shader object and returns its id GLuint compileShaders(string shader, GLenum type) {const char *shaderCode = shader.c_str();GLuint shaderId = glCreateShader(type);if (shaderId == 0){ // Error: Cannot create shader objectcout << "Error creating shaders!";return 0;}// Attach source code to this objectglShaderSource(shaderId, 1, &shaderCode, NULL);glCompileShader(shaderId); // compile the shader objectGLint compileStatus;// check for compilation statusglGetShaderiv(shaderId, GL_COMPILE_STATUS, &compileStatus);if (!compileStatus){ // If compilation was not successfullint length;glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &length);char *cMessage = new char[length];// Get additional informationglGetShaderInfoLog(shaderId, length, &length, cMessage);cout << "Cannot Compile Shader: " << cMessage;delete[] cMessage;glDeleteShader(shaderId);return 0;}return shaderId; }// Creates a program containing vertex and fragment shader // links it and returns its ID GLuint linkProgram(GLuint vertexShaderId, GLuint fragmentShaderId) {GLuint programId = glCreateProgram(); // crate a programif (programId == 0){cout << "Error Creating Shader Program";return 0;}// Attach both the shaders to itglAttachShader(programId, vertexShaderId);glAttachShader(programId, fragmentShaderId);// Create executable of this programglLinkProgram(programId);GLint linkStatus;// Get the link status for this programglGetProgramiv(programId, GL_LINK_STATUS, &linkStatus);if (!linkStatus){ // If the linking failedcout << "Error Linking program";glDetachShader(programId, vertexShaderId);glDetachShader(programId, fragmentShaderId);glDeleteProgram(programId);return 0;}return programId; }// Load data in VBO (Vertex Buffer Object) and return the vbo's id GLuint loadDataInBuffers() {GLfloat vertices[] = {// triangle vertex coordinates-0.5, -0.5, 0,0.5, -0.5, 0,0, 0.5, 0};GLuint vboId;// allocate buffer sapce and pass data to itglGenBuffers(1, &vboId);glBindBuffer(GL_ARRAY_BUFFER, vboId);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// unbind the active bufferglBindBuffer(GL_ARRAY_BUFFER, 0);return vboId; }// Initialize and put everything together void init() {// clear the framebuffer each frame with black colorglClearColor(0, 0, 0, 0);GLuint vboId = loadDataInBuffers();GLuint vShaderId = compileShaders(vertexShader, GL_VERTEX_SHADER);GLuint fShaderId = compileShaders(fragmentShader, GL_FRAGMENT_SHADER);GLuint programId = linkProgram(vShaderId, fShaderId);// Get the 'pos' variable location inside this programGLuint posAttributePosition = glGetAttribLocation(programId, "pos");GLuint vaoId;glGenVertexArrays(1, &vaoId); // Generate VAO (Vertex Array Object)// Bind it so that rest of vao operations affect this vaoglBindVertexArray(vaoId);// buffer from which 'pos' will receive its data and the format of that dataglBindBuffer(GL_ARRAY_BUFFER, vboId);glVertexAttribPointer(posAttributePosition, 3, GL_FLOAT, false, 0, 0);// Enable this attribute array linked to 'pos'glEnableVertexAttribArray(posAttributePosition);// Use this program for rendering.glUseProgram(programId); }// Function that does the drawing // glut calls this function whenever it needs to redraw void display() {// clear the color buffer before each drawingglClear(GL_COLOR_BUFFER_BIT);// draw triangles starting from index 0 and// using 3 indicesglDrawArrays(GL_TRIANGLES, 0, 3);// swap the buffers and hence show the buffers// content to the screenglutSwapBuffers(); }// main function // sets up window to which we'll draw int main(int argc, char **argv) {glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);glutInitWindowSize(500, 500);glutInitWindowPosition(100, 100);glutCreateWindow("Triangle Using OpenGL");glewInit();init();glutDisplayFunc(display);glutMainLoop();return 0; }將文件保存為HelloOpenGL.cpp,輸入以下命令:
g++ HelloOpenGL.cpp -o HelloOpenGL.exe -lopengl32 -lglew32 -lfreeglut -lglu32運行HelloOpenGL.exe, 你應當看到以下圖形
如果你看到以下這種錯誤, 那么你可能需要將“x86_64-w64-mingw32\bin”目錄下的“glew32.dll”文件復制到MinGW安裝目錄下的"bin"目錄下。
GLAD
由于OpenGL驅動版本眾多,它大多數函數的位置都無法在編譯時確定下來,需要在運行時查詢。所以任務就落在了開發者身上,開發者需要在運行時獲取函數地址并將其保存在一個函數指針中供以后使用。這種方式十分麻煩, 所幸我們有GLAD來幫助我們解決這個問題。
將生成的“libglad.a”庫文件放入MinGW的"x86_64-w64-mingw32\lib"目錄下, 以便之后的使用。之后, 我們只需要在編譯時加入相對應的鏈接庫即可。編譯的命令如下:
g++ ***.cpp -o ***.exe -lopengl32 -lglu32 -lglfw3 -lglew32 -lgdi32 -lglad gcc ***.cpp -o ***.exe -lopengl32 -lglu32 -lglfw3 -lglew32 -lgdi32 -lgladVisual Studio 的配置
關于Visual Studio的安裝, 相信網上有許多的教程, 再次就不再贅述了。
首先, 我們需要使用CMake工具生成我們的glfw3.lib庫文件, 打開CMake的GUI界面, 選擇已經解壓縮的glfw源文件, 選擇生成項目的目標目錄, 點擊“configure”,選擇生成的項目類型, 這里我們選擇“Visual Studio”類型的。.
點擊“finish”,等待配置完成之后, 再點擊“Generate”生成對應的項目文件。
打開項目的生成路徑, 你將會看到“GLFW.sln”的文件, 雙擊打開它。點擊“Visual Studio”上方的“生成”——>"生成解決方案“, 最終的lib庫文件將會在“src/Debug”目錄下。
將對應的glad.c文件轉變為對應的lib文件, 以便使用。打開Visual Studio, 創建一個glad靜態庫項目,在該項目路徑下創建“include”, 將glad.zip內的“include”內的內容復制到項目下的“include”目錄下, 將glad.c的內容復制到glad.cpp文件中, 在glad.cpp的第一行添加“#include “pch.h””,將下載的glad壓縮文件內的include目錄復制到項目的目錄下, 點擊“項目”——>"glad屬性“——>"C/C++“——>"常規“”, 將"附加包含目錄“設置為之前我們項目下的“include”目錄。
點擊“確定”。
點擊上方的“生成”——>“生成解決方案”。我們將在項目路徑下的“Debug”路徑下看到我們生成的glid.lib文件。
創建一個新的空白C++項目, 在項目目錄下創建目錄“include”、“lib”,將我們之前的glfw的“include”頭文件以及我們glad.zip文件內的“include”頭文件放入我們的創建的“include”目錄下,將我們之前得到的“glfw.lib”以及"glad.lib"放入我們創建的“lib”目錄下, 點擊上方的“項目”——>“屬性”——>"Visual C++目錄“, 將“包含目錄”設置為我們項目下的“include”目錄, 將“庫目錄”設置為我們創建的“lib”目錄下。
之后, 我們點擊“鏈接器”——>“輸入”, 在附加依賴項內輸入“opengl32.lib”、以及你的glfw的庫文件, 我這里的是glfw3.lib, 生成的glad庫文件, 我這里的是glad.lib。opengl32.lib是Visual Studio SDK自帶的一個庫文件。
點擊“確定”, 即可完成OpenGL的配置。
點擊“本地Windows調試”即可運行你的OpenGL程序。為了能夠正常運行你的程序, 在運行時請確保你的每個庫都是基于相同位數的, X86對應的是32位的, 而X64對應的是64位的。
參考
[1]: https://medium.com/@bhargav.chippada/how-to-setup-opengl-on-mingw-w64-in-windows-10-64-bits-b77f350cea7e
[2]: https://www.transmissionzero.co.uk/computing/using-glut-with-mingw/
[3]: https://learnopengl-cn.github.io/01%20Getting%20started/02%20Creating%20a%20window/
總結
以上是生活随笔為你收集整理的Windows 下OpenGL的基本安装与配置(基于Visual Studio 2019 与 MinGW)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android之socket编程实例
- 下一篇: 百度富文本编辑器UEditor的使用