首先,引入头文件,如下图所示:
#define GLEW_STATIC #include<iostream>GLE #include<GL/glew.h> #include<GLFW/glfw3.h>
定义GLEW_STATIC宏是因为我们需要使用GLEW静态的链接库。iostream头文件是用于输出。
这里要确保GLEW的头文件要写在GLFW之前,在glew.h的头文件中会引入许多OpenGL所必要的头文件,所以你需要在包含其它依赖于OpenGL的头文件之前先包含GLEW头文件。
接下来创建main函数来实例化GLFW:
int main() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
}
首先,我们使用gifwInit()方法来初始化GLFW,接下来我们使用glfwWindowHinit()方法来配置GLFW,在这里我们设置OpenGl的主版本号为3,次版本号也为3,即使用3.3版本的OpegGL。同时告诉GLFW我们使用的是核心模式(CORE_PROFILE)。
然后我们来创建一个窗口对象:
GLFWwindow *window = glfwCreateWindow(800, 600, "My OpenGL Window", NULL, NULL); if (window == NULL) { printf("Open Window Filed!"); glfwTerminate(); return -1; } glfwMakeContextCurrent(window);
glfwCreatWindow函数的前两个参数分别表示窗口的宽和高,第三个参数为窗口的名字,后两个参数我们暂时忽略掉,赋值为NULL即可。这个方法会返回一个GLFWwindow的对象,我们将它存储在指针window中,它将会被其它GLFW函数所调用。接下来进行安全校验,如果返回的值为空时,表示打开窗口失败,使用glfwTerminate()方法停止窗口的绘制并回收资源。如果返回值不为空,则通知GLFW将我们窗口的上下文设置为当前线程的主上下文。
Viewport(视口)
在开始渲染之前,我们需要设置需要绘制的窗口的大小,这样OpemGL才知道怎么相对于窗口大小显示数据和坐标。在这里我们可以使用glViewport来设置窗口的维度:
glViewport(0, 0, 800, 600);
前两个参数表示我们绘制的窗口的左下角的位置,第三个第四个参数设置我们要渲染的窗口的宽和高(单位为像素),数值要和我们之前设置的GLFW的窗口的宽和高相同。
事实上,OpenGL通过glViewport中定义的坐标和宽高进行转换,将OpenGL中的位置坐标转换为我们的屏幕坐标。其中处理过的OpenGL坐标范围为(-1,1),例子中我们就是将(-1,1)范围内的坐标映射到(0,800)和(0,600)
我们当然想看到我们绘制的窗口,并让我们的窗口接受用户的输入,渲染图片什么的,而不是让它一闪而过。这里我们可以使用一个while循环来实现:
while (!glfwWindowShouldClose(window)) { glfwSwapBuffers(window); glfwPollEvents(); }
glfwWindowShouleClose()可以在每次循环时判断当前窗口是否被关闭,如果被关闭则退出循环,如果没有被关闭,则使用glfwSwapBuffers()交换色彩缓冲区(在GLFW中包含每个像素的值的缓冲区),在循环没有退出时,它将会持续渲染并显示在自己的屏幕上。glfwPollEvents方法监听事件并作出相应的回应(比如键盘的输入和鼠标的拖动)。
关于双缓冲:OplenGL的渲染是从上到下,从左到右。而双缓冲则包括了一个前缓冲和后缓冲,前缓冲只负责将渲染的图片显示到屏幕上,后缓冲则负责调用渲染的命令,当后缓冲中的命令执行完毕之后,前缓冲和后缓冲交换位置,这样做能够让图片立刻展示在用户面前。
在结束程序之前,我们需要回收所有GLFW所调用的资源。代码如下:
glfwTerminate(); return 0;
然后运行程序,我们就可以得到我们自己的窗口: