本文主要是介绍【openGL4.x手册04】基元,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、说明
OpenGL 中的术语“基元”用于指代两个相似但独立的概念。 “原语”的第一个含义是指 OpenGL 使用的解释方案来确定渲染时顶点流所代表的内容,例如“GL_POINTS”。这样的顶点序列可以是任意长的。
“原语”的另一个含义,也称为“基本原语”,指的是顶点流的解释结果,作为原语组装的一部分。因此,通过这些基元解释之一处理顶点流会产生基元的有序序列。各个基元有时被称为“基本基元”。
二、顶点流
顶点流是顶点的有序列表。该流的来源取决于 Primitive Assembly 发生的时间以及涉及渲染管道的哪些阶段。顶点流可以来自:
- 顶点渲染命令,通过顶点规范定义并由顶点着色器处理。原始类型是渲染命令指定的类型。
- 曲面细分,执行曲面细分评估着色器后。原始类型由 TES 中指定的抽象补丁类型定义。
- 几何着色器基元输出。原始类型由 GS 指定。
与流关联的图元定义了如何将该流分解为基本图元的有序序列:点、线或三角形。
三、点基元
只有一种点原语:GL_POINTS。这将导致 OpenGL 将流中的每个单独的顶点解释为一个点。映射了纹理的点通常称为“点精灵”。
点被光栅化为给定窗口空间大小的屏幕对齐正方形。大小可以通过两种方法给出:通过最后一个活动顶点处理着色器阶段或通过上下文的状态。要从着色器设置点大小,请启用带参数 (GL_PROGRAM_POINT_SIZE) 的 glEnable 以从程序设置点大小。如果启用 GL_PROGRAM_POINT_SIZE,则点大小来自输出变量 float gl_PointSize。如果禁用,则图元中所有点的点大小都是恒定的,并由 glPointSize 函数设置。
大小定义了点正方形每条边占用的窗口像素数。该点的位置定义了该正方形的中心。
无论点大小如何定义,它都必须大于 0,否则会导致未定义的行为。点大小有一个实现定义的范围,并且任一方法给出的大小都被限制在该范围内。您可以使用 GL_POINT_SIZE_RANGE 查询范围(返回 2 个浮点数)。还有一个点粒度,可以用 GL_POINT_SIZE_GRANULARITY 查询;该实现会将大小限制为最接近的粒度倍数。
3.1 点片段输入
点仅由单个顶点定义。因此,通过光栅化该点生成的每个片段都会被赋予相同的用户定义输入值。然而,准确地知道特定片段着色器调用在点内的位置是有用的。虽然片段的具体位置 gl_FragCoord 会发生变化,但根据片段的位置,了解片段相对于点基元本身的位置会更有用。
为了帮助实现这一点,片段着色器可以使用内置输入 vec2 gl_PointCoord。这给出了 [0, 1] 范围内的坐标。 (0, 0) 的位置取决于 GL_POINT_SPRITE_COORD_ORIGIN 的点参数设置:如果设置为 GL_LOWER_LEFT,则 (0, 0) 是左下坐标。而如果是GL_UPPER_LEFT,那么(0, 0)就是左上角坐标。默认值为 GL_UPPER_LEFT,适合 OpenGL 常用的右手坐标系。
3.2 多重采样和衰落
TODO:此部分需要填写。
当使用多重采样渲染和绘制点时,片段着色器输出变量可以调整其 alpha 以表示点“淡出”。
四、线基元
根据顶点流的不同解释,有 3 种线基元。
- GL_LINES:顶点 0 和 1 被视为一条线。顶点 2 和 3 被视为一条线。等等。如果用户指定非偶数个顶点,则多余的顶点将被忽略。
- GL_LINE_STRIP:相邻顶点被视为线。因此,如果通过 n 个顶点,您将得到 n-1 条线。如果用户仅指定 1 个顶点,则绘图命令将被忽略。
- GL_LINE_LOOP:作为线带,只不过第一个和最后一个顶点也用作线。因此,您将获得 n 个输入顶点的 n 条线。如果用户仅指定 1 个顶点,则绘图命令将被忽略。第一个和最后一个顶点之间的线出现在序列中所有先前线之后。
4.1 线宽
TODO:此部分需要填写。
线条被光栅化为宽度均匀的屏幕对齐四边形。
五、基本三角形
三角形是由 3 个顶点形成的图元。它是顶点数量最少的 2D 形状,因此渲染器通常旨在渲染它们。由于它仅由 3 个顶点创建,因此也保证是平面的。
根据对顶点流的不同解释,有 3 种三角形基元:
- GL_TRIANGLES:顶点 0、1 和 2 形成一个三角形。顶点 3、4 和 5 形成一个三角形。等等。
- GL_TRIANGLE_STRIP:每组 3 个相邻顶点形成一个三角形。条带的面方向由第一个三角形的缠绕确定。每个连续的三角形的有效面顺序都会颠倒,因此系统通过以相反的方式测试它来补偿这一点。长度为 n 的顶点流将生成 n-2 个三角形。
- GL_TRIANGLE_FAN:第一个顶点始终保持固定。从那时起,每组 2 个相邻顶点与第一个顶点形成一个三角形。因此,使用顶点流,您会得到一个三角形列表,如下所示: (0, 1, 2) (0, 2, 3), (0, 3, 4) 等。长度为 n 的顶点流将生成 n- 2个三角形。
任何不完整的原语都将被忽略。例如,将 GL_TRIANGLES 与多个不能被 3 整除的顶点一起使用将忽略最后的不完整图元。少于 3 个顶点的渲染将导致无渲染。
以下是一些更具说明性的示例:
GL_TRIANGLES:
Indices: 0 1 2 3 4 5 ...
Triangles: {0 1 2}{3 4 5}
GL_TRIANGLE_STRIP:Indices: 0 1 2 3 4 5 ...
Triangles: {0 1 2}{1 2 3} drawing order is (2 1 3) to maintain proper winding{2 3 4}{3 4 5} drawing order is (4 3 5) to maintain proper winding
GL_TRIANGLE_FAN:Indices: 0 1 2 3 4 5 ...
Triangles: {0 1 2}{0} {2 3}{0} {3 4}{0} {4 5}
5.1 三角面
缠绕顺序决定三角形的面。三角形的面可用于根据正面还是背面来剔除面。即使不使用面剔除,三角形的面也可以在模板测试中使用,并且片段数据的一部分是一个布尔值,表示片段是从三角形的正面还是背面生成。这允许片段着色器根据三角形的面进行不同的处理。
面仅对三角形原始光栅化很重要。所有非三角形基元类型都被视为对正面进行光栅化,并且面剔除仅适用于三角形。
六、四边形
警告:本节介绍已从核心 OpenGL 3.1 及更高版本中删除的旧版 OpenGL API(仅在 OpenGL 3.0 中弃用)。建议您不要在程序中使用此功能。
四边形是 4 个顶点的四边形基元。四个顶点预计共面;如果不这样做可能会导致不确定的结果。
四边形通常被光栅化为一对三角形。 GL 规范没有定义这一点,但它是允许的。由于顶点/几何着色器输出如何在 2 个生成的三角形上进行插值,这可能会导致一些伪影。
GL_QUADS:顶点 0-3 形成一个四边形,顶点 4-7 形成另一个四边形,依此类推。顶点流必须是可被 4 整除的顶点数才能工作。
GL_QUAD_STRIP:与三角形带类似,四边形带使用相邻边形成下一个四边形。对于四边形,一个四边形的第三个和第四个顶点用作下一个四边形的边。所以顶点 0-3 是一个四边形,2-5 是一个四边形,依此类推。长度为 n 的顶点流将生成 (n - 2) / 2 个四边形。与三角形条带一样,每隔一个四边形的四边形的缠绕顺序都会发生变化。
七、邻接原语
TODO:此部分需要填写。
这些是特殊的基元,预计专门与几何着色器 (GS) 一起使用。这些图元为几何着色器提供了更多顶点来处理每个输入图元。通常,当使用上述任何原语时,GS 仅获得基本类型之一。如果您将 GS 与 GL_TRIANGLE_STRIP 一起使用,则 GS 的每次执行只会看到一个特定三角形的 3 个顶点。这些特殊的基元模式允许 GS 访问相邻三角形的顶点数据。
八、补丁
主条目:曲面细分#补丁
GL_PATCHES 原始类型只能在 Tessellation 处于活动状态时使用。它是一个具有用户定义数量的顶点的图元,然后根据控制和评估着色器将其细分为规则的点、线或三角形,具体取决于 TES 的设置。
每个补丁的顶点数是通过使用 GL_PATCH_VERTICES 和一定数量的顶点调用 glPatchParameteri 来定义的,该数量必须小于 GL_MAX_PATCH_VERTICES。如果补丁中的顶点数量为 v,则系统会将每个 v顶点解释为单独的补丁,就像 GL_LINES 和 GL_TRIANGLES 一样。因此,如果您想要类似条带的行为,则需要使用索引。
与从流中获取多个值的其他基元类型一样,不完整的补丁将被忽略。因此,如果您渲染的顶点数量不能被 v 整除,那么最后的顶点将被忽略。
九、激发顶点
输出基元中的顶点之一被指定为“激发顶点”。该顶点对于图元具有特殊含义。例如,当对输出变量使用平面着色时,仅使用来自激发顶点的输出;该基元生成的每个片段都从引发顶点的输出获取输入。
每个基元类型定义顶点流中的哪个索引定义特定输出基元的激发顶点。有一种方法可以更改激发顶点约定(主要是为了 D3D 兼容性):
void glProvokingVertex(GLenum provokeMode);
provokeMode可以是下表列出的两个枚举器之一;默认为 GL_LAST_VERTEX_CONVENTION。该表定义了哪个顶点索引(使用基于一的索引)是特定基元类型的引发顶点。 i 表示正在绘制的图元的从一开始的索引。例如,如果您绘制具有 5 个顶点的 GL_TRIANGLE_FANS,则会产生 3 个图元,因此 i的范围将超过 [1, 3]。因此,当使用最后一个顶点约定时,基元索引 2 的引发顶点将是顶点索引 4(该顶点的从零开始的索引是 3)。
同样,该表使用基于 1 的索引。
Primitive type | GL_FIRST_VERTEX_CONVENTION | GL_LAST_VERTEX_CONVENTION |
---|---|---|
GL_POINTS | i | i |
GL_LINES | 2i - 1 | 2i |
GL_LINE_LOOP | i | i + 1, if i < the number of vertices.1 if i is equal to the number of vertices. |
GL_LINE_STRIP | i | i + 1 |
GL_TRIANGLES | 3i - 2 | 3i |
GL_TRIANGLE_STRIP | i | i + 2 |
GL_TRIANGLE_FAN | i + 1 | i + 2 |
GL_LINES_ADJACENCY | 4i - 2 | 4i - 1 |
GL_LINE_STRIP_ADJACENCY | i + 1 | i + 2 |
GL_TRIANGLES_ADJACENCY | 6i - 5 | 6i - 1 |
GL_TRIANGLE_STRIP_ADJACENCY | 2i - 1 | 2i + 3 |
补丁没有引发顶点,因为 GL_PATCHES 只能与曲面细分一起使用。此过程将路径图元转换为其他类型的图元,因此当光栅化器看到它时,它不再是补丁。 TES 的输出基元确实具有激发顶点,但对于特定线/三角形来说哪个顶点是激发顶点是实现定义的,因此不能依赖。因此,如果不同的基元需要不同的值,则使用平面插值的曲面细分是一个可疑的前景。
十、原始重启
主条目:顶点渲染#Primitive Restart
设置基元重新启动索引将导致在顶点流中达到该索引时重置基元的解释。该索引处的顶点数据将不会被处理,也不会将顶点插入到该索引值的顶点流中。
这篇关于【openGL4.x手册04】基元的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!