OpenGL学习(2)—— 创建第一个窗口
创建
GLFW
GLFW是一个专门针对OpenGL的C语言库,它提供了一些渲染物体所需的最低限度的接口。它允许用户创建OpenGL上下文,定义窗口参数以及处理用户输入,这正是我们需要的。
#include <GLFW/glfw3.h>
int main() {
//——————————初始化——————————
glfwInit();
/*glfwWindowHint()可以设置一些关于窗口的选项*/
/*由于GFLW创建的OpenGL上下文可能是任何版本的,所以你可以设置OpenGL的最低版本
下面的代码设置了OpenGL最低版本为4.0*/
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); // OpenGL主版本号
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); // OpenGL副版本号
/*OpenGL模式(GLFW_OPENGL_PROFILE),下列为设置为核心模式*/
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//——————————创建窗口——————————
/*glfwCreateWindow()接受5个参数。
第一个、第二个是窗口的宽和高,以像素为单位;第三个是窗口标题*/
GLFWwindow* window = glfwCreateWindow(800, 600, "OPENGL", NULL, NULL);
//——————————渲染引擎——————————
while (!glfwWindowShouldClose(window))
{
/*glfwPollEvents()用来检查是否有事件被触发,例如点击关闭按钮、点击鼠标、按下键盘,等等。*/
glfwPollEvents();
}
//——————————退出——————————
/*循环执行完毕后,我们需要释放前面所申请的资源*/
glfwTerminate();
return 0;
}
GLAD
因为OpenGL只是一个标准/规范,具体的实现是由驱动开发商针对特定显卡实现的。由于OpenGL驱动版本众多,它大多数函数的位置都无法在编译时确定下来,需要在运行时查询。所以任务就落在了开发者身上,开发者需要在运行时获取函数地址并将其保存在一个函数指针中供以后使用。取得地址的方法因平台而异,在Windows上会是类似这样:
// 定义函数原型
typedef void (*GL_GENBUFFERS) (GLsizei, GLuint*);
// 找到正确的函数并赋值给函数指针
GL_GENBUFFERS glGenBuffers = (GL_GENBUFFERS)wglGetProcAddress("glGenBuffers");
// 现在函数可以被正常调用了
GLuint buffer;
glGenBuffers(1, &buffer);
你可以看到代码非常复杂,而且很繁琐,我们需要对每个可能使用的函数都要重复这个过程。幸运的是,有些库能简化此过程,其中GLAD是目前最新,也是最流行的库。
#include <glad\glad.h> //必须写在GLFW头文件之前
#include <GLFW/glfw3.h>
#include <stdio.h>
int main() {
//——————————glfw初始化——————————
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "OPENGL", NULL, NULL);
// 创建失败时给出反馈
if (window == NULL) {
printf("err:windows is NULL");
glfwTerminate();
return -1;
}
//设置当前的窗口上下文,即让当前窗口的环境在当前线程上成为当前环境
glfwMakeContextCurrent(window);
//——————————glad初始化——————————
/*一定要在设置完当前的窗口上下文之后*/
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
return -1;
}
//——————————渲染引擎——————————
while (!glfwWindowShouldClose(window))
{
// gl开头的函数,是OpenGL的函数
/* glClearColor窗口被清除时的颜色,也就是背景颜色,前三个参数分别为R,G,B,第四个参数是透明度*/
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
/* 这将会清除当前窗口,把所有像素的颜色都设置为前面所设置的清除颜色。*/
glClear(GL_COLOR_BUFFER_BIT);
glfwPollEvents();
// 交换缓冲区,即在window上更新内容
glfwSwapBuffers(window);
}
//——————————退出——————————
glfwTerminate();
return 0;
}
Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.