一、基本概念
1.OpenGL:是图形硬件的一种软件接口。通俗点讲就是一套API,调用接口而已,用于图像的渲染。与微软的Direct类似,不过它是跨平台的。
OpenGL自身是一个巨大的状态机(State Machine):一系列的变量描述OpenGL此刻应当如何运行。OpenGL的状态通常被称为OpenGL上下文(Context)。我们通常使用如下途径去更改OpenGL状态:设置选项,操作缓冲。最后,我们使用当前OpenGL上下文来渲染。
在我们画出出色的效果之前,首先要做的就是创建一个OpenGL上下文(Context)和一个用于显示的窗口。然而,这些操作在每个系统上都是不一样的,OpenGL有目的地从这些操作抽象(Abstract)出去。这意味着我们不得不自己处理创建窗口,定义OpenGL上下文以及处理用户输入。
2.GLFW库:一个专门针对OpenGL的C语言库,它提供了一些渲染物体所需的最低限度的接口。它允许用户创建OpenGL上下文,定义窗口参数以及处理用户输入。
3.Windows上的OpenGL库:如果你是Windows平台,opengl32.lib已经包含在Microsoft SDK里了,它在Visual Studio安装的时候就默认安装了。由于这篇教程用的是VS编译器,并且是在Windows操作系统上,我们只需将opengl32.lib添加进连接器设置里就行了。
4.GLAD:一个开源的库,由于OpenGL驱动版本众多,它大多数函数的位置都无法在编译时确定下来,需要在运行时查询。在这里我们能够告诉GLAD需要定义的OpenGL版本,并且根据这个版本加载所有相关的OpenGL函数。
5.GLEW:GLEW库是OpenGL的扩展库,用于支持OpenGL1.1以上的版本。比如着色器特性。一般非集成显卡都能支持到OpenGL2.0或者更高,但是没有GLEW库依然无法调用高版本OpenGL的函数。GLEW能自动识别你的平台所支持的全部OpenGL高级扩展涵数。也就是说,只要包含一个glew.h头文件,你就能使用gl, glu, glext, wgl, glx的全部函数。
二、你好,窗口
#include <glad/glad.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;
int main()
{
// 初始化GLFW
// 我们将主版本号(Major)和次版本号(Minor)都设为3。
// 我们同样明确告诉GLFW我们使用的是核心模式(Core-profile)。
// ------------------------------
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); // uncomment this statement to fix compilation on OS X
#endif
// 创建一个窗口对象
// --------------------
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);
// 当用户改变窗口的大小的时候,视口也应该被调整。
// 我们可以对窗口注册一个回调函数(Callback Function),它会在每次窗口大小被调整的时候被调用。
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
// 初始化GLAD
// ---------------------------------------
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();
return 0;
}
void processInput(GLFWwindow *window)
{
// 按下ESC,关闭窗口
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
//OpenGL渲染窗口的尺寸大小,即视口(Viewport),这样OpenGL才只能知道怎样根据窗口大小显示数据和坐标
glViewport(0, 0, width, height);
}