Summary: 上周看书学习OpenGLES关于纹理的知识,云里雾里的,看完的感觉是好多东西都明白,涉及到许多opengl的内容,不过照着书里的内容运行了几个Demo,大致算是有些总结,现做一下回顾,上几个例子。
不过这里有一点,这本书看完下一步还是要细研究一下opengl,初步决定从《计算机图形学》这本书入手。好了,之后的事情不多说,先做好当下的事情。
Demo:渲染图片Demo代码
首先是关于纹理的一些概念:
纹理是什么?纹理是一个用来保存图像的元素值的OGE缓存,就是颜色缓存;
当用一个图像初始化一个纹理缓存后,每一个像素就变成了纹理中的纹素(texel);
像素通常表示屏幕上的一个实际的颜色点,纹素是在一个虚拟的坐标系中;
GPU会转换OGE坐标系中的每个点为帧缓存中的真实像素坐标(视口viewport坐标);
转换几何形状数据为帧缓存中的颜色像素的过程叫做点阵化(rasterizing),每个颜色像素叫做片元(fragment);
纹素决定片元的对齐过程,叫做映射(mapping);
取样(sampling)是GPU从每个片元的U、V位置选择纹素的过程;
MIP贴图是为一个纹理存储多个细节的技术,它通过减少GPU的取样来提高渲染的性能;
下面的例子展示了使用一个图片渲染的图片缓存:
在GLKViewController
中,设置OGE的上下文:
1 | GLKView *view = (GLKView *)self.view; |
上面的AGLKContext
是EAGLContext
的子类,setCurrentContext:
是继承自父类的方法,设备当前上下文;
设置提供基础功能:
1 | // Create a base effect that provides standard OpenGL ES 2.0 |
上面的这个constantColor,说是顶点缓冲,这里可能是顶点的颜色缓存,具体应该是与opengl相关的东西,这里这么用着,我改过这里的值,会修改渲染出来图的背景色,暂且认为是渲染用的一个底色吧;
设置当前上下文的“清除颜色”:
1 | // Set the background color stored in the current context |
接下来要进行渲染图片了,大致与渲染一个三角形的过程差不多,可对照开始OpenGLES的探索,同样也是6步:
这里我们自定义了一个AGLKVertexAttribArrayBuffer
封装了关于一些OGE的操作,来说明一下:
1 | // This data type is used to store information for each vertex |
下面是init方法:
1 | // This method creates a vertex attribute array buffer in |
从这里可以看到图形渲染的前三步,生成缓存glGenBuffers
,绑定缓存glBindBuffer
,复制数据到缓存glBufferData
;
下面我们来进入今天的重点:
1 | // Setup texture |
textureWithCGImage:
实现具体细节:
1 | // This method generates a new OpenGL ES texture buffer and |
上面这个方法使用Core Graphics图像的像素数据生成一个新的OGE缓存并初始化它,此方法返回一个不变的AGLKtextureinfo实例。
解释一下这个方法glTexParameteri
,该方法为创建的纹理缓存设置OGE取样和循环模式。如果使用了MIP贴图,第二个参数会被设置成GL_LINEAR_MIPMAP_LINEAR,这会告诉OGE使用与被取样的S,T坐标最接近的纹素的线性插值取样两个最合适的MIP贴图图像尺寸。然后,来自MIP贴图的两个样本被线性差值来产生最终的片元颜色。这里涉及的两个概念需要对opengl进行深入了解。
其中AGLKDataWithResizedCGImageBytes
把指定的cgImmage拖入imageData提供的字节中,Core Graphics把cgImage拖入一个适当大小的Core Graphics上下文中,这个过程会把图像的尺寸调整为2的幂,图像在绘制的时候还会被上下翻转,这是因为OGE的原点在左下角而iOS的实现原点却是在左上角,翻转Y轴确保了图像字节拥有适用于纹理缓存的正确的方向。
1 | static NSData *AGLKDataWithResizedCGImageBytes( |
最后在glk回调中实现真正画图:
1 | - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect |
glEnableVertexAttribArray
,
glVertexAttribPointer
,
glDrawArrays
这里提前熟悉一下这些函数,虽然现在还是对它们不是太理解。
后面的例子就不一一写了,过程笔记都在代码中,分别涉及到一些概念