实际的OpenGL库的开发者通常是显卡的生产商。你购买的显卡所支持的OpenGL版本都为这个系列的显卡专门开发的。可以用上次提到的OpenGL Extensions View来查看OpenGL版本,我的就是OpenGL4.3。
之前选择GLAD的时候,选择OpenGL的核心模式(Core-profile)下进行开发效率高、灵活而且开发者可以了解OpenGL的具体运作。
原先的立即渲染模式(Immediate mode,也就是固定渲染管线)效率低且不灵活虽然上手容易。
1. State Machine ——OpenGL的状态通常被称为上下文(Context)
使用一系列变量描述OpenGL应该如何去工作。
更改上下文变量改变OpenGL状态——设置选项,操作缓冲——使用当前OpenGL上下文来渲染。
2. Object ——一些选项的集合,它代表OpenGL状态的一个子集
unsigned int objectId = 0;// 创建对象
glGenObject(1, &objectId);
glBindObject(GL_WINDOW_TARGET, objectId);// 绑定对象至上下文
// 设置当前绑定到 GL_WINDOW_TARGET 的对象的一些选项
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_WIDTH, 800);
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_HEIGHT, 600);
// 将上下文对象设为默认
glBindObject(GL_WINDOW_TARGET, 0);
开始创建窗口
1) 实例化GLFW窗口
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); //OpenGL版本4.3
//使用的是核心模式(Core-profile)
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
2) 创建窗口
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);
//创建完窗口我们就可以通知GLFW将我们窗口的上下文设置为当前线程的主上下文
3) 初始化GLAD ——管理OpenGL函数指针
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
load系统相关的OpenGL函数指针地址的函数。GLFW给我们的是glfwGetProcAddress
,它根据我们编译的系统定义了正确的函数。
4)视口(Viewport)
将OpenGL中的位置坐标转换为你的屏幕坐标。例如,OpenGL中的坐标(-0.5, 0.5)有可能(最终)被映射为屏幕中的坐标(200,450)。注意,处理过的OpenGL坐标范围只为-1到1,因此我们事实上将(-1到1)范围内的坐标映射到(0, 800)和(0, 600)。
glViewport(0, 0, 800, 600);
窗口注册一个回调函数(Callback Function),它会在每次窗口大小被调整的时候被调用
framebuffer_size_callback(GLFWwindow* window, int width, int height);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
5)渲染循环(Render Loop)
while(!glfwWindowShouldClose(window))
{
// 渲染指令
glCle
arColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// 检查并调用事件,交换缓冲
glfwSwapBuffers(window);
glfwPollEvents();
}