La Red de Conocimientos Pedagógicos - Currículum vitae - Problema de mezcla de colores en OpenGL (canal Alfa)

Problema de mezcla de colores en OpenGL (canal Alfa)

Mezcla de colores OpenGL 2009-10-14 10:05 Hoy presentaré los conocimientos básicos sobre la mezcla OpenGL. La mezcla es una técnica común que a menudo se puede utilizar para lograr translucidez. Pero, de hecho, también es muy flexible. Puede obtener diferentes resultados de mezcla a través de diferentes configuraciones, produciendo algunas imágenes interesantes o extrañas.

¿Qué es mezclar? Mezclar es mezclar dos colores. Para ser más específicos, se trata de mezclar el color original de una determinada posición de píxel y el color a pintar de alguna forma para lograr un efecto especial.

Supongamos que necesitamos dibujar una escena como esta: mirando un objeto verde a través de un cristal rojo, entonces podemos dibujar primero el objeto verde y luego el cristal rojo. Al dibujar vidrio rojo, use la función "Mezclar" para mezclar el rojo que va a dibujar con el verde original, de modo que obtenga un nuevo color que parezca translúcido.

Para usar la función de combinación de OpenGL, simplemente llame a: glEnable(GL_BLEND);.

Para desactivar la función de mezcla de OpenGL, simplemente llame a: glDisable(GL_BLEND);.

Nota: La función de fusión solo se puede utilizar en el modo RGBA. La función de fusión no se puede utilizar en el modo de índice de color.

1. Factor fuente y factor objetivo

Hemos mencionado antes que la mezcla requiere encontrar el color original y el color a pintar, y procesarlo de alguna forma para obtener una Planta nueva. bandera. Aquí, el color a pintar se denomina "color de origen" y el color original se denomina "color de destino".

OpenGL tomará el color de origen y el color de destino cada uno y los multiplicará por un coeficiente (el coeficiente por el cual se multiplica el color de origen se llama "factor de origen", y el coeficiente por el cual se multiplica el color de destino El color se multiplica se denomina "factor objetivo") y luego los suma para obtener el nuevo color. (No es necesario que sea una suma. La nueva versión de OpenGL puede establecer el método de operación, incluida la suma, la resta, tomar el mayor de los dos, tomar el menor de los dos, operaciones lógicas, etc., pero por el bien de simplicidad, no lo discutiremos aquí. Esto es todo)

A continuación se utilizan fórmulas matemáticas para expresar este método de operación. Suponga que los cuatro componentes del color de origen (refiriéndose a rojo, verde, azul, valor alfa) son (Rs, Gs, Bs, As), y los cuatro componentes del color de destino son (Rd, Gd, Bd, Ad) y suponga que los factores de origen son (Sr, Sg, Sb, Sa) y los factores de destino son (Dr, Dg, Db, Da). Entonces el nuevo color producido al mezclar se puede expresar como:

(Rs*Sr Rd*Dr, Gs*Sg Gd*Dg, Bs*Sb Bd*Db, As*Sa Ad*Da)

Por supuesto, si un determinado componente del color excede 1.0, se interceptará automáticamente a 1.0 y no es necesario considerar problemas fuera de límites.

El factor de origen y el factor de destino se pueden configurar a través de la función glBlendFunc. glBlendFunc tiene dos parámetros, el primero representa el factor de origen y el segundo representa el factor de destino. Estos dos parámetros pueden tener múltiples valores. Los más utilizados se presentan a continuación.

GL_ZERO: Indica usar 0.0 como factor, lo que en realidad equivale a no usar este color para participar en la operación de mezcla.

GL_ONE: Indica usar 1.0 como factor, lo que en realidad equivale a usar completamente este color para participar en la operación de mezcla.

GL_SRC_ALPHA: Indica utilizar el valor alfa del color de origen como factor.

GL_DST_ALPHA: Indica utilizar el valor alfa del color objetivo como factor.

GL_ONE_MINUS_SRC_ALPHA: Indica usar 1.0 menos el valor alfa del color de origen como factor.

GL_ONE_MINUS_DST_ALPHA: Indica usar 1.0 menos el valor alfa del color objetivo como factor.

