OpenGL编程指南-理解入门笔记

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)

参考:
《OpenGL编程指南-第8版》
http://www.zeinb.net/jishu/1468.html
https://www.techpowerup.com/forums/threads/rops-and-tmus-what-is-it.227596/
https://en.wikipedia.org/wiki/Shader
http://www.cfan.com.cn/2017/0703/128574.shtml

1. 前言

之前开发中一直做的图形的上层开发,直接使用OpenGL的机会很少,偶尔也只是自己开发个小的Demo试试手,对于OpenGL没有一个系统的认识。虽然这本书《OpenGL编程指南》已经翻了不少页,却未能真正入门。
这次,经历了一场面试发现不足之后,压力之下,再看起书来,发现很快就人门了,对于OpenGL所能起的作用和心目中的预期样子联系了起来,觉得就应该是这样子的,许多疑惑也豁然开朗。

2. OpenGL中没有什么

a. OpenGL中没有对窗口的监听处理
b. OpenGL中没有对用户输入输出的处理
c. OpenGL中没有提供表达三维物体模型的处理
d. OpenGL中没有读取图像文件的处理
OpenGL提供的是基础几何图元geometric primitive(包括点、线、三角形 和 Patch块)。
通过OpenGL不能做什么,就可以比较清楚的知道,OpenGL和三维模型是没有必然关系的,它提供的是对独立的空间几何图元向屏幕的渲染过程,渲染过程主要是通过调用显卡中的计算能力来做计算,并把计算后的各屏幕像素显示结果向屏幕输出。
也基于次,当理解OpenGL的使用时,考虑对OpenGL的调用,主要考虑它如何利用gpu的算力进行渲染处理。对于模型包装、窗口响应、输入响应等都是需要外围来做的事情。
这样这个库的外部界限就清楚了,功能相对独立的OpenGL的可专业性、可移植性、通用性等都可以很好的保证了。
也就可以想出来为什么有glut库了,为什么glut库不在opengl的基本库中—因为glut提供的模型包装、窗口响应和输入响应都不属于OpenGL提供服务的范畴。

3. OpenGL与显卡的配合

OpenGL是一种API,对图形硬件设备特性进行访问的软件库。
它使用客户端-服务端的形式实现,编写的应用程序可以看作客户端,而显卡中厂商提供的OpenGL实现支持可以看作服务端。
显卡在图像有内存中的三角面片数据,转换到屏幕中去,显卡扮演的作用有:
a. 使用vertex shader等着色器程序对输入的图元数据(点、线、三角形、Patch)执行计算操作,包括位置、颜色、渲染属性(使用到显卡的shader)
b. 为光栅化提供计算支持:三角面片转换采样成屏幕像素
c. 使用fragment shader片元/像素着色器程序,对像素进行处理,计算出最终颜色、位置(用到显卡的shader)
d. 把屏幕像素对应的颜色信息输出到屏幕中去(用到显卡的ROPs/TMUs)
OpenGL客户端程序扮演的作用是对上面的调用者和数据组织者:

  1. 为显卡介绍和装载数据:把图元数据(点、线、三角形、Patch)、颜色数据传递给显卡
  2. 为显卡准备shader程序:把着色器程序传递到显卡
  3. shader装配,把shader之间能够传递的变量告知显卡
  4. 按照OpenGL设定的渲染管线rendering pipeline顺序,调用显卡的shader处理,间或其它处理

下面是显卡的参数的几个重要的指标:**Shader, ROPs/TMUs(Raster Operations Units/Texture Mapping Units),Pixel fillrate, Texture fillrate, ** :
Shader: 着色器数目
实际指GPU所含流处理器核心数量,这些流处理器已经远不是最初的GPU着色器,而是具有一定的通用数据处理能力(可以设计用于并行计算)。

Pixel fillrate, Texture fillrate: 像素填充率,纹理填充率
目前它实际指的是能够输出到屏幕的像素/纹理数量,目前这一指标已经与所谓的Shader无关了,只考虑ROPs/TMUs(光栅化处理单元/纹理单元)和运行频率,显示的数据其实分别为光栅化处理单元和纹理单元与运行频率的乘积。

