opengl 相关概念

wanghualin0 2014-05-19

一个固定流水线:

1,顶点变换(VertexTransformation)

这里一个顶点是一个信息集合,包括空间中的位置、顶点的颜色、法线、纹理坐标等。

通常进行如下工作:

·顶点位置变换

·为每个顶点计算光照

·纹理坐标的生成与变换

2,图元组合和光栅化(PrimitiveAssemblyandRasterization)

输入:是变换后的顶点和连接信息(connectivityinformation)。

输出:

·帧缓存中片断的位置

·在顶点变换阶段计算出的信息对每个片断的插值

连接信息告诉流水线顶点如何组成图元(三角形、四边形等)。

此阶段还负责视景体(viewfrustum)裁剪和背面剔除。

光栅化决定了片断(fragment),以及图元的像素位置。

片断是指一块数据,用来更新帧缓存(framebuffer)中特定位置的一个像素。

一个片断包含颜色,法线和纹理坐标等属性,这些信息用来计算新的像素颜色值。

这个阶段利用在顶点变换阶段算出的数据,结合连接信息计算出片断的数据。

3,片断纹理化和色彩化(FragmentTexturingandColoring)

输入:是经过插值的片断信息。

输出:是片断的颜色值以及深度信息。

插值得到的纹理坐标和一个颜色值,本阶段用来和纹理元素进行组合。

此外,这一阶段还可以进行雾化处理。

4,光栅操作(RasterOperations)

输入:像素位置和片断深度和颜色值

在这个阶段对片断进行一系列的测试,包括:

·剪切测试(scissortest)

·Alpha测试

·模版测试

·深度测试

如果测试成功,则根据当前的混合模式(blendmode)用片断信息来更新像素值。

取代固定的功能(ReplacingFixedFunctionality)

现在的显卡允许程序员自己编程实现上述流水线中的两个阶段:

·顶点shader实现顶点变换阶段的功能

·片断shader替代片断纹理化和色彩化的功能

顶点处理器用来运行顶点shader(着色程序)。

顶点shader的输入是顶点数据,即位置、颜色、法线等。

一个顶点shader可以编写代码实现如下功能:

·使用模型视图矩阵以及投影矩阵进行顶点变换

·法线变换及归一化

·纹理坐标生成和变换

·逐顶点或逐像素光照计算

·颜色计算

一旦你使用了顶点shader,顶点处理器的所有固定功能都将被替换。

顶点shader至少需要一个变量:gl_Position,通常要用模型视图矩阵以及投影矩阵进行变换。

顶点处理器并不知道连接信息,因此这里不能执行拓扑信息有关的操作。它只是操作顶点而不是面。

片断处理器可以运行片断shader,这个单元可以进行如下操作:

·逐像素计算颜色和纹理坐标

·应用纹理

·雾化计算

片断处理器的输入是顶点坐标、颜色、法线等计算插值得到的结果。

片断处理器只对每个片断独立进行操作,并不知道相邻片断的内容。

一个片断shader有两种输出:

·抛弃片断内容,什么也不输出

·计算片断的最终颜色gl_FragColor,当要渲染到多个目标时计算gl_FragData。

片断shader不能访问帧缓存,所以混合(blend)这样的操作只能发生在这之后。

每个shader类似一个C模块,首先需要单独编译(compile),然后一组编译好的shader连接(link)成一个完整程序。

glCreateProgram()

glAttachShader()

glAttachShader()

glLinkProgram()

glUseProgram()

VBO是VertexBufferObject,用于存储顶点坐标/顶点uv/顶点法线/顶点颜色

VBO其实就是显卡中的显存,将要绘制的顶点数据缓存在显存中,这样就不需要将要绘制的顶点数据重复从CPU发送到GPU。

IBO为索引缓冲区

VAO是VertexArrayObject

VAO则是一个容器,可以包括多个VBO,它类似于以前的calllist,由于它进一步将VBO容于其中,所以绘制效率将在VBO的基础上更进一步。

取代以前的glBegin/glEnd,显示列表,顶点数组。

最后用VAO将多个VBO,IBO绑定到一起。

一个常规的网格模型就是VAO.attach(PositionVBO,TexcoordVBO,NormalVBO,IBO)

以下为VBO的创建,分配100字节的空间,未初始化:

GLuintvbo;

glGenBuffers(1,&vbo);

glBindBuffer(GL_ARRAY_BUFFER,vbo);

glBufferData(GL_ARRAY_BUFFER,100,0,GL_STATIC_DRAW);

以下为IBO的创建,分配100字节的空间,未初始化:

GLuintibo;

glGenBuffers(1,&ibo);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibo);

glBufferData(GL_ELEMENT_ARRAY_BUFFER,100,0,GL_STATIC_DRAW);

以下为VAO的创建:

GLuintvao;

glGenVertexArrays(1,&vao);

glBindVertexArray(vao);

向VBO提交数据,无论提交全部还是部分都用这个,ibo类似

glBindBuffer(GL_ARRAY_BUFFER,vbo);

glBufferSubData(GL_ARRAY_BUFFER,size,len,src);

MapBuffer和BufferSubData/BufferData同样是向server端“提交”数据,但是方法却是截然不同的。MapBuffer通过cilent端映射server端的数据存储,然后范围一个映射到客户端内存的指针,这时候你进行的工作是一种CPU_write/CPU-read的工作;而BufferSubData/BufferData则是一种GPU-read的过程,两者是很大的差距的。

当数据量比较小的时候,BufferSubData是远远超过MapBuffer的效率的,但是当数据足够大的时候,MapBuffer会压倒性的超越BufferSubData,据测试这个值大概是32k

参考:

http://blog.csdn.net/racehorse/article/details/6593719

http://www.cnblogs.com/eggine/archive/2012/12/07/2807245.html

相关推荐