为 2D 纹理数组生成 mip 级别
Posted
技术标签:
【中文标题】为 2D 纹理数组生成 mip 级别【英文标题】:Generating mip levels for a 2D texture array 【发布时间】:2011-09-30 22:17:18 【问题描述】:我有一个关于 OpenGL 纹理数组的简单(我认为)问题。我使用以下内容创建纹理数组:
glTexImage3D( GL_TEXTURE_2D_ARRAY,
0,
formatGL,
width,
height,
slices,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
nullptr);
请注意,我还不想实际将任何图像加载到其中。我只是在创建稍后将填充数据的结构。
所以我的问题是:
如何为纹理数组的每个“切片”生成 mip 链?我不想物理生成mip,我只想通过告诉它mip来完成纹理。我可以用 2D 纹理简单地通过调用 glTexImage2D 函数和 mip 级别、大小并传入一个 nullptr 来实现。鉴于没有“切片”参数,我看不到如何使用 glTexImage3D 函数执行此操作。 OpenGL 超级示例仅将 .bmp 加载到数组中每个纹理的第一个 mip 级别。说使用 glTexSubImage3D 并传入 nullptr 将为数组中的给定纹理创建我想要的 mip 级别是否正确?
khronos.org 上关于 glGenerateMipMap 的文档仅指定 GL_TEXTURE_2D 或 GL_TEXTURE_CUBE_MAP。那么说我不能将这种方法用于 2D 纹理数组是否正确?
以下是我使用 2D 纹理创建 mip 链的方法:
size_t i = 0, mipSizeX = width, mipSizeY = height;
while(mipSizeX >= 1 || mipSizeY >= 1)
// Generate image for this mip level
glTexImage2D( GL_TEXTURE_2D,
i,
formatGL,
mipSizeX,
mipSizeY,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
nullptr);
// Go to the next mip size.
mipSizeX >>= 1;
mipSizeY >>= 1;
// and the next mipmap level.
i++;
【问题讨论】:
【参考方案1】:我可以简单地通过调用 glTexImage2D 函数和 mip 级别、大小并传入一个 nullptr 来处理 2D 纹理。鉴于没有“切片”参数,我看不到如何使用 glTexImage3D 函数执行此操作。
为什么不呢? glTexImage3D 采用 mipmap 级别,就像 glTexImage2D 一样。它需要一个大小,在 2D 中是二维,但在 3D 中是三个维度。
确实,两个函数之间的唯一区别在于它们采用的维数(以及可能的target
参数)。并且有一个“切片”参数;您在向我们展示的通话中将其与 glTexImage3D 一起使用。在那里,它被称为depth
。
3D 纹理和 2D 数组纹理之间的区别在于,depth
在 2D 数组的较低 mipmap 中不会改变。数组的每个 mipmap 与其他每个 mipmap 具有相同数量的“切片”。
khronos.org 上的文档
如果它是在“khronos.org”而不是“opengl.org”,那么几乎可以肯定是在谈论 OpenGL ES,它没有数组纹理(稍后说明: strong> ES 3.0 添加了数组纹理)。
如果不实际为您编写代码,我真的不知道如何变得更清晰。
size_t i = 0, mipSizeX = width, mipSizeY = height;
while(mipSizeX >= 1 || mipSizeY >= 1)
// Generate image for this mip level
glTexImage3D( GL_TEXTURE_2D_ARRAY,
i,
formatGL,
mipSizeX,
mipSizeY,
arrayCount,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
nullptr);
// Go to the next mip size.
mipSizeX >>= 1;
mipSizeY >>= 1;
// and the next mipmap level.
i++;
另外,您需要检查 mipmap 大小的最小值是否为 1。因为 (1 >> 1) == 0
。
【讨论】:
我不确定在这种情况下将什么放入“切片”参数中。零?这里的问题是我正在构建一个 2d 纹理,通过 3d 界面并没有真正用我的大脑计算:p。 @Robinson:问题在于您没有制作 2D 纹理。您正在制作 2D 纹理的 array。该数组中元素的数量是 depth (我不知道你从哪里得到“切片”,因为the documentation 清楚地使用了“深度”这个词。 抱歉,slices 在其他地方是这样称呼的!所以我迭代mip级别也迭代“深度”,调用glTextImage3D,GL会随着深度的增加自动扩展数组?我假设深度是“我想要数组中有多少图像”,而不是“索引到数组中”,主要是因为当我第一次调用它时,数组还不存在。 @Robinson:深度是“我想要数组中有多少图像”;这就是我在写“该数组中元素的数量是深度”时所说的。 @Robinson:把它想象成用new[]
分配一个对象数组。 depth
是您放入 [] 的内容。以上是关于为 2D 纹理数组生成 mip 级别的主要内容,如果未能解决你的问题,请参考以下文章
CCTexture2D CCSpriteBatchNode CCTextureCache CCSpriteFrameCache 分析
CCTexture2D CCSpriteBatchNode CCTextureCache CCSpriteFrameCache 分析
如何在 glTexImage2D 中使用动态大小的纹理数组?