-/**
- * Apply a conventional OpenGL texture env mode (REPLACE, ADD, BLEND,
- * MODULATE, or DECAL) to an array of fragments.
- * Input: textureUnit - pointer to texture unit to apply
- * format - base internal texture format
- * n - number of fragments
- * primary_rgba - primary colors (may alias rgba for single texture)
- * texels - array of texel colors
- * InOut: rgba - incoming fragment colors modified by texel colors
- * according to the texture environment mode.
- */
-static void
-texture_apply( const GLcontext *ctx,
- const struct gl_texture_unit *texUnit,
- GLuint n,
- CONST GLfloat primary_rgba[][4], CONST GLfloat texel[][4],
- GLchan rgbaChan[][4] )
-{
- GLint baseLevel;
- GLuint i;
- GLfloat Rc, Gc, Bc, Ac;
- GLenum format;
- GLfloat rgba[MAX_WIDTH][4];
-
- (void) primary_rgba;
-
- ASSERT(texUnit);
- ASSERT(texUnit->_Current);
-
- baseLevel = texUnit->_Current->BaseLevel;
- ASSERT(texUnit->_Current->Image[0][baseLevel]);
-
- format = texUnit->_Current->Image[0][baseLevel]->_BaseFormat;
-
- if (format == GL_COLOR_INDEX || format == GL_YCBCR_MESA) {
- format = GL_RGBA; /* a bit of a hack */
- }
- else if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
- format = texUnit->_Current->DepthMode;
- }
-
- if (texUnit->EnvMode != GL_REPLACE) {
- /* convert GLchan colors to GLfloat */
- for (i = 0; i < n; i++) {
- rgba[i][RCOMP] = CHAN_TO_FLOAT(rgbaChan[i][RCOMP]);
- rgba[i][GCOMP] = CHAN_TO_FLOAT(rgbaChan[i][GCOMP]);
- rgba[i][BCOMP] = CHAN_TO_FLOAT(rgbaChan[i][BCOMP]);
- rgba[i][ACOMP] = CHAN_TO_FLOAT(rgbaChan[i][ACOMP]);
- }
- }
-
- switch (texUnit->EnvMode) {
- case GL_REPLACE:
- switch (format) {
- case GL_ALPHA:
- for (i=0;i<n;i++) {
- /* Cv = Cf */
- /* Av = At */
- rgba[i][ACOMP] = texel[i][ACOMP];
- }
- break;
- case GL_LUMINANCE:
- for (i=0;i<n;i++) {
- /* Cv = Lt */
- GLfloat Lt = texel[i][RCOMP];
- rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt;
- /* Av = Af */
- }
- break;
- case GL_LUMINANCE_ALPHA:
- for (i=0;i<n;i++) {
- GLfloat Lt = texel[i][RCOMP];
- /* Cv = Lt */
- rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt;
- /* Av = At */
- rgba[i][ACOMP] = texel[i][ACOMP];
- }
- break;
- case GL_INTENSITY:
- for (i=0;i<n;i++) {
- /* Cv = It */
- GLfloat It = texel[i][RCOMP];
- rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = It;
- /* Av = It */
- rgba[i][ACOMP] = It;
- }
- break;
- case GL_RGB:
- for (i=0;i<n;i++) {
- /* Cv = Ct */
- rgba[i][RCOMP] = texel[i][RCOMP];
- rgba[i][GCOMP] = texel[i][GCOMP];
- rgba[i][BCOMP] = texel[i][BCOMP];
- /* Av = Af */
- }
- break;
- case GL_RGBA:
- for (i=0;i<n;i++) {
- /* Cv = Ct */
- rgba[i][RCOMP] = texel[i][RCOMP];
- rgba[i][GCOMP] = texel[i][GCOMP];
- rgba[i][BCOMP] = texel[i][BCOMP];
- /* Av = At */
- rgba[i][ACOMP] = texel[i][ACOMP];
- }
- break;
- default:
- _mesa_problem(ctx, "Bad format (GL_REPLACE) in texture_apply");
- return;
- }
- break;
-
- case GL_MODULATE:
- switch (format) {
- case GL_ALPHA:
- for (i=0;i<n;i++) {
- /* Cv = Cf */
- /* Av = AfAt */
- rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
- }
- break;
- case GL_LUMINANCE:
- for (i=0;i<n;i++) {
- /* Cv = LtCf */
- GLfloat Lt = texel[i][RCOMP];
- rgba[i][RCOMP] = rgba[i][RCOMP] * Lt;
- rgba[i][GCOMP] = rgba[i][GCOMP] * Lt;
- rgba[i][BCOMP] = rgba[i][BCOMP] * Lt;
- /* Av = Af */
- }
- break;
- case GL_LUMINANCE_ALPHA:
- for (i=0;i<n;i++) {
- /* Cv = CfLt */
- GLfloat Lt = texel[i][RCOMP];
- rgba[i][RCOMP] = rgba[i][RCOMP] * Lt;
- rgba[i][GCOMP] = rgba[i][GCOMP] * Lt;
- rgba[i][BCOMP] = rgba[i][BCOMP] * Lt;
- /* Av = AfAt */
- rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
- }
- break;
- case GL_INTENSITY:
- for (i=0;i<n;i++) {
- /* Cv = CfIt */
- GLfloat It = texel[i][RCOMP];
- rgba[i][RCOMP] = rgba[i][RCOMP] * It;
- rgba[i][GCOMP] = rgba[i][GCOMP] * It;
- rgba[i][BCOMP] = rgba[i][BCOMP] * It;
- /* Av = AfIt */
- rgba[i][ACOMP] = rgba[i][ACOMP] * It;
- }
- break;
- case GL_RGB:
- for (i=0;i<n;i++) {
- /* Cv = CfCt */
- rgba[i][RCOMP] = rgba[i][RCOMP] * texel[i][RCOMP];
- rgba[i][GCOMP] = rgba[i][GCOMP] * texel[i][GCOMP];
- rgba[i][BCOMP] = rgba[i][BCOMP] * texel[i][BCOMP];
- /* Av = Af */
- }
- break;
- case GL_RGBA:
- for (i=0;i<n;i++) {
- /* Cv = CfCt */
- rgba[i][RCOMP] = rgba[i][RCOMP] * texel[i][RCOMP];
- rgba[i][GCOMP] = rgba[i][GCOMP] * texel[i][GCOMP];
- rgba[i][BCOMP] = rgba[i][BCOMP] * texel[i][BCOMP];
- /* Av = AfAt */
- rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
- }
- break;
- default:
- _mesa_problem(ctx, "Bad format (GL_MODULATE) in texture_apply");
- return;
- }
- break;
-
- case GL_DECAL:
- switch (format) {
- case GL_ALPHA:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- case GL_INTENSITY:
- /* undefined */
- break;
- case GL_RGB:
- for (i=0;i<n;i++) {
- /* Cv = Ct */
- rgba[i][RCOMP] = texel[i][RCOMP];
- rgba[i][GCOMP] = texel[i][GCOMP];
- rgba[i][BCOMP] = texel[i][BCOMP];
- /* Av = Af */
- }
- break;
- case GL_RGBA:
- for (i=0;i<n;i++) {
- /* Cv = Cf(1-At) + CtAt */
- GLfloat t = texel[i][ACOMP], s = 1.0F - t;
- rgba[i][RCOMP] = rgba[i][RCOMP] * s + texel[i][RCOMP] * t;
- rgba[i][GCOMP] = rgba[i][GCOMP] * s + texel[i][GCOMP] * t;
- rgba[i][BCOMP] = rgba[i][BCOMP] * s + texel[i][BCOMP] * t;
- /* Av = Af */
- }
- break;
- default:
- _mesa_problem(ctx, "Bad format (GL_DECAL) in texture_apply");
- return;
- }
- break;
-
- case GL_BLEND:
- Rc = texUnit->EnvColor[0];
- Gc = texUnit->EnvColor[1];
- Bc = texUnit->EnvColor[2];
- Ac = texUnit->EnvColor[3];
- switch (format) {
- case GL_ALPHA:
- for (i=0;i<n;i++) {
- /* Cv = Cf */
- /* Av = AfAt */
- rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
- }
- break;
- case GL_LUMINANCE:
- for (i=0;i<n;i++) {
- /* Cv = Cf(1-Lt) + CcLt */
- GLfloat Lt = texel[i][RCOMP], s = 1.0F - Lt;
- rgba[i][RCOMP] = rgba[i][RCOMP] * s + Rc * Lt;
- rgba[i][GCOMP] = rgba[i][GCOMP] * s + Gc * Lt;
- rgba[i][BCOMP] = rgba[i][BCOMP] * s + Bc * Lt;
- /* Av = Af */
- }
- break;
- case GL_LUMINANCE_ALPHA:
- for (i=0;i<n;i++) {
- /* Cv = Cf(1-Lt) + CcLt */
- GLfloat Lt = texel[i][RCOMP], s = 1.0F - Lt;
- rgba[i][RCOMP] = rgba[i][RCOMP] * s + Rc * Lt;
- rgba[i][GCOMP] = rgba[i][GCOMP] * s + Gc * Lt;
- rgba[i][BCOMP] = rgba[i][BCOMP] * s + Bc * Lt;
- /* Av = AfAt */
- rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
- }
- break;
- case GL_INTENSITY:
- for (i=0;i<n;i++) {
- /* Cv = Cf(1-It) + CcIt */
- GLfloat It = texel[i][RCOMP], s = 1.0F - It;
- rgba[i][RCOMP] = rgba[i][RCOMP] * s + Rc * It;
- rgba[i][GCOMP] = rgba[i][GCOMP] * s + Gc * It;
- rgba[i][BCOMP] = rgba[i][BCOMP] * s + Bc * It;
- /* Av = Af(1-It) + Ac*It */
- rgba[i][ACOMP] = rgba[i][ACOMP] * s + Ac * It;
- }
- break;
- case GL_RGB:
- for (i=0;i<n;i++) {
- /* Cv = Cf(1-Ct) + CcCt */
- rgba[i][RCOMP] = rgba[i][RCOMP] * (1.0F - texel[i][RCOMP])
- + Rc * texel[i][RCOMP];
- rgba[i][GCOMP] = rgba[i][GCOMP] * (1.0F - texel[i][GCOMP])
- + Gc * texel[i][GCOMP];
- rgba[i][BCOMP] = rgba[i][BCOMP] * (1.0F - texel[i][BCOMP])
- + Bc * texel[i][BCOMP];
- /* Av = Af */
- }
- break;
- case GL_RGBA:
- for (i=0;i<n;i++) {
- /* Cv = Cf(1-Ct) + CcCt */
- rgba[i][RCOMP] = rgba[i][RCOMP] * (1.0F - texel[i][RCOMP])
- + Rc * texel[i][RCOMP];
- rgba[i][GCOMP] = rgba[i][GCOMP] * (1.0F - texel[i][GCOMP])
- + Gc * texel[i][GCOMP];
- rgba[i][BCOMP] = rgba[i][BCOMP] * (1.0F - texel[i][BCOMP])
- + Bc * texel[i][BCOMP];
- /* Av = AfAt */
- rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
- }
- break;
- default:
- _mesa_problem(ctx, "Bad format (GL_BLEND) in texture_apply");
- return;
- }
- break;
-
- /* XXX don't clamp results if GLfloat is float??? */
-
- case GL_ADD: /* GL_EXT_texture_add_env */
- switch (format) {
- case GL_ALPHA:
- for (i=0;i<n;i++) {
- /* Rv = Rf */
- /* Gv = Gf */
- /* Bv = Bf */
- rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
- }
- break;
- case GL_LUMINANCE:
- for (i=0;i<n;i++) {
- GLfloat Lt = texel[i][RCOMP];
- GLfloat r = rgba[i][RCOMP] + Lt;
- GLfloat g = rgba[i][GCOMP] + Lt;
- GLfloat b = rgba[i][BCOMP] + Lt;
- rgba[i][RCOMP] = MIN2(r, 1.0F);
- rgba[i][GCOMP] = MIN2(g, 1.0F);
- rgba[i][BCOMP] = MIN2(b, 1.0F);
- /* Av = Af */
- }
- break;
- case GL_LUMINANCE_ALPHA:
- for (i=0;i<n;i++) {
- GLfloat Lt = texel[i][RCOMP];
- GLfloat r = rgba[i][RCOMP] + Lt;
- GLfloat g = rgba[i][GCOMP] + Lt;
- GLfloat b = rgba[i][BCOMP] + Lt;
- rgba[i][RCOMP] = MIN2(r, 1.0F);
- rgba[i][GCOMP] = MIN2(g, 1.0F);
- rgba[i][BCOMP] = MIN2(b, 1.0F);
- rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
- }
- break;
- case GL_INTENSITY:
- for (i=0;i<n;i++) {
- GLfloat It = texel[i][RCOMP];
- GLfloat r = rgba[i][RCOMP] + It;
- GLfloat g = rgba[i][GCOMP] + It;
- GLfloat b = rgba[i][BCOMP] + It;
- GLfloat a = rgba[i][ACOMP] + It;
- rgba[i][RCOMP] = MIN2(r, 1.0F);
- rgba[i][GCOMP] = MIN2(g, 1.0F);
- rgba[i][BCOMP] = MIN2(b, 1.0F);
- rgba[i][ACOMP] = MIN2(a, 1.0F);
- }
- break;
- case GL_RGB:
- for (i=0;i<n;i++) {
- GLfloat r = rgba[i][RCOMP] + texel[i][RCOMP];
- GLfloat g = rgba[i][GCOMP] + texel[i][GCOMP];
- GLfloat b = rgba[i][BCOMP] + texel[i][BCOMP];
- rgba[i][RCOMP] = MIN2(r, 1.0F);
- rgba[i][GCOMP] = MIN2(g, 1.0F);
- rgba[i][BCOMP] = MIN2(b, 1.0F);
- /* Av = Af */
- }
- break;
- case GL_RGBA:
- for (i=0;i<n;i++) {
- GLfloat r = rgba[i][RCOMP] + texel[i][RCOMP];
- GLfloat g = rgba[i][GCOMP] + texel[i][GCOMP];
- GLfloat b = rgba[i][BCOMP] + texel[i][BCOMP];
- rgba[i][RCOMP] = MIN2(r, 1.0F);
- rgba[i][GCOMP] = MIN2(g, 1.0F);
- rgba[i][BCOMP] = MIN2(b, 1.0F);
- rgba[i][ACOMP] = rgba[i][ACOMP] * texel[i][ACOMP];
- }
- break;
- default:
- _mesa_problem(ctx, "Bad format (GL_ADD) in texture_apply");
- return;
- }
- break;
-
- default:
- _mesa_problem(ctx, "Bad env mode in texture_apply");
- return;
- }
-
- /* convert GLfloat colors to GLchan */
- for (i = 0; i < n; i++) {
- CLAMPED_FLOAT_TO_CHAN(rgbaChan[i][RCOMP], rgba[i][RCOMP]);
- CLAMPED_FLOAT_TO_CHAN(rgbaChan[i][GCOMP], rgba[i][GCOMP]);
- CLAMPED_FLOAT_TO_CHAN(rgbaChan[i][BCOMP], rgba[i][BCOMP]);
- CLAMPED_FLOAT_TO_CHAN(rgbaChan[i][ACOMP], rgba[i][ACOMP]);
- }
-}
-
-
-