OpenGL 编程指南(第八版)学习笔记——10 几何着色器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wlk1229/article/details/81838570

OpenGL 编程指南学习资料以及我整理的代码下载地址https://pan.baidu.com/s/1bqrcspD

文中提到的代码为下载文件中的“OpenGL编程指南 VS2015代码.zip”文件,代码也可以到github上下载:https://github.com/Kylewlk/OpenGL-Programming-Guide-8th-Edition-Code

10 几何着色器

几何着色器位于绘制流水线中图元装配前的一个步骤,是一个可选步骤,如果启用了几何着色器,几何着色器需要输出最终绘制的图元。几何着色器输入是图元,其输出也是图元,几何着色器可以根据输入的图元,修改图元,增加图元,删减图元等等。

 

处理步骤

  1. 接收点着色器或细分计算着色器输出的图元
  2. 对每个图元执行单独执行几何着色器,图元点的数据存放在gl_in[]数组中
  3. 每个图元可以执行多次几何着色器,执行次数由layout(invocations=n) in控制,执行时gl_InvocationID记录了当前执行第几次。
  4. 每次执行时需要用EmitVertex输出点,并用EndPrimitive组装成最后图元并输出到下一步
  5. 继续绘制

 

例子,对应代码10.3.1-01Tetrahedron,例子利用几何着色器将四个点的GL_LINES_ADJACENCY图元组装成一个四面体,输出结果如下:

 

Transform Feedback

第五章中有讲解关于如何使用Transform Feedback,这里主要讲的是如何将几何着色器的输出存到Transform Feedback中。

 

几何着色器输出如果要存放得到多个GL_TRANSFORM_FEEDBACK_BUFFER中,需要两个地方设置。

1. 着色器程序连接前需要通过函数glTransformFeedbackVaryings设置Transform Feedback需要记录的数据并用gl_NextBuffer来选择缓存。

2. 在几何着色器中通过EmitStreamVertex/EndStreamPrimitive函数传入buffer的索引。

 

查询Transform Feedback记录

  1. 通过glGenQueries创建查询对象
  2. 将glBeginQueryIndexed和glEndQueryIndexed“包住”需要查询的绘制。
  3. 通过glGetQueryObjectiv获取查询结果

 

绘制Transform Feedback

 

  1. 通过glBindBuffer(GL_ARRAY_BUFFER, fb)将Transform Feedback缓存绑定到VAO
  2. 通过函数glDrawTransformFeedbackStream/glDrawTransformFeedback可以自动绘制Transform Feedback中所有的顶点。
  • 代码:10.4-01TransformFeedback,程序通过几何着色器一次输出了两个四面体的数数据到Transform Feedback中,然后绘制,结果:

 

多视口绘制

  1. 通过函数glViewportIndexed*创建多个视口
  2. 在几何着色器中通gl_ViewportIndex指定当前图元输出的视口。几何着色器中可以通过invocations的配置多次执行几何着色器,也可以通过循环增加输出图元的次数,每次gl_ViewportIndex设置不同的视口

 

例子,代码:10.6-01FourViewport,程序一次绘制了一个模型的4个方向的图形到4个视口,结果如下:

 

分层渲染

分层渲染可以一次渲染数组纹理的多个切面,也可以渲染到Cube纹理的多个面,渲染过程如下:

  1. 创建帧缓存对象FBO
  2. 创建数组纹理
  3. 通过函数glFramebufferTexture将数组纹理绑定到帧缓存渲染
  4. 渲染帧缓存在几何着色器中通过gl_Layer设置渲染到帧缓的层。

 

这里有两个地方需要注意,1. 通过glFramebufferTexture绑定附件的帧缓存为分层缓存,其所有的附件都必须是分层的,包括深度缓存和模板缓存;2. 几何着色器需要通过invocations设置执行次数,每次设置gl_Layer,不可以在一次执行执行中多次设置不同的gl_Layer。

  • 代码10.6.2-01LayerRender,程序通过分层渲染生成了一个两个片面的数组纹理,并将两个片面绘制在窗口上,结果:

猜你喜欢

转载自blog.csdn.net/wlk1229/article/details/81838570