Además, están GL_SRC_COLOR (los cuatro componentes del color de origen se utilizan como los cuatro componentes del factor), GL_ONE_MINUS_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, etc. Los dos primeros sólo se pueden utilizar en versiones antiguas. de OpenGL Establezca el factor de destino. Los dos últimos solo se pueden usar para establecer el factor de origen en versiones anteriores de OpenGL. La nueva versión de OpenGL no tiene esta limitación y admite el nuevo GL_CONST_COLOR (establece un color constante y usa sus cuatro componentes como los cuatro componentes del factor), GL_ONE_MINUS_CONST_COLOR, GL_CONST_ALPHA, GL_ONE_MINUS_CONST_ALPHA. También está GL_SRC_ALPHA_SATURATE. Las versiones más nuevas de OpenGL también permiten diferentes factores de mezcla para los valores alfa y RGB de un color. Pero esto no es lo que necesitamos saber ahora. Después de todo, este es un libro de texto introductorio, por lo que no necesita ser demasiado complicado~

Por ejemplo:

Si glBlendFunc(GL_ONE, GL_ZERO); que el color de origen se utiliza por completo. El color de destino no se utiliza, por lo que el efecto de la imagen es el mismo que cuando no se utiliza ninguna mezcla (por supuesto, la eficiencia puede ser un poco menor). Si los factores de origen y destino no están configurados, esta es la configuración predeterminada.

Si se establece glBlendFunc(GL_ZERO, GL_ONE); significa que el color de origen no se utiliza en absoluto, por lo que no importa lo que quieras dibujar, al final no se dibujará. (Pero esto no significa que esta configuración sea inútil, a veces puede tener usos especiales)

Si se establece glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA), significa que el color de origen se multiplica por su propio valor alfa; y el color de destino Multiplique por 1,0 menos el valor alfa del color de origen. De esta manera, cuanto mayor sea el valor alfa del color de origen, mayor será la proporción del color de origen en el nuevo color resultante y menor será la proporción. del color objetivo. En este caso, podemos entender simplemente el valor alfa del color de origen como "opacidad". Este es también el método más utilizado al mezclar.

Si se establece glBlendFunc(GL_ONE, GL_ONE); significa que el color de origen y el color de destino se utilizan por completo, y el color final es en realidad una simple suma de los dos colores. Por ejemplo, al sumar rojo (1, 0, 0) y verde (0, 1, 0) se obtiene (1, 1, 0) y el resultado es amarillo.

Nota:

El llamado color de origen y el color de destino están relacionados con el orden de dibujo. Supongamos que primero se dibuja un objeto rojo y luego un objeto verde encima. Entonces el verde es el color de origen y el rojo es el color de destino. Si se invierte el orden, el rojo es el color de origen y el verde es el color de destino. Al dibujar, debe prestar atención al orden para que el color de origen del dibujo corresponda al factor de origen establecido y el color de destino corresponda al factor de destino establecido. No se deje confundir por el orden confuso.

2. Ejemplo de mezcla de gráficos bidimensionales

Veamos un ejemplo sencillo para mezclar dos colores diferentes. Para facilitar la observación, dibujamos dos rectángulos: glRectf(-1, -1, 0.5, 0.5); glRectf(-0.5, -0.5, 1, 1); estos dos rectángulos tienen un área superpuesta, lo cual es conveniente para que observemos el efecto mixto.

Primero veamos el uso de glBlendFunc(GL_ONE, GL_ZERO);.

void myDisplay(void)

