0
点赞
收藏
分享

微信扫一扫

OpenGL ES学习阶段性总结

前言

概念

帧缓存:接收渲染结果的缓冲区,为GPU指定存储渲染结果的区域。
帧缓存可以同时存在多个,但是屏幕显示像素受到保存在前帧缓存(front frame buffer)的特定帧缓存中的像素颜色元素的控制。
程序的渲染结果通常保存在后帧缓存(back frame buffer)在内的其他帧缓存,当渲染后的后帧缓存完成后,前后帧缓存会互换。(这部分操作由操作系统来完成)
前帧缓存决定了屏幕上显示的像素颜色,会在适当的时候与后帧缓存切换。
- (BOOL)presentRenderbuffer:(NSUInteger)target;
Core Animation的合成器会联合OpenGL ES层和UIView层、StatusBar层等,在后帧缓存混合产生最终的颜色,并切换前后帧缓存;
OpenGL ES坐标是以浮点数来存储,即使是其他数据类型的顶点数据也会被转化成浮点型;
framebuffer object 通常也被称之为 FBO,它相当于 buffer(color, depth, stencil)的管理者,三大buffer 可以附加到一个 FBO 上。我们是用 FBO 来在 off-screen buffer上进行渲染。

GPU运算和CPU运算是分开的。(如果需要同步返回,可以使用glFinish
glReadPixels 从图形硬件中复制数据,通常通过总线传输到系统内存。此时,应用程序将被阻塞,直到内存传输完成。
如果指定的像素布局与图像硬件的本地排列不同,数据进行重定格式会产生额外的性能开销。
在使用完缓存后,可以调用glBindBuffer把array绑定的对象重置为0,防止被其他地方误用;(注意,纹理对象需要在使用完后,再glBindTexture绑定为0)
CAEAGLLayer会与OpenGL ES的帧缓存共享它的像素颜色仓库。(这也是为什么我们想让绘制的内容显示到屏幕时,需要重载UIView的+layerClass方法,返回一个CAEAGLLayer实例。)
eaglLayer的属性kEAGLDrawablePropertyRetainedBacking为NO表示,不要试图保留任何以前绘制的图像留作以后重用。
在自定义UIView实现渲染时,需要在调整视图大小的回调中(layoutSubviews),调用-renderbufferStorage:fromDrawable: 方法来调整视图的尺寸,从而匹配层的新尺寸。
这个尺寸大小可以用glGetRenderbufferParameteriv()方法来获取;
glGetError返回错误,如果有多个错误,每次返回一个,需要多次调用。
CoreGraphics负责创建显示到屏幕上的数据模型,QuartzCore(CoreAnimation –> OpenGLES)负责把CoreGraphics创建的数据模型真正显示到屏幕上。

理想状态下,缓存生成后就不发生变化;
生成、初始化和删除缓存需要耗费时间来同步GPU和CPU,大多数情况下是CPU等待GPU,因为GPU在删除缓存之前必须等待该缓存相关的指令全部执行完毕;
故而一个程序在每帧都进行生成和删除缓存会有严重的性能消耗。
glDeleteFramebuffers
glDeleteRenderbuffers
glDeleteBuffers

坐标

齐次坐标表示法:用n+1维向量表示n维向量。
齐次坐标归一化,最后一个坐标为1。

整数才能归一化,浮点数无效。


万向节死锁:Wiki解释

纹理

纹理坐标系:S和T组成的2D轴。(0.0到1.0,还有1D和3D的纹理坐标系,R,S,T轴)
位图(bitmap):一系列表示开启和关闭像素值的0和1。
像素数据 != 位图。
像素图(pixmap):类似位图,每个像素需要一个以上的存储位来表示。

图像数据在内存中很少以紧密的形式存在,出于性能的考虑,每一行都该从特定的字节对齐地址开始。
OpenGL 采用4个字节的对齐方式。
存储大小 != 像素宽度 * 高度值。
应该是每行宽度 * 高度值,每行宽度可能会有填充的空字节。

1、纹理过滤

GL_TEXTURE_MIN_FILTER 表示多个纹素对应单个像素的时候
GL_TEXTURE_MAG_FILTER表示单个纹素对应多个像素的时候
GL_LINEAR 表示线性插值
GL_NEAREST 表示最近

2、纹理环绕

GL_TEXTURE_WRAP_S 表示S轴超过坐标系范围
GL_TEXTURE_WRAP_T 表示T轴超过坐标系范围
GL_CLAMP_TO_EDGE 表示取纹理边缘
GL_REPEAT 表示重复纹理
GL_MIRRORED_REPEAT 表示镜像重复纹理

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

OpenGL ES推荐使用尺寸为2的幂的纹理,其他纹理也支持,但是性能上会有额外的消耗。

3、各向异性过滤

非OpenGL标准的扩展支持,GL_EXT_texture_filter_anisotropic。

4、MIP纹理

glGenerateMipmap生成。

glPixelStorei 方法可以改变或者恢复像素的存储方式
GL_PACK_ALIGNMENT
GL_UNPACK_ALIGNMENT
默认4字节对齐,即一行的图像数据字节数必须是4的整数倍,即读取数据时,读取4个字节用来渲染一行,之后读取4字节数据用来渲染第二行。对RGB 3字节像素而言,若一行10个像素,即30个字节,在4字节对齐模式下,OpenGL会读取32个字节的数据,若不加注意,会导致glTextImage中致函数的读取越界崩溃。

当着色器计算出来一个完全不透明的像素颜色时,可以简单的替换帧缓存中对应位置的颜色,也可以通过glEnable(GL_BLEND)来开启混合功能,并通过glBlendFunc设置混合函数。
也可以通过gl_LastFragData,自己计算混合后的颜色;
也可以通过多重纹理来实现。

多通道渲染:多次读写像素颜色缓存来创建一个最终的渲染结果的过程;
(举例:开启混合,只有纹理单元0,先绑定为纹理1,绘制;再绑定纹理2,绘制;再绑定纹理3,绘制;这样得到最后的结果,是3张图片混合后的结果)

glTexImage2D (1D和3D在ES2的头文件没找到,3D可以在ES3找到)加载纹理,纹理对象需要通过glGenTexture和glDelete 来创建和销毁。
glTexSubImage2D 是替换纹理,可以替换部分,也可以替换全部纹理,速度比重新加载更快。

glCopyTexImage2D 可以用颜色缓冲区加载数据。
glCopyTexSubImage2D 同上。

在销毁纹理的时候,如果不确定对象索引是否是纹理(比如作为参数传递),glIsTexture来判断。

纹理高级知识

1、矩形纹理

GL_TEXTURE_RECTANGLE不能进行MIP贴图,只能加载glTexImage2D的第0层。 纹理坐标不是标准化的,纹理坐标实际上是对像素寻址,而不是从0到1的范围覆盖图像的。

2、立方体纹理

由6个正方形的2D图像组成的纹理。

3、多重纹理

同时使用两个或者更多纹理。

4、点块纹理

在一个顶点上应用纹理。

基本图形光栅化

1、直线

暴力法:微分方程,带入坐标,取整求解(x,y);
中点画线法:假设斜率在0~1之间,对于P(x, y),下一个点只能在P1或者P2,求P1P2中点M,直线与P1P2交点Q,判断M、Q的上下关系;
bresenham画线法:假设斜率在0~1之间,对于P(x, y),下一个点只能在P1或者P2,直线与P1P2交点为Q,判断P1Q和QP2的大小关系;

2、圆

圆具有八对称性,对于一个愿只需要绘制1/8的圆弧;
圆的bresenham,用D(P)来表示点P到原点的距离平方和圆的半径平方之差,
di = D(Si) + D(Ti)。

超级宝典遇到的问题

1、gltReadTGABits错误

2、Invalid storage qualifiers 'in' in global variable context

3、不支持的version

举报

相关推荐

0 条评论