OpenGL教程 001欢迎学习OpenGL

Welcome to OpenGL

openGL是一个图形API
现如今,API代表着用户图形接口(Application Program Interface)
通俗地来说
其基本上是一群函数
我们可以通过调用这些函数来做一些事情
这这种情况下
openGL是一个图形API
所以它允许我们做一些关于图形图像方面的事情
而且特别地
penGL实际上允许我们访问我们的GPU(显卡)
显卡可以更有力地绘制图形
实际上为了在电脑和设备(像手机)上使用用显卡

我们实际上需要使用一些API来操纵显卡

而OpenGL是这类API中的一个
我们也有其他这方面的API像是Direct3D(Window专用)
ulkan(最新一代的OpenGL,语法方面和OpenGL差异较大)
etal(苹果专用)和一些其他的。
总的来说

openGL允许我们一定程度上操纵我们的显卡

现在让我们澄清一些人们对OpenGL的误解
首先,很多人称OpenGL为”库“或者”引擎“,”框架“
但是这是不对的
openGL的核心本身是一种规范,类似于C++规范
实际上它并没有确定任何的代码或类似的事情
它本身只是个规范
说”Hey,这个函数应该存在
他需要这些参数
并且需要返回这个值“
他只是个告诉你可以利用这些API做什么的规范
而不提供任何的实现。
这意味着它肯定不是一个库
因为它本身是没有任何代码的
那么问题来了
我们上哪下载OpenGL呢?
这的确是一个困扰了很多人的问题
实际上你不需要下载它
它本身是个规范
那谁去实现它呢
谁去为那些你会使用的OpenGL函数写代码呢

答案是你的【显卡生产厂商

所以如果你用的是NVDIA的显卡
那么你的显卡驱动程序就会包含OpenGL的实现
并且所有的显卡厂商,像是AMD,Intel等
他们会有他们自己的实现。
当然
vidia不会和AMD开个会说
我们该这么写我们的代码“
所以每个厂商对OpenGL的实现都会有轻微的不同
这就是为什么在很多情况下
有些代码在基于NVIDIA显卡的驱动程序上能工作
但在AMD电视或者其他的显卡上显得有一些不同
甚至产生bug。
但无论怎么说
关键在于你的显卡厂商是如何编写OpenGL实现的
而这又可能引起下一个误解:OpenGL是开源的
导致这个误解的原因是他名字里面有个”Open”

但他其实不是开源的,你看不到他的源码

首先因为其是由显卡厂商实现的
他们显然不会将显卡驱动的源码开源
有些伙计会去写一些开源的OpenGL实现,因为。。。
好吧我也不知道
如果我造了个显卡并且我想要支持OpenGL
我需要为其写个驱动程序
那么我可能会选择将代码开源在Github上或以其他形式开源
但是在你电脑上运行的显卡,比如NVIDIA或AMD
你是没办法看到他们背后的OpenGL的源码的
所以OpenGL不可能是开源的
第一他只是规范,没有代码
第二你现在使用的OpenGL
也很可能不是开源的
那么OpenGL提供了什么
使得一些不幸的人高呼”OpenGL天下第一“?
可能是因为它是跨平台的
所以你可以只写一份OpenGL代码就可以在Windows,Mac(苹果电脑),Linux,iOS,安卓系统上运行
这时有人就会立刻想到
Oh,那OpenGL岂不是比Direct3D牛逼?因为它能在所有平台上运行”
不,不。请别再说那些话了
我刚刚意识到我刚才的话似乎在引战
我应该在开头就说“这视频只是我的个人观点”
我只是给出我的观点,你可以听或不听
我也没说我的观点就是对的(疯狂辩护中)
我只是说从我在EA的技术中心的工作经历来看
尤其是游戏引擎技术方面是这样
我已经涉及过很多图形API了
我不是OpenGL的超级粉丝
我的观念是,因为OpenGL是跨平台的API
你知道的,这是一种最好的方法来。。。
我来举个栗子
游戏制作通常会涉及到不止一个API
但那不是他们工作的方式
如果游戏引擎是跨平台的
那就意味着他们不能仅仅为了Xbox或其他一些平台做出实现
他们不能仅给Windows系统实现
他们不得不其实现很多的图形API
事实上为平台专门编写的API,像是Direct3D
一般要比跨平台的API好
记住,实际编写这些代码的人不是微软
微软的确和显卡厂商合作过要做出更好的代码
但是到头来,由于编写API的人职责不均衡
微软的愿望未能达成

但事实是OpenGL是跨平台的因此比Direct3D或Metal要好

