引擎自制之:OpenGL开发指北(1)
OpenGL是什么?
熟悉Unity的同学,会在PlayerSetting中发现这么一个设置项:

此项中,列举了各种图形API,Unity引擎的图形渲染就是由这些API来提供底层驱动支持的。其中就有OpenGLCore、OpenGLES3、OpenGLES2。
那OpenGL是啥?通常我们会将它当作API来认知,但其实不然,它是由khronos组织提出的一个图形规范,该规范严格规定了每个函数该如何执行,以及它们的输出值。而我们通常意义上说的学OpenGL是指的基于OpenGL规范,使用OpenGL的库,去开发软件,而OpenGL库通常由显卡厂商开发和维护。
开发环境配置
我们这里使用VisualStudio2022进行开发,安装vs后,点击菜单栏-工具-获取工具和功能。

确保勾选安装了C++模块

开发第一个应用
下载GLFW库
GLFW是一个专门针对OpenGL的C语言库,它提供了一些渲染物体所需的最低限度的接口,允许用户创建OpenGL上下文、定义窗口参数以及处理用户输入。
官方下载地址: http://www.glfw.org/download.html
我们这里选择下载源码来自行编译:

CMake
官方地址:https://cmake.org/download/

选择下载CMake的编译版本来安装,或者下载程序包直接使用。
打开CMake,四步走。其中:1为选择下好的GLFW路径。2为自定义一个输出路径。3为配置选项,选择对应的vs版本其他默认。4.为生成vs解决方案。

编译GLFW
打开上图的第二步的路径,打开已经生成的solution,在解决方案资源管理器中,直接生成解决方案:

然后,在Build/src/Debug文件夹内就会出现我们编译出的库文件glfw3.lib,用于后面项目备用。
配置GLAD
GLAD是一个开源的库,实现对底层OpenGL接口封装,方便开发者调用。
在线配置地址:https://glad.dav1d.de/
1、语言(Language)设置为C/C++
2、规范(Specification)设置为OpenGL
3、在API选项中,选择3.3以上的OpenGL(gl)版本
4、将模式(Profile)设置为Core。
5、确保选中了生成加载器(Generate a loader)选项
6、点击生成(Generate)按钮来生成库文件
7、下载glad.zip文件 备用



创建C++工程
创建一个新的C++项目:

选中项目,右键-属性,在VC++目录页签中,进行引用包含设置,指定之前下载的GLFW、glad以及用自己使用VS重新生成库文件路径。

在链接器的输入项中,添加glfw3.lib依赖。

使用添加文件功能,添加glad.c到项目

测试
新建一个cpp文件,添加以下代码,测试环境是否正常。
#include <glad/glad.h>
#include <GLFW/glfw3.h>
编写代码
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);
// 窗口设置
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
int main()
{
// glfw: 初始化和设置
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//MacOS平台设置
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
// 使用glfw创建窗口
// --------------------
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的函数指针的,调用前进行初始化
// ---------------------------------------
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
// 渲染循环
// -----------
while (!glfwWindowShouldClose(window))
{
// 输入
// -----
processInput(window);
// 渲染
// ------
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// 检查并调用事件,交换缓冲
// -------------------------------------------------------------------------------
glfwSwapBuffers(window);
glfwPollEvents();
}
// glfwterminate函数进行资源释放
// ------------------------------------------------------------------
glfwTerminate();
return 0;
}
// 处理输入
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
// 窗口调整大小时的回调处理
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
//glViewport设置窗口大小
glViewport(0, 0, width, height);
}
到这里,我们就实现了第一个简单的OpenGL程序了。
参考与引用
Learn OpenGL, extensive tutorial resource for learning Modern OpenGL