先看下效果图:
Demo下载地址:点击下载
一、 像素图像的数据包装
图像存储空间 = 图像width * 图像height * 每个像素的字节数
ps:有一张RGB的图像(每个颜色通道8位),图像的宽度199个像素,每行需要存储多少空间?
解:8位为一个字节,有三个颜色,所以一个RGB需要3个字节存储。
199(width) * 1(height)* 3(字节)
二、像素的存储方式
/**
@param pname:
GL_UNPACK_ALIGNMENT----图像数据从内存到缓冲区的解包设置
GL_PACK_ALIGNMENT ---- 图像数据从缓冲区到内存的封包设置
@param param:
内存中每个像素行起点的排列请求,允许设置为: 1(byte排列)、2(排列为偶数byte的行)、4(字word排列)、8(行从双字节边界开始)
*/
void glPixelStorei(GLenum pname,GLint param);
三、从颜色缓冲区中获取图像保存为图片
- 从颜色缓冲区读取像素数据到内存中
- 从内存到硬盘的图像文件保存
/**
x: 矩形左下角的窗口坐标
y: 矩行左下角的窗口坐标
width: 矩形的宽(像素)
height: 矩形的高(像素)
format: OpenGL指定的颜色布局(像素格式)。参考像素格式图。
type: 解释参数pixels指向的数据,告诉OpenGL,使用缓冲区中的什么数据类型来存储颜色分量,像素数据的数据类型。参考数据类型图。
pixels: 指向图形数据的指针
*/
void glReadPixels(GLint x,GLint y,GLSizei width,GLSizei
height, GLenum format, GLenum type,const void * pixels);
(颜色布局)像素格式图
像素数据的数据类型
针对像素数据的数据类型常量的解释
四、像素图数据的获取过程(从硬盘到内存)
/**
szFileName: 文件的名字
iWidth: 文件的宽度地址
iHeight: 文件的高度地址
iComponents: 文件颜色成分的存储大小和压缩状况地址
eFormat: 文件颜色布局地址 (像素格式),参考颜色布局图
*/
GLbyte *gltReadTGABits(const char *szFileName, GLint *iWidth, GLint *iHeight, GLint *iComponents, GLenum *eFormat, GLbyte *pData = NULL);
五、载入纹理
方式一
/**
//target: 纹理的维度(glTexImage1D/glTexImage2D/glTexImage3D)
//level: mip贴图层次
//internalformat: 加载纹理颜色成分(就是上述获取到的iComponents的数据)
//width: 加载纹理的宽
//height: 加载纹理的高
//border: 纹理的边框
//format: 像素数据的格式
//type: 使用缓冲区中的什么数据类型来存储颜色分量,像素数据的数据类型。参考数据类型图。
//data:指向纹理数据的指针
//详细可参考PPT
*/
void glTexImage1D(GLenum target,GLint level,GLint
internalformat,GLsizei width,GLint border,GLenum
format,GLenum type,void *data);
void glTexImage2D(GLenum target,GLint level,GLint
internalformat,GLsizei width,GLsizei height,GLint
border,GLenum format,GLenum type,void * data);
void glTexImage3D(GLenum target,GLint level,GLint internalformat,GLSizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,void *data);
方式二
void glCopyTexImage1D(GLenum target,GLint level,GLenum
internalformt,GLint x,GLint y,GLsizei width,GLint border);
void glCopyTexImage2D(GLenum target,GLint level,GLenum
internalformt,GLint x,GLint y,GLsizei width,GLsizei
height,GLint border);
源缓冲区是通过glReadBuffer(mode)函数设置的。 mode为GL_FRONT,GL_LEFT 等参数
注意:不存在glCopyTexImage3D, 因为我们无法从2D颜色缓冲区获取体积数据。
六、更新纹理和插入替换纹理
更新纹理
void glTexSubImage1D(GLenum target,GLint level,GLint xOffset,GLsizei width,GLenum
format,GLenum type,const GLvoid *data);
void glTexSubImage2D(GLenum target,GLint level,GLint xOffset,GLint yOffset,GLsizei
width,GLsizei height,GLenum format,GLenum type,const GLvoid *data);
void glTexSubImage3D(GLenum target,GLint level,GLint xOffset,GLint yOffset,GLint
zOffset,GLsizei width,GLsizei height,GLsizei depth,Glenum type,const GLvoid * data);
插入替换纹理
void glCopyTexSubImage1D(GLenum target,GLint level,GLint xoffset,GLint x,GLint y,GLsizei
width);
void glCopyTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yOffset,GLint x,GL
y,GLsizei width,GLsizei height);
void glCopyTexSubImage3D(GLenum target,GLint level,GLint xoffset,GLint yOffset,GLint
zOffset,GLint x,GLint y,GLsizei width,GLsizei height);
七、纹理对象
/**
分配纹理对象
n: 纹理对象的数量
textTures: 指针(指向一个无符号整形数组,由纹理对象标识符填充 )
*/
void glGenTextures(GLsizei n,GLuint * textTures);
/**
绑定纹理状态
target: GL_TEXTURE_1D、GL_TEXTURE_2D、 GL_TEXTURE_3D
texture: 纹理对象标识符
*/
void glBindTexture(GLenum target,GLunit texture);
/**
删除绑定纹理对象
n: 纹理对象的数量
textures: 纹理对象指针(指向一个无符号整形数组,由纹理对象标识符填充)
*/
void glDeleteTextures(GLsizei n,GLuint *textures);
/**
测试纹理对象是否有效
如果texture是一个已分配空间的纹理对象,那么这个函数会返回GL_TRUE, 否则返回GL_FALSE。
*/
GLboolean glIsTexture(GLuint texture);
八、设置纹理参数
/**
target: 纹理模式( GL_TEXTURE_1D、GL_TEXTURE_2D、 GL_TEXTURE_3D)
pname:需要设置哪个纹理参数(GL_TEXTURE_WRAP_S, GL_TEXTURE_MIN_FILTER, GL_TEXTURE_MAG_FILTER等等)
param: 设置特定纹理参数的值
*/
glTexParameterf(GLenum target,GLenum pname,GLFloat param);
glTexParameteri(GLenum target,GLenum pname,GLint param);
glTexParameterfv(GLenum target,GLenum pname,GLFloat *param);
glTexParameteriv(GLenum target,GLenum pname,GLint *param);
九、设置过滤方式
- 邻近过滤(GL_NEAREST)
- 线性过滤(GL_LINEAR)
//纹理缩小时,使用邻近过滤。
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST)
//纹理放大时,使用线性过滤。
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST)
十、设置环绕方式
- GL_REPEAT: 纹理坐标超过1.0的方向上对纹理进行重复。
- GL_MIRRORED_REOEAT: 纹理坐标超过1.0的方向上对纹理进行镜像重复
- GL_CLAMP_TO_EDGE: 环绕模式,强制对范围之外的纹理坐标沿着合法的纹理单元的最后一行或者最后一列进行采样。
- GL_CLAMP_TO_BORDER: 纹理坐标在0~1.0范围之外的只使用边界纹理单元。边界纹理单元是:围绕基本图像的额外的行和列,并与基本纹理图像一起加载的。
/**
参数1: GL_TEXTURE_1D、 GL_TEXTURE_2D、 GL_TEXTURE_3D
参数2:GL_TEXTURE_WRAP_S、 GL_TEXTURE_T、 GL_TEXTURE_R, 针对 s,t,r 纹理坐标
参数3:GL_REPEAT、 GL_MIRRORED_REOEAT、 GL_CLAMP_TO_EDGE、 GL_CLAMP_TO_BORDER
*/
glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAR_S,GL_CLAMP_TO_EDGE)
glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAR_T,GL_CLAMP_TO_EDGE)
十一、纹理计算
三维
二维