Pergunta

Eu tenho uma textura carregado na memória, o que é de formato RGBA com vários valores de alfa.

A imagem é carregada assim:

 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]);

Eu quero saber como eu posso tirar essa textura para que o canal alfa em que a imagem é tratada como todos os 1 e a textura é desenhada como uma imagem RGB.

Considere a imagem base:

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

Esta imagem é uma progressão de 0 a 255 alpha e tem o valor RGB de 255,0,0 todo

No entanto, se eu desenhe-a com a mistura de deficiência e obter uma imagem que se parece com:www.ldeo.columbia.edu/~jcoplan/alfa/no_alpha.png

Quando o que eu realmente quero é uma imagem que se parece com isso:www.ldeo.columbia.edu/~jcoplan/alfa/corrigir.png

Eu realmente aprecio alguns ponteiros para que ele ignorar o canal alfa completo.Note que eu não posso basta carregar a imagem em RGB, inicialmente, porque eu preciso o canal alfa em outros pontos.

Editar:Eu tentei usar GL_COMBINE para resolver o meu problema:

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];

Mas ainda sem sorte, ele desenha preto para o vermelho ainda.

Foi útil?

Solução

Eu tenho uma textura carregado na memória, o que é de formato RGBA com vários valores de alfa de

glDisable(GL_BLEND)

No entanto, se eu desenhe-a com a mistura de deficiência e obter uma imagem que se parece com:www.ldeo.columbia.edu/~jcoplan/alfa/no_alpha.png

Isso acontece porque, na sua imagem de origem de todos os pixels transparentes são pretos.É um problema com a sua textura de imagem, ou talvez com carregador de função, mas não é uma OpenGL problema.

Você provavelmente poderia tentar corrigi-lo usando glTexEnv(GL_COMBINE...) (i.é.mistura de texturas de cores subjacentes de cor de acordo com canal alpha), mas desde que eu não tenha feito algo assim, eu não estou completamente certo, e não pode dar o que você exato operandos.Foi possível no Direct3D9 (usando D3DTOP_MODULATEALPHA_ADDCOLOR), então provavelmente há uma maneira de fazê-lo em opengl.

Outras dicas

Você não deve desabilitar a mistura, mas usar o glBlendFunc com a devida parâmetros:

glBlendFunc(GL_ONE, GL_ZERO);

Ou você poderia dizer OpenGL para carregar apenas os canais RGB da imagem usando

glPixelStorei(GL_UNPACK_ALIGNMENT, 4)

antes de chamar glTexImage2D com formato de GL_RGB.Isso fará com que ele pule o quarto byte de cada pixel, i.é.o canal alfa.

Eu tive um problema semelhante, e descobri que era porque iOS imagem de loading era fazer um pré-multiplicar na RBG valores (como discutido em algumas das outras respostas e comentários aqui).Gostaria de saber se existe uma maneira de desabilitar a pré-multiplicação, mas, entretanto, eu sou "un-pré-multiplicando-se" usando o código de derivados de esta thread e esta thread.

    // 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 ; 
        }
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top