Нарисуйте текстуру в OpenGL, игнорируя ее альфа-канал
-
13-09-2020 - |
Вопрос
У меня есть текстура, загруженная в память в формате RGBA с различными альфа-значениями.
Изображение загружается следующим образом:
GLuint texture = 0;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
self.texNum = texture;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self.imageWidth, self.imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, [self.imageData bytes]);
Я хочу знать, как я могу нарисовать эту текстуру так, чтобы альфа-канал на изображении рассматривался как все 1, а текстура рисовалась как изображение RGB.
Рассмотрим базовое изображение:
Это изображение представляет собой прогрессию от 0 до 255 альфа и имеет значение RGB 255,0,0 на всем протяжении
Однако, если я нарисую его с отключенным смешиванием, я получу изображение, которое выглядит как:www.ldeo.columbia.edu /~jcoplan/alpha/no_alpha.png
Когда то, что я действительно хочу, - это изображение, которое выглядит следующим образом:www.ldeo.columbia.edu /~jcoplan/альфа/правильный.png
Я был бы очень признателен за несколько указаний, чтобы он полностью игнорировал альфа-канал.Обратите внимание, что я не могу просто изначально загрузить изображение в формате RGB, потому что мне нужен альфа-канал в других точках.
Редактировать:Я попытался использовать GL_COMBINE для решения моей проблемы как таковой:
glColorf(1,1,1,1);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
[self drawTexture];
Но по-прежнему безуспешно, он по-прежнему превращает черное в красное.
Решение
У меня есть текстура, загруженная в память, которая имеет формат RGBA с различными значениями альфа
gldisable (gl_blend)
Однако, если я рисую его с помощью смешивания, я получаю изображение, похожее на www.ldeo.columbia.edu/~jcoplan/alpha/no_alpha.png
Это происходит потому, что в вашем исходном изображении все прозрачные пиксели черные.Это проблема с вашей текстурой / изображением или, возможно, с функцией погрузчика, но это не проблема OpenGL.
Вы, вероятно, можете попытаться исправить его с помощью GLTEXEXENV (GL_COMBINE ...) (т. Е. Цвет текстуры смешивания с базовым цветом на основе альфа-канала), но так как я не сделал что-то подобное, я не совсем не совсемИ не могу дать вам точные операнды.Это было возможно в Direct3D9 (используя D3DTOP_MODULATEALPHA_ADDCOLOR), поэтому, скорее всего, есть способ сделать это в OpenGL.
Другие советы
Вы не должны отключить смешивание, но используйте Ta ref="http://pyopengl.sourceforge.net/documentation/manual/glblendfuncumpation/manual/glbleendfunc.3g.html" rel="nofollow noreferrer"> glblendfunc с правильнымПараметры:
glBlendFunc(GL_ONE, GL_ZERO);
. Или вы могли бы указать OpenGL загружать только каналы RGB вашего изображения, используя
glPixelStorei(GL_UNPACK_ALIGNMENT, 4)
прежде чем ты позвонишь glTexImage2D
с форматом, установленным на GL_RGB
.Это приведет к пропуску четвертого байта каждого пикселя, т.е.альфа-канал.
У меня была похожая проблема, и выяснила, что это потому, что загрузка изображений iOS выполняет превзойти на значения RBG (как обсуждалось в некоторых других ответах и комментариях здесь).Я хотел бы знать, есть ли способ отключить предварительное умножение, но тем временем я «не размножаясь», используя код, полученный из Эта нить и
// un pre-multiply
uint8_t *imageBytes = (uint8_t *)imageData ;
int byteCount = width*height*4 ;
for (int i=0; i < byteCount; i+= 4) {
uint8_t a = imageBytes[i+3] ;
if (a!=255 && a!=0 ){
float alphaFactor = 255.0/a ;
imageBytes[i] *= alphaFactor ;
imageBytes[i+1] *= alphaFactor ;
imageBytes[i+2] *= alphaFactor ;
}
}
.