Search code examples
openglglsltexturesopengl-3mipmaps

glsl non-mipmapped textures do not display


I have been successfully displaying textures on geometry using my own mini pipeline (using mipmaps), but I have decided not to use mip-maps because my software won't really need any change in level-of-detail. It's 2d and uses pixel art. Detail shouldn't change. I'll add that I am trying to loop textures within a texture atlas and disabling mip-mapping might help avoid issues.

However, not calling glGenerateMipmap yields a blank screen. Calling it yields the proper texture.

Is there another function that I must call instead?

The following is my texture generation function (I pass a pointer to an already-created texture id.)

GLboolean GL_texture_load(Texture* texture_id, const char* const path, const GLboolean alpha, const GLint param_edge)
{
    // load image
    SDL_Surface* img = nullptr; 
    if (!(img = IMG_Load(path))) {
        fprintf(stderr, "SDL_image could not be loaded %s, SDL_image Error: %s\n", 
               path, IMG_GetError());
        return GL_FALSE;
    }


    glBindTexture(GL_TEXTURE_2D, *texture_id);
    // image assignment
    GLuint format = (alpha) ? GL_RGBA : GL_RGB;
    glTexImage2D(GL_TEXTURE_2D, 0, format, img->w, img->h, 0, format, GL_UNSIGNED_BYTE, img->pixels);
    glGenerateMipmap(GL_TEXTURE_2D); // commenting this out yields a blank screen

    // wrapping behavior
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, param_edge);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, param_edge);
    // texture filtering
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // I won't want these because the texture should have constant detail / resolution
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);
    // free the surface
    SDL_FreeSurface(img);

    return GL_TRUE;
}

I use SDL2_Image for png files and the texture size is not necessarily power-of-two. (I am not optimizing this yet.)

What might I be missing? Which parameters should I set just to render a non-filtered texture? I doubt that mipmapping is a requirement. Is it possible that without mipmapping I am not able to use sampler2D or texture() as usual? That would be strange.

Thank you in advance.

EDIT: BDL's answer helped. For reference, the following is my modified code:

GLboolean GL_texture_load(Texture* texture_id, const char* const path, const GLboolean alpha, const GLint param_edge_x, const GLint param_edge_y)
{
    // load image
    SDL_Surface* img = nullptr; 
    if (!(img = IMG_Load(path))) {
        fprintf(stderr, "SDL_image could not be loaded %s, SDL_image Error: %s\n", 
               path, IMG_GetError());
        return GL_FALSE;
    }


    glBindTexture(GL_TEXTURE_2D, *texture_id);
    // image assignment
    GLuint format = (alpha) ? GL_RGBA : GL_RGB;
    glTexImage2D(GL_TEXTURE_2D, 0, format, img->w, img->h, 0, format, GL_UNSIGNED_BYTE, img->pixels);

    // wrapping behavior
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, param_edge_x);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, param_edge_y);
    // texture filtering
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glBindTexture(GL_TEXTURE_2D, 0);
    // free the surface
    SDL_FreeSurface(img);

    return GL_TRUE;
}

Solution

  • Whether mipmaps for a texture are required or not depends on the filter mode used. When a filtermode with ..._MIPMAP_... is used, then a mipmap has to be available (no matter if it is accessed or not).

    If you don't want mipmaps, use either GL_LINEAR or GL_NEAREST for the GL_TEXTURE_MIN_FILTER. For a pixelated look you will most probably need the GL_NEAREST.