最近,马三买了两本有关于“计算机图形学”的书籍,准备在工做之余鼓捣鼓捣图形学和OpenGL编程,提高本身的价值(奔着学完能涨一波工资去的)。俗话说得好,“工欲善其事,必先利其器”。想学习图形学和OpenGL编程必须先把开发环境搭建好,而马三只是在上学的时候稍稍作了一些基于Android平台的OpenGL开发学习,并无搭建过OpenGL开发环境。所以在搭建过程当中颇废了一番周折,也查阅了很多资料才算搭建成功,特此记录一下搭建过程,以备不时之需。html
这个没必要多说了,基本作过开发的都会安装这个“宇宙最强IDE”了。直接去官网下载安装助手,而后安装便可。ios
正常来讲开发进行OpenGL开发的话,glut库是必不可少的,可是马三在网上一搜啊,发现glut这个库过期了,如今比较新版的GLFW彻底能够替代它。关于这些名词相关的具体介绍,咱们会在稍后仔细介绍一下,咱们仍是先去 GLFW官网 把库下载下来。编程
图1:GLFW官网下载示意图微信
接着咱们还须要下载GLEW库,众所周知,OpenGL只是一个标准,不一样的显卡公司在不一样的平台下对其有不一样的实现,同时也是发布一些只支持自家显卡的拓展函数。经过引入glew库,咱们彻底能够不用理睬这些细节,安心写代码就行了。框架
一样仍是去 GLEW的官网 下载咱们所须要的内容:ide
图2:GLEW官网下载示意图函数
对于以上的这两个库和源代码,马三已经下载了写博客时的最新版本,并打成了压缩包,方便各位下载。下载请移步。工具
解压咱们下载的两个库,并在VS2017里面新建一个C++空项目。若是建立的是控制台或者其余项目的话,vs工具会自动帮你添加一个stdafx.h的预编译头,你必须在源文件的开头写上#include “stdafx.h”相关语句,并且以后引入glew,glfw包会有莫名其妙的错误。因此建立一个空项目。以下如所示:学习
图3:解压后的库测试
图4:建立新的空项目
而后,点击“解决方案资源管理器”,右键点击源文件,添加新项,建立.cpp源文件,能够随便命个名,好比main.cpp:
图5:新建源文件
接着,右键点击项目,在弹出的选项中,单击 “属性”,点击“VC++目录”,而后选择“包含目录”选项,单击下拉菜单中的“编辑”:
图五、6项目属性编辑
接着咱们在新打开的窗口中添加头文件。分别添加下载的glew和glfw文件夹下的include文件夹(include文件夹下是咱们须要的头文件),并点击“肯定”:
图7:include头文件
以后,再继续添加库文件到项目中,头文件一般是函数的声明,而函数的实现通常都放在了库中,两者相辅相成,只有都正确的引入了,才能正常工做。其对应的路径就是glew和glfw文件夹下的lib文件夹:
有两点须要咱们特别注意一下:
图8:lib库文件
只包含了库文件还不行,咱们须要手动指定一下。配置连接器:
图9:连接器配置
在里面手动加入以下选项,行与行之间请按回车,opengl32.lib是系统自带的。glfw3.lib,glew32s.lib 是咱们下载的库中的,其实就是以前包含的lib文件夹下的文件名(去掉glew32.lib):
opengl32.lib
glfw3.lib
glew32s.lib
图10:编辑连接器配置
通过上面一系列的繁琐的操做,咱们的OpenGL开发环境基本也算搭建完成了,下面让咱们在main.cpp中添加一些代码测试一下,环境是否搭建成功,咱们的程序是否可以跑起来。在main.cpp中加入以下测试代码:
1 #include<iostream> 2 #define GLEW_STATIC 3 #include <GL/glew.h> 4 #include <GLFW\glfw3.h> 5 6 using namespace std; 7 8 int main(int argc, char** argv[]) 9 { 10 /*glewExperimental = GL_TRUE; 11 if (glewInit()!=GLEW_OK) 12 { 13 cout << "failed to initalize GLEW" << endl; 14 return -1; 15 }*/ 16 17 glfwInit();//初始化 18 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//配置GLFW 19 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//配置GLFW 20 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// 21 glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); 22 23 GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr); 24 if (window == nullptr) 25 { 26 cout << "Failed to create GLFW window" << endl; 27 glfwTerminate(); 28 return -1; 29 } 30 glfwMakeContextCurrent(window); 31 while (!glfwWindowShouldClose(window)) 32 { 33 glfwPollEvents(); 34 glfwSwapBuffers(window); 35 } 36 glfwTerminate(); 37 return 0; 38 39 40 }
而后,点击调试,若是成功了的话能够看到相似于下面的这种窗口,实际上是初始化了一个空的OpenGL窗口:
图11:初始化OpenGL窗口
可是咱们会发如今vs的错误列表窗口中出现了一条警告:“警告 LNK4098 默认库“MSVCRT”与其余库的使用冲突;请使用 /NODEFAULTLIB:library BuildEnv F:\xxxx”
这个警告也是比较好解决的,打开咱们以前配置连接器的那个页面,而后选择忽略特定库选项,并编辑。在其中加入 "MSVCRT.lib",而后而后点击肯定,以后就会发现警告消失不见了。若是之后还有其余的相似的库冲突,咱们可使用一样的方法解决。
图12:解决库冲突
尽管咱们已经成功的搭建了OpenGL开发环境,可是相信此时必定有很多小伙伴和马三同样对OpenGL开发中的一些库和名词处于蒙蔽状态。马三也是搜集了这些名词的资料和你们一块儿分享一下。
OpenGL函数库相关的API有核心库(gl),实用库(glu),辅助库(aux)、实用工具库(glut),窗口库(glx、agl、wgl)和扩展函数库等。gl是核心,glu是对gl的部分封装。glx、agl、wgl 是针对不一样窗口系统的函数。glut是为跨平台的OpenGL程序的工具包,比aux功能强大(aux很大程度上已经被glut库取代。)。扩展函数库是硬件厂商为实现硬件更新利用OpenGL的扩展机制开发的函数。
这部分函数以glut开头,主要包括窗口操做函数,窗口初始化、窗口大小、窗口位置等函数;回调函数:响应刷新消息、键盘消息、鼠标消息、定时器函数等;建立复杂的三维物体;菜单函数;程序运行函数。gult对应的开源实现是freegult,freegult官网请移步。
GLUT或者FREEGLUT主要是1.0的基本函数功能;GLEW是使用OPENGL2.0以后的一个工具函数。不一样的显卡公司,也会发布一些只有自家显卡才支持的扩展函数,你要想用这数函数,不得不去寻找最新的glext.h,有了GLEW扩展库,你就不再用为找不到函数的接口而烦恼,由于GLEW能自动识别你的平台所支持的所有OpenGL高级扩展函数。也就是说,只要包含一个glew.h头文件,你就能使用gl,glu,glext,wgl,glx的所有函数。glew库提供高版本 gl 函数的支持。若是不嫌麻烦的话,也能够手写函数指针,来判断各个 opengl 高版本函数是否支持,可是 glew 库 作了大大的简化,使得 opengl 各个版本的函数像原生函数同样,能够随意调用。
GLFW无愧于其号称的lightweight的OpenGL框架,的确是除了跨平台必要作的事情都没有作,因此一个头文件,不多量的API,就完成了任务。GLFW的开发目的是用于替代glut的,从代码和功能上来看,我想它已经彻底的完成了任务。一个轻量级的,开源的,跨平台的library。支持OpenGL及OpenGL ES,用来管理窗口,读取输入,处理事件等。由于OpenGL没有窗口管理的功能,因此不少热心的人写了工具来支持这些功能,好比早期的glut,如今的freeglut等。
那么GLFW有何优点呢?glut太老了,最后一个版本仍是90年代的。freeglut彻底兼容glut,算是glut的代替品,功能齐全,可是bug太多。所以,GLFW应运而生。
综上所述:
1.glfw是glut的升级和改进
2.glew包含了OpenGL所需的核心
目前网上的一些教程还有使用glad库的,glad与glew有什么区别呢?简单说glad是glew的升级版。用哪一个都行。glew比较老,glad比较新。下面简单介绍一些glad如何使用:
glad有一个在线服务,直接下下来就能够用了(编译好的),将语言(Language)设置为C/C++,在API选项中,选择3.3以上的OpenGL版本(3.3是可编程管线版本,但更新的版本也能正常工做)。以后将模式(Profile)设置为Core,而且保证生成加载器(Generate a loader)的选项是选中的。如今能够先(暂时)忽略拓展(Extensions)中的内容。都选择完以后,点击生成(Generate)按钮来生成库文件。
下载到本地是个压缩文件,解压完成后会有这样的文件夹结构:
图13:glad文件目录
包含两个头文件目录(内有头文件glad.h和khrplatform.h),和一个src文件夹下的glad.c文件。只须要将原来的第五步的 VC++目录 -> 包含目录 中的glew的include文件夹改为glad的include文件夹便可。后面的步骤glad都不须要。
而后将glad.c文件复制到源文件夹下:
图14:glad复制到源文件夹
注意glad.c文件这时候或者编译的时候会出错,首先看看glad.c的include的路径是否是对的,有时候包含目录文件夹路径不同,你要改为你本身配置的glad路径(就是以前VC++目录配置的路径)。
而后须要将咱们的测试代码换成以下这段:
1 #include <glad/glad.h> 2 #include <GLFW/glfw3.h> 3 4 #include <iostream> 5 6 const unsigned int SCR_WIDTH = 800; 7 const unsigned int SCR_HEIGHT = 600; 8 9 int main() 10 { 11 glfwInit(); 12 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 13 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 14 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 15 16 GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL); 17 if (window == NULL) 18 { 19 std::cout << "Failed to create GLFW window" << std::endl; 20 glfwTerminate(); 21 return -1; 22 } 23 glfwMakeContextCurrent(window); 24 25 if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) 26 { 27 std::cout << "Failed to initialize GLAD" << std::endl; 28 return -1; 29 } 30 31 while (!glfwWindowShouldClose(window)) 32 { 33 34 glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 35 glClear(GL_COLOR_BUFFER_BIT); 36 37 glfwSwapBuffers(window); 38 glfwPollEvents(); 39 } 40 41 glfwTerminate(); 42 return 0;
在本篇博客中,马三和你们一块儿从头开始搭建了一个OpenGL开发环境,而且了解了一些OpenGL的概念与名词。接下来马三将会一边学习计算机图形学和OpenGL,一边随时随地的把想法记录下来与你们分享~
参考资料:
若是以为本篇博客对您有帮助,能够扫码小小地鼓励下马三,马三会写出更多的好文章,支持微信和支付宝哟!
做者:马三小伙儿
出处:http://www.javashuo.com/article/p-szumdrsi-v.html 请尊重别人的劳动成果,让分享成为一种美德,欢迎转载。另外,文章在表述和代码方面若有不妥之处,欢迎批评指正。留下你的脚印,欢迎评论!