( 本文为LearnOpenGL教程的学习记录及拓展学习,教程链接:https://learnopengl-cn.github.io/ )
创建OpenGL上下文通常需要编写特定于平台的代码才能创建窗口。它还需要从该上下文手动加载OpenGL函数。这些工具在大多数情况下提供了跨平台的解决方案,极大地简化了这些任务。LearnOpenGL教程使用GLFW创建上下文和窗口,使用GLAD来访问OpenGL规范接口。
GLFW是继GLUT、FreeGLUT之后,一个新的用于创建窗口,上下文和表面,接收输入和事件的第三方库,支持OpenGL,OpenGL ES和Vulkan,它提供了一些渲染物体所需的最低限度的接口。
GLAD是继GL3W,GLEW之后,一个新的用来访问OpenGL规范接口的第三方库
(其他环境的配置请自行搜索)
打开GLFW的官网(https://www.glfw.org/),因为官方提供了MSVC的二进制文件,我们可以直接点击标题栏下载:
进入下载页后,我们可以看到Windows的二进制下载选项,分32/64位,根据个人需求我选的32位:
下下来之后,解压,可以看到VS个版本对应的文件夹,里面是编译好的库文件:
我们只需要把include和lib配置到VS中去就行了。创建一个C++项目,打开项目属性页,可以在 VC++目录 中配置include和lib,不过这里我还是配置在 C/C++ 和 链接器 中。需要修改三个地方:
(附加依赖项填入opengl32.lib和glfw3.lib)
这里我们就把GLFW配置好了,由于直接使用的编译好的二进制文件,所以很简单。
打开GLAD的官方下载页:https://glad.dav1d.de/ ,根据需求选择配置,教程里只写了选择gl3.3以上版本,选择核心模式,所以这里我把全部都选了最高的:
点击右下角生成按钮后会进入下载页,我们直接点击zip文件进行下载:
解压之后包含include和src文件夹。再次打开VS属性页,把include放到附加包含目录中去:
右键添加现有项,把src文件夹中的glad.c文件包含进去:
至此,OpenGL最简单的环境就配置好了,其实VS2015/2017的配置也和VS2019差不多。
#include
#include
#include
void error_callback(int error, const char* description); //声明
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
void bufferresize_callback(GLFWwindow* window, int width, int height);
int main()
{
if (!glfwInit()) {
return -1; //初始化GLFW库失败
}
//注册错误回调,大多数事件都是通过回调报告的
glfwSetErrorCallback(error_callback);
//设置最低主版本号
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
//设置最低次版本号
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//设置为核心模式
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //mac系统加这一句
//创建窗口对象,如果要销毁窗口则glfwDestroyWindow(window)
GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
//创建失败则返回NULL,退出程序
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
//窗口位置,试了下不包含标题栏
glfwSetWindowPos(window, 100, 100);
//注册按键按下的回调
glfwSetKeyCallback(window, key_callback);
//注册帧缓冲区大小改变的回调
glfwSetFramebufferSizeCallback(window, bufferresize_callback);
//通知GLFW将我们窗口的上下文设置为当前线程的主上下文
//必须先具有当前的OpenGL上下文,然后才能使用OpenGL API,加载程序需要当前上下文才能加载
glfwMakeContextCurrent(window);
//在调用任何OpenGL的函数之前我们需要初始化GLAD
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
glfwTerminate();
return -1;
}
//检查GLFW是否被要求退出
while (!glfwWindowShouldClose(window))
{
//设置清空屏幕所用的颜色
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
//清空颜色缓冲
glClear(GL_COLOR_BUFFER_BIT);
//交换颜色缓冲
//默认情况下,GLFW窗口使用双缓冲。这意味着每个窗口都有两个渲染缓冲区。
//前缓冲区和后缓冲区。前缓冲区是要显示的缓冲区,后缓冲区是要渲染的缓冲区。
//渲染完整个帧后,需要相互交换缓冲区,因此后缓冲区将变为前缓冲区,反之亦然。
glfwSwapBuffers(window);
//检查有没有触发什么事件(比如键盘输入、鼠标移动等)
//并调用对应的回调函数(可以通过回调方法手动设置)
glfwPollEvents();
}
//销毁窗口
glfwDestroyWindow(window);
//使用GLFW的操作后,需要终止GLFW
glfwTerminate();
return 0;
}
void error_callback(int error, const char* description)
{
std::cout << "error:" << error << std::endl;
std::cout << "description:" << description << std::endl;
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
//Esc按下则触发WindowShouldClose为true
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
void bufferresize_callback(GLFWwindow* window, int width, int height)
{
//glViewport函数前两个参数控制渲染窗口左下角的位置
glViewport(0, 0, width, height);
}
程序跑起来之后可能还有警告:
原因是,选择 MT会用到LIBCMT.LIB,MTD会用到LIBCMTD.LIB,MD会用到MSVCRT.LIB,MDD会用到MSVCRTD.LIB。如果你使用的库用的MT,你自己的程序为MD,则会发生MSVCRTD.LIB和LIBCMTD.LIB的冲突(debug)或者MSVCRT.LIB和LIBCMT.LIB的冲突(release)。
这里列出几种解决方法:
a、【项目】>>【属性】>>【配置属性】>>【C/C++】>>【代码生成】>>【运行时库】,设置为“多线程DLL(/MD)"
b、【项目】>>【属性】>>【配置属性】>>【链接器】>>【输入】>>【忽略指定库】,输入:msvcrt.lib
或者:【项目】>>【属性】>>【配置属性】>>【链接器】>>【命令行】,输入:/NODEFAULTLIB:msvcrt.lib
(这个警告参照:https://blog.csdn.net/rankun1/article/details/51026117 )
还有就是程序运行的时候会有黑色的命令行窗口,一般可以把【项目】>>【属性】【配置属性】【链接器】【系统】【子系统】里把控制台改为窗口,但我使用这种方式编译错误,所以用的第二种方式,加一条指令在代码文件里(如 main.cpp 开头):
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
OpenGL学习:https://learnopengl-cn.github.io/
OpenGL了解:https://www.khronos.org/opengl/wiki/Getting_Started
OpenGL相关工具包和API:https://www.khronos.org/opengl/wiki/Related_toolkits_and_APIs
GLFW官网:https://www.glfw.org/
GLAD下载页:https://glad.dav1d.de/
GLFW入门:https://blog.csdn.net/zjz520yy/article/details/83000081
GLAD入门:https://blog.csdn.net/zjz520yy/article/details/83000096