赞
踩
本文记录VS 2022环境下配置openGL的流程,使用GLFW和GLEW第三方库。内容大致如下:
目录
创建一个VS空项目,勾选“将解决方案文件与项目置于同一目录”(可选项)。
在项目目录下新建文件夹"src", "lib", "include",分别用于存放源码、库文件和头文件。
其中,在"lib"文件夹下新建"debug", "release"文件夹,分别存放debug版本和release版本所使用的.lib文件。
首先,网络上通过GLFW、GLEW库的预编译来配置openGL的教程已经较多了,此处不再赘述,详情可以参考视频教程P2、P3部分
之所以要采用编译源码的方式配置环境,是由于我在通过预编译文件进行配置时,遇到了运行时冲突的warning,担心后续影响工作,所以决定自行编译,统一项目所用依赖库的运行时。
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编译完成。
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"目录下
在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 <GL\glew.h>
- #include <GLFW/glfw3.h>
-
- #include <iostream>
-
- void 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运行程序。若配置成功,则将显示如下三角形,并且不会闪退:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。