/*----------------------------------------------------------------------------- Name : liLayerColorAverage Description : Returns the average color of a layer Inputs : layer - layer to find average color of Outputs : Return : average color ----------------------------------------------------------------------------*/ color liLayerColorAverage(lilayer *layer) { udword red = 0, green = 0, blue = 0, alpha = 0, count, totalPixels; color *pColor; dbgAssert(layer->decompressed != NULL); dbgAssert(!bitTest(layer->flags, LFF_Channeled)); totalPixels = count = (layer->bounds.x1 - layer->bounds.x0) * (layer->bounds.y1 - layer->bounds.y0); pColor = layer->decompressed; while (count > 0) { red += colRed(*pColor); green += colGreen(*pColor); blue += colBlue(*pColor); alpha += colAlpha(*pColor); count--; pColor++; } red /= totalPixels; green /= totalPixels; blue /= totalPixels; alpha /= totalPixels; return(colRGBA(red, green, blue, alpha)); }
/*----------------------------------------------------------------------------- Name : primRectTranslucent2 Description : Draw a translucent 2d rectangle. Inputs : rect - pointer to rectangle structure containing coordinates. c - color to draw it in. Outputs : .. Return : void ----------------------------------------------------------------------------*/ void primRectTranslucent2(rectangle* rect, color c) { GLboolean blendOn; if (RGL && RGLtype == SWtype) { primRectTranslucentRGL2(rect, c); return; } blendOn = glIsEnabled(GL_BLEND); if (!blendOn) glEnable(GL_BLEND); if (glcActive()) { glcRectTranslucent2(rect, c); } else { glColor4ub(colRed(c), colGreen(c), colBlue(c), colAlpha(c)); glBegin(GL_QUADS); glVertex2f(primScreenToGLX(rect->x0), primScreenToGLY(rect->y0)); glVertex2f(primScreenToGLX(rect->x0), primScreenToGLY(rect->y1)); glVertex2f(primScreenToGLX(rect->x1), primScreenToGLY(rect->y1)); glVertex2f(primScreenToGLX(rect->x1), primScreenToGLY(rect->y0)); glEnd(); } if (!blendOn) glDisable(GL_BLEND); }
void liBlendScreen(color *buffer, color *layer, real32 opacity, sdword nPixels) { real32 redSource, greenSource, blueSource, alpha; real32 redDest, greenDest, blueDest;//, alphaDest; real32 oneMinusAlpha; while (nPixels > 0) { alpha = colUbyteToReal(colAlpha(*layer)) * opacity; oneMinusAlpha = 1.0f - alpha; redSource = colUbyteToReal(colRed(*layer)); //read pixel to floating point greenSource = colUbyteToReal(colGreen(*layer)); blueSource = colUbyteToReal(colBlue(*layer)); redDest = colUbyteToReal(colRed(*buffer)); greenDest = colUbyteToReal(colGreen(*buffer)); blueDest = colUbyteToReal(colBlue(*buffer)); redDest = (1.0f - (1.0f - redDest) * (1.0f - redSource)) * alpha + redDest * oneMinusAlpha; greenDest = (1.0f - (1.0f - greenDest) * (1.0f - greenSource)) * alpha + greenDest * oneMinusAlpha; blueDest = (1.0f - (1.0f - blueDest) * (1.0f - blueSource)) * alpha + blueDest * oneMinusAlpha; redDest = min(redDest, 1.0f); greenDest = min(greenDest, 1.0f); blueDest = min(blueDest, 1.0f); *buffer = colRGB(colRealToUbyte(redDest), colRealToUbyte(greenDest), colRealToUbyte(blueDest)); buffer++; layer++; nPixels--; } }
void liBlendOverlay(color *buffer, color *layer, real32 opacity, sdword nPixels) { real32 redSource, greenSource, blueSource, alpha; real32 redDest, greenDest, blueDest;//, alphaDest; real32 oneMinusAlpha; real32 redTemp, greenTemp, blueTemp; while (nPixels > 0) { alpha = colUbyteToReal(colAlpha(*layer)) * opacity; oneMinusAlpha = 1.0f - alpha; redSource = colUbyteToReal(colRed(*layer)); //read pixel to floating point greenSource = colUbyteToReal(colGreen(*layer)); blueSource = colUbyteToReal(colBlue(*layer)); redDest = colUbyteToReal(colRed(*buffer)); greenDest = colUbyteToReal(colGreen(*buffer)); blueDest = colUbyteToReal(colBlue(*buffer)); if (redDest < 0.5f) { redTemp = (2.0f * redSource * 2.0f * redDest) / 2.0f; } else { redTemp = 1.0f - ((2.0f * (1.0f - redSource)) * (2.0f * (1.0f - redDest)) / 2.0f); } if (greenDest < 0.5f) { greenTemp = (2.0f * greenSource * 2.0f * greenDest) / 2.0f; } else { greenTemp = 1.0f - ((2.0f * (1.0f - greenSource)) * (2.0f * (1.0f - greenDest)) / 2.0f); } if (blueDest < 0.5f) { blueTemp = (2.0f * blueSource * 2.0f * blueDest) / 2.0f; } else { blueTemp = 1.0f - ((2.0f * (1.0f - blueSource)) * (2.0f * (1.0f - blueDest)) / 2.0f); } redDest = redTemp * alpha + redDest * oneMinusAlpha; greenDest = greenTemp * alpha + greenDest * oneMinusAlpha; blueDest = blueTemp * alpha + blueDest * oneMinusAlpha; redDest = min(redDest, 1.0f); greenDest = min(greenDest, 1.0f); blueDest = min(blueDest, 1.0f); *buffer = colRGB(colRealToUbyte(redDest), colRealToUbyte(greenDest), colRealToUbyte(blueDest)); buffer++; layer++; nPixels--; } }
/*----------------------------------------------------------------------------- Name : partCircleSolid2 Description : Render a 2d circle, like the 3D one. Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void primCircleSolid2(sdword x, sdword y, sdword rad, sdword nSlices, color c) { sdword index; GLfloat v[3]; double theta; vector centre; real32 radiusX, radiusY; bool cull; if (glcActive()) { rectangle r; r.x0 = x - rad; r.y0 = y - rad; r.x1 = x + rad; r.y1 = y + rad; glcRectSolid2(&r, c); return; } cull = glIsEnabled(GL_CULL_FACE) ? TRUE : FALSE; centre.x = primScreenToGLX(x); centre.y = primScreenToGLY(y); radiusX = primScreenToGLScaleX(rad); radiusY = primScreenToGLScaleY(rad); glColor4ub(colRed(c), colGreen(c), colBlue(c), colAlpha(c)); v[0] = centre.x; v[1] = centre.y; glDisable(GL_CULL_FACE); glBegin(GL_TRIANGLE_FAN); glVertex2f(v[0], v[1]); for (index = 0, theta = 0.0; index < nSlices; index++) { v[0] = centre.x + (real32)(sin(theta)) * radiusX; v[1] = centre.y + (real32)(cos(theta)) * radiusY; theta += 2.0 * PI / (double)nSlices; glVertex2f(v[0], v[1]); } v[0] = centre.x; v[1] = centre.y + radiusY; glVertex2f(v[0], v[1]); glEnd(); if (cull) { glEnable(GL_CULL_FACE); } }
void primRectSolidTexturedFullRectC2(rectangle *rect, color c) { glColor4ub(colRed(c), colGreen(c), colBlue(c), colAlpha(c)); rndTextureEnable(TRUE); glBegin(GL_QUADS); COORD(0.0f, 0.0f, rect->x0, rect->y0); COORD(0.0f, 1.0f, rect->x0, rect->y1); COORD(1.0f, 1.0f, rect->x1, rect->y1); COORD(1.0f, 0.0f, rect->x1, rect->y0); glEnd(); rndTextureEnable(FALSE); }
/*----------------------------------------------------------------------------- Name : primRectSolid2 Description : Draw a solid 2d rectangle. Inputs : rect - pointer to rectangle structure containing coordinates. c - color to draw it in. Outputs : .. Return : void ----------------------------------------------------------------------------*/ void primRectSolid2(rectangle *rect, color c) { if (glcActive()) { glcRectSolid2(rect, c); } else { glColor4ub(colRed(c), colGreen(c), colBlue(c), colAlpha(c)); glBegin(GL_QUADS); glVertex2f(primScreenToGLX(rect->x0), primScreenToGLY(rect->y0)); glVertex2f(primScreenToGLX(rect->x0), primScreenToGLY(rect->y1)); glVertex2f(primScreenToGLX(rect->x1), primScreenToGLY(rect->y1)); glVertex2f(primScreenToGLX(rect->x1), primScreenToGLY(rect->y0)); glEnd(); } }
//This one not a perfect copy, but pretty close void liBlendColor(color *buffer, color *layer, real32 opacity, sdword nPixels) { real32 redSource, greenSource, blueSource, alpha; real32 redDest, greenDest, blueDest;//, alphaDest; real32 oneMinusAlpha; real32 hueS, satS, hueD, satD, lumS, lumD; real32 clumD, clumS; real32 redTemp, greenTemp, blueTemp; #if LI_VERBOSE_LEVEL >= 2 dbgMessagef("\nColor: Blending mode not implemented perfectly."); #endif while (nPixels > 0) { alpha = colUbyteToReal(colAlpha(*layer)) * opacity; oneMinusAlpha = 1.0f - alpha; redSource = colUbyteToReal(colRed(*layer)); //read pixel to floating point greenSource = colUbyteToReal(colGreen(*layer)); blueSource = colUbyteToReal(colBlue(*layer)); redDest = colUbyteToReal(colRed(*buffer)); greenDest = colUbyteToReal(colGreen(*buffer)); blueDest = colUbyteToReal(colBlue(*buffer)); clumS = (redSource * LI_RedGamma + greenSource * LI_GreenGamma + blueSource * LI_BlueGamma) / LI_TotalGamma; clumD = (redDest * LI_RedGamma + greenDest * LI_GreenGamma + blueDest * LI_BlueGamma) / LI_TotalGamma; colRGBToHLS(&hueS, &lumS, &satS, redSource, greenSource, blueSource); colRGBToHLS(&hueD, &lumD, &satD, redDest, greenDest, blueDest); colHLSToRGB(&redTemp, &greenTemp, &blueTemp, hueS, clumD, satS); redDest = redTemp * alpha + redDest * oneMinusAlpha; greenDest = greenTemp * alpha + greenDest * oneMinusAlpha; blueDest = blueTemp * alpha + blueDest * oneMinusAlpha; redDest = min(redDest, 1.0f); greenDest = min(greenDest, 1.0f); blueDest = min(blueDest, 1.0f); *buffer = colRGB(colRealToUbyte(redDest), colRealToUbyte(greenDest), colRealToUbyte(blueDest)); buffer++; layer++; nPixels--; } }
/*----------------------------------------------------------------------------- Name : primRectTranslucentRGL2 Description : helper for primRectTranslucent2, rGL(sw) only (will temporarily disable stippling) Inputs : rect - rectangle structure containing coordinates c - color of the rectangle Outputs : Return : ----------------------------------------------------------------------------*/ void primRectTranslucentRGL2(rectangle* rect, color c) { GLboolean blendOn; GLboolean stippleOn; blendOn = glIsEnabled(GL_BLEND); stippleOn = glIsEnabled(GL_POLYGON_STIPPLE); if (!blendOn) glEnable(GL_BLEND); if (stippleOn) glDisable(GL_POLYGON_STIPPLE); glColor4ub(colRed(c), colGreen(c), colBlue(c), colAlpha(c)); glBegin(GL_QUADS); glVertex2f(primScreenToGLX(rect->x0), primScreenToGLY(rect->y0)); glVertex2f(primScreenToGLX(rect->x0), primScreenToGLY(rect->y1)); glVertex2f(primScreenToGLX(rect->x1), primScreenToGLY(rect->y1)); glVertex2f(primScreenToGLX(rect->x1), primScreenToGLY(rect->y0)); glEnd(); if (!blendOn) glDisable(GL_BLEND); if (stippleOn) glEnable(GL_POLYGON_STIPPLE); }
/*----------------------------------------------------------------------------- Name : liLayerColorSolid Description : Colorize all non-colored pixels in a layer to a new color Inputs : layer - layer to colorize newColor - new color to assign all currently colored pixels threshold - alpha? value above which pixels have their colors changed Outputs : .. Return : void Note : layer must be decompressed first ----------------------------------------------------------------------------*/ void liLayerColorSolid(lilayer *layer, color newColor, ubyte threshold) { color *dest = layer->decompressed; sdword count = (layer->bounds.x1 - layer->bounds.x0) * (layer->bounds.y1 - layer->bounds.y0); dbgAssert(layer->decompressed != NULL); newColor &= 0x00ffffff; while (count > 0) { if (colAlpha(*dest) >= threshold) { //if a team color pixel *dest = ((*dest) & 0xff000000) | newColor; //make it pure team color } else { *dest &= 0x00ffffff; //else flag as a non-team-color pixel } dest++; count--; } }
void liBlendColorDodge(color *buffer, color *layer, real32 opacity, sdword nPixels) { real32 redSource, greenSource, blueSource, alpha; real32 redDest, greenDest, blueDest;//, alphaDest; real32 oneMinusAlpha; while (nPixels > 0) { alpha = colUbyteToReal(colAlpha(*layer)) * opacity; oneMinusAlpha = 1.0f - alpha; redSource = colUbyteToReal(colRed(*layer)); //read pixel to floating point greenSource = colUbyteToReal(colGreen(*layer)); blueSource = colUbyteToReal(colBlue(*layer)); redDest = colUbyteToReal(colRed(*buffer)); greenDest = colUbyteToReal(colGreen(*buffer)); blueDest = colUbyteToReal(colBlue(*buffer)); redDest = (redDest + redSource * redSource * redDest) * alpha + redDest * oneMinusAlpha; greenDest = (greenDest + greenSource * greenSource * greenDest) * alpha + greenDest * oneMinusAlpha; blueDest = (blueDest + blueSource * blueSource * blueDest) * alpha + blueDest * oneMinusAlpha; redDest = min(redDest, 1.0f); greenDest = min(greenDest, 1.0f); blueDest = min(blueDest, 1.0f); *buffer = colRGB(colRealToUbyte(redDest), colRealToUbyte(greenDest), colRealToUbyte(blueDest)); buffer++; layer++; nPixels--; } /* real32 redSource, greenSource, blueSource, alpha; real32 redDest, greenDest, blueDest;//, alphaDest; real32 oneMinusAlpha; real32 hueS, satS, valS, hueD, satD, valD; // real32 cvalD, cvalS; while (nPixels > 0) { alpha = colUbyteToReal(colAlpha(*layer)) * opacity; oneMinusAlpha = 1.0f - alpha; redSource = colUbyteToReal(colRed(*layer)); //read pixel to floating point greenSource = colUbyteToReal(colGreen(*layer)); blueSource = colUbyteToReal(colBlue(*layer)); redDest = colUbyteToReal(colRed(*buffer)); greenDest = colUbyteToReal(colGreen(*buffer)); blueDest = colUbyteToReal(colBlue(*buffer)); // redDest = (redDest + redSource * redSource * redDest) * alpha + redDest * oneMinusAlpha; // greenDest = (greenDest + greenSource * greenSource * greenDest) * alpha + greenDest * oneMinusAlpha; // blueDest = (blueDest + blueSource * blueSource * blueDest) * alpha + blueDest * oneMinusAlpha; colRGBToHSV(&hueS, &satS, &valS, redSource * alpha, greenSource * alpha, blueSource * alpha); colRGBToHSV(&hueD, &satD, &valD, redDest, greenDest, blueDest); valD += valS; valD = min(valD, 1.0f); colHSVToRGB(&redDest, &greenDest, &blueDest, hueD, satD, valD); *buffer = colRGB(colRealToUbyte(redDest), colRealToUbyte(greenDest), colRealToUbyte(blueDest)); buffer++; layer++; nPixels--; } */ }