2011-02-11 16 views
9

Hay 3 fondos en la imagen de abajo: negro blanco & gris¿Qué causaría las diferencias de mezcla alfa de OpenGL entre Windows y OS X?

Hay 3 bares en cada uno: negro -> transparente, blanco -> transparentes y colores -> transparente

estoy usando glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); y todos mis colores de vértice son 1,1,1,0.

El defecto es realmente visible en el blanco-> transparente sobre fondo blanco.

En Windows XP (y otros sabores de Windows), funciona perfectamente y me pongo completamente blanco. En Mac, sin embargo, ¡me pongo gris en el medio!

¿Qué podría causar esto, y por qué se volvería más oscuro cuando mezcle blanco sobre blanco?

Captura de pantalla de tamaño completo es @http://dl.dropbox.com/u/9410632/mac-colorbad.png

Screenshot

información Actualizado:

En Windows, es imposible parece importar sobre la versión de OpenGL. 2.0 a 3.2, todo funciona. En la Mac tengo frente a mí ahora, es 2.1.

Los degradados se mantuvieron en texturas, y todos los vértices son de color 1,1,1,1 (rgb blanco, alfa completo). Los fondos son solo texturas de 1x1 píxeles (atlased con los degradados) y los vértices se colorean según sea necesario, con alfa completo.

El atlas se ha creado con glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, data); Viene de un archivo dds ARGB que yo mismo he compuesto.

También debo señalar que todo lo que se dibuja usando un shader trivally simple:

 
uniform sampler2D tex1; 
uniform float alpha; 

void main() { 
    gl_FragColor = gl_Color * texture2D(tex1, gl_TexCoord[0].st) * vec4(1.0, 1.0, 1.0, alpha); 
} 

el uniforme alfa se establece en 1,0

Ahora, yo trato de cambiarlo por lo que el gradiente de blanco no era una textura, pero solo 4 vértices donde los de la izquierda eran de color blanco sólido y opaco, y los de la derecha eran 1,1,1,0, ¡y eso funcionó!

He comprobado tres veces la textura ahora, y solo es blanca, con variación de alfa 1.0-> 0.0.

Estoy pensando que esto puede ser un problema por defecto. La versión de OpenGL o el controlador puede inicializar las cosas de manera diferente.

Por ejemplo, recientemente descubrí que todos tienen GL_TEXTURE_2D glEnabled por defecto, pero no Intel GME965.

solución encontrada

En primer lugar, un poco más de fondo. Este programa está realmente escrito en .NET (usando Mono en OS X), y el archivo DDS que estoy escribiendo es un atlas generado automáticamente compactando un directorio de archivos PNG de 24 bits en la textura más pequeña que pueda. Estoy cargando esos PNG utilizando System.Drawing.Bitmap y los renderizo en un mapa de bits más grande después de determinar el diseño. Ese mapa de bits posterior al diseño está bloqueado (para obtenerlo en sus bytes), y esos están escritos en un DDS por el código que escribí.

Al leer los consejos de Bahbar, comprobé las texturas en la memoria y fueron realmente diferentes. Mi DDS cargado parece ser el culpable y no cualquier configuración de OpenGL. En un presentimiento hoy, revisé el archivo DDS en sí mismo en las dos plataformas (utilizando un byte para comparación de bytes), y de hecho, ¡eran diferentes! Cuando cargo los archivos DDS usando WTV (http://developer.nvidia.com/object/windows_texture_viewer.html), parecían idénticos. Sin embargo, al usar WTV, puede apagar cada canal (R G B A). Cuando apagué el canal Alpha, en las ventanas vi una imagen realmente mala. Ningún alfa daría lugar a bordes antialias, por lo que, por supuesto, se vería horrible. Cuando apagué el canal alfa en el OSX DDS, ¡se veía bien!

El cargador PNG en Mono es premultiplicado, causando todos mis problemas. Ingresé un ticket para ellos (https://bugzilla.novell.com/show_bug.cgi?id=679242) y cambié a usar directamente libpng.

¡Gracias a todos!

+0

¿cuál es el formato de superficie de representación? esp. con respecto a SRGB? Sin embargo, el blanco sobre blanco me ha dejado perplejo. – Bahbar

+1

¿Las barras se dibujan utilizando texturas o usando interpolación de color? – rotoglup

+0

cuyos vértices son 1,1,1,0? incluso los fondos negros, blancos, grises? –

Respuesta

1

Revise su cargador de dds. Podría estar haciendo la pre-multiplicación de la que hablaba John Bartholomew con carga, solo en una plataforma.

Una manera fácil de verificar es también mirar los datos mientras se cargan en la textura, en la llamada glTexImage. ¿Es esa información completamente uniforme?

+0

bien, encontré el problema y lo clavaste. –

2

Esto es algo así como una puñalada en la oscuridad, pero verifica (o configura explícitamente) los modos de transferencia de píxeles.

El resultado que está obteniendo se parece a los resultados que esperaría si estuviera usando texturas con alfa pre-multiplicada pero luego usando el modo de fusión que ha establecido. Algo puede haber configurado los modos de transferencia de píxeles para multiplicar alfa en los canales de color cuando se cargan las texturas.

También puede comprobar si el resultado de Mac es correcto (con texturas) cuando establece el modo de fusión en glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA).

+0

Es una DDS sin comprimir, y estoy de cargarlo usando: 'glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, datos);' no estoy premultiplicando ella .. me simplemente lea el archivo DDS del disco y pase la parte que no corresponde al encabezado a la llamada anterior. ¿Qué llamadas OpenGL afectarían cómo la carga posiblemente se premultiplica? –

+0

Imprimí el valor de GL _ * _ SCALE y GL _ * _ BIAS y ambos son iguales en Windows y Mac (1 para las escalas, 0 para el sesgo), así que no es eso. Cuando uso el modo de combinación GL_ONE en lugar de GL_SRC_ALPHA, veo el blanco correctamente, pero luego se rompen todas las superposiciones de mi oscurecimiento. –

+0

Existe (o puede haber, según la versión y las extensiones opengl) una matriz de color aplicada durante la transferencia de píxeles. Intente borrarlo con 'glMatrixMode (GL_COLOR); glLoadIdentity(); ' –

Cuestiones relacionadas