'Textures show black when using GL_LINEAR_MIPMAP_LINEAR in emscripten

I have a small program that just draws a full screen quad with a texture.

This program works fine when I run it on Windows.

However it seems to fail when compiling to WebGL2 (GLES3) using Emscripten. It just shows a black quad.

I have figured out that the problem happens only when I enable mipmapping.

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

This is the code that initializes the texture:

glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
struct Color { u8 r, g, b; };
const Color pixels[] = {
    {255, 0, 0}, {0, 255, 0},
    {0, 0, 255}, {255, 255, 0}
};
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

EDIT:

I have found that, if instead of calling glGenerateMipmap, I specify the mip levels manually, it works!

glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
glTexImage2D(GL_TEXTURE_2D, 1, GL_SRGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);

Repo with the full code: https://github.com/tuket/emscripten_problem_with_mipmap_textures

EDIT2:

Another interesting finding: if instead of using a 3-channel texture, I use a 4-channel texture, it works!

struct Color { u8 r, g, b, a; };
const Color pixels[] = {
    {255, 0, 0, 255}, {0, 255, 0, 255},
    {0, 0, 255, 255}, {255, 255, 0, 255}
};
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
glGenerateMipmap(GL_TEXTURE_2D);


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source