Нарисуйте текстуру в OpenGL, игнорируя ее альфа-канал - PullRequest
3 голосов
/ 08 июля 2010

У меня загружена текстура в память формата 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.

Рассмотрим базовое изображение:

http://www.ldeo.columbia.edu/~jcoplan/alpha/base.png

Это изображение представляет собой последовательность от 0 до 255 альфа и имеет значение RGB 255,0,0 на всем протяжении

Однако, если я нарисую его с отключенным смешиванием, я получу изображение, которое выглядит следующим образом: www.ldeo.columbia.edu/~jcoplan/alpha/no_alpha.png

Когда то, что я действительно хочу, это изображение, которое выглядит так: www.ldeo.columbia.edu/~jcoplan/alpha/correct.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];

Но все-таки не повезло, оно все еще тянет от черного к красному.

Ответы [ 4 ]

3 голосов
/ 08 июля 2010

У меня загружена текстура в память формата RGBA с различными значениями альфа

glDisable (GL_BLEND)

Однако, если я рисую ее сотключение смешивания Я получаю изображение, которое выглядит следующим образом: www.ldeo.columbia.edu/~jcoplan/alpha/no_alpha.png

Это происходит потому, что в исходном изображении все прозрачные пиксели имеют черный цвет.Это проблема с вашей текстурой / изображением или, возможно, с функцией загрузчика, но это не проблема OpenGL.

Возможно, вы можете попытаться исправить это с помощью glTexEnv (GL_COMBINE ...) (то есть смешать цвет текстуры сосновной цвет, основанный на альфа-канале), но так как я не сделал что-то подобное, я не совсем уверен, и не могу дать вам точные операнды.Это было возможно в Direct3D9 (с использованием D3DTOP_MODULATEALPHA_ADDCOLOR), поэтому, скорее всего, есть способ сделать это в opengl.

1 голос
/ 08 июля 2010

Вы не должны отключать смешивание, а использовать glBlendFunc с правильными параметрами:

glBlendFunc(GL_ONE, GL_ZERO);
0 голосов
/ 23 декабря 2011

У меня была похожая проблема, и я обнаружил, что это произошло потому, что загрузка изображений 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 ; 
        }
    }
0 голосов
/ 09 июля 2010

Или вы можете указать OpenGL загружать только каналы RGB вашего изображения, используя

glPixelStorei(GL_UNPACK_ALIGNMENT, 4)

перед вызовом glTexImage2D с форматом, установленным на GL_RGB. Это заставит его пропускать четвертый байт каждого пикселя, то есть альфа-канал.

...