对opengl的理解
1.从硬件处理流程上;
定点着色器,接受顶点坐标输入,对顶点经过处理,再经过几何着手器,片元着色器等。对要绘制的顶点,得到基本的轮廓和片元,转换成二位平面的坐标,再对片元进行光栅化处理,转换成像素坐标。
片元着色器,对每一个片元,上颜色。
定点着色器和片元着色器是可编程的。定点着色器功能一般是加载顶点坐标,顶点坐标的加载,需要顶点缓冲器和buffer缓存器,即VAO和VBO实现。通过VBO将CPU内存中的顶点数据拷贝到GPU,通过VAO绑定着色器中输入顶点到VBO。
顶点是GPU渲染需要的输入,另外需要指定,渲染的方式三角形四边形等,有了这些GPU就能画出图形的轮廓并且光栅化成片元。顶点着色器输入是三维顶点坐标,输出是变换后的三维顶点坐标,从顶点得到三维轮廓。再经过光栅化片元处理后,能将三维轮廓映射到二维像素片元。
剩下的是需要对片元进行着色,着色一般是需要指定纹理,将读入的纹理映射到绘制的片元上,得到每个片元的颜色。通过加载纹理,将CPU中图像读入到GPU中纹理。纹理怎么和每个片元对应上呢?
每个顶点坐标都和一个纹理坐标对应,这样就能将纹理映射到顶点所绘制的图像上了。那顶点坐标和纹理坐标怎么对应上的?
绘制的时候只绘制了四个顶点,其他填充点都是按照这个四个点同样的方式,按比例处理。
顶点着色器只处理顶点;输入是顶点,输出是变换后的顶点和对应纹理坐标;
片元着色器会处理所有顶点轮廓包含的像素,其处理方式与顶点的类似,都是按同样的方式来处理,所以写程序时可以只用考虑顶点是怎么处理的,这里循环的变量(并行处理)是像素坐标,顶点坐标不同,纹理坐标不同,颜色就不一样。每一个顶点坐标都需指定对应一个纹理坐标。
通过纹理坐标,可以得到对于的纹理像素值,及周围其他橡树点纹理值。所有顶点颜色确定了,经过拉伸缩放映射,所有像素点的颜色也就确定了。片元作色器,输入是纹理坐标,输出是纹理颜色。纹理需要指定缩放方式。
纹理是怎么被读入的,关键的函数;
glGenTexture()
glActiveTexture()
giBindTexture()
glTexParameteri()
glTexImage2D()
glGetUniformLocation()
glUniform1i()
glDeleteTexture()
顶点坐标和纹理坐标是怎么被读入的,VAO,VBO:
glGenVertexArrays
glGenBuffers
glBindBuffer
glBufferData
glBufferSubData
glBindVertexArray(VAO)
glBindBuffer(VBO)
glBufferSubData()
glVertexAttribPointer
glEnableVertexAttribArray
总结,写一个opengl渲染代码,基本流程:
着色器部分:
所有的中心,一切都围绕着色器展开;
顶点着色器:输入顶点属性(顶点坐标,纹理坐标,颜色)/变换矩阵,输出(纹理坐标,颜色等);
片段着色器:输入纹理坐标/颜色,输入uniform纹理,输出颜色。
glprogram:
编译着色器,链接,useprogram等;(调gluniform前一定要先调useprogram)
顶点数组:
VAO,VBO建立。为顶点着色器提供顶点坐标,和对应纹理坐标。
纹理加载:
textureId,glTexImage2D,为片段着色器提供输入纹理;
循环渲染部分:
绑定顶点,(glbindvertexarrays)
绑定纹理,(glactive gibindtexture)
gldraw
flush buffer (前面都是设置状态,这步开始真正执行)
OpenGL最大的问题是,程序出了问题不好检查和调试,比如某个状态错了,结果不对,无法调试得到具体是哪错了,只能逐个排查。而OpenGL内部状态很杂很乱,没有一条很清晰直观的流程,出错的概率有很大,只能平时多理解多积累经验。
主要可能出错地方:
1.顶点属性绑定不对,纹理绑定不对,着色器不对,这些都还比较好排查。
2.流程上,某个地方少设置了某个状态,导致内部状态不对,但是又没报错。这种比较难查。尤其是纹理相关。
主循环渲染需要绑定顶点/绑定纹理,绑定纹理需要先激活对应纹理,否则多纹理时容易出错。
调用gluniform给着色器传数据前需要先调gluseprogram。
主循环需要调用flush buffer,交换缓存才能显示图像;
3.编译着色器程序时要指定上下文,[context makeCurrentContext]
关于帧缓存渲染,帧缓存要有一个附加的texture;如果通过cvpixelbuffer来创建texture,那么帧缓存输出就直接输出到pixelbuffer了。帧缓存使用流程:
创建glgenframebuffer,
绑定glbindframebuffer,
通过pixelbuffer创建texture,CVOpenGLTextureCacheCreateTextureFromImage
给framebuffer附加纹理,glFramebufferTexture2D。
渲染时要先绑定到framebuffer,这样渲染输出就到对应的帧缓存。渲染后解绑,到默认显示缓存,不影响上屏渲染。