文章目录
第六章 纹理
6.9 纹理视图
- OpenGL可以再多个纹理之间共享一个数据存储,每个都有自己的格式和维数;首先,创建一个纹理,用数据存储函数(例如glTexStorage2D())初始化它的数据存储;接下来,创建父纹理的texture view;这为第一个纹理分配的下层存储增加引用计数
- void glTextureView(GLuint texture, GLenum target, GLuint origTexture, GLenum internalFormat, GLuint minLevel, GLuint numLevels, GLuint minLayer, GLuint numLayers)
为名称为origTexture的纹理创建新视图,名称必须是已经存在的纹理的名称,且对应纹理的数据已经初始化且不变
当创建已经存在的纹理的视图时,新纹理的目标必须与原始纹理的目标兼容
texture被关联到origTexture存储的数据,并且重新变为目标用target设置的不变纹理
纹理的内部格式用internalFormat设置,它必须与origTexture的内部格式兼容
minLevel和numLeves分别为新纹理设置第一个mipmap层和mipmap层的数据
minLayer和numLayers设置关联到texture数组纹理的第一个层和层的数目
- 纹理视图的纹理目标兼容性:
- 纹理视图的内部格式兼容性
6.10 压缩纹理
-
压缩是减少存储和传输信息需要的数据量的机制
-
压缩算法主要分为两类,有损和无损
-
OpenGL中压缩数据有两种方法:
- 让OpenGL为你压缩;在这种情况下,需要提供压缩数据并设置压缩内部格式;OpenGL将获取未压缩的原始数据,并尝试压缩它们;这是一个实时过程,OpenGL将快速压缩数据,导致压缩纹理质量低
- 把压缩纹理数据送给OpenGL的方法;是离线压缩(例如,在程序运行前),把压缩好的数据直接传给OpenGL;使用这个方法,可以花尽可能多的时间来获取需要的质量,而不用牺牲运行时性能
-
OpenGL的压缩一定支持两个格式组,分别是RGTC(红绿纹理压缩)和BPTC(分块纹理压缩);这两个格式都是基于块的,以4x4纹素块为单元存储纹理;这意味着它们用4x4纹素块存储图像,每个都被独立压缩;这样的块在从主存传到显卡纹理缓存时可以很容易的被硬件解压缩
-
为了实现使用压缩格式的纹理的不可变存储,可以使用glTexStorage1D/2D/3D()函数,也可以使用glCompressedTexImage1D/2D/3D()为纹理创建可变存储
-
void glCompressedTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, const void* data)
-
void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
-
void glCompressedTexImage3D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data)
为使用压缩内部格式的纹理实现可变存储;释放绑定到target的当前纹理单元级数level的任意现有数据量,并在它的位置实现新的存储
internalFormat设置纹理数据的格式,它必须是支持的压缩内部纹理格式
width设置新存储的宽度,单位是纹素
data设置纹理中使用的压缩图像数据在内存中的地址,以及imageSize是内存中数据的大小
border是保留值,必须是零
设置压缩数据后,数据的绝对大小是由压缩格式确定的;所有的压缩图像数据函数都有设置这个大小的参数,单位是字节
应用程序必须确保这个大小是正确的,并且应用程序给OpenGL的数据选择是压缩格式的有效形式;实现纹理对象的存储后,可以使用下面的函数更新纹理部分
- void glCompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data)
- void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
- void glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data)
更新绑定到target目标纹理单元的纹理level中的压缩纹理数据
xoffset和width设置纹理数据的x轴偏移和宽度,单位是纹素
对于2维和3维纹理,yoffset和height设置纹理数据的y轴偏移和高度
对于1维数组纹理,yoffset和height设置要跟新的开始切片和切片的数目
对于3维纹理,zoffset和depth设置纹理数据的z轴偏移和深度
对于2维数组纹理,zoffset和depth设置要更新的开始切片和切片的数目
format设置压缩图像数据的格式并且必须匹配纹理的内部格式
imageSize和data设置用来更新纹理数据的大小和位置
6.11 滤波
6.11.1 线性滤波
- 线性滤波是用坐标来从离散采样信号选择临近样本的技术,并且使用原始信号的线性近似来代替这些信号
- OpenGL把传给它的浮点坐标看做一个浮点数,寻找和它最近的两个样本,分别使用到这两个点的距离为每个样本创建权重,然后使用这些权重来创建它们的加权平均值;因为线性重采样是可以分离的,OpenGL可以首先在1维上应用这个技术,然后在第二维上再次使用来重构2维图像,甚至对于3维纹理第三次使用
- 线性滤波不但可以用来在1维、2维和3维纹理上从一个样本到临近样本平滑过滤,也可用来混合从纹理中临近mipmap级采样的纹素
- OpenGL从它需要的mipmap级来选择样本,并且计算的结果通常是一个带分数部分的浮点值;这与使用分数纹理坐标一样,用来滤波空间临近的纹素;两个最近的mipmap用来重建一对样本,并且lod计算的分数部分用来加权平均两个采样
- 所有滤波选项都要用OpenGL采样器对象的纹理滤波模式来控制;采样器对象表示一组控制纹素从纹理中读取的一组参数; 这些参数中有两个:GL_TEXTURE_MAG_FILTER和GL_TEXTURE_MIN_FILTER,控制OpenGL如何过滤纹理
- GL_TEXTURE_MAG_FILTER在纹理放大时使用,也就是说需要LOD是比最高分辨率mipmap级更高分辨率(默认级别0)的LOD,表示mipmap计算生成了一个小于等于0的级;因为在放大时,只有一个mipmap级被使用,只对它提供两个选项:GL_NEAREST和GL_LINEAR;第一个表示禁用滤波,返回样本位置最近的纹素;第二个启用线性滤波;纹理缩小时也就是mipmap生效的地方
6.11.2 使用和生成mipmap
-
在对纹理数据采样时,当视点与纹理的距离突然改变很大时,被采样的纹理在一定转换点处也会突然改变,为了消除这个效果,可以预先滤波纹理图,并且把滤波后的图像存储为完整分辨率图像的连续低分辨率版本,这称为mipmap
-
使用mipmap时,OpenGL根据被映射对象的大小(单位是像素),自动决定使用纹理的哪个分辨率级;随着对象的图像变小,纹理图的大小也将减少
-
mipmap需要一些额外的计算和纹理存储空间;但是如果不使用mipmap,那么映射到更小图像上的纹理将随着物体移动而闪烁
-
参数GL_TEXTURE_MIN_FILTER控制在mipmap级数大于0时如何重建纹素; 这个参数有6个设置:
- GL_NEARSET
- GL_LINEAR 这前两个与用于放大的相同,选择这两个模式时禁用mipmap,OpenGL将使用纹理的基级数(0级);其他四个模式启用mipmap,控制mipmap如何使用
- GL_NEAREST_MIPMAP_NEAREST
- GL_NEAREST_MIPMAP_LINEAR
- GL_LINEAR_MIPMAP_NEAREST
- GL_LINEAR_MIPMAP_LINEAR 这四个模式由两部分组成,结构是GL_{A}MIPMAP{B}; 第一部分{A}控制来自每个mipmap级的纹素的构造并且与GL_TEXTURE_MAG_FILTER设置一样工作;第二个{B}控制mipmap级之间的采样混合,当它是NEAREST时,只使用最近的mipmap级,当它是LINEAR则表示最近的两个mipmap线性插值
-
为了使用mipmap,必须提供纹理在最大尺寸和1x1图之间的所有大小是2的幂的纹理级别;如果不想使用mipmap到1x1纹理的所有变化,可以将GL_TEXTURE_MAX_LEVEL的值设置为提供的最大级数,并且OpenGL不考虑更进一步的级别
-
OpenGL提供一个函数,在应用程序的控制下为纹理自动生成所有的mipmap,这个函数是glGenerateMipmap()
-
void glGenerateMipmap(GLenum target)
为target关联的纹理图像生成一组mipmap;target可以是GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D、GL_TEXTURE_1D_ARRAY、GL_TEXTURE_2D_ARRAY或者GL_TEXTURE_CUBE_MAP之一
构建的mipmap级由GL_TEXTURE_BASE_LEVEL和GL_TEXTURE_MAX_LEVEL控制
6.11.3 计算mipmap级别
- 计算特定像素的纹理级别时,其结果取决于纹理图像和纹理映射的多边形大小比例因子ρ,再定义第二个值λ,且λ=log2ρ + lod(bias)。( 因为纹理图像可以是多维的,所以声明ρ是所有维的最大比例因子是很重要的)
- lod(bias)是采样器的细节层次偏移,使用参数pname将GL_TEXTURE_LOD_BIAS设置为调用glSamplerParameteri()设置的一个常熟值,用来调整λ
- 默认lod(bias)=0.0,这没有效果;如果λ<=0.0,则纹素小于像素,所以用放大滤波器;如果λ>0.0,则使用缩小滤波器;如果缩小滤波器使用mipmap,那么λ是mipmap级别
- GL_TEXTURE_MAG_FILTER和GL_TEXTURE_MIN_FILTER的默认参数分别是GL_LINEAR和GL_LINEAR_MIPMAP_LINEAR。注意默认的缩小滤波器启用mipmap。这很重要
- 为了使用mipmap,纹理必须有一组完整的mipmap level,并且它们必须有一组连续的分辨率;否则,认为纹理是不完整的,并且不会为着色器返回有用的数据。使用glTexStorage2D()函数的纹理分别通常是完整的,所有不用担心;但是在创建纹理时没有数据,这很容易引起错误,因为容易忘记改版滤波模式或者为新创建的纹理填充mipmap
6.11.4 mipmap细节层次控制
- 通过GL_TEXTURE_BASE_LEVEL和GL_TEXTURE_MAX_LEVEL参数来提供对于mipmap金字塔选择level的进一步控制,这些参数使用glSampleParameteri()来设置
- GL_TEXTURE_BASE_LEVEL设置被采样的最低的mipmap级别(最高分辨率),与λ的值无关
- GL_TEXTURE_MAX_LEVEL设置被采样的最高mipmap级别(最低分辨率)
- GL_TEXTURE_BASE_LEVEL的一个潜在用处时纹理流
6.12 高级纹理查询函数
6.12.1 显示细节层次
- gvec4 textureLod(gsampler1D tex, float P, float lod)
- gvec4 textureLod(gsampler2D tex, vec2 P, float lod)
- gvec4 textureLod(gsampler3D tex, vec3 P, float lod)
- gvec4 textureLod(gsamplerCube tex, vec3 P, float lod)
- gvec4 textureLod(gsampler1DArray tex, vec2 P, float lod)
- gvec4 textureLod(gsampler2DArray tex, vec3 P, float lod)
- gvec4 textureLod(gsampler2DRect tex, vec2 P, float lod)
- gvec4 textureLod(gsamplerCubeArray tex, vec4 P, float lod)
从tex给出的采样器中采样P给出的纹理坐标位置的一个纹素,使用lod给出的显示细节层次
textureLod支持的采样器中不包括samplerBuffer和samplerRect
6.12.2 显示梯度设置
- 可以在流程的早期阶段重载mipmap的细节层次计算,而不是直接显示细节层次参数;当使用梯度纹理函数时,纹理坐标的偏微分则作为参数给出
- gvec4 textureGrad(gsampler1D tex, float P, float dPdx, float dPdy)
- gvec4 textureGrad(gsampler2D tex, vec2 P, vec2 dPdx, vec2 dPdy)
- gvec4 textureGrad(gsampler3D tex, vec3 P, vec3 dPdx, vec3 dPdy)
- gvec4 textureGrad(gsamplerCube tex, vec3 P, vec3 dPdx, vec3 dPdy)
- gvec4 textureGrad(gsampler1DArray tex, vec2 P, float dPdx, float dPdy)
- gvec4 textureGrad(gsampler2DArray tex, vec3 P, vec2 dPdx, vec2 dPdy)
- gvec4 textureGrad(gsampleCubeArray tex, vec4 P, vec3 dPdx, vec3 dPdy)
从tex给出的采样器中采样一个P给出的纹理坐标位置的一个纹素,这里使用P在x和y上的偏微分,分别用dPdx和dPdy设置
6.12.3 偏移后的纹理获取
- 一些应用需要兴趣区域附近的一些纹素,也可能需要在采样时轻微偏移纹理坐标
- gvec4 textureOffset(gsampler1D tex, float P, int offset[, float bias])
- gvec4 textureOffset(gsampler2D tex, vec2 P, ivec2 offset[, float bias])
- gvec4 textureOffset(gsampler3D tex, vec3 P, ivec3 offset[, float bias])
- gvec4 textureOffset(gsampler1DArray tex, vec2 P, int offset[, float bias])
- gvec4 textureOffset(gsampler2DArray tex, vec3 P, ivec2 offset[, float bias])
- gvec4 textureOffset(gsampler2DRect tex, vec2 P, ivec2 offset[, float bias])
从tex给出的采样器中采样P给出的纹理坐标处的一个纹素;在浮点纹理坐标P已经被合适的缩放和转换到绝对纹理坐标以后,以及在执行纹理以前,将offset加到纹理坐标上
6.12.4 投影纹理
- 投影纹理用于用来变换纹理坐标的透视变换矩阵;变换的输入是一组齐次坐标,而输出是一个最后一个分量近似为1的向量;
- 函数textureProj可以用最后一个分量来除,把纹理坐标投射进纹理的坐标空间
- gvec4 textureProj(gsampler1D tex, vec2 P[, float bias])
- gvec4 textureProj(gsampler1D tex, vec4 P[, float bias])
- gvec4 textureProj(gsampler2D tex, vec3 P[, float bias])
- gvec4 textureProj(gsampler2D tex, vec4 P[, float bias])
- gvec4 textureProj(gsampler3D tex, vec4 P[, float bias])
- gvec4 textureProj(gsamplerRect tex, vec3 P)
- gvec4 textureProj(gsamplerRect tex, vec4 P)
用P的最后一个分量除P设置的纹理坐标来执行纹理查询,并且使用结果值执行普通texture执行的纹理查询
6.12.5 着色器中的纹理查询
- 下面前两组内置的GLSL函数不从纹理读取,但是返回纹理和纹理如何执行的信息
- vec2 textureQueryLod(gsampler1D tex, float P)
- vec2 textureQueryLod(gsampler2D tex, vec2 P)
- vec2 textureQueryLod(gsampler3D tex, vec3 P)
- vec2 textureQueryLod(gsamplerCube tex, vec3 P)
- vec2 textureQueryLod(gsampler1DArray tex, float P)
- vec2 textureQueryLod(gsampler2DArray tex, vec2 P)
- vec2 textureQueryLod(gsamplerCubeArray tex, vec3 P)
- vec2 textureQueryLod(gsampler1DShadow tex, float P)
- vec2 textureQueryLod(gsampler2DShadow tex, vec2 P)
- vec2 textureQueryLod(gsamplerCubeShadow tex, vec3 P)
- vec2 textureQueryLod(gsampler1DArrayShadow tex, float P)
- vec2 textureQueryLod(gsampler2DArrayShadow tex, vec2 P)
- vec2 textureQueryLod(gsamplerCubeArrayShadow tex, vec3 P)
返回值的x分量是将要被访问的mipmap数组,而y分量是计算得到的相对于基础级别的细节层次
- 对于每个textureQueryLod函数,都有一个对应的查询函数textureQueryLevels(),其返回mipmap级别的数目
- int textureQueryLevels(gsampler1D tex)
- int textureQueryLevels(gsampler2D tex)
- int textureQueryLevels(gsampler3D tex)
- int textureQueryLevels(gsamplerCube tex)
- int textureQueryLevels(gsampler1DArray tex)
- int textureQueryLevels(gsampler2DArray tex)
- int textureQueryLevels(gsamplerCubeArray tex)
- int textureQueryLevels(gsampler1DShadow tex)
- int textureQueryLevels(gsampler2DShadow tex)
- int textureQueryLevels(gsamplerCubeShadow tex)
- int textureQueryLevels(gsampler1DArrayShadow tex)
- int textureQueryLevels(gsampler2DArrayShadow tex)
- int textureQueryLevels(gsamplerCubeArrayShadow tex)
返回提供采样器包含的mipmap级别的数目
- 有时,需要知道准备读取采样的纹理维度;例如,需要把表示绝对纹素位置的整数纹理坐标缩放到适合于从纹理中采样的浮点范围,或者迭代纹理中的所有采样;函数textureSize()将返回指定细节层次的纹理的维度数
- int textureSize(gsampler1D tex, int lod)
- ivec2 textureSize(gsampler2D tex, int lod)
- ivec3 textureSize(gsampler3D tex, int lod)
- ivec2 textureSize(gsamplerCube tex, int lod)
- ivec2 textureSize(gsamplerRect tex, int lod)
- ivec3 textureSize(gsamplerCubeRect tex)
- ivec2 textureSize(gsampler1DArray tex, int lod)
- ivec3 textureSize(gsampler2DArray tex, int lod)
- int textureSize(gsamplerBuffer tex)
返回绑定到采样器tex纹理的细节层次lod的维度数;返回值的分量依次是纹理的宽度、高度和深度;对于数组形式,返回值的最后一个分量是数组中切片的数目
6.12.6 收集纹素
- 函数textureGather是可以使着色器读取四个用来从2维纹理创建双线性插值的纹素采样的特殊函数
- 典型的是使用单通道纹理,函数可选的comp分量可以选择一个通道,而不是底层数据的x或者r分量。在需要从纹理的一个通道采样多次时,这个函数有很大的性能优势。因为根据需要的访问模式,使用这个函数可以减掉四分之三的纹理查询数目
- gvec4 textureGather(gsampler2D tex, vec2 P[, int comp])
- gvec4 textureGather(gsampler2DArray tex, vec3 P[, int comp])
- gvec4 textureGather(gsamplerCube tex, vec3 P[, int comp])
- gvec4 textureGather(gsamplerCubeArray tex, vec4 P[, int comp])
- gvec4 textureGather(gsamplerRect tex, vec2 P[, int comp])
从绑定到采样器tex的矩形、二维(数组),或者立方体映射(数组)纹理中采集四个纹素,这通常用于创建双线性滤波纹素值,以及返回返回值中的四个分量中四个纹素中一个选择分量
如果已经设置,则comp使用0、1、2和3分别表示x、y、z和w分量来获取分辨率;如果没有设置comp,则返回x分量
6.12.7 合并特殊函数
- gvec4 textureProjLod(gsampler2D tex, vec2 P, float lod)
- gvec4 textureProjGrad(gsampler2D tex, vec3 P, vec2 dPdx, vec2 dPdy)
- gvec4 textureProjOffset(gsampler2D tex, vec3 P, ivec2 offset[, float bias])
- gvec4 textureProjLodOffset(gsampler2D tex, vec3 P, float lod, ivec2 offset)
- gvec4 textureProjGradOffset(gsampler2D tex, vec3 P, vec2 dPdx, vec2 dPdy, ivec2 offset)
可以合并高级纹理查询函数来在一次调用中执行多个特殊函数
textureProjLod从绑定到tex表示的单元纹理执行投影纹理,这类似于执行textureProj;并且有lod设置显示细节层次
textureProjGrad执行投影纹理查询,并有dPdx和dPdy传递显式梯度
6.13 点精灵
- 点精灵是使用片元着色器渲染的OpenGL点、运行的时候考虑点内的片元坐标
- 点内的坐标是二维向量gl_PointCoord;这个变量的常见用处是作为纹理坐标使用(这是点精灵的原点)、或者用于计算颜色或覆盖率
6.13.1 带纹理的点精灵
- 在片元着色器中使用gl_PointCoord来查询纹理中的纹素,可以生成简单的点精灵
- 每个点精灵使用正方形来显示纹理
- 在顶点着色器中写入gl_PointSize来控制点精灵的大小;使用它相对于近平面的距离来缩放
解析的颜色和形状
- 我们并不只限于从纹理加载点精灵数据;纹理的分辨率是有限的,但gl_PointCoord可以相当精确
6.13.2 控制点的外观
- 有一些控制可以通过应用程序来调整点的外观;这些参数使用glPointParameterf()和glPointParameteri()来设置
- void glPointParameter{if}(GLenum pname, TYPE param)
- void glPointParameter{if}v(GLenum pname, const TYPE* param)
设置pname指定的点参数为param指定的值
pname必须是GL_POINT_SPRITE_COORD_ORIGIN或者GL_POINT_FADE_THRESHOLD_SIZE
如果pname是GL_POINT_SPRITE_COORD_ORIGIN,那么param必须是GL_LOWER_LEET或者GL_UPPER_LEFT
如果pname是GL_POINT_FADE_THRESHOLD_SIZE,那么param必须是一个大于等于0的浮点值
- 使用glPointParameteri()和glPointParameterf()改变的两个参数是gl_PointCoord 使用原点(使用GL_POINT_SPRITE_COORD_ORIGIN)和消隐阈值(使用GL_POINT_FADE_THRESHOLD_SIZE)
- 在点精灵坐标原点控制片元着色器中点被光栅化时gl_PointCoord.y是从上到下还是从下到上增加;GL_POINT_SPRITE_COORD_ORIGIN的默认值是GL_UPPER_LEFT,意味着它从上到下增加;注意这与窗口坐标是相反的
- GL_POINT_FADE_THRESHOLD控制点和点精灵如何反走样;当点的大小在这个阈值之下时,OpenGL有权力来停止执行正在的反走样,并且使用混合使点消失在背景中;这个参数的默认值是1.0,这意味着如果一个大小小于1.0的点被光栅化时,不只是每个片元内的一个采样着色,而是这个采样中的所有片元着色,最后它的alpha分量使用点消隐阈值因子来衰减
6.14 渲染到纹理贴图
- 除了使用帧缓存对象用于离屏渲染,也可以使用FBO更新纹理图。可以用这个来指示用于表面纹理的变化;如果进行GPU计算,也可以用来更新查询表中的值。在这些情况下,我们可以绑定纹理图的一个级别,并作为帧缓存附件。渲染结束后,可以把纹理图从帧缓存对象中取消关联,以用于接下来的渲染
- void glFramebufferTexture(GLenum target, GLenum attachment, GLuint texture, GLint level)
- void glFramebufferTexture1D(GLenum target, GLenum attachemet, GLenum texturetarget, GLuint texture, GLint level)
- void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum texturetarget, GLuint texture, GLint level)
- void glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum texturetarget, GLuint texture, GLint level, GLint layer)
这个系列的函数可以将纹理图的level级别关联作为帧缓存附件
glFramebufferTexture()可以将纹理对象texture的level关联到attachment
glFramebufferTexture1D()、glFramebufferTexture2D()和glFramebufferTexture3D()分别关联纹理对象的纹理图作为帧缓存对象的渲染附件
target必须是GL_READ_FRAMEBUFFER、GL_DRAW_FRAMEBUFFER或者GL_FRAMEBUFFER之一
attachment必须是帧缓存附件点之一:GL_COLOR_ATTACHMENTi、GL_DEPTH_ATTACHMENT、GL_STENCIL_ATTACHMENT或者GL_DEPTH_STENCIL_ATTACHMENT
如果texture是0,则说明绑定到attachment的任意纹理被释放,后面没有绑定到attachment;在这种情况下,忽略texturetarget、level和layer
如果纹理不是0,它必须是现有的纹理对象的名称,texturetarget与纹理对象关联的纹理类型匹配
- void glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
关联3维纹理,或者1维或2维数组纹理的一层作为帧缓存附件
6.14.1 丢弃已渲染的数据
- OpenGL的渲染规则:渲染每一帧之前应该清空帧缓存
- 现代GPU实现压缩和其他技术来改进性能、内存带宽需求等
- void glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments)
- void glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLint width, GLint height)
让OpenGL丢弃x、y、width和height限制区域内的指定帧缓存附件的内容
glInvalidateFramebuffer()丢弃指定的attachments的全部内容;附件的数目以及各个标识符数组的地址由numAttachments和attachments给出;
对于非默认的帧缓存,存储在attachments数组的标识符必然来自GL_COLOR_ATTACHMENTi、GL_DEPTH_ATTACHMENT、GL_STENCIL_ATTACHMENT和GL_DEPTH_STENCIL_ATTACHMENT中
- 根据OpenGL的实现,丢弃帧缓存的内容比清空它的效率高很多;另外,在于一个GPU的系统中,它可以避免昂贵的数据拷贝
- 如果向直接丢弃纹理的内容,而不是帧缓存的attachment的内容,则可以调用glInvalidateTexImage()或者glInvalidateTexSubImage()
- void glInvalidateTexImage(GLuint texture, GLint level)
- void glInvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint width, GLint height, GLint depth)
让OpenGL丢弃名称由texture给出的纹理指定的level的内容
glInvalidateTexImage()丢弃纹理对象的全部图像level,而glInvalidateTexSubImage()只丢弃width、height和depth指定的原点在xoffset、yoffset和zoffset的区域