• 【游戏开发】基于VS2017的OpenGL开发环境搭建


    一、简介

      最近,马三买了两本有关于“计算机图形学”的书籍,准备在工作之余鼓捣鼓捣图形学和OpenGL编程,提升自己的价值(奔着学完能涨一波工资去的)。俗话说得好,“工欲善其事,必先利其器”。想学习图形学和OpenGL编程必须先把开发环境搭建好,而马三只是在上学的时候稍稍做了一些基于Android平台的OpenGL开发学习,并没有搭建过OpenGL开发环境。因此在搭建过程中颇废了一番周折,也查阅了不少资料才算搭建成功,特此记录一下搭建过程,以备不时之需。

    二、搭建环境

    1.VS2017

      这个不必多说了,基本做过开发的都会安装这个“宇宙最强IDE”了。直接去官网下载安装助手,然后安装即可。

    2.GLFW库

      正常来说开发进行OpenGL开发的话,glut库是必不可少的,但是马三在网上一搜啊,发现glut这个库过时了,现在比较新版的GLFW完全可以替代它。关于这些名词相关的具体介绍,我们会在稍后仔细介绍一下,我们还是先去 GLFW官网 把库下载下来。

      图1:GLFW官网下载示意图

     3.GLEW库

      接着我们还需要下载GLEW库,众所周知,OpenGL只是一个标准,不同的显卡公司在不同的平台下对其有不同的实现,同时也是发布一些只支持自家显卡的拓展函数。通过引入glew库,我们完全可以不用理睬这些细节,安心写代码就好了。

      同样还是去 GLEW的官网 下载我们所需要的内容:

      图2:GLEW官网下载示意图

      对于以上的这两个库和源代码,马三已经下载了写博客时的最新版本,并打成了压缩包,方便各位下载。下载请移步

    4.安装并测试运行

      解压我们下载的两个库,并在VS2017里面新建一个C++空项目。如果创建的是控制台或者其他项目的话,vs工具会自动帮你添加一个stdafx.h的预编译头,你必须在源文件的开头写上#include “stdafx.h”相关语句,而且之后引入glew,glfw包会有莫名其妙的错误。所以创建一个空项目。如下如所示:

    图3:解压后的库

    图4:创建新的空项目

      然后,点击“解决方案资源管理器”,右键点击源文件,添加新项,创建.cpp源文件,可以随便命个名,比如main.cpp:

    图5:新建源文件

      接着,右键点击项目,在弹出的选项中,单击 “属性”,点击“VC++目录”,然后选择“包含目录”选项,单击下拉菜单中的“编辑”:

    图5、6项目属性编辑

      接着我们在新打开的窗口中添加头文件。分别添加下载的glew和glfw文件夹下的include文件夹(include文件夹下是我们需要的头文件),并点击“确定”:

    图7:include头文件

       之后,再继续添加库文件到项目中,头文件通常是函数的声明,而函数的实现一般都放在了库中,二者相辅相成,只有都正确的引入了,才能正常工作。其对应的路径就是glew和glfw文件夹下的lib文件夹:

      有两点需要我们特别注意一下:

    • 当添加glew时,当选到lib文件夹后请继续选择,lib->Release->Win32,请选择Win32后点击“选择文件夹”(x64会有莫名其妙的问题)
    • 当添加glfw时,低版本请选择对应版本,2015以上版本请选择“lib-vc2015”。马三用的是2017所以选择lib-vc2015

    图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 <GLFWglfw3.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开发中的一些库和名词处于蒙蔽状态。马三也是搜集了这些名词的资料和大家一起分享一下。

    1.OpenGL是什么

      OpenGL函数库相关的API有核心库(gl),实用库(glu),辅助库(aux)、实用工具库(glut),窗口库(glx、agl、wgl)和扩展函数库等。gl是核心,glu是对gl的部分封装。glx、agl、wgl 是针对不同窗口系统的函数。glut是为跨平台的OpenGL程序的工具包,比aux功能强大(aux很大程度上已经被glut库取代。)。扩展函数库是硬件厂商为实现硬件更新利用OpenGL的扩展机制开发的函数。

    2.gult:OpenGL工具库(OpenGL Utility Toolkit)

      这部分函数以glut开头,主要包括窗口操作函数,窗口初始化、窗口大小、窗口位置等函数;回调函数:响应刷新消息、键盘消息、鼠标消息、定时器函数等;创建复杂的三维物体;菜单函数;程序运行函数。gult对应的开源实现是freegult,freegult官网请移步

    3.glew库是什么

      GLUT或者FREEGLUT主要是1.0的基本函数功能;GLEW是使用OPENGL2.0之后的一个工具函数。不同的显卡公司,也会发布一些只有自家显卡才支持的扩展函数,你要想用这数函数,不得不去寻找最新的glext.h,有了GLEW扩展库,你就再也不用为找不到函数的接口而烦恼,因为GLEW能自动识别你的平台所支持的全部OpenGL高级扩展函数。也就是说,只要包含一个glew.h头文件,你就能使用gl,glu,glext,wgl,glx的全部函数。glew库提供高版本 gl 函数的支持。如果不嫌麻烦的话,也可以手写函数指针,来判断各个 opengl 高版本函数是否支持,但是 glew 库 做了大大的简化,使得 opengl 各个版本的函数像原生函数一样,可以随意调用。

    4.glfw

      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所需的核心

    5.glad库

      目前网上的一些教程还有使用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)按钮来生成库文件。

      下载到本地是个压缩文件,解压完成后会有这样的文件夹结构:

    test

    图13:glad文件目录

      包含两个头文件目录(内有头文件glad.h和khrplatform.h),和一个src文件夹下的glad.c文件。只需要将原来的第五步的 VC++目录 -> 包含目录 中的glew的include文件夹改成glad的include文件夹即可。后面的步骤glad都不需要。

      然后将glad.c文件复制到源文件夹下:

    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;
    View Code

    四、总结

      在本篇博客中,马三和大家一起从头开始搭建了一个OpenGL开发环境,并且了解了一些OpenGL的概念与名词。接下来马三将会一边学习计算机图形学和OpenGL,一边随时随地的把想法记录下来与大家分享~

      参考资料:

    如果觉得本篇博客对您有帮助,可以扫码小小地鼓励下马三,马三会写出更多的好文章,支持微信和支付宝哟!

           

    作者:马三小伙儿
    出处:https://www.cnblogs.com/msxh/p/9622617.html 
    请尊重别人的劳动成果,让分享成为一种美德,欢迎转载。另外,文章在表述和代码方面如有不妥之处,欢迎批评指正。留下你的脚印,欢迎评论!

  • 相关阅读:
    计算几何——交点、面积的计算
    计算几何——认识基本object:点、线、面 。
    图的拓扑排序——卡恩算法
    Manacher
    如何不改造 HBase 就能应对复杂查询场景
    如何做沟通
    大数据磁盘阵列技术
    Android系统架构开篇
    Apache Kylin 原理介绍与新架构分享(Kylin On Parquet)
    遭遇突然提问慌了?掌握关键2点完美应对zz
  • 原文地址:https://www.cnblogs.com/msxh/p/9622617.html
Copyright © 2020-2023  润新知