【OpenGL】蓝宝书第五章摘抄笔记总结

载入纹理图形  glTexImage/glTexSubImage
设置纹理贴图参数 glTexParameter
管理多重纹理 glGenTextures/glDeleteTextures/glBindTexture
生成Mip贴图 glGenerateMipmap
使用各向异性过滤 glGetFloatv/glTexParameter
载入压缩纹理 glCompressedTexImage/glCompressedTexSubImage

纹理贴图 texture mapping

纹理只是一种能够应用到场景中的三角形上的图像数据,它通过经过过滤的纹理单元(texel,相当于基于纹理的像素)填充到实心区域。在UnityShader里我对纹理贴图的运用理解是简单的通过片段上的纹理坐标采样像素颜色信息进行运算,贴图的数据可代表什么取决于使用者,多数情况是直接代表输出颜色,其他的例如遮罩值。

原始图像数据

位图(一系列表示开启和关闭像素值的0和1)表示,每个内存块中的每个位都与屏幕上某一个像素的状态一一对应。
像素图(pixmap),每一个像素都显示了256种不同深度的灰色中的一种。
”位图“经常用在饱含灰度或全彩色数据的图像中,它是.BMP文件扩展名的文件。

像素包装

图像数据在内存中很少以紧密包装的形式存在。出于性能上考虑,一幅图像的每一行都应该从一种特定的字节对齐地址开始。绝大多数编译器会自动把变量和缓冲区放置在一个针对该架构对齐优化的地址上。
默认情况下,OpenGL采用4个字节的对齐方式,普遍上适用于目前正在使用的系统。

一张图片宽度和高度已知,且知道每个像素占据3位,我们一般都认为是高度*宽度*3就是图片字节数,其实并不都是如此,如果硬件本身的体系结构是4字节排列(大部分是这样的),假设图片宽度199个像素,正常思考是199*3=597个字节,但实际是600个,因为硬件体系结构是4字节排列的,它会多出3个空字节,即图片每一行像素会多出3个字节!这是为了使得每一行的存储器地址从一个能被4整除的地址开始!这种问题解决方法就是坚持用二次幂尺寸大小的纹理,例如将199变成2次幂即200,200*3=600字节,虽然这从结果上还是用开辟了不必要的字节开销,但这有利于CPU更高速地获取数据块。

BMP文件是4字节排列的,TGA文件是1字节排列的;为什么内存分配意图对于OpenGL来说这么重要?因为我们向OpenGL提交图像数据或从OpenGL获取图像数据时,OpenGL需知道我们想在内存中对数据进行怎样的包装或解包装操作。

改变像素的存储方式:  void glPixelStorei(GLenum pname, GLint param);
恢复像素的存储方式:  void glPixelStoref(GLenum pname, GLint param);  

例如, glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 从内存缓冲区中读取数据并以紧密包装形式解包?(书籍解释的不是很清楚)
用GL_PACK_ALIGHMENT来告诉OpenGL如何将从像素缓冲区中读取并放置到一个用户指定的内存缓冲区的数据进行包装(即指定如何对已经读出来缓存的图像数据进行包装的)
glPixelStore参数不再列出,可自行查阅文档;这类知识比较难懂,后续可能会反复尝试理解(后续掌握后,补充内容便于理解,缺少实例)

像素图  pixmap

每个像素将需要一个以上的存储位来表示。每个像素的附加位(?)允许存储强度(intensity, 或亮度即luminance值)或者颜色分量值。在OpenGL核心版本中,无法直接将一个像素图绘制到颜色缓冲区中,但可用如下函数将颜色缓冲区的内容作为像素图直接读取。(相当于读屏幕像素,但信息可能不止于RGBA)

void glReadPixels(GLint x, GLint y, GLSizei width, GLSizei height, GLenum format, GLenum type, const void *pixels);

【使用进行时会阻碍应用程序,因它是通过总线传输到系统内存的;若指定一个与图形硬件的本地排列不同的像素格式类型和像素数据类型,那么在转格式时会产生性能开销。】

x,y是屏幕左下角的窗口坐标,width,height是矩形宽、高值(像素形式),如果读取的颜色缓冲区存储的数据与我们要求不同,可以使用format进行制定转换成我们想要的像素格式,可用type制定像素数据类型。例如:glReadPixels(0,0, width, height, GL_BGR, GL_UNSIGNED_BYTE, pBits);  GL_BGR格式按照蓝、绿、红顺序排列GL_UNSIGNED_BYTE类型(每种颜色分量都是1个8位无符号整数)的像素。即这个像素是24位的,0~7位是B分量,8~15位是G分量,16~23位是R分量。

较为特殊的像素数据类型如:UNSIGNED_BYTE_3_2_2 则代表一个像素占8位,且像素只有RGB三个分量,第一个、第二个分量占3位,第三个分量占2位;UNSIGNED_BYTE_2_3_3则代表像素占8位,且只有RGB三个分量,第三个占2位,第二和第一占3位;注意我这里的顺序就是存储在8位存储器内的描述,左边是高位,右边是低位,而R、G、B分量谁是第一个,第二个,第三个和像素格式类型有关,使用GL_RGB,则第一个分量是R,使用GL_BGR则第一个分量是B。关于像素数据格式和像素数据类型更多变量自行查阅。

一般情况下双缓存渲染环境下会在后台缓冲区进行读取,而单缓冲区环境下则在前台缓冲区进行。
void glReadBuffer(GLenum mode);  指定读取缓冲区时在哪进行
mode:  GL_FRONT、GL_BACK、GL_LEFT、GL_RIGHT、GL_FRONT_LEFT、GL_FRONT_RIGHT、GL_BACK_LEFT、GL_BACK_RIGHT、GL_NONE。
(很多参数没搞懂什么意思,书上解释不清,姑且认为是能自定义在什么前台还是后台缓冲区进行读取操作)

保存像素

glWriteTGA函数:从前台颜色缓冲区中读取颜色数据并存储到一个Targa文件格式的图像文件中。

猜你喜欢

转载自blog.csdn.net/qq_39574690/article/details/115189445