OpenGL系列之一——绘制窗口

it2024-12-26  11

前文已经教了如何配置OpenGL环境,这一篇开始正式走进OpenGL的世界,首先我们先来用代码画一个窗口,看看配置的环境能不能用。 一、新建一个.cpp文件,然后引入头文件 特别注意:glad的头文件必须要在GLFW的头文件之前引入。因为glad的头文件包含了正确的OpenGL头文件,所以需要在其它依赖于OpenGL的头文件之前包含glad,如果这两个文件顺序颠倒,会编译出错,大家可以试一下,当时找了好久才知道是因为这个头文件引入的顺序问题……

#include <glad/glad.h> #include <GLFW/glfw3.h> #include <iostream>

接下来创建main函数

int main() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); return 0; }

首先,在main函数中调用glfwInit函数来初始化GLFW,然后我们可以使用glfwWindowHint函数来配置GLFW。 glfwWindowHint函数的第一个参数代表选项的名称 第二个参数接受一个整型,用来设置这个选项的值 因为我是用OpenGL 3.3版本来开展工作的,所以我们需要告诉GLFW我们要使用的OpenGL版本是3.3,这样GLFW会在创建OpenGL上下文时做出适当的调整。这也可以确保用户在没有适当的OpenGL版本支持的情况下无法运行。我们将主版本号(Major)和次版本号(Minor)都设为3。我们同样明确告诉GLFW我们使用的是核心模式(Core-profile)。 接下来创建一个窗口对象

GLFWwindow* window = glfwCreateWindow(800, 600, "MyFirstOpenGL", NULL, NULL); if (window == NULL) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window);

glfwCreateWindow函数需要窗口的宽和高作为它的前两个参数。第三个参数表示这个窗口的名字。最后两个参数我们暂时忽略。这个函数将会返回一个GLFWwindow对象,我们会在其它的GLFW操作中使用到。创建完窗口我们就可以通知GLFW将我们窗口的上下文设置为当前线程的主上下文了。 然后初始化glad(glad是用来管理OpenGL的函数指针的)

if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cout << "Failed to initialize GLAD" << std::endl; return -1; }

通过调用glViewport函数来设置窗口的维度

glViewport(0, 0, 800, 600);

glViewport函数前两个参数控制窗口左下角的位置。第三个和第四个参数控制渲染窗口的宽度和高度(像素)。 OpenGL幕后使用glViewport中定义的位置和宽高进行2D坐标的转换,将OpenGL中的位置坐标转换为你的屏幕坐标。例如,OpenGL中的坐标(-0.5, 0.5)有可能(最终)被映射为屏幕中的坐标(200,450)。注意,处理过的OpenGL坐标范围只为-1到1,因此我们事实上将(-1到1)范围内的坐标映射到(0, 800)和(0, 600)。 然而,当用户改变窗口的大小的时候,视口也应该被调整。我们可以对窗口注册一个回调函数(Callback Function),它会在每次窗口大小被调整的时候被调用。这个回调函数的原型如下:

void framebuffer_size_callback(GLFWwindow* window, int width, int height);

这个帧缓冲大小函数需要一个GLFWwindow作为它的第一个参数,以及两个整数表示窗口的新维度。每当窗口改变大小,GLFW会调用这个函数并填充相应的参数供你处理。

void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); }

我们还需要注册这个函数,告诉GLFW我们希望每当窗口调整大小的时候调用这个函数:

glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

真正的渲染

while(!glfwWindowShouldClose(window)) { glfwSwapBuffers(window); glfwPollEvents(); }

glfwWindowShouldClose函数在我们每次循环的开始前检查一次GLFW是否被要求退出,如果是的话该函数返回true然后渲染循环便结束了,之后为我们就可以关闭应用程序了。 glfwPollEvents函数检查有没有触发什么事件(比如键盘输入、鼠标移动等)、更新窗口状态,并调用对应的回调函数(可以通过回调方法手动设置)。 glfwSwapBuffers函数会交换颜色缓冲(它是一个储存着GLFW窗口每一个像素颜色值的大缓冲),它在这一迭代中被用来绘制,并且将会作为输出显示在屏幕上。 最后当渲染循环结束后我们需要正确释放/删除之前的分配的所有资源。我们可以在main函数的最后调用glfwTerminate函数来完成

glfwTerminate(); return 0;

如果没问题的话,运行程序应该是这样的: 下面是全部代码:

#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 WIDTH = 800; const unsigned int HEIGHT = 600; int main() { //初始化 glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //创建窗口对象 GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "MyFirstOpenGL", NULL, NULL); if (window == NULL) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cout << "Failed to initialize GLAD" << std::endl; return -1; } //渲染循环 while (!glfwWindowShouldClose(window)) { processInput(window); glfwSwapBuffers(window); glfwPollEvents(); } 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(0, 0, width, height); }
最新回复(0)