Я использую stb_image для загрузки 32-битного файла PNG (RGBA), и я создаю текстуру OpenGL с ним.
Он отлично работает для 24-битных файлов PNG (без альфа-канала), но когда я использую 32-битный файл PNG, что-то идет не так.
Вот как должна выглядеть текстура:
И вот как это выглядит при рендеринге с OpenGL (черные части должны быть прозрачными, и когда я включаю смешивание):
Вот как я загружаю текстуру:
int w;
int h;
int comp;
unsigned char* image = stbi_load(filename.c_str(), &w, &h, &comp, STBI_rgb);
if(image == nullptr)
throw(std::string("Failed to load texture"));
glGenTextures(1, &m_texture);
glBindTexture(GL_TEXTURE_2D, m_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if(comp == 3)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
else if(comp == 4)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glBindTexture(GL_TEXTURE_2D, 0);
stbi_image_free(image);
И это параметры окна (с использованием SDL)
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
Что происходит?
Изменение STBI_rgb на STBI_rgb_alpha в вызове функции stbi_load исправило это.
Наверное, лучше не указывать RGB, когда его RGBA: D
Ваша настоящая ошибка в том, что вы используете comp
определить свой format
(GL_RBA
/GL_RGBA
) параметр к glTexImage2D
, Это происходит потому, что при загрузке изображения с помощью stbi_load
, значение возвращается в comp
всегда будет соответствовать исходному изображению, а не возвращенным данным изображения.
Более конкретно, ваша ошибка в том, что вы используете STBI_rgb
, вызывая stbi_load
вернуть 3 байта пикселей, но затем вы загружаете его с glTexImage2D
как 4 байта пикселей с GL_RGBA
так как comp
4, когда вы загружаете 32-битное изображение.
Вы должны установить формат в вашем звонке glTexImage2D
в GL_RGB
если вы используете STBI_rgb
и к GL_RGBA
если вы используете STBI_rgb_alpha
,
Бонус другим читателям
У вас есть похожая проблема, и вышеупомянутое все еще не помогает? Тогда ваши данные изображения могут не иметь строк в выравнивании, ожидаемом OpenGL. Пытаться glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
прежде чем позвонить glTexImage2D
, Увидеть https://www.khronos.org/opengl/wiki/Pixel_Transfer#Pixel_layout для дополнительной информации.