{

glClear(GL_COLOR_BUFFER_BIT

glEnable(GL_BLEND

glBlendFunc(GL_ONE, GL_ZERO);

glColor4f(1, 0, 0, 0.5);

glRectf(-1, -1, 0.5, 0.5);

glColor4f(0, 1, 0, 0.5);

glRectf(-0.5, -0.5, 1, 1);

glutSwapBuffers();

}

Intente cambiar los parámetros de glBlendFunc a glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); y glBlendFunc(GL_ONE, GL_ONE); En el primer caso, el efecto es el mismo que sin fusión, y las formas dibujadas más tarde sobrescribirán las formas dibujadas primero. En el segundo caso, alfa se trata como "opacidad" y, dado que está establecido en 0,5, ambos rectángulos parecen semitransparentes, por lo que se puede ver un fondo negro. La tercera forma es sumar los colores, el rojo y el verde se suman para obtener el amarillo.

3. Implementa la fusión tridimensional

Quizás no puedas esperar para dibujar una escena tridimensional con objetos translúcidos. Pero me temo que ahora no es posible. Hay otro punto al que se debe prestar atención al mezclar escenas tridimensionales, y es el búfer de profundidad.

El búfer de profundidad es un dato que registra qué tan cerca está cada píxel del espectador. Con la prueba de búfer de profundidad habilitada, se dibujará un píxel si el píxel que se va a dibujar está más cerca que el píxel original. De lo contrario, el píxel se ignora y no se dibuja. Esto es muy útil al dibujar objetos opacos: ya sea que dibuje objetos cercanos primero y luego objetos lejanos, o que dibuje objetos distantes primero y luego objetos cercanos, o simplemente los dibuje en un orden caótico, el resultado final de la visualización siempre será Los objetos cercanos cubren los distantes. objetos.

Sin embargo, cuando necesitas conseguir un efecto traslúcido, descubres que no todo es tan bonito. Si dibuja un objeto semitransparente de cerca, retendrá cierta información en el búfer de profundidad para que los objetos distantes ya no se puedan dibujar. Aunque un objeto traslúcido sigue siendo traslúcido, lo que se ve a través de él ya no es el contenido correcto.

Para resolver el problema anterior, debe configurar el búfer de profundidad en solo lectura al dibujar un objeto translúcido. De esta manera, aunque se dibuja el objeto translúcido, el búfer de profundidad permanece en su estado original. . Si hay otro objeto que aparece después del objeto translúcido y antes del objeto opaco, también se puede dibujar (porque la profundidad del objeto opaco se registra en el búfer de profundidad en este momento). Cuando desee dibujar objetos opacos en el futuro, solo necesitará configurar el búfer de profundidad en un formato legible y grabable. ¿Eh? ¿Me preguntas cómo dibujar un objeto que sea parcialmente translúcido y parcialmente opaco? Esto es fácil de hacer, simplemente divide el objeto en dos partes, una parte es completamente translúcida y la otra es completamente opaca, y puedes dibujarlas por separado.

Incluso después de utilizar las técnicas anteriores, todavía no podemos dibujar en un orden caótico como deseamos. Primero se deben dibujar los objetos opacos y luego los transparentes. De lo contrario, supongamos que el fondo es azul, un trozo de vidrio rojo cerca y un objeto verde en el medio. Si se dibuja primero el vidrio rojo translúcido, primero se mezclará con el fondo azul. Luego, cuando se dibuje más tarde el objeto verde en el medio, ya no será posible mezclarlo solo con el vidrio rojo.

En resumen, el orden de dibujo es: dibujar primero todos los objetos opacos. Si ambos objetos son opacos, no importa cuál aparece primero. Luego, configure el búfer de profundidad en solo lectura.

A continuación, dibuja todos los objetos semitransparentes. Si ambos objetos son translúcidos, sólo necesita decidir quién viene primero y quién viene último (tenga en cuenta que el que se dibuje primero se convertirá en el "color de destino" y el que se dibuje después se convertirá en el "color de origen", por lo que el orden de el sorteo tendrá algún impacto en los resultados). Finalmente, configure el búfer de profundidad en formato legible y grabable.

Llame a glDepthMask(GL_FALSE); el búfer de profundidad se puede configurar en formato de solo lectura. Llame a glDepthMask(GL_TRUE); el búfer de profundidad se puede configurar en formato legible y grabable.

Algunos tutoriales en línea, incluido el famoso tutorial de NeHe, desactivan directamente el búfer de profundidad cuando se utiliza la combinación 3D, es decir, llamando a glDisable(GL_DEPTH_TEST);. Esto no es correcto. Si primero dibuja un objeto opaco y luego dibuja un objeto translúcido detrás de él, el objeto translúcido detrás de él no se mostrará (cubierto por el objeto opaco), pero si el búfer de profundidad está deshabilitado, aún se mostrará. mezcla. NeHe mencionó que algunas tarjetas gráficas pueden tener algunos problemas al usar la función glDepthMask, pero puede deberse a mi experiencia limitada que no he encontrado tal situación.

Entonces, hagamos una demostración práctica. Dibujemos algunas esferas translúcidas y opacas. Supongamos que hay tres esferas, una roja opaca, una verde translúcida y una azul translúcida. El rojo es el más lejano, el verde está en el medio y el azul es el más cercano. Según lo dicho anteriormente, primero se debe dibujar la esfera roja opaca, mientras que las esferas verde y azul se pueden modificar en cualquier orden. Para demostrar aquí los peligros de no prestar atención a la configuración del búfer de profundidad, dibujamos deliberadamente primero la esfera azul más cercana y luego la esfera verde.

Para darle un poco de tridimensionalidad a estas esferas utilizamos iluminación. Establezca una fuente de luz blanca en (1, 1, -1). El código es el siguiente:

void setLight(void)

{

static const GLfloat light_position[] = {1.0f, 1.0f, -1.0f , 1.0f };

const estática GLfloat light_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};

const estática GLfloat light_diffuse[] = {1.0f , 1.0f , 1.0f, 1.0f};

const estática GLfloat light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};

