(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
之前开发中一直做的图形的上层开发,直接使用OpenGL的机会很少,偶尔也只是自己开发个小的Demo试试手,对于OpenGL没有一个系统的认识。虽然这本书《OpenGL编程指南》已经翻了不少页,却未能真正入门。
这次,经历了一场面试发现不足之后,压力之下,再看起书来,发现很快就人门了,对于OpenGL所能起的作用和心目中的预期样子联系了起来,觉得就应该是这样子的,许多疑惑也豁然开朗。
a. OpenGL中没有对窗口的监听处理
b. OpenGL中没有对用户输入输出的处理
c. OpenGL中没有提供表达三维物体模型的处理
d. OpenGL中没有读取图像文件的处理
OpenGL提供的是基础几何图元geometric primitive(包括点、线、三角形 和 Patch块)。
通过OpenGL不能做什么,就可以比较清楚的知道,OpenGL和三维模型是没有必然关系的,它提供的是对独立的空间几何图元向屏幕的渲染过程,渲染过程主要是通过调用显卡中的计算能力来做计算,并把计算后的各屏幕像素显示结果向屏幕输出。
也基于次,当理解OpenGL的使用时,考虑对OpenGL的调用,主要考虑它如何利用gpu的算力进行渲染处理。对于模型包装、窗口响应、输入响应等都是需要外围来做的事情。
这样这个库的外部界限就清楚了,功能相对独立的OpenGL的可专业性、可移植性、通用性等都可以很好的保证了。
也就可以想出来为什么有glut库了,为什么glut库不在opengl的基本库中—因为glut提供的模型包装、窗口响应和输入响应都不属于OpenGL提供服务的范畴。
OpenGL是一种API,对图形硬件设备特性进行访问的软件库。
它使用客户端-服务端的形式实现,编写的应用程序可以看作客户端,而显卡中厂商提供的OpenGL实现支持可以看作服务端。
显卡在图像有内存中的三角面片数据,转换到屏幕中去,显卡扮演的作用有:
a. 使用vertex shader等着色器程序对输入的图元数据(点、线、三角形、Patch)执行计算操作,包括位置、颜色、渲染属性(使用到显卡的shader)
b. 为光栅化提供计算支持:三角面片转换采样成屏幕像素
c. 使用fragment shader片元/像素着色器程序,对像素进行处理,计算出最终颜色、位置(用到显卡的shader)
d. 把屏幕像素对应的颜色信息输出到屏幕中去(用到显卡的ROPs/TMUs)
OpenGL客户端程序扮演的作用是对上面的调用者和数据组织者:
下面是显卡的参数的几个重要的指标:**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造型的外壳或皮肤。
着色器脚本的执行是在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的接口方法传递给显卡流处理调用使用。
a. 物体显示在屏幕的过程?
主要核心步骤简化来看:
建立物体的图元等信息–>进行顶点着色计算,计算投影坐标等–>基于屏幕坐标剪裁物理位于投影视口外的部分–>光栅化,三角形坐标颜色等离散采样–>基于深度/遮挡情况确定像素显示
b. 如何把彩色的物体改成灰色?
c. 着色器有那些,分别的作用?
新版本,程序渲染,至少需要vertex shader和fragment shader,主要功能分别为:一个是确定屏幕坐标位置,一个是确定光栅话后屏幕像素点的颜色。
另外还有一些其它着色器:细分着色器(处理Patch数据,添加新的Patch几何图元)、几何着色器(可以改变几何图元、添加几何图元),计算着色器(可以做通用的计算)。
(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)