文章目录
一、GDI概述二、OpenGL三、什么是DirectX?四、GDI与OpenGL与DirectX之间的区别五、显卡驱动1.显卡概述2.显卡工作原理六、C++图形化GUI开发框架1.MFC介绍1) API2) SDK3) 控制台程序4) GUI程序5) MFC程序6) 字符编码:Unicode和多字节2.Qt是什么?Qt简介Qt 可以做什么?七、游戏开发引擎1、Unity 3D2、虚幻引擎一、GDI概述
GDI在全称是Graphics Device Interface,即图形设备接口。是图形显示与实际物理设备之间的桥梁。GDI使得用户无需关心具体设备的细节,而只需在一个虚拟的环境(即逻辑设备)中进行操作
先上一个图,窗口渲染的过程,自己的理解可能有问题
二、OpenGL
OpenGL是一套应用程序编程接口(API),借助这个API我们开发人员就可以开发出对图形硬件具有访问的能力的程序。我们可以使用OpenGL开发出运行效率较高的图形程序或游戏,因为OpenGL非常接近底层硬件并且OpenGL使得我们不必去关注图形硬件的细节。既然我们开发人员不必关注图形硬件的细节,那么我们需要关注什么呢?我们需要关注OpenGL如何绘制,按照专业术语就是根据物体的规格参数及相关属性,借助虚拟照相机和光照生成一幅该物体的图像。OpenGL程序与平台是无关的,所以OpenGL API中不包含任何输入函数或窗口函数,原因是因为这两种函数都要依赖于特定的平台,例如Windows,Linux或是其他系统。
OpenGL API是过程性的,不是描述性的,即OpenGL不是面向对象的,所以OpenGL无法利用面向对象的特性,例如重载,继承等,但是我们可以使用面向对象的程序与OpenGL的实现进行链接就可以了。作为开发人员来说,我们不需要去描述场景的性质和外观,而是去确定一些操作步骤,为些操作步骤是为实现一定图形或图像所服务的。我们在实现这些步骤时可以调用OpenGL中的一些命令,可以利用这些命令绘制点、直线、多边形或是其它图形,还可以调用这些命令实现光照、着色,动画等各种效果。
OpenGL的实现可以是软件实现,也可以是硬件实现。软件实现是对OpengGL函数调用时作出的响应并创建二维或三维图像的函数库,那么硬件实现则是通过设置能够绘制图形或图像的图形卡驱动程序。一般来说,硬件实现要比软件实现快得多。我们都应该熟悉,在Windows上,是由图形设备接口将图形或图像显示在屏幕上或是其他显示设备上的。OpenGL的实现就软件实现来说,在Windows上会根据程序命令的要求,生成相应的图形或图像,然后会将这个图形或图像移交给图形设备接口,由图形设备接口将图形或是图像显示在我们的屏幕上或是其他显示设备。这样一说,我们可能会明白一点OpengGL原来是在应用程序和图形设备接口之间运作,但我感觉还不能准确地这样说。大家看下下面的图对OpenGL的工作原理可能会理解得更明白一点:
上图是OpenGL的软件实现的工作原理。需要注意的是上图中的构造图形是通过软件进行构造的。
OpenGL的硬件实现与软件实现稍微有些不同,硬件实现是将OpenGL的调用传递给硬件驱动程序,而硬件驱动程序不会将生成的图形或图像传递给图形设备接口,而是直接与显示设备通信,直接将图形或图像结果传递给显示器或其他显示设备。如下图所示:
OpenGL在绘制图形时是基于一个被称为流水线模型的模式。也就是说其中的几何图形在程序中通过描述空间位置或顶点来指定其形状并由程序生成,这些顶点在流经一系列模块时,每个模块在图形的基本组成部分(在这里称为图元)经过时对其实施一种或多种操作。模块负责对流经的图元实施一种或多种操作变换,例如:旋转、平移、缩放及对摄像机进行定位等。
OpenGL中包含许多对图形图像处理的函数,主要包括以下几种:
图元函数:指定要生成图形或图像的图元。主要有两种类型,一种是绘制二维或三维的几何图元,如点,线,多边形等;另一种是离散型的实体,例如:位图。
属性函数:属性函数主要是控制图元的外观及样式,例如:对图元的颜色、线型、光照及纹理等效果处理。
观察函数:观察函数主要是对摄像机属性的操作。我们可以操作摄像机显示图形或图像近距或是远距效果。
控制函数:能够让我们启用或是彬各种OpenGL的特性。
查询函数:可以让我们查询OpenGL状态变量的值。
输入与窗口控制函数:这个本身不属于OpenGL,但是由于我们会经常在程序中输入输出或是窗口控制操作,所以,这些函数还是比较重要的。
OpenGL函数库一般包含在两个库中,分别称为GL或GLU。GL是OpenGL的核心库,包含必需的OpenGL函数。GLU是OpenGL的实用库,包含许多的新函数。下面的代码显示了许多的Windows程序包含的典型头文件:
#include <GL/gl.h>#include <GL/glu.h>#include <windows.h>
但是为了实现和窗口系统的交互,一般使用如下代码引用头文件:
#include <GL/glut.h>
GLUT表示OpenGL工具箱,体现了现代窗口系统所共有的功能函数库。GLUT的目的就是隐藏平台的细节,glut.h已经包含了gl.h和glu.h。使用GLUT是因为OpenGL没有包含输入和窗口命令,而输入和窗口命令是由平台所决定的,与平台的相关性较大。但是前面说过,OpenGL是与平台无关的,也就是说OpenGL是跨平台的。这样设计人员就需要专门设计一个需要和窗口系统进行交互的函数库。
三、什么是DirectX?
DirectX是一种应用程序接口(API),它可让以windows为平台的游戏或多媒体程序获得更高的执行效率,加强3d图形和声音效果,并提供设计人员一个共同的硬件驱动标准,让游戏开发者不必为每一品牌的硬件来写不同的驱动程序,也降低用户安装及设置硬件的复杂度。这样说是不是有点不太明白,其实从字面意义上说,Direct就是直接的意思,而后边的X则代表了很多的意思,从这一点上我们就可以看出DirectX的出现就是为了为众多软件提供直接服务的。
DirectX是由很多API组成的,按照性质分类,可以分为四大部分,显示部分、声音部分、输入部分和网络部分。
显示部分担任图形处理的关键,分为DirectDraw(DDraw)和 Direct3D(D3D),前者主要负责2D图像加速。它包括很多方面:我们播放mpg、DVD电影、看图、玩小游戏等等都是用的DDraw,你可以把它理解成所有划线的部分都是用的DDraw。后者则主要负责3D效果的显示,比如CS中的场景和人物、FIFA中的人物等等,都是使用了DirectX的 Direct3D。
四、GDI与OpenGL与DirectX之间的区别
OpenGL、Direct3D、GDI这三个是不同的API, 没有谁属于谁,其次OpenGL和Direct3D主要用于三维渲染, GDI只能用于绘制二维图形图像。前面两个主要用于实时渲染,后者主要用于Win32程序绘图。
五、显卡驱动
1.显卡概述
显卡(Video card,Graphics card)全称显示接口卡,又称显示适配器,是计算机最基本配置、最重要的配件之一。显卡作为电脑主机里的一个重要组成部分,是电脑进行数模信号转换的设备,承担输出显示图形的任务。我们在显示器上看到的图像是由很多个小点组成的,这些小点称为“像素”。在最常用的分辨率设置下,屏幕显示一百多万个像素,电脑必须决定如何处理每个像素,以便生成图像。为此,它需要一位“翻译”,负责从CPU获得二进制数据,然后将这些数据转换成人眼可以看到的图像。除非电脑的主板内置了图形功能,否则这一转换是在显卡上进行的。也就是说,显卡的功能就是将计算机中由1和0表示的二进制数据转换为图像显示出来。
显卡的主要部件是:主板连接设备、监视器连接设备、处理器和内存。主板连接设备,主要用于传输数据和供电;处理器,又称为显示芯片(Video chipset)、图形处理器(GPU)或视觉处理器(VPU),是显卡的主要处理单元,用于决定如何处理屏幕上的每个像素,由于它工作时会产生大量热量,所以它的上方通常安装有散热器或风扇;内存,常被称为“显示存储器”,简称显存,用于存放有关每个像素的信息以及暂时存储已完成的图像;监视器连接设备便于我们查看最终结果。
2.显卡工作原理
数据(data)一旦离开CPU,必须通过4个步骤,最后才会到达显示屏:
1.从总线(Bus)进入GPU(Graphics Processing Unit,图形处理器):将CPU送来的数据送到北桥(主桥)再送到GPU(图形处理器)里面进行处理。
2.从 Video Chipset(显卡芯片组)进入 Video RAM(显存):将芯片处理完的数据送到显存。
3.从显存进入Digital Analog Converter (= RAM DAC,随机读写存储数—模转换器):从显存读取出数据再送到RAM DAC进行数据转换的工作(数字信号转模拟信号)。但是如果是DVI接口类型的显卡,则不需要经过数字信号转模拟信号。而直接输出数字信号。
4.从DAC进入显示器(Monitor):将转换完的模拟信号送到显示屏。
驱动程序:驱动程序是一个软件组件,可让操作系统和设备彼此通信。例如,假设应用程序需要从设备中读取某些数据;应用程序会调用由操作系统实现的函数,操作系统会调用由驱动程序实现的函数。 驱动程序(由设计和制造该设备的同一公司编写)了解如何与设备硬件通信以获取数据。 当驱动程序从设备获取数据后,它会将数据返回到操作系统,操作系统会将数据返回至应用程序。
显卡驱动是由生产硬件的硬件厂商写的,它是为某个系列的显卡所开发的OpenGL的实现;而我们开发一个OpenGL的应用程序时所使用的OpenGL仅仅是一套接口,它是公共的,独立于硬件平台和操作系统的,我们根据OpenGL规范所是实现的这个程序描述的只是我们想要做什么,至于具体怎么做、实现结果是什么效果,它是由显卡驱动和硬件决定的;
OpenGL所提供的只是接口,我们所调用的也只是接口;具体的实现由显卡生产商实现,也就是他们所提供的显卡驱动;我们使用OpenGL可以调用API(这个api仅仅是函数名,仅仅是接口而已)去绘制一个三角形,但是硬件如何知道这个函数是用来绘制三角形的,这一部分就是由显卡驱动来完成,显卡驱动里会提供这个接口的具体实现,也就是说如果没有安装显卡驱动或者显卡驱动里并没有提供绘制三角形的实现,那么OpenGL里的api是毫无意义的;
由于OpenGL的大多数实现都是由显卡厂商编写的,当产生一个bug时通常可以通过升级显卡驱动来解决。这些驱动会包括你的显卡能支持的最新版本的OpenGL,这也是为什么总是建议你偶尔更新一下显卡驱动。
开发者通过图像编程接口发出渲染命令,这些渲染命令也就是DrawCall,只有显卡驱动知道如何和GPU通信,;正是因为显卡驱动的存在,显卡驱动会将接收到的渲染命令翻译成GPU能够理解的语言,也负责将纹理等数据转换成GPU所支持的格式,之后GPU才能懂OpenGL和DirectX,显卡驱动就像是一个中介,介于图形编程接口(OpenGL和DirectX)和GPU之间。
可以将显卡驱动比喻是显卡的操作系统,是显卡的灵魂;
六、C++图形化GUI开发框架
这边主要就介绍两个比较常见的框架:MFC和QT。
1.MFC介绍
微软基础类库(英语:Microsoft Foundation Classes,简称MFC)是微软公司提供的一个类库(class libraries),以C++类的形式封装了Windows API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。
图形设备接口(Graphics Device Interface,GDI),把应用程序的函数调用传递给图形设备驱动程序,由设备驱动程序来执行与硬件相关的函数。GDI向应用程序提供了一个设备无关的编程,同时以设备相关的格式和具体的硬件设备交互。
在MFC中使用GDI进行绘图操作一般会涉及两个对象,一是设备上下文对象,包括CDC及其派生类;二是GDI对象,包括CFont、CBrush、CPen等。
介绍MFC之前,需要先介绍几个MFC的概念。
1) API
Windows操作系统提供了各种各样的函数,以方便我们开发Windows应用程序。这些程序是Windows操作系统提供给应用程序编程的接口(Application Programming Interface),简称为API函数。我们在编写Windows程序时所说的API函数,就是指系统提供的函数,所有主要的Windows函数都在Windows头文件中进行了声明。
举个例子,Windows中播放声音的API函数,函数原型如下:
BOOL PlaySound(LPCSTR pszSound, HMODULE hmod,DWORD fdwSound);
pszSound就是你要播放的文件路径,fdwSound就是你要选择的播放模式。具体的用法可以查阅相关的资料。
在使用API时,注意头文件和库文件对API的支持,否则程序编译或链接会提示错误。API PlaySound需要头文件mmsystem.h和库文件WINMM.LIB的支持。
#include <mmsystem.h>#pragma comment(lib, "WINMM.LIB")
2) SDK
SDK(Software Development Kit, 即软件开发工具包 )一般是一些被软件工程师用于为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件的开发工具的集合。举个例子,假如我们要开发无线信号发射器,在购买芯片或主板的同时,厂商同时会提供主板的SDK开发包,以方便我们对主板的编程操作。这个开发包通常会包含主板的API函数、帮助文档、使用手册、辅助工具等资源,也就是定义里面说的,SDK实际上一个开发所需资源的一个集合。
3) 控制台程序
所谓的控制台应用程序,就是能够运行在MS-DOS环境中的程序。控制台应用程序通常没有可视化的界面,只是通过字符串来显示或者监控程序。控制台程序常常被应用在测试、监控等用途,用户往往只关心数据,不在乎界面。一个典型的应用就是ping网络,如图1-1所示:
图1-1 控制台程序示例
DOS 的这种界面叫CUI (Command line User Interface ) 命令行模式的人机接口。
4) GUI程序
GUI 是 Graphical User Interface 的简称,即图形用户界面,如Windows是以图形界面方式操作的,因为你可以用鼠标来点击按钮来进行操作,很直观。而DOS就不具备GUI,所以他只能输入命令。另外,GUI 还是一种结合计算机科学、美学、心理学、行为学,及各商业领域需求分析的人机系统工程,强调人—机—环境三者作为一个系统进行总体设计。这种面向客户的系统工程设计其目的是优化产品的性能,使操作更人性化,减轻使用者的认知负担,使其更适合用户的操作需求,直接提升产品的市场竞争力。
5) MFC程序
MFC是微软基础类库的简称,是微软公司实现的一个c++类库,主要封装了大部分的windows API函数,所以在MFC中,你可以直接调用 windows API,同时需要引用对应的头文件或库文件;另外,MFC除了是一个类库以外,还是一个框架,在vc++里新建一个MFC的工程,开发环境会自动帮你产生许多文件,同时它使用了mfcxx.dll。xx是版本,它封装了mfc内核,所以你在你的代码看不到原本的SDK编程中的消息循环等等东西,因为MFC框架帮你封装好了,这样你就可以专心的考虑你程序的逻辑,而不是这些每次编程都要重复的东西。但是由于是通用框架,没有最好的针对性,当然也就丧失了一些灵活性和效率,但是MFC的封装很浅,所以在灵活性以及效率上损失不大,可以忽略不计。
MFC程序就是基于MFC编译出来的可执行程序,是一种GUI程序。
6) 字符编码:Unicode和多字节
字符编码是一个复杂的过程。简单地讲,就是将机器语言(0和1组成的字符串)转换成我们能识别的信息的一个过程。我们不必在这里深究这个过程是怎么完成的,暂时没有必要。这里我们知道的是,MFC有两种编码方式,Unicode和多字节并且可以设置切换。切换方法是打开项目属性页,常规项对应的字符集中可切换编码方式。Visual C++6.0用的是多字节编码;Virtual Studio 默认使用的是Unicode编码,所以在代码移植的时候经常会提示很多编码方式相关的错误,解决方法是将Unicode编码改为多字节编码即可。这里提示一点,使用 _T 宏有条件地编写字符串的代码,使之可移植到 Unicode。这一招可以解决大多数编码方式不匹配引发的问题。
可以用visual studio 创建一个默认的MFC项目。
执行之后,生成了一个图形界面程序:
2.Qt是什么?Qt简介
Qt(官方发音 [kju:t],音同 cute)是一个跨平台的 C++ 开发库,主要用来开发图形用户界面(Graphical User Interface,GUI)程序,当然也可以开发不带界面的命令行(Command User Interface,CUI)程序。
Qt 是纯 C++ 开发的,所以学好 C++ 非常有必要。
Qt 还存在 Python、Ruby、Perl 等脚本语言的绑定, 也就是说可以使用脚本语言开发基于 Qt 的程序。开源社区就是这样,好东西就会被派生扩展,到处使用, 越来越壮大。
Qt 支持的操作系统有很多,例如通用操作系统 Windows、Linux、Unix,智能手机系统 Android、iOS、WinPhone, 嵌入式系统 QNX、VxWorks 等等。
Qt 可以做什么?
Qt 虽然经常被当做一个 GUI 库,用来开发图形界面应用程序,但这并不是 Qt 的全部;Qt 除了可以绘制漂亮的界面(包括控件、布局、交互),还包含很多其它功能,比如多线程、访问数据库、图像处理、音频视频处理、网络通信、文件操作等,这些 Qt 都已经内置了。
Qt 是应用程序开发的一站式解决方案,有了 Qt,你就可以高枕无忧了!Qt 本身包含的模块也日益丰富, 一直有新模块和第三方模块加入进来。
大部分应用程序都可以使用 Qt 实现,除了与计算机底层结合特别紧密的,例如驱动开发,它直接使用硬件提供的编程接口,而不能使用操作系统自带的函数库。
1997年,Qt 被用来开发 Linux 桌面环境 KDE,大获成功,使 Qt 成为 Linux 环境下开发 C++ GUI 程序的事实标准。
下面的程序都使用 Qt 开发:WPS、YY语音、Skype、豆瓣电台、虾米音乐、淘宝助理、千牛、暴雪的战网客户端、VirtualBox、Opera、咪咕音乐、Google地图、Adobe Photoshop Album 等。
Linux 也是嵌入式的主力军,广泛应用于消费类电子、工业控制、军工电子、电信/网络/通讯、航空航天、汽车电子、医疗设备、仪器仪表等相关行业。
Qt 虽然也支持手机操作系统,但是由于 Android 本身已经有 Java 和 Kotlin,iOS 本身已经有 Objective-C 和 Swift,所以 Qt 在移动端的市场份额几乎可以忽略。
总起来说,Qt 主要用于桌面程序开发和嵌入式开发。
七、游戏开发引擎
游戏引擎是指一些已编写好的可编辑电脑游戏系统或者一些互交式实时图像应用程序的核心组件。这些系统为游戏设计者提供各种编写游戏所需的各种工具,其目的在于让游戏设计者能容易和快速地做出游戏程序而不用由零开始。
游戏引擎作为开发商研发游戏时必备的工具,每一款引擎的运用都关乎自家大作未来的销量,所以游戏商们对引擎的选择也非常小心翼翼。现在,手游、页游等新兴平台的表现又非常强势,所以选择正确的游戏引擎变得尤为重要。
1、Unity 3D
Unity 3D是一个用于创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的综合型创作工具,由Unity Technologies开发,是一个全面整合的专业游戏引擎。对游戏开发者们来说,Unity 3D是一个真正可以负担得起的引擎,具有其他引擎难以匹敌的用户量。更重要的是,你只需要付费一次,而且,不管你的游戏如何成功,都不用担心Unity会分走你的收入。这对于很多开发商来说当然是非常具有吸引力的,尤其是初创公司和新入行的开发者们。
Unity引擎的优点和缺点:
**优点:**业内最 具竞争力的授 权条款;易于使用,且兼容所有游戏平台;开发者社区支持强大;学习门槛非常低;开发商使用率最 高。
**缺点:**工具数量有限,所以开发商必须给自己创作工具;做复杂和多样化的效果比较耗时。
2、虚幻引擎
虚幻引擎的设计目的非常明确,每个方面都具有较高的易用性,尤其侧重于数据生成和程序编写的方面,这样,美工只需要程序员的很少量的协助,就能尽可能多地开发游戏的数据资源,并且这个过程是在完全可视化环境中完成的,实际操作非常便利。
数年以来,虚幻引擎一直是做高端EA游戏最 受欢迎的引擎。《战争机器》、《蝙蝠侠:阿卡汉姆疯人院》(Batman:ArkhamAsylum)、《质量效应》以及其他很多著名作品都是出自该引擎之手。
虚幻引擎的优点和缺点:
**优点:**开发商使用率较高,开发商社区强烈支持,有视频教程和大量资源。拥有最 佳的引擎支持,随时更新其他引擎平台的功能,增加新的工具,且管理相对容易,工具简单易用。很多系统都兼容,如:iOS、Android、Linux、Mac、Windows等和大多数游戏主机。
**缺点:**授权条款只适合大作,商业授 权价格为99美元,在游戏收入超过5万美元之后,必须支付25%的分成。也有一些开发者抱怨有些工具不好用,学习门槛较高。