glLightfv(GL_LIGHT0, GL_POSITION, posición_luz);

glLightfv (GL_LIGHT0, GL_AMBIENT, light_ambient);

glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse);

glEnable(GL_LIGHT0); /p>

glEnable(GL_LIGHTING);

glEnable(GL_DEPTH_TEST);

}

Cada esfera tiene un color diferente. Por eso sus materiales también son diferentes. Aquí se utiliza una función para configurar el material.

void setMatirial(const GLfloat mat_diffuse[4], GLfloat mat_shininess)

{

static const GLfloat mat_specular[] = {0.0f, 0.0f, 0.0 f, 1.0f};

const estática GLfloat mat_emission[] = {0.0f, 0.0f, 0.0f, 1.0f};

glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_diffuse);

glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);

glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);

glMaterialf (GL_FRONT, GL_SHINESS, mat_shininess);

p>

}

Con estas dos funciones podemos escribir el código completo del programa basándonos en los conocimientos previos.

Se pueden establecer coordenadas. El sistema de coordenadas predeterminado de OpenGL es de hecho lo que dijeron las dos personas anteriores, pero estoy más acostumbrado a que el eje Z sea vertical al plano del monitor, así que lo cambié.

glOrtho(-1, 1, -1, 1, 1, -1); //Caso predeterminado

glOrtho(-1, 1, -1, 1, -1); , 1); // La situación que configuré

Aquí solo se proporciona la parte del dibujo, las otras partes las puede completar usted mismo.

void myDisplay(void)

{

// Definir algunos colores de materiales

const static GLfloat red_color[] = {1.0f , 0.0f, 0.0f, 1.0f};

const static GLfloat green_color[] = {0.0f, 1.0f, 0.0f, 0.3333f};

const static GLfloat blue_color [] = {0.0f, 0.0f, 1.0f, 0.5f};

//Borrar la pantalla

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Iniciar la fusión y establecer los factores de fusión

glEnable(GL_BLEND);

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

// Establecer la fuente de luz

setLight();

// Con (0, 0, 0.5) como centro, dibuja una esfera roja opaca con un radio de .3 (la más alejada del observador)

setMatirial (color_rojo, 30.0);

glPushMatrix();

glTranslatef(0.0f, 0.0f, 0.5f);

glutSolidSphere(0.3, 30, 30 );

glPopMatrix();

// Los objetos translúcidos se dibujarán debajo, así que configure el búfer de profundidad en solo lectura

glDepthMask( GL_FALSE);

// Tomando (0.2, 0, -0.5) como centro, dibuja una esfera azul translúcida con un radio de .2 (la más cercana al observador)

setMatirial (color_azul, 30.0);

glPushMatrix();

glTranslatef(0.2f, 0.0f, -0.5f);

glutSolidSphere(0.2, 30, 30);

glPopMatrix();

// Con (0.1, 0, 0) como centro, dibuja una esfera verde translúcida con un radio de .15 (entre las primeras). dos esferas )

setMatirial(green_color, 30.0);

glPushMatrix();

glTranslatef(0.1, 0, 0); >glutSolidSphere (0.15, 30, 30);

glPopMatrix();

// Completa el dibujo de objetos translúcidos y restaura el búfer de profundidad a un formato legible y grabable

glDepthMask(GL_TRUE);

glutSwapBuffers();

}

También puedes eliminar las dos glDepthMasks anteriores y verás el resultado. la bola azul más cercana es translúcida, la bola roja está directamente detrás de ella y la bola verde en el medio no está dibujada correctamente.

