我正在阅读有关加载DDS纹理的内容。我阅读了this文章并看到this发帖。 (我还阅读了wiki about S3TC)
我理解了大部分代码,但有两行我没有完全理解。
blockSize = (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16;
和
size = ((width + 3) / 4) * ((height + 3) / 4) * blockSize;
和
bufsize = mipMapCount > 1 ? linearSize * 2 : linearSize;
什么是blockSize
?为什么我们将8
用于DXT1
和16
用于其余部分?
我们在计算size
时到底发生了什么?更多
具体为什么我们添加3
,除以4
然后再乘以
按blockSize
?
2
?mipMapCount > 1
醇>
答案 0 :(得分:2)
DXT1-5格式也称为BCn格式(以数字结尾但不完全相同),BC代表块压缩。像素不是单独存储的,它只存储相当于4x4像素的数据块。
第一个行检查它是否是DXT1,因为它的每个块大小为8个字节。 DXT3和DXT5每块使用16个字节。 (请注意,存在较新的格式,其中至少有一个是8字节/块:BC4)。
第二将纹理的尺寸四舍五入为块的多个维度。这是必需的,因为这些格式只能存储块,而不能存储像素。例如,如果您的纹理为15x6像素,并且由于BCn块为4x4像素,则需要每列存储4个块,每行存储2个块,即使最后一列/每行块仅部分填充
将正整数(将其称为QCustomLabel *list[80];
QMdiSubWindowMod *onglet = m_mainArea->activeSubWindow(); //Problem here because of the type of return which is a QMdiSubWindow and not a QMdiSubWindowMod
)四舍五入为另一个正整数的倍数(让我们称之为i
)的一种方法是:< / p>
m
在这里,我们需要获取每个维度上的块数,然后乘以块的大小以获得纹理的总大小。为此,我们将(i + m - 1) / m * m
和width
四舍五入到下一个4的倍数,除以4得到块数,最后将其乘以块的大小:
height
如果你仔细观察,那么a * 4后跟一个可以简化的/ 4。如果你这样做,你将得到完全相同的代码。所有这些结论都可以评论任何不完全明显的代码:P
第3行行可能是近似值,用于计算足够大的缓冲区大小,以便轻松存储整个mipmap链。但我不确定这是size = (((width + 3) / 4 * 4) * ((height + 3) / 4 * 4)) / 4 * blockSize;
// ^ ^ ^
是什么;它对应DDS header中的linearSize
。在任何情况下,您都不需要这个值,因为您可以使用上面的代码轻松计算每个级别的大小。