本文記錄VS 2022環境下配置openGL的流程,使用GLFW和GLEW第三方庫。內容大致如下:
成都創新互聯公司成立于2013年,我們提供高端成都網站建設、成都網站制作、成都網站設計、網站定制、營銷型網站、小程序開發、微信公眾號開發、網站推廣服務,提供專業營銷思路、內容策劃、視覺設計、程序開發來完成項目落地,為建筑動畫企業提供源源不斷的流量和訂單咨詢。目錄
1. 創建VS項目
2. 編譯GLFW源碼
3. 編譯GLEW源碼
4. 配置VS項目屬性
創建一個VS空項目,勾選“將解決方案文件與項目置于同一目錄”(可選項)。
在項目目錄下新建文件夾"src", "lib", "include",分別用于存放源碼、庫文件和頭文件。
其中,在"lib"文件夾下新建"debug", "release"文件夾,分別存放debug版本和release版本所使用的.lib文件。
2. 編譯GLFW源碼首先,網絡上通過GLFW、GLEW庫的預編譯來配置openGL的教程已經較多了,此處不再贅述,詳情可以參考視頻教程P2、P3部分
【譯】TheCherno-OpenGL系列教程
之所以要采用編譯源碼的方式配置環境,是由于我在通過預編譯文件進行配置時,遇到了運行時沖突的warning,擔心后續影響工作,所以決定自行編譯,統一項目所用依賴庫的運行時。
GLFW庫的官網鏈接如下:
An OpenGL library | GLFW
進入以后選擇右上角的Download進入下載頁面,或者直接點擊右側Download按鈕下載源碼。
進入下載頁面以后,可以選擇下載源碼或者預編譯文件,此處選擇下載源碼。
下載以后,解壓縮文件,進入文件目錄。文件目錄內包含如下文件:
運行CMake工具,將CMakeList.txt所在目錄輸入到源碼目錄一欄("Where is the source code: ")。依照習慣,在恰當位置建立文件夾"build"用以存放生成的文件。將build文件夾路徑輸入到下一欄中。隨后點擊Configure按鈕,進行生成配置。
選擇項目的編譯環境為"Visual Studio 17 2022",平臺為win32(本案例以win32為所使用平臺)。隨后點擊按鈕“完成”。
待窗口中列出生成選項之后,注意到最后一個選項"USE_MSVC_RUNTIME_LIBRARY_DLL",此處若勾選為“是”,則編譯中將使用動態運行時,若不勾選,則將使用靜態運行時。由于考慮到使用動態運行時生成的程序,在轉移到其他機器時容易因缺少運行時環境而無法運行,所以此處采用靜態運行時,將運行時直接打包到生成的文件中。所以取消勾選該選項。
關于運行時可以參考此篇博客:帶你玩轉Visual Studio——帶你跳出坑爹的Runtime Library坑
完成修改后,先點擊Configure保存修改,再點擊Generate生成文件。
隨后在build文件夾中可以找到生成的Visual Studio項目。編譯此項目即可完成GLFW的編譯。
用VS 2022打開GLFW.sln文件。
在GLFW3/glfw文件上右鍵,選擇propeties選項,打開屬性界面。先在上方選擇Configure為Debug,Platform為win32,轉至C/C++ —>Code Generation —>Runtime Library,檢查此項是否為Multi-threaded Debug(/MTd)。同理,再將上方Configure選為Release,檢查此選項是否為Multi-threaded。
退出窗口,現在上方將VS模式選擇為Debug, Win32,在左側Solution "GLFW"上右鍵,選擇Build Solution。隨后再切換模式為Release, Win32,同樣Build Solution。
編譯完成后,將編譯生成的.lib文件和頭文件復制到自己的項目里面。
在Build目錄下,進入src文件夾,內有兩個目錄,分別為"Debug", "Release",分別將兩個文件夾內的文件復制到先前創立的VS項目中,"lib\debug"和"lib\release"目錄下
又退回到CMakeList.txt所在目錄下,進入include文件夾,將GLFW文件夾完整復制到自己所創建項目下的include文件夾內。
GLFW編譯完成。
3. 編譯GLEW源碼GLEW官方網站鏈接如下:
GLEW: The OpenGL Extension Wrangler Library (sourceforge.net)
進入以后,仿照先前流程,下載源碼zip文件
下載之后,解壓縮,進入目錄。在沿路徑build>vc12找到VS?Solution文件,打開。
由于目前GLEW官方源碼文件中的Solution文件最高僅到vc12,所以打開以后會有提示將項目進行重定向,選擇“是”。
重定向之后,手動修改各項目的運行時庫,依照GLFW配置時的操作,Debug版本使用(\MTd),Release版本使用(\MT),平臺選擇Win32。對四個項目都進行同樣的配置。
設置完成后,仿照GLFW的構建,先選擇Debug+win32模式進行Build,再選擇Release+win32模式進行構建。注意,此處可能出現報錯,如果Release模式構建成功一次以后,再次進行Build會產生“無法解釋的外部符號”報錯,原因未知。
兩次Build均完成以后,退回目錄"glew-2.1.0",進入"./lib/Debug/Win32"目錄下,將一下兩個文件復制到自建項目的"lib/debug"目錄下
同理,將?"./lib/Release/Win32"的以下文件也復制到自建項目的"lib/release"目錄下
4. 配置VS項目屬性在VS項目的src目錄下,新建"application.cpp"文件。
完成以上步驟后,VS項目的目錄應該呈現如下形式:
在項目標簽上右鍵,選擇Propeties,打開屬性設置窗口:
首先將Configuration調整為All Configuration,Platform調整為Win32。
在C/C++ >Genral >Additional include Directories處添加"$(SolutionDir)include"。
在C/C++ >Preprocessor >Preprocessor Definitions處添加"GLEW_STATIC"(這是由于我們所使用的GLEW庫是靜態庫版本,所以需要預先聲明)
完成以上兩項后,點擊“應用(A)”。
隨后將Configuration切換至Debug,Platform不改變。進入C/C++ >Code Generation >Runtime Library,設置為"(/MTd)"。
進入Linker >General >Additional Library Directories,添加"$(SolutionDir)lib\debug"。?
進入Linker >Input >Additional Dependencies,添加"glew32sd.lib","glfw3.lib","opengl32.lib"。也就是將lib\debug下的所有.lib文件添加進去,并附加上一個opengl32.lib。
應用以上修改。再將Configuration改為"Release",同理進行以上操作,只不過將Runtime Library設置為"(/MT)"?,添加的Additional Library Directories為"$(SolutionDir)lib\release",添加的Additional Dependencies是"$(SolutionDir)lib\release"下的所有lib文件以及opengl32.lib文件。
最后,退出屬性配置窗口,將以下測試代碼復制到application.cpp文件中:
#include#include#includevoid framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec3 aColor;\n"
"out vec3 ourColor;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos, 1.0);\n"
" ourColor = aColor;\n"
"}\0";
const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"in vec3 ourColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(ourColor, 1.0f);\n"
"}\n\0";
int main()
{
// glfw: initialize and configure
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
// glfw window creation
// --------------------
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);
// glew: initialize library
// ---------------------------------------
if (glewInit() != GLEW_OK)
{
std::cout<< "Failed to initialize GLEW"<< std::endl;
return -1;
}
// build and compile our shader program
// ------------------------------------
// vertex shader
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
// check for shader compile errors
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout<< "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n"
<< infoLog<< std::endl;
}
// fragment shader
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// check for shader compile errors
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout<< "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n"
<< infoLog<< std::endl;
}
// link shaders
unsigned int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
// check for linking errors
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout<< "ERROR::SHADER::PROGRAM::LINKING_FAILED\n"
<< infoLog<< std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// set up vertex data (and buffer(s)) and configure vertex attributes
// ------------------------------------------------------------------
float vertices[] = {
// positions // colors
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom left
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // top
};
unsigned int VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
// glBindVertexArray(0);
// as we only have a single shader, we could also just activate our shader once beforehand if we want to
glUseProgram(shaderProgram);
// render loop
// -----------
while (!glfwWindowShouldClose(window))
{
// input
// -----
processInput(window);
// render
// ------
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// render the triangle
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers(window);
glfwPollEvents();
}
// optional: de-allocate all resources once they've outlived their purpose:
// ------------------------------------------------------------------------
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
// glfw: terminate, clearing all previously allocated GLFW resources.
// ------------------------------------------------------------------
glfwTerminate();
return 0;
}
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
// make sure the viewport matches the new window dimensions; note that width and
// height will be significantly larger than specified on retina displays.
glViewport(0, 0, width, height);
}
分別在Release模式和Debug模式下嘗試生成解決方案:
如果無報錯,嘗試通過 Local Windows Debugger運行程序。若配置成功,則將顯示如下三角形,并且不會閃退:
你是否還在尋找穩定的海外服務器提供商?創新互聯www.cdcxhl.cn海外機房具備T級流量清洗系統配攻擊溯源,準確流量調度確保服務器高可用性,企業級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧
文章標題:VS2022配置openGL環境(GLFW+GLEW)-創新互聯
轉載源于:http://vcdvsql.cn/article6/ejjig.html
成都網站建設公司_創新互聯,為您提供網站內鏈、品牌網站建設、小程序開發、定制開發、自適應網站、App開發
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