|
|
@@ -1,8 +1,9 @@ |
|
|
|
/* |
|
|
|
* Mesa 3-D graphics library |
|
|
|
* Version: 6.5.1 |
|
|
|
* Version: 7.5 |
|
|
|
* |
|
|
|
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved. |
|
|
|
* Copyright (C) 1999-2008 Brian Paul All Rights Reserved. |
|
|
|
* Copyright (C) 2009 VMware, Inc. All Rights Reserved. |
|
|
|
* |
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a |
|
|
|
* copy of this software and associated documentation files (the "Software"), |
|
|
@@ -66,9 +67,9 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n, |
|
|
|
GLchan (*rgba)[4] ) |
|
|
|
{ |
|
|
|
const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]); |
|
|
|
const GLchan (*argRGB [3])[4]; |
|
|
|
const GLchan (*argA [3])[4]; |
|
|
|
const GLuint RGBshift = textureUnit->_CurrentCombine->ScaleShiftRGB; |
|
|
|
const GLchan (*argRGB [4])[4]; |
|
|
|
const GLchan (*argA [4])[4]; |
|
|
|
const GLint RGBshift = textureUnit->_CurrentCombine->ScaleShiftRGB; |
|
|
|
const GLuint Ashift = textureUnit->_CurrentCombine->ScaleShiftA; |
|
|
|
#if CHAN_TYPE == GL_FLOAT |
|
|
|
const GLchan RGBmult = (GLfloat) (1 << RGBshift); |
|
|
@@ -80,7 +81,7 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n, |
|
|
|
static const GLchan zero[4] = { 0, 0, 0, 0 }; |
|
|
|
const GLuint numColorArgs = textureUnit->_CurrentCombine->_NumArgsRGB; |
|
|
|
const GLuint numAlphaArgs = textureUnit->_CurrentCombine->_NumArgsA; |
|
|
|
GLchan ccolor[3][MAX_WIDTH][4]; |
|
|
|
GLchan ccolor[4][MAX_WIDTH][4]; |
|
|
|
GLuint i, j; |
|
|
|
|
|
|
|
ASSERT(ctx->Extensions.EXT_texture_env_combine || |
|
|
@@ -98,7 +99,7 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n, |
|
|
|
*/ |
|
|
|
|
|
|
|
/* |
|
|
|
* Do operand setup for up to 3 operands. Loop over the terms. |
|
|
|
* Do operand setup for up to 4 operands. Loop over the terms. |
|
|
|
*/ |
|
|
|
for (j = 0; j < numColorArgs; j++) { |
|
|
|
const GLenum srcRGB = textureUnit->_CurrentCombine->SourceRGB[j]; |
|
|
@@ -295,7 +296,36 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n, |
|
|
|
} |
|
|
|
break; |
|
|
|
case GL_ADD: |
|
|
|
{ |
|
|
|
if (textureUnit->EnvMode == GL_COMBINE4_NV) { |
|
|
|
/* (a * b) + (c * d) */ |
|
|
|
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; |
|
|
|
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; |
|
|
|
const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2]; |
|
|
|
const GLchan (*arg3)[4] = (const GLchan (*)[4]) argRGB[3]; |
|
|
|
for (i = 0; i < n; i++) { |
|
|
|
#if CHAN_TYPE == GL_FLOAT |
|
|
|
rgba[i][RCOMP] = (arg0[i][RCOMP] * arg1[i][RCOMP] + |
|
|
|
arg2[i][RCOMP] * arg3[i][RCOMP]) * RGBmult; |
|
|
|
rgba[i][GCOMP] = (arg0[i][GCOMP] * arg1[i][GCOMP] + |
|
|
|
arg2[i][GCOMP] * arg3[i][GCOMP]) * RGBmult; |
|
|
|
rgba[i][BCOMP] = (arg0[i][BCOMP] * arg1[i][BCOMP] + |
|
|
|
arg2[i][BCOMP] * arg3[i][BCOMP]) * RGBmult; |
|
|
|
#else |
|
|
|
const GLint shift = CHAN_BITS - RGBshift; |
|
|
|
GLint r = (PROD(arg0[i][RCOMP], arg1[i][RCOMP]) >> shift) + |
|
|
|
(PROD(arg2[i][RCOMP], arg3[i][RCOMP]) >> shift); |
|
|
|
GLint g = (PROD(arg0[i][GCOMP], arg1[i][GCOMP]) >> shift) + |
|
|
|
(PROD(arg2[i][GCOMP], arg3[i][GCOMP]) >> shift); |
|
|
|
GLint b = (PROD(arg0[i][BCOMP], arg1[i][BCOMP]) >> shift) + |
|
|
|
(PROD(arg2[i][BCOMP], arg3[i][BCOMP]) >> shift); |
|
|
|
rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); |
|
|
|
rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); |
|
|
|
rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
/* 2-term addition */ |
|
|
|
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; |
|
|
|
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; |
|
|
|
for (i = 0; i < n; i++) { |
|
|
@@ -315,7 +345,37 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n, |
|
|
|
} |
|
|
|
break; |
|
|
|
case GL_ADD_SIGNED: |
|
|
|
{ |
|
|
|
if (textureUnit->EnvMode == GL_COMBINE4_NV) { |
|
|
|
/* (a * b) + (c * d) - 0.5 */ |
|
|
|
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; |
|
|
|
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; |
|
|
|
const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2]; |
|
|
|
const GLchan (*arg3)[4] = (const GLchan (*)[4]) argRGB[3]; |
|
|
|
for (i = 0; i < n; i++) { |
|
|
|
#if CHAN_TYPE == GL_FLOAT |
|
|
|
rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] * |
|
|
|
arg2[i][RCOMP] + arg3[i][RCOMP] - 0.5) * RGBmult; |
|
|
|
rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] * |
|
|
|
arg2[i][GCOMP] + arg3[i][GCOMP] - 0.5) * RGBmult; |
|
|
|
rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] * |
|
|
|
arg2[i][BCOMP] + arg3[i][BCOMP] - 0.5) * RGBmult; |
|
|
|
#else |
|
|
|
GLint r = (((PROD(arg0[i][RCOMP], arg1[i][RCOMP]) + |
|
|
|
PROD(arg2[i][RCOMP], arg3[i][RCOMP])) >> CHAN_BITS) - half) |
|
|
|
<< RGBshift; |
|
|
|
GLint g = (((PROD(arg0[i][GCOMP], arg1[i][GCOMP]) + |
|
|
|
PROD(arg2[i][GCOMP], arg3[i][GCOMP])) >> CHAN_BITS) - half) |
|
|
|
<< RGBshift; |
|
|
|
GLint b = (((PROD(arg0[i][BCOMP], arg1[i][BCOMP]) + |
|
|
|
PROD(arg2[i][BCOMP], arg3[i][BCOMP])) >> CHAN_BITS) - half) |
|
|
|
<< RGBshift; |
|
|
|
rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); |
|
|
|
rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); |
|
|
|
rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; |
|
|
|
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; |
|
|
|
for (i = 0; i < n; i++) { |
|
|
@@ -324,9 +384,9 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n, |
|
|
|
rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] - 0.5) * RGBmult; |
|
|
|
rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] - 0.5) * RGBmult; |
|
|
|
#else |
|
|
|
GLint r = (GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP] -half; |
|
|
|
GLint g = (GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP] -half; |
|
|
|
GLint b = (GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP] -half; |
|
|
|
GLint r = (GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP] - half; |
|
|
|
GLint g = (GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP] - half; |
|
|
|
GLint b = (GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP] - half; |
|
|
|
r = (r < 0) ? 0 : r << RGBshift; |
|
|
|
g = (g < 0) ? 0 : g << RGBshift; |
|
|
|
b = (b < 0) ? 0 : b << RGBshift; |
|
|
@@ -573,9 +633,28 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n, |
|
|
|
} |
|
|
|
break; |
|
|
|
case GL_ADD: |
|
|
|
{ |
|
|
|
if (textureUnit->EnvMode == GL_COMBINE4_NV) { |
|
|
|
/* (a * b) + (c * d) */ |
|
|
|
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; |
|
|
|
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; |
|
|
|
const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2]; |
|
|
|
const GLchan (*arg3)[4] = (const GLchan (*)[4]) argA[3]; |
|
|
|
for (i = 0; i < n; i++) { |
|
|
|
#if CHAN_TYPE == GL_FLOAT |
|
|
|
rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] + |
|
|
|
arg2[i][ACOMP] * arg3[i][ACOMP]) * Amult; |
|
|
|
#else |
|
|
|
const GLint shift = CHAN_BITS - Ashift; |
|
|
|
GLint a = (PROD(arg0[i][ACOMP], arg1[i][ACOMP]) >> shift) + |
|
|
|
(PROD(arg2[i][ACOMP], arg3[i][ACOMP]) >> shift); |
|
|
|
rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
/* two-term add */ |
|
|
|
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; |
|
|
|
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; |
|
|
|
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; |
|
|
|
for (i = 0; i < n; i++) { |
|
|
|
#if CHAN_TYPE == GL_FLOAT |
|
|
|
rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP]) * Amult; |
|
|
@@ -587,7 +666,27 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n, |
|
|
|
} |
|
|
|
break; |
|
|
|
case GL_ADD_SIGNED: |
|
|
|
{ |
|
|
|
if (textureUnit->EnvMode == GL_COMBINE4_NV) { |
|
|
|
/* (a * b) + (c * d) - 0.5 */ |
|
|
|
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; |
|
|
|
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; |
|
|
|
const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2]; |
|
|
|
const GLchan (*arg3)[4] = (const GLchan (*)[4]) argA[3]; |
|
|
|
for (i = 0; i < n; i++) { |
|
|
|
#if CHAN_TYPE == GL_FLOAT |
|
|
|
rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] + |
|
|
|
arg2[i][ACOMP] * arg3[i][ACOMP] - |
|
|
|
0.5) * Amult; |
|
|
|
#else |
|
|
|
GLint a = (((PROD(arg0[i][ACOMP], arg1[i][ACOMP]) + |
|
|
|
PROD(arg2[i][ACOMP], arg3[i][ACOMP])) >> CHAN_BITS) - half) |
|
|
|
<< Ashift; |
|
|
|
rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
/* a + b - 0.5 */ |
|
|
|
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; |
|
|
|
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; |
|
|
|
for (i = 0; i < n; i++) { |
|
|
@@ -596,7 +695,7 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n, |
|
|
|
#else |
|
|
|
GLint a = (GLint) arg0[i][ACOMP] + (GLint) arg1[i][ACOMP] -half; |
|
|
|
a = (a < 0) ? 0 : a << Ashift; |
|
|
|
rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); |
|
|
|
rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |