GPU和CPU交互的那部分可以看成一个全局表GPU_table,
这个表里的一级下表为ARRAY_BUFFER,ELEMENT_ARRAY_BUFFER等各种buffer
单看这个一级表可以把他们理解为各种缓冲区
这个表里的二级下表为各种glID缓冲对象
这个表里的三级下表为实实在在的data
特别注意:GPU操作渲染数据都是依靠指定缓冲区和缓冲对象绑定的,所以缓冲对象和缓冲区必须事先绑定
##顶点缓冲区操作如下:
this._glID = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, this._glID);将缓冲区和缓冲对象绑定(类似GPU_table[buffer][glID]);
gl.bufferData(gl.ARRAY_BUFFER, data, glUsage);将顶点数据发送到显存(类似GPU_table[buffer][glID]=data);
gl.bufferSubData(gl.ARRAY_BUFFER, byteOffset, data);这个也是操作gl.bufferData,只是存放的时候按照偏移存放的;
gl.bindBuffer(gl.ARRAY_BUFFER, null);GPU_table[buffer][null];解除锁定
gl.deleteBuffer(this._glID);删除缓冲对象及其绑定的缓冲数据GPU_table[buffer][glID] = null;
##索引缓冲区操作如下:
this._glID = gl.createBuffer()
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._glID);将缓冲区和缓冲对象绑定(类似GPU_table[buffer][glID]);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, data, glUsage);将索引数据发送到显存(类似GPU_table[buffer][glID]=data);
gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, byteOffset, data);这个也是操作gl.bufferData,只是存放的时候按照偏移存放的;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);GPU_table[buffer][null];解除锁定
gl.deleteBuffer(this._glID);删除缓冲对象及其绑定的缓冲数据GPU_table[buffer][glID] = null;
##纹理缓冲区绑定
this._glID = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);激活第0块纹理单元,关于这个纹理单元至少有八块
gl.bindTexture(gl.TEXTURE_2D, this._glID);将缓冲区和缓冲对象绑定(类似GPU_table[gl.TEXTURE+“i”][buffer][glID]);
下面这四个函数可以理解为都是将纹理相关数据发往显存的 类似GPU_table[gl.TEXTURE+“i”][buffer][glID][type] = data;
图象从纹理图象空间映射到帧缓冲图象空间(映射需要重新构造纹理图像,这样就会造成应用到多边形上的图像失真),这时就可用glTexParmeteri()函数来确定如何把纹理象素映射成像素
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, glFilter(gl, this._minFilter, mipFilter));
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glFilter(gl, this._magFilter, -1));
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, this._wrapS);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, this._wrapT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
#一些参数解释
GL_TEXTURE_2D: 操作2D纹理.
GL_TEXTURE_WRAP_S: S方向上的贴图模式.
GL_CLAMP: 将纹理坐标限制在0.0,1.0的范围之内.如果超出了会如何呢.不会错误,只是会边缘拉伸填充.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);这里同上,只是它是T方向
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);这是纹理过滤
GL_TEXTURE_MAG_FILTER: 放大过滤
GL_LINEAR: 线性过滤, 使用距离当前渲染像素中心最近的4个纹素加权平均值
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
GL_TEXTURE_MIN_FILTER: 缩小过滤
GL_LINEAR_MIPMAP_NEAREST: 使用GL_NEAREST对最接近当前多边形的解析度的两个层级贴图进行采样,然后用这两个值进行线性插值.
GL_LINEAR 使用了线性滤波的纹理贴图。这需要机器有相当高的处理能力,但它们看起来很不错。
GL_NEAREST从原理上讲,这种方式没有真正进行滤波。它只占用很小的处理能力,看起来也很差。唯一的好处是这样我们的工程在很快和很慢的机器上都可以正常运行。
我们在 GL_TEXTURE_MIN_FILTER和 GL_TEXTURE_MAG_FILTER时你可以混合使用 GL_NEAREST 和 GL_LINEAR。纹理看起来效果会好些,如果我们更关心速度,可以全采用低质量贴图。
GL_TEXTURE_MIN_FILTER在图像绘制时小于贴图的原始尺寸时采用。GL_TEXTURE_MAG_FILTER在图像绘制时大于贴图的原始尺寸时采用
// 线形滤波
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);// 接近滤波
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);//这个函数是加载一个没有被压缩的纹理
void glTexImage2D(GLenum target,
GLint level,
GLint internalFormat,
GLsizei width,
GLsizei height,
GLint border,
GLenum format,
GLenum type,
const GLvoid * data);
用法举例:
这个函数是加载没有被压缩的图片
glTexImage2D(GL_TEXTURE_2D, //此纹理是一个2D纹理
0, //代表图像的详细程度, 默认为0即可
3, //颜色成分R(红色分量)、G(绿色分量)、B(蓝色分量)三部分,若为4则是R(红色分量)、G(绿色分量)、B(蓝色分量)、Alpha
TextureImage[0]->sizeX, //纹理的宽度
TextureImage[0]->sizeY, //纹理的高度
0, //边框的值
GL_RGB, //告诉OpenGL图像数据由红、绿、蓝三色数据组成
GL_UNSIGNED_BYTE, //组成图像的数据是无符号字节类型
TextureImage[0]->data); //告诉OpenGL纹理数据的来源,此例中指向存放在TextureImage[0]记录中的数据
使用glTexImage2D()时所采用的位图文件分辨率必须为:64×64、128×128、256×256三种格式,如果其他大小则会出现绘制不正常。
//这个函数是加载一个被压缩的纹理
gl.compressedTexImage2D(
gl.TEXTURE_2D,
options.level,
glFmt.internalFormat,
options.width,
options.height,
0,
img
);