无法手动设置每个纹理 mipmap 级别

Posted

技术标签:

【中文标题】无法手动设置每个纹理 mipmap 级别【英文标题】:Not able to set each texture mipmap level manually 【发布时间】:2019-10-14 15:06:30 【问题描述】:

我无法在 opengl 中手动设置 mipmap 级别。这不会引发错误,但不会显示纹理。取消注释 glGenerateMipmap(GL_TEXTURE_2D) 有效(意味着它可以工作,mipmap 级别不是由我设置的)。

我的 mipmap 级别似乎是完整的,因为最后一个级别 (12) 是 1x1 图像。 知道我在这里做错了什么吗?

Texture::Texture(const std::string texture_levels[]) 
: m_FilePath(texture_levels[0]), m_LocalBuffer(nullptr), m_Width(0), m_Height(0), m_BPP(0)


    stbi_set_flip_vertically_on_load(1);
    GLCall(glGenTextures(1, &m_RendererID));
    GLCall(glBindTexture(GL_TEXTURE_2D, m_RendererID));
    GLCall(glTexParameteri(GL_TEXTURE\_2D, GL_TEXTURE_BASE_LEVEL, 0));
    GLCall(glTexParameteri(GL_TEXTURE\_2D, G_TEXTURE_MAX_LEVEL, 12));

    for (int i = 0; i < 13; i++) 
        m_LocalBuffer = stbi_load(texture_levels[i].c_str(), &m_Width, &m_Height, &m_BPP, 4);
            GLCall(glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_LocalBuffer));
    

    GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR));
    GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
    GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
    GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));

    // glGenerateMipmap(GL_TEXTURE_2D);

    GLCall(glBindTexture(GL_TEXTURE_2D, 0));
    if (m_LocalBuffer)
            stbi_image_free(m_LocalBuffer);



Texture::~Texture()

    GLCall(glDeleteTextures(1, &m_RendererID));


void Texture::Bind(unsigned int slot) const

    GLCall(glActiveTexture(GL_TEXTURE0 + slot));
    GLCall(glBindTexture(GL_TEXTURE_2D, m_RendererID));


void Texture::Unbind()

    GLCall(glBindTexture(GL_TEXTURE_2D, 0));

在 Main.cpp 中:


std::string texture_levels[] =

    "res/textures/istanbul/01.png",
    "res/textures/istanbul/02.png",
    "res/textures/istanbul/03.png",
    "res/textures/istanbul/04.png",
    "res/textures/istanbul/05.png",
    "res/textures/istanbul/06.png",
    "res/textures/istanbul/07.png",
    "res/textures/istanbul/08.png",
    "res/textures/istanbul/09.png",
    "res/textures/istanbul/10.png",
    "res/textures/istanbul/11.png",
    "res/textures/istanbul/12.png",
    "res/textures/istanbul/13.png"
;



Texture texture(texture_levels);
texture.Bind();

【问题讨论】:

注意,a 级别的大小必须是前一个级别向下舍入的一半。见Mipmap completeness。 @Rabbid76,非常感谢。这就是问题所在。 【参考方案1】:

一个级别的mitmap的大小必须是前一个级别大小的一半,向下取整。 见Mipmap completeness。

更具体地说,i 级别的 mipmap 的宽度、高度或深度的大小是纹理图像的相应大小除以 2^i 的组成部分。最后一个mipmap级别的大小对于所有维度都是1,因此mipmap级别的数量取决于纹理的大小并且是log2(maxsize) + 1(截断),其中maxsize是最大尺寸的纹理的dimesnison。

规范中的相关部分是OpenGL 4.6 API Core Profile Specification - 8.14.3 Mipmapping, page 265

【讨论】:

以上是关于无法手动设置每个纹理 mipmap 级别的主要内容,如果未能解决你的问题,请参考以下文章

如何基于最大值而不是默认合并创建 mipmap?

最后显示mipmap某一级别纹理时 这个级别是gpu选择的还是写的渲染程序里设置的

mipmap到底有啥作用

所有 OpenGL 纹理调用中使用的“级别”参数到底是啥?

OpenGL RGB DXT1压缩纹理mipmap上传

TextureFilters(MipMap生成)如何影响性能?