Resumen:

Esta lección presenta el conocimiento relevante de las funciones de mezcla de OpenGL.

Mezclar significa que al dibujar, el nuevo color no se superpone directamente al color antiguo original, sino que el color nuevo y el color antiguo se someten a ciertas operaciones para producir un color nuevo. El nuevo color se denomina color de origen y el color antiguo se denomina color de destino. Mezclar en el sentido tradicional es multiplicar el color de origen por el factor de origen, multiplicar el color de destino por el factor de destino y luego sumarlos.

Se pueden configurar el factor de origen y el factor de destino. Los diferentes ajustes del factor fuente y del factor objetivo conducen directamente a diferentes resultados de mezcla. Es un método común utilizar el valor alfa del color de origen como factor de origen y restar el valor alfa del color de origen de 1,0 como factor de destino. En este momento, el valor alfa del color de origen es equivalente al efecto de "opacidad". Esta función se puede utilizar para dibujar algunos objetos translúcidos.

A la hora de mezclar, el orden en el que dibujas es importante. Porque al dibujar, lo que se dibuja es el color de origen y lo que existe originalmente es el color de destino. Por lo tanto, el objeto dibujado primero se convierte en el color de destino y el objeto dibujado después se convierte en el color de origen. El orden de dibujo debe considerarse cuidadosamente, de modo que el color de destino corresponda al factor de destino establecido y el color de origen corresponda al factor de origen establecido.

Al realizar una fusión 3D, no solo se deben considerar los factores de origen y destino, sino también el búfer de profundidad. Primero se deben dibujar todos los objetos opacos y luego los translúcidos. Antes de dibujar objetos translúcidos, también debe configurar el búfer de profundidad en modo de solo lectura; de lo contrario, pueden producirse errores en la imagen.

Transparencia simple

La mayoría de los efectos especiales en OpenGL están relacionados con algún tipo de mezcla (de color).

La mezcla de colores se define como combinar el color de un determinado píxel con el color del píxel correspondiente dibujado en la pantalla.

La forma de combinar estos dos colores depende de los valores de los componentes del canal alfa del color y/o de la función de mezcla de colores utilizada.

Alfa suele ser el cuarto componente de color al final del valor del color.

En las lecciones anteriores utilizamos GL_RGB para especificar los tres componentes del color.

El GL_RGBA correspondiente puede especificar el valor del componente alfa.

Además, podemos usar glColor4f() en lugar de glColor3f().

La mayoría de la gente piensa que el componente Alfa representa la transparencia del material.

Esto significa que el material representado por un valor alfa de 0,0 es completamente transparente.

Un valor alfa de 1,0 representa un material completamente opaco.

Fórmula para mezclar colores

Si no estás interesado en las matemáticas y solo quieres ver cómo lograr transparencia, omite esta sección.

Si quieres tener una comprensión más profunda de cómo funciona la mezcla (de colores), esta sección debería ser para ti.

『Añadido de CKER: En realidad no es difícil^-^. La fórmula del artículo original es la siguiente, deja que CKER hable un poco más de ella.

De hecho, el principio básico de la mezcla es separar el color de cada píxel y el color de fondo de la imagen según las reglas RGB.

Según RGB componente de color de la imagen* El componente de color RGB del fondo con valor alfa * (valor alfa 1)

-Después de mezclar una fórmula tan simple, los componentes RGB mezclados finalmente se vuelven a fusionar. 』

La fórmula es la siguiente:

(Rs Sr Rd Dr, Gs Sg Gd Dg, Bs Sb Bd Db, As Sa Ad Da)

OpenGL sigue lo anterior La fórmula calcula la mezcla de colores de estos dos píxeles.

Las s y r minúsculas representan los píxeles de origen y los píxeles de destino, respectivamente. La S y la D mayúsculas son los factores de mezcla de colores correspondientes.

Estos determinan cómo se mezclan los colores de estos píxeles.

En la mayoría de los casos, los valores de mezcla alfa de cada canal de color son los mismos,

De esta forma, los píxeles de origen tienen (As, As, As, As),

Los píxeles de destino son 1, 1, 1, 1) - (As, As, As, As).

La fórmula anterior queda como sigue:

(Rs As Rd (1 - As), Gs As Gd (1 - As), Bs As Bs (1 - As ), As Como Anuncio (1 - Como))

