环境配置
解压后将两个文件移动至同一个目录,这里移动到了 D:\OpenGL
打开 VS,新建一个 C++ 空白项目,这里我将其命名为OpenGLTest
。项目创建完成后在解决方案下一行处右键 添加-> 新建项,选择 C++ 文件,命名为 main.cpp
右键 OpenGLTest
-> 属性,将属性页的配置改为“所有配置”“所有平台”,选择“C/C++ -> 常规”中的“附加包含目录”,将 glew
和 glfw
添加进来,如图即可
选择“链接器 -> 一般”中的“附加库目录”,将 glew
和 glfw
添加进来,如图即可(请根据自己的系统位数和 VS 版本选择文件夹,这里以 2022、64 位做示范)
选择“链接器 -> 输入”中的“附加依赖项”,添加以下三个附加库
opengl32.lib
glfw3.lib
glew32s.lib
配置完成!
Hello Window
创建 main
函数,在这个函数中我们将会实例化GLFW窗口:
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
int main()
{
glfwInit();
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);
return 0;
}
GLFW_CONTEXT_VERSION_MAJOR
和GLFW_CONTEXT_VERSION_MINOR
表示选择的 OpenGL 版本号是3.3,GLFW_OPENGL_CORE_PROFILE
表示我们使用的是核心模式(Core-profile),意味着我们只能使用OpenGL功能的一个子集(没有我们已不再需要的向后兼容特性)。如果使用的是Mac OS X系统,你还需要加入第 11 行代码到你的初始化代码中这些配置才能起作用(将上面的代码解除注释)。
接下来我们创建一个窗口对象,这个窗口对象存放了所有和窗口相关的数据,而且会被GLFW的其他函数频繁地用到。
GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwCreateWindow
函数需要窗口的宽和高作为它的前两个参数。第三个参数表示这个窗口的名称(标题),这里我们使用 “LearnOpenGL”,当然你也可以使用你喜欢的名称。最后两个参数我们暂时忽略。这个函数将会返回一个 GLFWwindow
对象,我们会在其它的 GLFW 操作中使用到。创建完窗口我们就可以通知 GLFW 将我们窗口的上下文设置为当前线程的主上下文了。
GLEW
初始化 GLEW
// Init GLEW
glewExperimental = true;
if (glewInit() != GLEW_OK)
{
cout << "Init GLEW failed" << endl;
glfwTerminate();
return -1;
}
视口
在我们开始渲染之前还有一件重要的事情要做,我们必须告诉OpenGL渲染窗口的尺寸大小,即视口(Viewport),这样OpenGL才只能知道怎样根据窗口大小显示数据和坐标。我们可以通过调用 glViewport
函数来设置窗口的维度(Dimension):
glViewport(0, 0, 800, 600);
glViewport
函数前两个参数控制窗口左下角的位置。第三个和第四个参数控制渲染窗口的宽度和高度(像素)。
准备好你的引擎
我们可不希望只绘制一个图像之后我们的应用程序就立即退出并关闭窗口。我们希望程序在我们主动关闭它之前不断绘制图像并能够接受用户输入。因此,我们需要在程序中添加一个 while
循环,我们可以把它称之为渲染循环(Render Loop),它能在我们让 GLFW 退出前一直保持运行。下面几行的代码就实现了一个简单的渲染循环:
while(!glfwWindowShouldClose(window))
{
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwWindowShouldClose
函数在我们每次循环的开始前检查一次GLFW是否被要求退出,如果是的话该函数返回true
然后渲染循环便结束了,之后为我们就可以关闭应用程序了。glfwPollEvents
函数检查有没有触发什么事件(比如键盘输入、鼠标移动等)、更新窗口状态,并调用对应的回调函数(可以通过回调方法手动设置)。glfwSwapBuffers
函数会交换颜色缓冲(它是一个储存着 GLFW 窗口每一个像素颜色值的大缓冲),它在这一迭代中被用来绘制,并且将会作为输出显示在屏幕上。
最后一件事
当渲染循环结束后我们需要正确释放/删除之前的分配的所有资源。我们可以在 main
函数的最后调用glfwTerminate
函数来完成。
glfwTerminate();
return 0;
这样便能清理所有的资源并正确地退出应用程序。