Search code examples
c++openglgraphicstextures

Not able to set each texture mipmap level manually


I'm not able to manually set the mipmap levels in opengl. This doesn't throw an error but no texture is displayed. Uncommenting glGenerateMipmap(GL_TEXTURE_2D) works (means it works the mipmap levels aren't set by me).

My mipmap levels seem to be complete as the last level (12) is a 1x1 image. Any idea what I could be doing wrong here?

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));
}

In 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();

Solution

  • The size of a mitmap at a level has to be half of the size of the previous level, rounded down. See Mipmap completeness.

    More concretely, the size of a width, height or depth of a mipmap at a level i is the integral part of a division of the corresponding size of the texture image by 2^i. The size of the last mipmap level is 1 for all dimensions, so the number of mipmap levels depends on the size of the texture and is log2(maxsize) + 1 (truncated), where maxsize is the dimesnison of the texture with the greatest size.

    Th relevant part in the specification is OpenGL 4.6 API Core Profile Specification - 8.14.3 Mipmapping, page 265