OpenGL ES 1.1: ¿Cómo cambiar el color de la textura sin perder luminancia?
Tengo partículas que quiero poder cambiar el color de en código, así que cualquier color puede ser utilizado. Así que sólo tengo una textura que básicamente tiene luminosidad.
He estado usando glColor4f(1f, 0f, 0f, 1f);
Para aplicar el color.
- El impacto del código nativo en el desarrollo de aplicaciones para Android / iPhone
- ¿Qué trabajo se ha hecho en el desarrollo móvil multiplataforma?
- Desarrollo móvil - Native VS Cross Platform VS JavaScript
- Facebook SSO y registro de sitio de terceros en un solo paso?
- ¿Detecta el arrastre de dedos con Javascript en teléfonos táctiles?
Cada blendfunc he intentado que se ha acercado a trabajar termina como la última imagen a continuación. Todavía quiero conservar la luminancia, como en el cuadro medio. (Esto es como los filtros Overlay o Soft Light en Photoshop, si la capa de color estaba encima de la capa de textura).
¿Alguna idea de cómo hacerlo sin shaders programables? Además, puesto que éstas son partículas, no quiero una caja negra detrás de ella, quiero añadirla a la escena.
- Biblioteca WebSocket para Android, iOS y Flash
- Buscando buenas fuentes para iconos, ilustraciones, etc
- ¿Es posible tener un solo ensayo por dispositivo?
- Los esfuerzos de Dev para diferentes plataformas móviles
- ¿Los navegadores iPhone / Android admiten CSS @media handheld?
- Puede una página web en un navegador móvil preguntar / obtener la ubicación de los usuarios desde el teléfono?
- ¿Hay Android concepto de intención en el iPhone SDK
- Cómo crear API de sitio web
Aquí hay una solución que podría estar cerca de lo que estás buscando:
glColor4f(1.0f, 0.0f, 0.0f, 1.0f); glActiveTexture( GL_TEXTURE0 ); glEnable( GL_TEXTURE_2D ); glBindTexture(GL_TEXTURE_2D, spriteTexture); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); glActiveTexture( GL_TEXTURE1 ); glEnable( GL_TEXTURE_2D ); glBindTexture(GL_TEXTURE_2D, spriteTexture); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD );
Lo que hace es multiplicar la textura original por el color especificado y luego agrega los valores de píxeles de la textura original en la parte superior:
final_color.rgba = original_color.rgba * color.rgba + original_color.rgba;
Esto resultará en una imagen más brillante de lo que usted ha pedido, pero podría ser lo suficientemente bueno con algunos ajustes.
Si desea conservar el valor alfa de la textura, deberá utilizar GL_COMBINE en lugar de GL_ADD (+ set GL_COMBINE_RGB y GL_COMBINE_ALPHA correctamente).
Aquí hay algunos resultados utilizando esta técnica en su textura.
¡DISPARATES! Usted no tiene que usar la multi-texturización. Sólo premultiply su alfa.
Si premultiply alfa en la imagen después de cargarlo en y antes de crear la textura GL para él, entonces sólo necesita una unidad de textura para el modo de textura env GL_ADD.
Si estás en iOS, las librerías de Apple pueden premultiplicarse para ti. Consulte el ejemplo de la clase Texture2D y busque el indicador kCGImageAlphaPremultipliedLast.
Si no está utilizando un cargador de imágenes que admita premultiplicación, debe realizarlo manualmente después de cargar la imagen. Pseudo código:
uint8* LoadRGBAImage(const char* pImageFileName) { Image* pImage = LoadImageData(pImageFileName); if (pImage->eFormat != FORMAT_RGBA) return NULL; // allocate a buffer to store the pre-multiply result // NOTE that in a real scenario you'll want to pad pDstData to a power-of-2 uint8* pDstData = (uint8*)malloc(pImage->rows * pImage->cols * 4); uint8* pSrcData = pImage->pBitmapBytes; uint32 bytesPerRow = pImage->cols * 4; for (uint32 y = 0; y < pImage->rows; ++y) { byte* pSrc = pSrcData + y * bytesPerRow; byte* pDst = pDstData + y * bytesPerRow; for (uint32 x = 0; x < pImage->cols; ++x) { // modulate src rgb channels with alpha channel // store result in dst rgb channels uint8 srcAlpha = pSrc[3]; *pDst++ = Modulate(*pSrc++, srcAlpha); *pDst++ = Modulate(*pSrc++, srcAlpha); *pDst++ = Modulate(*pSrc++, srcAlpha); // copy src alpha channel directly to dst alpha channel *pDst++ = *pSrc++; } } // don't forget to free() the pointer! return pDstData; } uint8 Modulate(uint8 u, uint8 uControl) { // fixed-point multiply the value u with uControl and return the result return ((uint16)u * ((uint16)uControl + 1)) >> 8; }
Personalmente, estoy usando libpng y premultiplying manualmente.
De todos modos, después de premultiply, sólo enlazar los datos de bytes como una textura RGBA OpenGL. Uso de glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); Con una sola unidad de textura debe ser todo lo que necesita después de eso. Usted debe obtener exactamente (o bastante cerca) a lo que quieres. Es posible que tenga que utilizar glBlendFunc (GL_SRC_ALPHA, GL_ONE); Así como si usted realmente quiere hacer la cosa mira btw brillante.
Esto es sutilmente diferente del método de Ozirus. Nunca está "reduciendo" los valores RGB de la textura al premultiplicarse, por lo que los canales RGB se añaden demasiado y se ven como lavados / demasiado brillantes.
Supongo que el método premultiply es más parecido a Overlay mientras que el método Ozirus es Soft Light.
Para obtener más información, consulte:
http://en.wikipedia.org/wiki/Alpha_compositing
Búsqueda de "premultiplied alpha"
- No Commons Iniciar sesión en Android?
- Procesamiento de problemas con el nuevo TextInputLayout para EditText