LearnOpenGL笔记:Window和Triangle (一)

Hello Window

原文链接

Double Buffer

Windows应用程序使用双缓冲(double buffer)的方式来渲染,前缓冲(front buffer)保存着已经绘制到屏幕的最终的图像,而同时渲染指令绘制到后缓冲(back buffer)中。一旦渲染指令执行完,我们就将前后缓冲互换,这样图像就可以立即呈现给用户,避免单缓冲会出现的失真现象。

当我们的应用程序以单缓冲(single buffer)的方式绘制时最终的图像有可能出现闪烁的情况。

State-Setting vs State-Using function

如下的代码所示,我们调用了glClearColor来设置了一个用来清理屏幕的颜色,当我们调用glClear来清理颜色缓冲(color buffer)时,这个颜色就会被使用到。所以我们称glClearColor为State-Setting函数,glClear为State-Using函数。

glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

Hello Triangle

在OpenGL里所有东西都是在3D空间中的,但我们的屏幕和窗口是一个2D的像素数组,所以OpenGL做的事情中有很大一部分是如何将3D坐标转换成可以显示到屏幕上的2D像素,这部分工作是由图形管线(Graphic Pipeline)来做的。图形管线的工作可以划分成两部分:

  • 将3D坐标转换成2D坐标
  • 将2D坐标转换成要显示的像素值

图形管线可以划分成几个步骤,每个步骤以前一个的输出为输入。每个步骤都是高度的特定化的(它们都有一个特定的功能),而且可以很容易的并行处理。正是因为这些步骤的并行特性,现今的显卡有上千个小的处理内核运行每个步骤中的显卡小程序,以这样方式来快速处理你传到图形管线上的数据。这些所谓的显卡小程序被称为shader

某些shader是可以由开发者来定制,这样可以允许我们用自己写的shader来取代已有的默认shader。这些可定制的shader给了我们对图形管线的某些步骤更好的粒度控制,另外因为shader运行在GPU,所以也帮我们省了宝贵的CPU时间。

图形管线的输入涉及到的概念:

  • 顶点Vertex:每个3D坐标的数据集合
  • 顶点属性Vertex Attributes:每个顶点可以包含的任意数据,出于简化理解,我们可以认为每个顶点只包含位置和一些颜色值

为了让OpenGL知道你要用这些坐标和颜色的集合用来做什么,OpenGL需要你示意你要用这些数据构成什么样的渲染类型,比如是一系列的点,是一系列的三角形,还是只是一条长线。这里说的示意被称为在调用任意渲染指令时给OpenGL指定的图元(primitive),比如GL_POINTSGL_TRANGLESGL_LINE_STRIP

图形管线的各个步骤:

  • Vertex Shader: 以单个顶点(vertex)为输入,把3D坐标转换到不同3D坐标,同时可以让我们对顶点属性做一些基本的处理。

  • 图元组装:以vertex shader输出的用来构成图元的顶点为输入,将这些顶点组装成指定的图元,比如三角形

  • Geometry Shader:以构成图元的顶点集合为输入,它能通过产生新的顶点来构成新的图元,比如从一个三角形变成两个三角形

  • 光栅化:将来自Geometry Shader的最终的图元映射成屏幕上对应的像素,生成片元(fragment)供fragment shader使用。在运行fragment shader前,片元会经过裁剪处理。

裁剪会丢弃你可见范围外的片元,这样可以提升性能。在OpenGL中,片元包含了OpenGL渲染单个像素所需的所有数据。

  • Fragment Shader:主要的功能就是计算出像素的最终颜色值,通常这一步是高级OpenGL特效产生的地方。

Fragment Shader包含了可以用来计算最终颜色值和3D场景有关的数据(像光照,阴影,光照的颜色等等)。

  • Alpha 测试和混合:这个步骤做了以下的事:
  • 测试片元的深度值(depth)和模板值(stencil),以确定该片元是在其他的对象前还是后,以此来确定是否要丢弃。
  • 检查Alpha值(Alpha值用来定义一个对象的透明度),并根据这个值来混合这些对象。

在现代OpenGL中,我们被要求至少定义一个Vertex和Fragment shader(在GPU里并没有默认的Vertex/Fragment shader)。

你可能感兴趣的:(游戏开发)