Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

WebGL(拾伍) texImage2D参数说明

  在之前的文章中,texImage2D这个函数一共出现过两次多载,一次是在使用IMG贴图的时候,我们直接传入IMG对象,不用设置尺寸。还有一次是在把缓冲帧当内的数据当作贴图来使用的时候,那是是需要指定内容尺寸的,为什么这样呢?这就是它的奇葩之处。
  由于WebGL移植到Web上的OpenGL,很多参数都是移植时遗留的问题或是扩展预留的东西。这些东西会让方法的参数变的一团糟。我觉得,一个优秀的函数不应该有太多不相干的参数,甚至不应该有太多的多载。以我的标准看这个“texImage2D”,它显然不是什么优秀的函数,应该说糟糕透了。
  最初说WebGL贴图的文章中就有使用到“texImage2D”这个函数,当时是直接使用IMG对象作为数据参数的。 webgl.texImage2D(
  webgl.TEXTURE_2D,0,webgl.RGBA,webgl.RGBA,webgl.UNSIGNED_BYTE,img
);
  IMG对象包含的数据可不止图片的数据而已,还有图片的尺寸。所以我们直接使用图片对象作为参数就不用给这个函数传入尺寸。除了IMG对象之外,还可以使用CANVAS对象和VIDEO对象作为参数。这些都是DOM对象,可以归为一个多载吧。这些DOM对象都有自带的图形数据和相应的尺寸数据,所以在使用DOM对象作为数据参数时不需要在参数中制定尺寸。
  除了DOM对象之外,在WebGL帧缓冲的那一篇中我们还用了null作为数据参数。没错,因为那时的Texture对象是绑定到了帧缓冲对象中的,所以设置为null把数据指针交给帧缓冲管理。 webgl.texImage2D(
  webgl.TEXTURE_2D,0,webgl.RGB,256,256,0,
  webgl.RGB,webgl.UNSIGNED_BYTE,null
);
  也许是因为数据的存储结构的关系(猜测),即使把数据指针交给帧缓冲管理我们也必须在“texImage2D”的参数中设置好图片的尺寸。其实在OpenGL中,这个函数的原型就是这样的。OpenGL中的“texImage2D”并没有WebGL中这样的多载,因为它没用DOM对象。也就是说,图片数据指针这个参数应该是不折不扣的内存指针才对。而JavaScript同样有数据内存指针的概念(JavaScript的强类型数组),所以我们也可以在JavaScript中,直接使用内存指针来调用这个函数。 //绘制32*32的数据 一三象限白色,二四象限黑色,用作平铺国际象棋棋盘
dat=[];
for(i=0;i<32;i++)for(j=0;j<32;j++)
  k=i<16^j<16?255:0,dat.push(k,k,k);
//把数组转换成内存指针作为texImage2d的参数
webgl.texImage2D(
  webgl.TEXTURE_2D,0,webgl.RGB,32,32,0,webgl.RGB,
  webgl.UNSIGNED_BYTE,new Uint8Array(dat)
);

  这样就可以绘制我们自己传入的图片数据了,不过要注意这里传入的类型是字节,所以颜色值是从0到255的,而不是着色器语言中的0到1。循环中dat.push的参数是3个,也就是每一个颜色都放入三个字节的值,这是因为类型是RGB,如果是RGBA就需要4个字节。而且你会发现代码中有两个参数都是RGB,也就是说有两个地方有颜色取样的操作。但是令人蛋疼的是,如果这两个值不同就会抛出异常

  看到这个异常提示是不是觉得这个函数设计的很糟糕了?更糟糕的还有呢!在尺寸参数后面还有个参数是0吧?根据官方的文档,这个参数的含义是“border”,但是我翻到这个参数的介绍时顿时吐了三升血!“This value must be 0.”这是要闹哪样啊?
  这个函数蛋疼的就那俩家伙了,其他的还算比较正常。倒数第二个参数是指定内存指针所指向的数据类型,这个常量之前的文章中就用过好多次了,如果需要详细资料可以在官方文档中找到。第一参数是贴图的类型,其实我很长一段时间都以为WebGL只能支持2D贴图的也就是TEXTURE_2D这个常量,但是后来才发现原来TEXTURE_CUBE_MAP也是可以支持的。这内容就多了,这篇文章就不扯那么远了,依然只停留在TEXTURE_2D上。这个函数的第二个参数也是一个数值根据官方文档的说明是指定mipmap的等级的,这个概念可能有点模糊。如果把mipmap看作一个图标组的话,所谓等级就是其中某个缩放的图标。也就是说,使用这个方法可以把操作精确到mipmap中的某个缩略图上。这些冷门的参数我也没有一个个去试了,都是道听途说而已,如果有什么错误请帮我纠正下。
  最后是上面国际象棋棋盘例子的完整代码
  WebGL国际象棋棋盘

参考:
  http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml
网名:
34.203.245.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^