概述
本章节主要总结如何使用GLFW来创建Opengl窗口。主要包括如下内容:
OpenGL窗口创建介绍
能用于OpenGL的窗口库有很多,常见的有glut、freeglut、SDL、GLFW等。glut基本已经被废弃,其他几个再不同场合都有不同的应用。GLFW为opengl superbible 6th & 7th中推荐的第三方开源窗口库。GLFW的特点大概总结如下:
- 跨平台,能在window、Linux和wayland中使用;
- 支持OpenGL、OpenGL ES;
- 底层的可配置性;
下面我们来实际看下使用GLFW的实际意义。
OpenGL ES在嵌入式开发中实际比在PC上开发opengl的环境搭建似乎要复杂很多,通常嵌入式开发中使用EGL创建OpenGL渲染的surface,使用wayland创建窗口的surface来实现。在实际开发过程中,我们想通过在PC上开发EGL + OpenGl ES的程序,这个时候,如果平台不同,我们往往在不同平台上实现不同的窗口,如:
- window:OpenGL ES + EGL + Window系统窗口(实际运行还需要加OpenGL ES的模拟器,OpenGL.ES.3.0.Programming.Guide中有介绍高通芯片等模拟器的使用的章节);
- Linux: OpenGL ES + EGL + X11窗口;
- ARM: OpenGL ES + EGL + wayland窗口;
window 窗口系统、X11窗口和wayland窗口的创建和窗口事件获取及处理方式各不相同,而GLFW所做的事情,就是提供统一的窗口创建的方法,使我们能在GLFW上开发与平台无关的OpenGL ES代码。
GLFW Window版编译介绍
GLFW官网有详细的各个平台编译步骤介绍,在此我们针对Window + VS2005 + EGL + Mail模拟器进行进行介绍。
- 下载CMake并安装(官网可直接尚在安装包进行安装);
- 下载Mail模拟器安装包,安装完成后,在安装路径下可以看待我们在开发过程中需要用到的头文件和相应的dll,大家可以点击mali-cube.exe来测试自己的机器是否能正常运行此模拟器,VM虚拟机对OpenGL版本的支持比较低,一般无法运行此虚拟机,因此大家可能在虚拟机上开发OpenGL ES会受到一些障碍;
- 下载GLFW源码,使用CMake GUI编译GLFW;
- 在CMake安装目录bin下找到cmake-gui.exe并运行;
- 选择源码路径和编译路径;
配置完成后我们点击Generate,即可完成项目文件的创建; 在build的目录下,我们可以使用vs2005 打开GLFW.sln并编译GLFW库;
至此,编译部分大致介绍完成,大家在实际编译过程中可能会遇到其他问题,参考官网的介绍应该都能解决。
GLFW简单工程源码介绍
我们把GLFW编译出来的库和头文件复制到我们的OpenGL ES VS工程中(当然也必须添加模拟器的Dll),如下为实例代码:
#define GLFW_INCLUDE_ES2 #include <GLFW/glfw3.h> void errorfunc(int error, const char* discription) { fputs(discription,stderr); } void keyfunc(GLFWwindow* window, int key, int scancode, int action, int mods) //按键回调函数 { if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { glfwSetWindowShouldClose(window,GL_TRUE); //退出是销毁窗口 } } int main() { GLFWwindow* windows; glfwSetErrorCallback(errorfunc); if (!glfwInit()) { exit(EXIT_FAILURE); } windows = glfwCreateWindow(600, 480, "test opengl windows", NULL, NULL); //创建窗口 if (!windows) { glfwTerminate(); } glfwMakeContextCurrent(windows); glfwSetKeyCallback(windows,keyfunc); while (!glfwWindowShouldClose(windows)) //渲染循环 { glClear(GL_COLOR_BUFFER_BIT); glClearColor(....); //do something about opengl glfwSwapBuffers(windows); glfwPollEvents(); } glfwDestroyWindow(windows); glfwTerminate(); return 0;