LearnOpenGL从入门到入魔(2):绘制2D图形

总目录

LearnOpenGL从入门到入魔(1):OpenGL简介
LearnOpenGL从入门到入魔(2):绘制2D图形
LearnOpenGL从入门到入魔(3):绘制纹理
LearnOpenGL从入门到入魔(4):绘制3D图形
LearnOpenGL从入门到入魔(5):简单滤镜效果
LearnOpenGL从入门到入魔(6):光照(光照基础,材质)
LearnOpenGL从入门到入魔(7):光照(光照贴图,投光物)

1. OpenGL基本概念

1.1 图像渲染管线

 在OpenGL中,任何事物都在3D空间中,而屏幕和窗口却是2D像素数组,这导致OpenGL的大部分工作都是关于把3D坐标转变为适应你屏幕的2D像素。3D坐标转为2D坐标的处理过程是由OpenGL的图形渲染管线(GraphicsPipeline,或称管线)管理的,该过程可表述为将一堆原始图形数据途经一个输送管道,期间经过各种变化处理最终出现在屏幕的过程。图形渲染管线可以被划分为两个主要部分:第一部分将输入的3D坐标转换为2D坐标,第二部分是把2D坐标转变为实际的有颜色的像素。下图表示一个图形渲染管线的每个阶段的抽线表示:

管线

 蓝色部分着色器允许我们自定义,即可编程着色器,包括顶点着色器几何着色器片段着色器,而几何着色器通常使用默认的就可以了,其它部分也是用默认的即可。在现代OpenGL中,我们必须定义至少一个顶点着色器和一个片段着色器,因为GPU中没有默认的顶点/片段着色器。

图形渲染管线各阶段功能如下:

  • 顶点着色器(Vertex Shader)

 顶点着色器接收一组顶点数组作为输入,这些顶点数据使用顶点属性表示,它会将每个顶点的3D坐标转换为另一种3D坐标,同时对该顶点的顶点属性进行一些基本处理,然后再将经过处理后的顶点数组。

  • 顶点属性

 顶点属性指定了每个顶点的各种属性,包括坐标(postion)、颜色(color)、法线(normal)以及纹理(Texture)等。下面演示了如何定义一组顶点数据,其中每个顶点包含了坐标、颜色和纹理属性:

  GLfloat vertex[ 4*(3+4+2)] =
    {
       //x,y,z,              r,g,b,a                  s,t(纹理)
        -0.5f,  0.5f, 0.0f,   0.0f, 0.0f, 0.5f, 1.0f,  0.0f, 1.0f, // 第1个顶点
         0.5f,  0.5f, 0.0f,   0.0f, 0.5f, 0.0f, 1.0f,  1.0f, 0.0f, // 第2个顶点
        -0.5f, -0.5f, 0.0f,   0.5f, 0.0f, 1.0f, 1.0f,  0.0f, 1.0f, // 第3个顶点
         0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 0.5f, 1.0f,  1.0f, 1.0f, // 第4个顶点
    };

 在OpenGL中,顶点属性数据存储在一段连续的内存空间。下图展示了3个顶点的存储情况,其中每个顶点的坐标和颜色属性分别占3个float,即12字节(BYTE):
image

  • 形状(图元)装配(SHAPE/Primitive Assembly)

 图元(Primitive),或称形状,是指OpenGL的渲染类型,当我们将输入的坐标和颜色渲染成具体的某种表示时,需要在调用OpenGL的指令时指定图元,比如GL_POINTS表示点,GL_TRIANGLES表示三角形以及GL_LINE_STRIP表示一系列的连续直线等。因此,图元装配的作用时将顶点着色器输出的所有顶点作为输入,输出制定的基本图元。

  • 几何着色器(Gemometry Shader)

 几何着色器把基本图元形式的顶点的集合作为输入,可以通过产生新顶点构造出新的(或是其他的)基本图元来生成其他形状。

  • 光栅化(Rasterization Stage)

 光栅化阶段将几何着色器输出图元映射为最终屏幕上相应的像素,生成供片段着色器使用的片段(Fragment)。在片段着色器运行之前会执行裁切,而裁切的目的即为丢弃超出我们视图以外的所有像素,以便提升执行效率。

