问题:
在向FontAtlas提交纹理数据时,第三个参数是CacheTextureWidth,而这个值是512,也就是说每次是以行为单位进行纹理数据提交的,为什么呢?
_atlasTextures[_currentPage]->updateWithData(data, 0, startY, CacheTextureWidth, _currentPageOrigY - startY + _currLineHeight);
原因:
是因为纹理字节对齐,在Texture2D生成的时候,会自动计算字节对齐:
unsigned int bytesPerRow = pixelsWide * info.bpp / 8;
if(bytesPerRow % 8 == 0)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 8);
}
else if(bytesPerRow % 4 == 0)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
}
else if(bytesPerRow % 2 == 0)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
}
else
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
}
宽度为512的纹理字节对齐为8,那么对应的这个纹理单元的对齐也是8,之后如果要更新纹理数据,也需要注意width,否则在存储纹理的时候就会出现倾斜的问题,所以engine选择以行为单位进行纹理提交,就避免了这个问题。
如果要修改CacheTextureWidth
,需要注意alignment即可。
解决这个问题还有其他思路,比如提交的纹理数据自动补齐,满足alignment的要求即可。
相关资料
在OpenGL规范里面,也有这个说明:
glPixelStorei
sets pixel storage modes that affect the operation of subsequent glReadPixels
as well as the unpacking of texture patterns (see glTexImage2D
, glTexImage3D
, glTexSubImage2D
, glTexSubImage3D
).
GL_UNPACK_ALIGNMENT
Specifies the alignment requirements for the start of each pixel row in memory. The allowable values are 1 (byte-alignment), 2 (rows aligned to even-numbered bytes), 4 (word-alignment), and 8 (rows start on double-word boundaries).
网友评论