etal是苹果系列专用的API
所以关于“API哪家强”的争论是没有意义的
因为平台原生的东西往往要更好一些
这也就是说OpenGL像是个确切的规范,他很普通
如果你把它和低层次的,像DirectX12或Vulkan比较的话
所以根据OpenGL的复杂性来看
我认为OpenGL可能是。。。
有一些像Metal
etal比OpenGL要底层但是比Vulkan高级一些
我只能说OpenGL可能是你现在能学到的最简单的那个API了
所以OpenGL绝对值得学习
另一个跨平台API,Vulkan,仍然和新并且很底层
而且驱动程序仍需要一些更多的工作
举个栗子
就像上周我看到一个Vulkan程序重启了Android机子
因为程序的某些bug
而且。。。你在学习Vulkan时会有更多的困难
我真的只推荐你学Vulkan在出于娱乐的情况下
现在是2017年9月
但是讲真我能不用Vulkan写游戏就不用它写
因为像OpenGL之类的比他更稳定
不管怎么说,我的观点是这个系列会讲述OpenGL
而且我仍然认为OpenGL是用来学习的最好的API
因为它很简单
他真的是学起来比较简单的那一个而且他还是跨平台的
所以如果你不是一个游戏工作室
如果你没有帮你做游戏引擎的团队
或者你没精力对不同的系统用不同的原生API写程序的话
我相信看视频的各位都没有
那OpenGL的跨平台性你值得拥有
如果你想制作跨平台的游戏的话,他将会是最简单的
这就是为什么我们学习OpenGL的原因
我的确很喜欢OpenGL,喜欢这类小的个人的项目
但显然
如果我在游戏引擎方面是欧洲三连冠的话
这可能不是我最后对选择的API
因为首先这个API比不上DirectX11
对我而言最喜欢的图形API设计可能是Direct3d11
对于是那些在写游戏引擎或者渲染引擎的人们来说
可能更倾向于写一个基于OpenGL的Direct3D的包装器
所以换而言之
他们可能底层用的OpenGL
但是将实际的API接口写的很像Direct3D
因为讲真Direct3D11的确是创造图形API的好办法
当然这只是我的观点。
但是我在公司交谈过的大多数人都100%同意这个观点
先不说这个了
现在你已经有了上面那些问题的答案
像是“OpenGL是在你的显卡驱动程序里实现的”
他本身只是一个让我们可以控制GPU的规范
现在,在我们这个系列中
我们主要是学习现代OpenGL
你可能已经听过很多关于老OpenGL和现代OpenGL之间的区别了
之所以有这些区别的原因是OpenGL在90年代发布
那时的情况和现在大不相同
那时GPU并不是灵活的并且可编程的
你不并能随心所欲地去操控它
尤其是使用较底层的API
但是现在
人们可以很大程度上控制它
或者我该说显卡厂商给了程序员和开发者更多的控制权
显然这很好
我们可以进一步地去优化显卡的使用
现在的OpenGL更强大
让你比以前更好的控制GPU
老OpenGL则更像是一个流水线
所以从另一方面来说
你说我要画一个三角形
并且我要加入光源
那么你要怎么加入这个光源呢

你可以告诉OpenGL类似“Lighting = True”的代码

这样可以启用光照
然后你告诉OpenGL想要在这里加入光照
像这样的就叫流水线式的操作
这种老OpenGL很容易被使用,代码也很少
但不幸的是你也没什么控制权
我们想要更多的控制权
我们想要实现更多的令人惊叹的图形

老OpenGL和现代OpenGL的最大区别在于“着色器”

你可能听过“着色器”这个词如果你对计算机图形学有兴趣的话
着色器是一段运行在GPU上的程序

所以如果我们【用C++或Java或C#其他什么编程语言写的程序都是运行在CPU上的

但当我们针对图形处理的时候
我们想要精确控制GPU

所以可能要将一些【代码从CPU放到GPU上】

因为他们可以【在GPU上运行地更快】

这就是着色器存在的意义
着色器只是允许我们在GPU上写程序
这也是这个系列主要想做的事情
因为如果你想要计算出复杂的光照算法
你一定会想在GPU上计算而不是像过去一样在CPU上解决

所以老OpenGL和现代OpenGL最重要的区别在于【是否有可编程着色器】

当然也有其他的区别,我们之后会说到
不过现在只是提醒你在看的是现代OpenGL的教程
另一个我之后会提到的重要的事是
我们不会提到很高级的东西
我们不会去做游戏引擎或者游戏框架
或者库什么的
我们只是学习OpenGL
我之后几周可能会开另一个关于“如何制作游戏引擎”的教程
在那个教程里面我们会着手做一个完整的游戏引擎
并且将OpenGL作为其渲染API
所以如果你想看OpenGL在游戏引擎中的应用
你可以去看看那个
但在这个教程里面我们只是学习OpenGL
以便于我们后面可以写出那样的游戏引擎
正因如此
这个系列中我们不会浪费时间在“如何做一个材质系统”这类事情上
我们只是着眼于OpenGL本身
你之后可以随意地在你的游戏引擎中使用这些知识
如果你没开始的话也可以跟着我后面的游戏引擎教程做
这个系列中我们只着眼于OpenGL
并且编写原始的OpenGL代码
我们可能会写一些小的工具类像是 mass或者加载着色器类
加载纹理的类
因为这些代码都是可以复用的样板代码
但当我们真正准备在屏幕上渲染某些东西时
我们不会将这些步骤省略
我们会从头开始写
我们打算使用C++编写OpenGL程序

因为我认为【C++是最适合这种工作的语言】

我们的程序应当可以跨平台
并且我也会尽可能地让他跨平台
这样无论是Mac,Linux还是Windows的人都可以直接编译它
我打算在Windows上用Visual Studio编写
因为这可能是大多数人使用的开发环境
而且我个人也认为这是最好的开发环境
总而言之
我打算在这个系列里讲述2D图形
快速2D图形
并且学习批处理和类似的东西
然后编写一个非常非常快速的2D渲染器
当然我也会讲3D的方方面面
也会包含一些很酷的东西比如光照和阴影
延迟着色
BR物理渲染
旧的后处理技术像是Bloom
雾的特效
AO
屏幕空间的反射
我们基本上要把所有事情做一遍
我很乐意再去实现一遍这些我以前做过的东西
并且将这些例子做出来也是很令人兴奋的
你们可以去尽情探索这些例子
希望你们可以在你们的游戏或引擎中实现这些
我真的很激动
因为图形编程是我最喜欢的领域
再次提醒
这个教程里面我不会去做游戏引擎
我们只是关注于如何用OpenGL
openGL只是很多图形API中的一个
并且我们不会涉及到其他的API。
如果你和我一样激动的话
可以给我点个喜欢
你也可以去patreon.com/TheCherno网站支持我