尝试使用RGBA格式的数据创建1px x 4px的纹理,如下所示:
const texture = gl.createTexture()
gl.activeTexture(gl.TEXTURE0)
gl.bindTexture(gl.TEXTURE_2D, texture)
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([
255, 0, 0, 255,
0, 255, 0, 255,
0, 0, 255, 255,
255, 255, 0, 255
]))
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
但是,尝试像这样对RGB格式做同样的事情:
const texture = gl.createTexture()
gl.activeTexture(gl.TEXTURE0)
gl.bindTexture(gl.TEXTURE_2D, texture)
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 4, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array([
255, 0, 0,
0, 255, 0,
0, 0, 255,
255, 255, 0
]))
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
在Firefox中给出此错误:
错误:WebGL警告:texImage2D:所需的上载需要的数据多于可用数据:(3行加1像素所需,3行加0像素可用)
Chrome中的此错误:
WebGL:INVALID_OPERATION:texImage2D:ArrayBufferView不足以容纳请求
交换gl.texImage2D的width和height参数,所以我有一个4px x 1px的纹理,然后可以与gl.RGB一起使用,但是2px x 2px的纹理则不能。我在这里出什么毛病/误解了?
答案 0 :(得分:2)
由于WebGL 1.0基于OpenGL ES 2.0 API,因此我将引用OpenGL ES 2.0 refpages glPixelStorei
GL_UNPACK_ALIGNMENT
指定内存中每个像素行开始的对齐要求。允许值为1(字节对齐),2(行与偶数字节对齐),4(字对齐)和8(行从双字边界开始)。
UNPACK_ALIGNMENT
对齐参数的初始值为4。
如果您指定宽度为4像素的RGB纹理,则一行的大小(以3 * 4 = 12个字节)。
如果纹理的高度为1,则预期的纹理大小为12 * 1 = 12。
但是,如果您指定的RGB纹理具有1个像素,则一行的大小为3 * 1 = 3个字节。
如果UNPACK_ALIGNMENT
为4,则此大小对齐为4个字节。
如果纹理的高度为4,则预期的纹理大小为4 * 4 = 16字节。
第二种情况与您用来初始化纹理的数据数组不匹配,这会导致错误。
要解决此问题,必须将纹理的每一行对齐到4个字节:
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 4, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array([
255, 0, 0, 0, // add 1 byte for alignment to 4 bytes
0, 255, 0, 0, // add 1 byte
0, 0, 255, 0, // add 1 byte
255, 255, 0, 0 // add 1 byte
]))
或通过gl.pixelStorei
将gl.UNPACK_ALIGNMENT
参数设置为1:
gl.pixelStorei( gl.UNPACK_ALIGNMENT, 1 )
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 4, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array([
255, 0, 0,
0, 255, 0,
0, 0, 255,
255, 255, 0
]))