ROPs/TMUs: 光栅化处理单元/纹理单元
Raster operations pipeline is one of the final steps in the rendering process of modern 3D accelerator boards.
A TMU is able to rotate, resize, and distort a bitmap image --performing texture sampling.
光栅化处理单元将计算的顶点数据等转换为符合分辨率的点,同时删除不用显示的部分。
纹理单元的责任就是将纹理填充到架构中,形成可在屏幕平面显示的—3D造型的外壳或皮肤。

4. Shader脚本的执行

着色器脚本的执行是在GPU的的shader流处理器中做的。
一个GPU拥有的shader数量通常在成百到几千个不等,这样就相当于并行量是非常巨大的,就相当与有这么多个处理器内核在并行处理。
例如我使用的2012年的macbookpro笔记本,它的显卡是Intel HD Graphics 4000,该显卡的配置为:
参考https://www.techpowerup.com/gpu-specs/hd-graphics-4000.c1266
Clock Speeds:Boost Clock 1300 MHz
Render Config:Shading Units 128 / TMUs 16 / ROPs 2
Theoretical Performance:FP32 (float) performance 332.8 GFLOPS
Shader计算时,有128个核心在计算,总线带宽是64位(可以进行2个32位的计算),理论速度 1300MHZ * 128 * 2,每秒可以有332.8G个float运算。

对于需要并行的处理,数据的独立性要求的比较高,所以可以看出shader程序所处理各个顶点着色时、处理各个像素着色时都是互相独立处理的,不存在顶点着色、像素着色顺序上的依赖。

另外是硬件级的并行,不会像线程进程那样的额外开销,但程序一般也不会太复杂,毕竟gpu指令集一般不会像cpu支持的指令集那么多。另外硬件级的并行,脚本程序相当于一个独立的程序在做,用的void main()做入口,变量传入传出、buffer传入也都是通过OpenGL的接口方法传递给显卡流处理调用使用。

5. 回过头来看几个常见问题

a. 物体显示在屏幕的过程?
主要核心步骤简化来看:
建立物体的图元等信息–>进行顶点着色计算,计算投影坐标等–>基于屏幕坐标剪裁物理位于投影视口外的部分–>光栅化,三角形坐标颜色等离散采样–>基于深度/遮挡情况确定像素显示

  • 首先物体的几何模型需要建立起来,通过OpenGL的几何图元来表达出来。
  • 几何图元进行顶点着色阶段(包括Vertex Shader、细分着色器、Geometry Shader)的处理,基于视口信息变换,会计算出相关的投影屏幕坐标信息
  • 图元装配,把点与图元(点、线、三角形,Patch)关联起来
  • 基于投影坐标进行初步的裁剪,把屏幕viewport之外的裁剪掉
  • 之后会把几何图元三角面片进行光栅化(面片会进行采样),光栅化之后会进行Fragment Shader程序处理,计算出相关的像素颜色和深度
  • 再进行深度测试基于深度(也即遮挡情况)来确定像素的显示。

b. 如何把彩色的物体改成灰色?

  • 方法一:使用像素着色器Fragment shader,把rgb值换算成灰度值对应的rgb值输出,从而直接从像素级把物体的颜色改变掉
  • 方法二:如果是使用顶点颜色决定三角面片颜色的化,可以在vertex shader时,把rgb值换算为灰度值对应的rgb值作为输出颜色,经过光栅化面片上的点和颜色会离散采样后输出给fragment shader使用。
  • 方法三:如果是一个图片的颜色的化,可以预处理图片存储的rgb信息,在传入texture buffer前计算修改为灰度图。加载texture时,使用这个灰度图片的buffer。

c. 着色器有那些,分别的作用?
新版本,程序渲染,至少需要vertex shader和fragment shader,主要功能分别为:一个是确定屏幕坐标位置,一个是确定光栅话后屏幕像素点的颜色。

  • Vertex shader一般来说,通常是把输入投影矩阵*模型坐标,得出顶点投影坐标;另外也要把顶点对应的纹理坐标输出。
  • Fragment shader一般来说,通常是使用纹理sample和纹理坐标,获取出对应的纹理颜色作为输出。

另外还有一些其它着色器:细分着色器(处理Patch数据,添加新的Patch几何图元)、几何着色器(可以改变几何图元、添加几何图元),计算着色器(可以做通用的计算)。

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春夜喜雨

稀罕你的喜欢!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值