Esta fórmula generará un efecto transparente/translúcido.

Mezcla de colores en OpenGL

Los pasos para implementar la mezcla de colores en OpenGL son similares al proceso OpenGL que mencionamos antes.

Luego configure la fórmula y desactive el caché de profundidad de escritura al dibujar objetos transparentes.

Porque queremos dibujar el objeto detrás de una imagen semitransparente.

Esta no es la forma correcta de mezclar colores, pero la mayoría de las veces funciona muy bien en proyectos sencillos.

Añadido de Rui Martins: El proceso correcto de mezcla de colores debe ser dibujar primero la escena completa y luego dibujar la imagen transparente.

Y dibuja en el orden inverso al búfer de profundidad (dibuja primero el objeto más lejano).

Considere la combinación alfa de dos polígonos (1 y 2). Diferentes órdenes de dibujo darán resultados diferentes.

(Aquí se supone que el polígono 1 es el más cercano al observador, entonces el proceso correcto debería ser dibujar el polígono 2 primero y luego dibujar el polígono 1.

Como puedes ver en realidad,

La luz que viene detrás de estos dos polígonos transparentes siempre pasa primero por el polígono 2,

luego pasa por el polígono 1 y finalmente llega al observador.

p>

Cuando el almacenamiento en caché de profundidad está habilitado, debes ordenar las imágenes transparentes por profundidad

y dibujar estos objetos transparentes después de que se haya dibujado toda la escena. De lo contrario obtendrá resultados incorrectos.

Sé que a veces puede ser muy doloroso hacer esto, pero es la forma correcta de hacerlo.

Usaremos el código de la Lección 7.

Comience agregando dos nuevas variables al comienzo del código. Reescribí todo el código para mayor claridad.

}

Var

h_RC: HGLRC; // Contexto de renderizado (tabla de descripción de sombreado).

h_DC: HDC; // Contexto del dispositivo (tabla de descripción del dispositivo)

h_Wnd: HWND; // Identificador de ventana

h_Instance: HINST // Instancia del programa (ejemplo).

teclas: Array[0..255] Of Boolean; // Array para rutinas de teclado

light: Boolean; // Encendido/apagado de la fuente de luz

blend: Boolean; // ¿Fusión desactivada/activada? (nuevo)

lp: Boolean; // ¿Está presionada la tecla L?

fp: Boolean; ¿Tecla presionada?

bp: Boolean; // ¿Está presionada la tecla B? (nueva)

xrot: GLfloat; // Rotación X

yrot: GLfloat ; // rotación Y

xspeed: GLfloat; // velocidad de rotación X

yspeed: GLfloat; // velocidad de rotación Y

z: GLfloat = -5.0 f; // Distancia profunda en la pantalla

LightAmbient: Array[0..3] Of GLfloat = (0.5, 0.5, 0.5, 1.0); //Parámetros de luz ambiental (Nuevo)

LightDiffuse: Array[0..3] Of GLfloat = (1.0, 1.0, 1.0, 1.0); // Parámetros de luz difusa (nuevo)

LightPosition: Array[0..3] Of GLfloat = (0.0, 0.0, 2.0, 1.0); // Posición de la fuente de luz (nueva)

filtro: GLuint; // Tipo de filtro

textura: Array[0..2 ] De GLuint; // Espacio de almacenamiento para 3 texturas

Procedimiento glGenTextures(n: GLsizei; Var texturas: GLuint; external

opengl32;

Procedimiento glBindTexture(objetivo: GLenum; textura: GLuint); stdcall; external

opengl32;

Función gluBuild2DMipmaps(objetivo: GLenum; componentes, ancho, alto: GLint;

formato

, tipo: GLenum; datos: puntero): entero;

nombre interno de glu32

gluBuild2DMipmaps;

{

Luego baje a LoadGLTextures().

Encuentra la línea if (TextureImage[0]=LoadBMP(Data/Crate.bmp))

. Actualmente estamos usando una textura de vidrio tintado en lugar de la textura de caja de madera de la lección anterior.

if (TextureImage[0]=LoadBMP("Data/glass.bmp")); // Cargar mapa de bits de vidrio (modificado)

}

Función LoadTexture: boolean; // Carga el mapa de bits y convierte a textura

Var

Estado: booleano; // Indicador de estado

TextureImage: Array[0..1 ] Of PTAUX_RGBImageRec; //Crear espacio de almacenamiento de texturas

Comenzar

Estado:= false;

ZeroMemory(@TextureImage, sizeof (TextureImage)); Establezca el puntero en NULL

TextureImage[0]:= LoadBMP(Walls.bmp);

If TextureImage[0] lt Nil Then

Comenzar

Estado:= TRUE; // Establecer estado en TRUE

glGenTextures(1, textura[0]); // Crear textura

p>

/ / Crear mapa de filtro más cercano

glBindTexture(GL_TEXTURE_2D, textura[0]);

// Generar textura

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); / (nuevo)

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // (nuevo)

glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[ 0].sizeX,

TextureImage[0].sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,

TextureImage[0].data

glBindTexture(GL_TEXTURE_2D, textura[1]); / Utiliza texturas típicas generadas a partir de datos de mapa de bits

// Genera texturas

glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0].sizeX ,

TextureImage[ 0].sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,

TextureImage[0].data

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Filtrado lineal

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Filtrado lineal

// Crear textura MipMapped

glBindTexture(GL_TEXTURE_2D, textura[2]);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,

GL_LINEAR_MIPMAP_NEAREST ) ; // (nuevo)

gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0].sizeX,

TextureImage[0].sizey, GL_RGB, GL_UNSIGNED_BYTE,

TextureImage[0].data); //(new) }

Fin;

Si está asignado(TextureImage[0]) Entonces // Si la textura existe

Si está asignado (TextureImage[0].data) Entonces // Si la imagen de textura existe

TextureImage[0].data := Nil; p>

TextureImage[0] := Nil; // Liberar la estructura de la imagen

resultado := Estado; >{

Agregue las siguientes dos líneas al segmento de código glInit().

La primera línea dibuja este objeto con el brillo máximo y le da una mezcla alfa de 50 (semitransparente).

Cuando la opción de fusión está activada, este objeto tendrá un efecto de transparencia del 50%.

La segunda línea establece el tipo de mezcla utilizada.

Adición de Rui Martins:

Un valor de canal alfa de 0,0 significa que el material del objeto es completamente transparente.

1.0 significa completamente opaco.

}

Fin;

¿Pero cómo se puede especificar el color de la mezcla al utilizar el mapeo de texturas? Es muy sencillo,

Al ajustar el modo de textura, el color de cada píxel del mapa de textura se obtiene multiplicando el parámetro del canal alfa

y el color del píxel actual.

Por ejemplo, el color dibujado es (0.5, 0.6, 0.4),

Multiplicaremos los colores para obtener (0.5, 0.6, 0.4, 0.2)

(Cuando no se especifica el parámetro alfa, el valor predeterminado es cero).

¡Eso es! ¡Implementar la combinación Alpha en OpenGL es realmente muy simple!

}

{

Nota original (13/11/99)

Mi código de mezcla de colores (NeHe) se ha modificado a Haga que los objetos mostrados parezcan más realistas.

El uso del parámetro alfa para combinar los píxeles de origen y de destino al mismo tiempo hará que los rastros artificiales del objeto parezcan muy obvios.

Hará que la parte posterior del objeto parezca más oscura a lo largo de los lados.

Básicamente, el objeto se verá realmente extraño.

El método de mezcla de colores que utilicé puede que no sea el óptimo, pero funciona.

Con las luces habilitadas, los objetos parecen muy realistas.

Gracias a Tom por proporcionar el código original, el método de mezcla de colores que utilizó es correcto,

pero el objeto no se ve tan atractivo como se esperaba :)

El código se modificó nuevamente debido a problemas con la función glDepthMask() en algunas tarjetas gráficas.

Este comando no parece ser muy eficiente al habilitar o deshabilitar la prueba de búfer de profundidad en algunas tarjetas,

así que convertí el código para habilitar o deshabilitar la prueba de búfer de profundidad a glEnable y glDisable anticuados.

Mezcla alfa de mapas de textura

El parámetro alfa utilizado para los mapas de textura se puede leer tanto en el mapa del problema como en el color.

El método es el siguiente. Debe cargar el material requerido y obtener su parámetro alfa al mismo tiempo.

Luego use el formato de color de GL_RGBA cuando llame a glTexImage2D().

}