Pregunta

Tengo una textura cargada en la memoria que es de formato RGBA con varios valores alfa.

La imagen se carga así:

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

Quiero saber cómo puedo dibujar esta textura para que el canal alfa de la imagen se trate como todos unos y la textura se dibuje como una imagen RGB.

Considere la imagen base:

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

Esta imagen es una progresión de 0 a 255 alfa y tiene un valor RGB de 255,0,0 en todo momento.

Sin embargo, si lo dibujo con la combinación desactivada, obtengo una imagen similar a la siguiente:www.ldeo.columbia.edu/~jcoplan/alpha/no_alpha.png

Cuando lo que realmente quiero es una imagen como esta:www.ldeo.columbia.edu/~jcoplan/alpha/correct.png

Realmente agradecería algunos consejos para que ignore el canal alfa por completo.Tenga en cuenta que inicialmente no puedo cargar la imagen como RGB porque necesito el canal alfa en otros puntos.

Editar:Intenté usar GL_COMBINE para resolver mi problema como tal:

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

Pero aún así no hubo suerte, todavía dibuja de negro a rojo.

¿Fue útil?

Solución

Tengo una textura cargada en la memoria que es del formato RGBA con varios valores alfa

gldisable (gl_blend)

Sin embargo, si lo dibujo con la mezcla deshabilitada, obtengo una imagen que parece: www.ldeo.columbia.edu/~jcoplan/alpha/no_alpha.png

Esto sucede porque en su imagen de origen, todos los píxeles transparentes son negros.Es un problema con su textura / imagen, o tal vez con la función del cargador, pero no es un problema de OpenGL.

probablemente podría intentar solucionarlo usando GLTEXENV (GL_COMBINE ...) (es decir, mezcle el color de la textura con un color subyacente basado en el canal alfa), pero como no he hecho algo así, no estoy completamente seguro,y no puedo darte operandos exactos.Fue posible en Direct3D9 (usando D3DTOP_MODULATATEALPHA_ADDCOLOR), lo más probable es que haya una manera de hacerlo en OpenGL.

Otros consejos

No debe deshabilitar la mezcla, sino que use la glblendfunc con el correctoParámetros:

glBlendFunc(GL_ONE, GL_ZERO);

O podría decirle a OpenGL que cargue solo los canales RGB de su imagen usando

glPixelStorei(GL_UNPACK_ALIGNMENT, 4)

antes de llamar glTexImage2D con el formato establecido en GL_RGB.Hará que se salte el cuarto byte de cada píxel, es decir.el canal alfa.

Tuve un problema similar, y descubrí que fue porque IOS Image Loading estaba haciendo un valor premultivo en los valores de RBG (como se discutió en algunas de las otras respuestas y comentarios aquí).Me encantaría saber si hay una forma de deshabilitar la multiplicación previa, pero mientras tanto, estoy "des-multiplicando" usando el código derivado de este hilo y este hilo .

    // 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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top