片段(Fragment):指OpenGL渲染一个像素所需的所有数据。

  • 片段着色器(Fragment Shader)

 片段着色器以光栅化阶段生成的片段作为输入,它的作用是计算一个像素的最终颜色,这也是所有OpenGL高级效果产生的地方。通常,片段着色器包含3D场景的数据(比如光照、阴影、光的颜色等等),这些数据可以被用来计算最终像素的颜色值。

  • 测试与混合(Test & Blend)

 该阶段的目的为检测片段对应的深度值,用它们来判断这个像素是其它物体的前面还是后面,决定是否应该丢弃。同时,也会检查用于定义物体透明度的alpha值,并对物体进行混合。所以,即使在片段着色器中计算出来了一个像素输出的颜色,在渲染多个有重叠的物体的时候最后的像素颜色也可能完全不同。

1.2 着色器

 图形渲染管线接受一组3D坐标,然后把它们转变为屏幕上的有色2D像素输出。图形渲染管线可以被划分为几个阶段,每个阶段将会把前一个阶段的输出作为输入。所有这些阶段都是高度专门化的(它们都有一个特定的函数),并且很容易并行执行。正是由于它们具有并行执行的特性,当今大多数显卡都有成千上万的小处理核心,它们在GPU上为每一个(渲染管线)阶段运行各自的小程序,从而在图形渲染管线中快速处理你的数据。这些小程序叫做着色器(Shader)。OpenGL的着色器使用着色器语言GLSL(OpenGL Shading Language)编写,通过编译顶点着色器的源码,就可以在程序中使用它。

1.2.1 顶点着色器

 顶点着色器接收一组顶点数据(VertextData)作为输入,这些顶点数据使用顶点属性表示,它会将每个顶点的3D坐标转换为另一种3D坐标(标准化设备坐标),同时对该顶点的顶点属性进行一些基本处理,需要注意的是,顶点着色器依次处理顶点集合中的顶点数据。比如,我们要绘制一个三角形,那么就需要向顶点着色器输入3个顶点数据,且每个顶点的坐标(postion)是3D的。下列代码描述一个非常简单的顶点着色器源码:

// 注释(1)
#version 330 core
// 注释(2)
layout (location = 0) in vec3 aPos;

void main()
{
   
    // 注释(3)
    // GLSL中一个向量最多有四个分量,使用vec4表示
    // 每个分量值表示空间中的坐标,即
    // vec.x 表示x轴坐标;
    // vec.y 表示y轴坐标;
    // vec.z 表示z轴坐标;
    // vec.w 不用做表达空间的位置,主要应用再透视除法(后续解释)
    gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}

注释(1) 用于指明OpenGL的使用版本为3.3,采用核心模式;注释(2) 有两个作用,一是使用in关键字在顶点着色器中声明所有的输入顶点属性(注:本例中只关心顶点的位置position数据),二是通过layout (location = 0)设定输入变量的位置值Location;注释(3) 用于设置顶点着色器的输出,即将位置数据赋值给预定义变量gl_Position,该变量的类型为vec4,这是一个包含4个分量的向量。

  • 标准化设备坐标

 当顶点坐标经过顶点着色器处理后,将会被转换为标准化设备坐标,所谓标准化设备坐标,是一个x、y和z值在-1.0~1.0的一小段空间。任何落在范围外的坐标都会被丢弃或者裁剪,不会显示在设备屏幕上。下图展示了在标准化坐标中定义一个2D三角形,即忽略z轴。

image

1.2.2 片段着色器

 片段着色器用于计算一个像素的最终颜色值,该阶段是OpenGL高级效果产生的地方。通常,片段着色器包含3D场景的数据,比如光照、阴影、光的颜色等等,这些数据将被用来计算最终像素的颜色值。在计算机图形中,一个像素的颜色值由4个分量组成,即R(红色)、G(绿色)、B(蓝色)和A(透明度),就是我们熟知的RGBA。在OpenGL中,颜色的每个分量的取值范围为0.0f~1.0f,颜色程度由浅色到深色。下列代码演示了如何创建一个简单的片段着色器:

// 指明OpenGL的使用版本为3.3,并采用核心模式
#version 330 core
// 定义片段着色器的输出
// 输出一个vec4类型的变量,该变量表示像素的颜色值
out vec4 FragColor;

void main()
{
   
    // 对变量进行赋值
    // 即每个像素的颜色为红色
    FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值