Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygens_blend.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 7.1 00004 * 00005 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00025 00038 #include "main/glheader.h" 00039 #include "main/context.h" 00040 #include "main/colormac.h" 00041 #include "main/macros.h" 00042 00043 #include "s_blend.h" 00044 #include "s_context.h" 00045 #include "s_span.h" 00046 00047 00048 #if defined(USE_MMX_ASM) 00049 #include "x86/mmx.h" 00050 #include "x86/common_x86_asm.h" 00051 #define _BLENDAPI _ASMAPI 00052 #else 00053 #define _BLENDAPI 00054 #endif 00055 00056 00063 #define DIV255(X) (divtemp = (X), ((divtemp << 8) + divtemp + 256) >> 16) 00064 00065 00066 00072 static void _BLENDAPI 00073 blend_noop(GLcontext *ctx, GLuint n, const GLubyte mask[], 00074 GLvoid *src, const GLvoid *dst, GLenum chanType) 00075 { 00076 GLint bytes; 00077 00078 ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD); 00079 ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD); 00080 ASSERT(ctx->Color.BlendSrcRGB == GL_ZERO); 00081 ASSERT(ctx->Color.BlendDstRGB == GL_ONE); 00082 (void) ctx; 00083 00084 /* just memcpy */ 00085 if (chanType == GL_UNSIGNED_BYTE) 00086 bytes = 4 * n * sizeof(GLubyte); 00087 else if (chanType == GL_UNSIGNED_SHORT) 00088 bytes = 4 * n * sizeof(GLushort); 00089 else 00090 bytes = 4 * n * sizeof(GLfloat); 00091 00092 _mesa_memcpy(src, dst, bytes); 00093 } 00094 00095 00100 static void _BLENDAPI 00101 blend_replace(GLcontext *ctx, GLuint n, const GLubyte mask[], 00102 GLvoid *src, const GLvoid *dst, GLenum chanType) 00103 { 00104 ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD); 00105 ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD); 00106 ASSERT(ctx->Color.BlendSrcRGB == GL_ONE); 00107 ASSERT(ctx->Color.BlendDstRGB == GL_ZERO); 00108 (void) ctx; 00109 (void) n; 00110 (void) mask; 00111 (void) src; 00112 (void) dst; 00113 } 00114 00115 00120 static void _BLENDAPI 00121 blend_transparency_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[], 00122 GLvoid *src, const GLvoid *dst, GLenum chanType) 00123 { 00124 GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; 00125 const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; 00126 GLuint i; 00127 00128 ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD); 00129 ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD); 00130 ASSERT(ctx->Color.BlendSrcRGB == GL_SRC_ALPHA); 00131 ASSERT(ctx->Color.BlendSrcA == GL_SRC_ALPHA); 00132 ASSERT(ctx->Color.BlendDstRGB == GL_ONE_MINUS_SRC_ALPHA); 00133 ASSERT(ctx->Color.BlendDstA == GL_ONE_MINUS_SRC_ALPHA); 00134 ASSERT(chanType == GL_UNSIGNED_BYTE); 00135 00136 (void) ctx; 00137 00138 for (i = 0; i < n; i++) { 00139 if (mask[i]) { 00140 const GLint t = rgba[i][ACOMP]; /* t is in [0, 255] */ 00141 if (t == 0) { 00142 /* 0% alpha */ 00143 COPY_4UBV(rgba[i], dest[i]); 00144 } 00145 else if (t != 255) { 00146 GLint divtemp; 00147 const GLint r = DIV255((rgba[i][RCOMP] - dest[i][RCOMP]) * t) + dest[i][RCOMP]; 00148 const GLint g = DIV255((rgba[i][GCOMP] - dest[i][GCOMP]) * t) + dest[i][GCOMP]; 00149 const GLint b = DIV255((rgba[i][BCOMP] - dest[i][BCOMP]) * t) + dest[i][BCOMP]; 00150 const GLint a = DIV255((rgba[i][ACOMP] - dest[i][ACOMP]) * t) + dest[i][ACOMP]; 00151 ASSERT(r <= 255); 00152 ASSERT(g <= 255); 00153 ASSERT(b <= 255); 00154 ASSERT(a <= 255); 00155 rgba[i][RCOMP] = (GLubyte) r; 00156 rgba[i][GCOMP] = (GLubyte) g; 00157 rgba[i][BCOMP] = (GLubyte) b; 00158 rgba[i][ACOMP] = (GLubyte) a; 00159 } 00160 } 00161 } 00162 } 00163 00164 00165 static void _BLENDAPI 00166 blend_transparency_ushort(GLcontext *ctx, GLuint n, const GLubyte mask[], 00167 GLvoid *src, const GLvoid *dst, GLenum chanType) 00168 { 00169 GLushort (*rgba)[4] = (GLushort (*)[4]) src; 00170 const GLushort (*dest)[4] = (const GLushort (*)[4]) dst; 00171 GLuint i; 00172 00173 ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD); 00174 ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD); 00175 ASSERT(ctx->Color.BlendSrcRGB == GL_SRC_ALPHA); 00176 ASSERT(ctx->Color.BlendSrcA == GL_SRC_ALPHA); 00177 ASSERT(ctx->Color.BlendDstRGB == GL_ONE_MINUS_SRC_ALPHA); 00178 ASSERT(ctx->Color.BlendDstA == GL_ONE_MINUS_SRC_ALPHA); 00179 ASSERT(chanType == GL_UNSIGNED_SHORT); 00180 00181 (void) ctx; 00182 00183 for (i = 0; i < n; i++) { 00184 if (mask[i]) { 00185 const GLint t = rgba[i][ACOMP]; 00186 if (t == 0) { 00187 /* 0% alpha */ 00188 COPY_4V(rgba[i], dest[i]); 00189 } 00190 else if (t != 65535) { 00191 const GLfloat tt = (GLfloat) t / 65535.0F; 00192 GLushort r = (GLushort) ((rgba[i][RCOMP] - dest[i][RCOMP]) * tt + dest[i][RCOMP]); 00193 GLushort g = (GLushort) ((rgba[i][GCOMP] - dest[i][GCOMP]) * tt + dest[i][GCOMP]); 00194 GLushort b = (GLushort) ((rgba[i][BCOMP] - dest[i][BCOMP]) * tt + dest[i][BCOMP]); 00195 GLushort a = (GLushort) ((rgba[i][ACOMP] - dest[i][ACOMP]) * tt + dest[i][ACOMP]); 00196 ASSIGN_4V(rgba[i], r, g, b, a); 00197 } 00198 } 00199 } 00200 } 00201 00202 00203 static void _BLENDAPI 00204 blend_transparency_float(GLcontext *ctx, GLuint n, const GLubyte mask[], 00205 GLvoid *src, const GLvoid *dst, GLenum chanType) 00206 { 00207 GLfloat (*rgba)[4] = (GLfloat (*)[4]) src; 00208 const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst; 00209 GLuint i; 00210 00211 ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD); 00212 ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD); 00213 ASSERT(ctx->Color.BlendSrcRGB == GL_SRC_ALPHA); 00214 ASSERT(ctx->Color.BlendSrcA == GL_SRC_ALPHA); 00215 ASSERT(ctx->Color.BlendDstRGB == GL_ONE_MINUS_SRC_ALPHA); 00216 ASSERT(ctx->Color.BlendDstA == GL_ONE_MINUS_SRC_ALPHA); 00217 ASSERT(chanType == GL_FLOAT); 00218 00219 (void) ctx; 00220 00221 for (i = 0; i < n; i++) { 00222 if (mask[i]) { 00223 const GLfloat t = rgba[i][ACOMP]; /* t in [0, 1] */ 00224 if (t == 0.0F) { 00225 /* 0% alpha */ 00226 COPY_4V(rgba[i], dest[i]); 00227 } 00228 else if (t != 1.0F) { 00229 GLfloat r = (rgba[i][RCOMP] - dest[i][RCOMP]) * t + dest[i][RCOMP]; 00230 GLfloat g = (rgba[i][GCOMP] - dest[i][GCOMP]) * t + dest[i][GCOMP]; 00231 GLfloat b = (rgba[i][BCOMP] - dest[i][BCOMP]) * t + dest[i][BCOMP]; 00232 GLfloat a = (rgba[i][ACOMP] - dest[i][ACOMP]) * t + dest[i][ACOMP]; 00233 ASSIGN_4V(rgba[i], r, g, b, a); 00234 } 00235 } 00236 } 00237 } 00238 00239 00240 00245 static void _BLENDAPI 00246 blend_add(GLcontext *ctx, GLuint n, const GLubyte mask[], 00247 GLvoid *src, const GLvoid *dst, GLenum chanType) 00248 { 00249 GLuint i; 00250 00251 ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD); 00252 ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD); 00253 ASSERT(ctx->Color.BlendSrcRGB == GL_ONE); 00254 ASSERT(ctx->Color.BlendDstRGB == GL_ONE); 00255 (void) ctx; 00256 00257 if (chanType == GL_UNSIGNED_BYTE) { 00258 GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; 00259 const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; 00260 for (i=0;i<n;i++) { 00261 if (mask[i]) { 00262 GLint r = rgba[i][RCOMP] + dest[i][RCOMP]; 00263 GLint g = rgba[i][GCOMP] + dest[i][GCOMP]; 00264 GLint b = rgba[i][BCOMP] + dest[i][BCOMP]; 00265 GLint a = rgba[i][ACOMP] + dest[i][ACOMP]; 00266 rgba[i][RCOMP] = (GLubyte) MIN2( r, 255 ); 00267 rgba[i][GCOMP] = (GLubyte) MIN2( g, 255 ); 00268 rgba[i][BCOMP] = (GLubyte) MIN2( b, 255 ); 00269 rgba[i][ACOMP] = (GLubyte) MIN2( a, 255 ); 00270 } 00271 } 00272 } 00273 else if (chanType == GL_UNSIGNED_SHORT) { 00274 GLushort (*rgba)[4] = (GLushort (*)[4]) src; 00275 const GLushort (*dest)[4] = (const GLushort (*)[4]) dst; 00276 for (i=0;i<n;i++) { 00277 if (mask[i]) { 00278 GLint r = rgba[i][RCOMP] + dest[i][RCOMP]; 00279 GLint g = rgba[i][GCOMP] + dest[i][GCOMP]; 00280 GLint b = rgba[i][BCOMP] + dest[i][BCOMP]; 00281 GLint a = rgba[i][ACOMP] + dest[i][ACOMP]; 00282 rgba[i][RCOMP] = (GLshort) MIN2( r, 255 ); 00283 rgba[i][GCOMP] = (GLshort) MIN2( g, 255 ); 00284 rgba[i][BCOMP] = (GLshort) MIN2( b, 255 ); 00285 rgba[i][ACOMP] = (GLshort) MIN2( a, 255 ); 00286 } 00287 } 00288 } 00289 else { 00290 GLfloat (*rgba)[4] = (GLfloat (*)[4]) src; 00291 const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst; 00292 ASSERT(chanType == GL_FLOAT); 00293 for (i=0;i<n;i++) { 00294 if (mask[i]) { 00295 /* don't RGB clamp to max */ 00296 rgba[i][RCOMP] += dest[i][RCOMP]; 00297 rgba[i][GCOMP] += dest[i][GCOMP]; 00298 rgba[i][BCOMP] += dest[i][BCOMP]; 00299 rgba[i][ACOMP] += dest[i][ACOMP]; 00300 } 00301 } 00302 } 00303 } 00304 00305 00306 00311 static void _BLENDAPI 00312 blend_min(GLcontext *ctx, GLuint n, const GLubyte mask[], 00313 GLvoid *src, const GLvoid *dst, GLenum chanType) 00314 { 00315 GLuint i; 00316 ASSERT(ctx->Color.BlendEquationRGB == GL_MIN); 00317 ASSERT(ctx->Color.BlendEquationA == GL_MIN); 00318 (void) ctx; 00319 00320 if (chanType == GL_UNSIGNED_BYTE) { 00321 GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; 00322 const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; 00323 for (i=0;i<n;i++) { 00324 if (mask[i]) { 00325 rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] ); 00326 rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] ); 00327 rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] ); 00328 rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] ); 00329 } 00330 } 00331 } 00332 else if (chanType == GL_UNSIGNED_SHORT) { 00333 GLushort (*rgba)[4] = (GLushort (*)[4]) src; 00334 const GLushort (*dest)[4] = (const GLushort (*)[4]) dst; 00335 for (i=0;i<n;i++) { 00336 if (mask[i]) { 00337 rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] ); 00338 rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] ); 00339 rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] ); 00340 rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] ); 00341 } 00342 } 00343 } 00344 else { 00345 GLfloat (*rgba)[4] = (GLfloat (*)[4]) src; 00346 const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst; 00347 ASSERT(chanType == GL_FLOAT); 00348 for (i=0;i<n;i++) { 00349 if (mask[i]) { 00350 rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] ); 00351 rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] ); 00352 rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] ); 00353 rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] ); 00354 } 00355 } 00356 } 00357 } 00358 00359 00364 static void _BLENDAPI 00365 blend_max(GLcontext *ctx, GLuint n, const GLubyte mask[], 00366 GLvoid *src, const GLvoid *dst, GLenum chanType) 00367 { 00368 GLuint i; 00369 ASSERT(ctx->Color.BlendEquationRGB == GL_MAX); 00370 ASSERT(ctx->Color.BlendEquationA == GL_MAX); 00371 (void) ctx; 00372 00373 if (chanType == GL_UNSIGNED_BYTE) { 00374 GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; 00375 const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; 00376 for (i=0;i<n;i++) { 00377 if (mask[i]) { 00378 rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] ); 00379 rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] ); 00380 rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] ); 00381 rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] ); 00382 } 00383 } 00384 } 00385 else if (chanType == GL_UNSIGNED_SHORT) { 00386 GLushort (*rgba)[4] = (GLushort (*)[4]) src; 00387 const GLushort (*dest)[4] = (const GLushort (*)[4]) dst; 00388 for (i=0;i<n;i++) { 00389 if (mask[i]) { 00390 rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] ); 00391 rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] ); 00392 rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] ); 00393 rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] ); 00394 } 00395 } 00396 } 00397 else { 00398 GLfloat (*rgba)[4] = (GLfloat (*)[4]) src; 00399 const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst; 00400 ASSERT(chanType == GL_FLOAT); 00401 for (i=0;i<n;i++) { 00402 if (mask[i]) { 00403 rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] ); 00404 rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] ); 00405 rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] ); 00406 rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] ); 00407 } 00408 } 00409 } 00410 } 00411 00412 00413 00418 static void _BLENDAPI 00419 blend_modulate(GLcontext *ctx, GLuint n, const GLubyte mask[], 00420 GLvoid *src, const GLvoid *dst, GLenum chanType) 00421 { 00422 GLuint i; 00423 (void) ctx; 00424 00425 if (chanType == GL_UNSIGNED_BYTE) { 00426 GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; 00427 const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; 00428 for (i=0;i<n;i++) { 00429 if (mask[i]) { 00430 GLint divtemp; 00431 rgba[i][RCOMP] = DIV255(rgba[i][RCOMP] * dest[i][RCOMP]); 00432 rgba[i][GCOMP] = DIV255(rgba[i][GCOMP] * dest[i][GCOMP]); 00433 rgba[i][BCOMP] = DIV255(rgba[i][BCOMP] * dest[i][BCOMP]); 00434 rgba[i][ACOMP] = DIV255(rgba[i][ACOMP] * dest[i][ACOMP]); 00435 } 00436 } 00437 } 00438 else if (chanType == GL_UNSIGNED_SHORT) { 00439 GLushort (*rgba)[4] = (GLushort (*)[4]) src; 00440 const GLushort (*dest)[4] = (const GLushort (*)[4]) dst; 00441 for (i=0;i<n;i++) { 00442 if (mask[i]) { 00443 rgba[i][RCOMP] = (rgba[i][RCOMP] * dest[i][RCOMP] + 65535) >> 16; 00444 rgba[i][GCOMP] = (rgba[i][GCOMP] * dest[i][GCOMP] + 65535) >> 16; 00445 rgba[i][BCOMP] = (rgba[i][BCOMP] * dest[i][BCOMP] + 65535) >> 16; 00446 rgba[i][ACOMP] = (rgba[i][ACOMP] * dest[i][ACOMP] + 65535) >> 16; 00447 } 00448 } 00449 } 00450 else { 00451 GLfloat (*rgba)[4] = (GLfloat (*)[4]) src; 00452 const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst; 00453 ASSERT(chanType == GL_FLOAT); 00454 for (i=0;i<n;i++) { 00455 if (mask[i]) { 00456 rgba[i][RCOMP] = rgba[i][RCOMP] * dest[i][RCOMP]; 00457 rgba[i][GCOMP] = rgba[i][GCOMP] * dest[i][GCOMP]; 00458 rgba[i][BCOMP] = rgba[i][BCOMP] * dest[i][BCOMP]; 00459 rgba[i][ACOMP] = rgba[i][ACOMP] * dest[i][ACOMP]; 00460 } 00461 } 00462 } 00463 } 00464 00465 00473 static void 00474 blend_general_float(GLcontext *ctx, GLuint n, const GLubyte mask[], 00475 GLfloat rgba[][4], GLfloat dest[][4], 00476 GLenum chanType) 00477 { 00478 GLuint i; 00479 00480 for (i = 0; i < n; i++) { 00481 if (mask[i]) { 00482 /* Incoming/source Color */ 00483 const GLfloat Rs = rgba[i][RCOMP]; 00484 const GLfloat Gs = rgba[i][GCOMP]; 00485 const GLfloat Bs = rgba[i][BCOMP]; 00486 const GLfloat As = rgba[i][ACOMP]; 00487 00488 /* Frame buffer/dest color */ 00489 const GLfloat Rd = dest[i][RCOMP]; 00490 const GLfloat Gd = dest[i][GCOMP]; 00491 const GLfloat Bd = dest[i][BCOMP]; 00492 const GLfloat Ad = dest[i][ACOMP]; 00493 00494 GLfloat sR, sG, sB, sA; /* Source factor */ 00495 GLfloat dR, dG, dB, dA; /* Dest factor */ 00496 GLfloat r, g, b, a; /* result color */ 00497 00498 /* XXX for the case of constant blend terms we could init 00499 * the sX and dX variables just once before the loop. 00500 */ 00501 00502 /* Source RGB factor */ 00503 switch (ctx->Color.BlendSrcRGB) { 00504 case GL_ZERO: 00505 sR = sG = sB = 0.0F; 00506 break; 00507 case GL_ONE: 00508 sR = sG = sB = 1.0F; 00509 break; 00510 case GL_DST_COLOR: 00511 sR = Rd; 00512 sG = Gd; 00513 sB = Bd; 00514 break; 00515 case GL_ONE_MINUS_DST_COLOR: 00516 sR = 1.0F - Rd; 00517 sG = 1.0F - Gd; 00518 sB = 1.0F - Bd; 00519 break; 00520 case GL_SRC_ALPHA: 00521 sR = sG = sB = As; 00522 break; 00523 case GL_ONE_MINUS_SRC_ALPHA: 00524 sR = sG = sB = 1.0F - As; 00525 break; 00526 case GL_DST_ALPHA: 00527 sR = sG = sB = Ad; 00528 break; 00529 case GL_ONE_MINUS_DST_ALPHA: 00530 sR = sG = sB = 1.0F - Ad; 00531 break; 00532 case GL_SRC_ALPHA_SATURATE: 00533 if (As < 1.0F - Ad) { 00534 sR = sG = sB = As; 00535 } 00536 else { 00537 sR = sG = sB = 1.0F - Ad; 00538 } 00539 break; 00540 case GL_CONSTANT_COLOR: 00541 sR = ctx->Color.BlendColor[0]; 00542 sG = ctx->Color.BlendColor[1]; 00543 sB = ctx->Color.BlendColor[2]; 00544 break; 00545 case GL_ONE_MINUS_CONSTANT_COLOR: 00546 sR = 1.0F - ctx->Color.BlendColor[0]; 00547 sG = 1.0F - ctx->Color.BlendColor[1]; 00548 sB = 1.0F - ctx->Color.BlendColor[2]; 00549 break; 00550 case GL_CONSTANT_ALPHA: 00551 sR = sG = sB = ctx->Color.BlendColor[3]; 00552 break; 00553 case GL_ONE_MINUS_CONSTANT_ALPHA: 00554 sR = sG = sB = 1.0F - ctx->Color.BlendColor[3]; 00555 break; 00556 case GL_SRC_COLOR: 00557 sR = Rs; 00558 sG = Gs; 00559 sB = Bs; 00560 break; 00561 case GL_ONE_MINUS_SRC_COLOR: 00562 sR = 1.0F - Rs; 00563 sG = 1.0F - Gs; 00564 sB = 1.0F - Bs; 00565 break; 00566 default: 00567 /* this should never happen */ 00568 _mesa_problem(ctx, "Bad blend source RGB factor in blend_general_float"); 00569 return; 00570 } 00571 00572 /* Source Alpha factor */ 00573 switch (ctx->Color.BlendSrcA) { 00574 case GL_ZERO: 00575 sA = 0.0F; 00576 break; 00577 case GL_ONE: 00578 sA = 1.0F; 00579 break; 00580 case GL_DST_COLOR: 00581 sA = Ad; 00582 break; 00583 case GL_ONE_MINUS_DST_COLOR: 00584 sA = 1.0F - Ad; 00585 break; 00586 case GL_SRC_ALPHA: 00587 sA = As; 00588 break; 00589 case GL_ONE_MINUS_SRC_ALPHA: 00590 sA = 1.0F - As; 00591 break; 00592 case GL_DST_ALPHA: 00593 sA = Ad; 00594 break; 00595 case GL_ONE_MINUS_DST_ALPHA: 00596 sA = 1.0F - Ad; 00597 break; 00598 case GL_SRC_ALPHA_SATURATE: 00599 sA = 1.0; 00600 break; 00601 case GL_CONSTANT_COLOR: 00602 sA = ctx->Color.BlendColor[3]; 00603 break; 00604 case GL_ONE_MINUS_CONSTANT_COLOR: 00605 sA = 1.0F - ctx->Color.BlendColor[3]; 00606 break; 00607 case GL_CONSTANT_ALPHA: 00608 sA = ctx->Color.BlendColor[3]; 00609 break; 00610 case GL_ONE_MINUS_CONSTANT_ALPHA: 00611 sA = 1.0F - ctx->Color.BlendColor[3]; 00612 break; 00613 case GL_SRC_COLOR: 00614 sA = As; 00615 break; 00616 case GL_ONE_MINUS_SRC_COLOR: 00617 sA = 1.0F - As; 00618 break; 00619 default: 00620 /* this should never happen */ 00621 sA = 0.0F; 00622 _mesa_problem(ctx, "Bad blend source A factor in blend_general_float"); 00623 return; 00624 } 00625 00626 /* Dest RGB factor */ 00627 switch (ctx->Color.BlendDstRGB) { 00628 case GL_ZERO: 00629 dR = dG = dB = 0.0F; 00630 break; 00631 case GL_ONE: 00632 dR = dG = dB = 1.0F; 00633 break; 00634 case GL_SRC_COLOR: 00635 dR = Rs; 00636 dG = Gs; 00637 dB = Bs; 00638 break; 00639 case GL_ONE_MINUS_SRC_COLOR: 00640 dR = 1.0F - Rs; 00641 dG = 1.0F - Gs; 00642 dB = 1.0F - Bs; 00643 break; 00644 case GL_SRC_ALPHA: 00645 dR = dG = dB = As; 00646 break; 00647 case GL_ONE_MINUS_SRC_ALPHA: 00648 dR = dG = dB = 1.0F - As; 00649 break; 00650 case GL_DST_ALPHA: 00651 dR = dG = dB = Ad; 00652 break; 00653 case GL_ONE_MINUS_DST_ALPHA: 00654 dR = dG = dB = 1.0F - Ad; 00655 break; 00656 case GL_CONSTANT_COLOR: 00657 dR = ctx->Color.BlendColor[0]; 00658 dG = ctx->Color.BlendColor[1]; 00659 dB = ctx->Color.BlendColor[2]; 00660 break; 00661 case GL_ONE_MINUS_CONSTANT_COLOR: 00662 dR = 1.0F - ctx->Color.BlendColor[0]; 00663 dG = 1.0F - ctx->Color.BlendColor[1]; 00664 dB = 1.0F - ctx->Color.BlendColor[2]; 00665 break; 00666 case GL_CONSTANT_ALPHA: 00667 dR = dG = dB = ctx->Color.BlendColor[3]; 00668 break; 00669 case GL_ONE_MINUS_CONSTANT_ALPHA: 00670 dR = dG = dB = 1.0F - ctx->Color.BlendColor[3]; 00671 break; 00672 case GL_DST_COLOR: 00673 dR = Rd; 00674 dG = Gd; 00675 dB = Bd; 00676 break; 00677 case GL_ONE_MINUS_DST_COLOR: 00678 dR = 1.0F - Rd; 00679 dG = 1.0F - Gd; 00680 dB = 1.0F - Bd; 00681 break; 00682 default: 00683 /* this should never happen */ 00684 dR = dG = dB = 0.0F; 00685 _mesa_problem(ctx, "Bad blend dest RGB factor in blend_general_float"); 00686 return; 00687 } 00688 00689 /* Dest Alpha factor */ 00690 switch (ctx->Color.BlendDstA) { 00691 case GL_ZERO: 00692 dA = 0.0F; 00693 break; 00694 case GL_ONE: 00695 dA = 1.0F; 00696 break; 00697 case GL_SRC_COLOR: 00698 dA = As; 00699 break; 00700 case GL_ONE_MINUS_SRC_COLOR: 00701 dA = 1.0F - As; 00702 break; 00703 case GL_SRC_ALPHA: 00704 dA = As; 00705 break; 00706 case GL_ONE_MINUS_SRC_ALPHA: 00707 dA = 1.0F - As; 00708 break; 00709 case GL_DST_ALPHA: 00710 dA = Ad; 00711 break; 00712 case GL_ONE_MINUS_DST_ALPHA: 00713 dA = 1.0F - Ad; 00714 break; 00715 case GL_CONSTANT_COLOR: 00716 dA = ctx->Color.BlendColor[3]; 00717 break; 00718 case GL_ONE_MINUS_CONSTANT_COLOR: 00719 dA = 1.0F - ctx->Color.BlendColor[3]; 00720 break; 00721 case GL_CONSTANT_ALPHA: 00722 dA = ctx->Color.BlendColor[3]; 00723 break; 00724 case GL_ONE_MINUS_CONSTANT_ALPHA: 00725 dA = 1.0F - ctx->Color.BlendColor[3]; 00726 break; 00727 case GL_DST_COLOR: 00728 dA = Ad; 00729 break; 00730 case GL_ONE_MINUS_DST_COLOR: 00731 dA = 1.0F - Ad; 00732 break; 00733 default: 00734 /* this should never happen */ 00735 dA = 0.0F; 00736 _mesa_problem(ctx, "Bad blend dest A factor in blend_general_float"); 00737 return; 00738 } 00739 00740 /* compute the blended RGB */ 00741 switch (ctx->Color.BlendEquationRGB) { 00742 case GL_FUNC_ADD: 00743 r = Rs * sR + Rd * dR; 00744 g = Gs * sG + Gd * dG; 00745 b = Bs * sB + Bd * dB; 00746 a = As * sA + Ad * dA; 00747 break; 00748 case GL_FUNC_SUBTRACT: 00749 r = Rs * sR - Rd * dR; 00750 g = Gs * sG - Gd * dG; 00751 b = Bs * sB - Bd * dB; 00752 a = As * sA - Ad * dA; 00753 break; 00754 case GL_FUNC_REVERSE_SUBTRACT: 00755 r = Rd * dR - Rs * sR; 00756 g = Gd * dG - Gs * sG; 00757 b = Bd * dB - Bs * sB; 00758 a = Ad * dA - As * sA; 00759 break; 00760 case GL_MIN: 00761 r = MIN2( Rd, Rs ); 00762 g = MIN2( Gd, Gs ); 00763 b = MIN2( Bd, Bs ); 00764 break; 00765 case GL_MAX: 00766 r = MAX2( Rd, Rs ); 00767 g = MAX2( Gd, Gs ); 00768 b = MAX2( Bd, Bs ); 00769 break; 00770 default: 00771 /* should never get here */ 00772 r = g = b = 0.0F; /* silence uninitialized var warning */ 00773 _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); 00774 return; 00775 } 00776 00777 /* compute the blended alpha */ 00778 switch (ctx->Color.BlendEquationA) { 00779 case GL_FUNC_ADD: 00780 a = As * sA + Ad * dA; 00781 break; 00782 case GL_FUNC_SUBTRACT: 00783 a = As * sA - Ad * dA; 00784 break; 00785 case GL_FUNC_REVERSE_SUBTRACT: 00786 a = Ad * dA - As * sA; 00787 break; 00788 case GL_MIN: 00789 a = MIN2( Ad, As ); 00790 break; 00791 case GL_MAX: 00792 a = MAX2( Ad, As ); 00793 break; 00794 default: 00795 /* should never get here */ 00796 a = 0.0F; /* silence uninitialized var warning */ 00797 _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); 00798 return; 00799 } 00800 00801 /* final clamping */ 00802 #if 0 00803 rgba[i][RCOMP] = MAX2( r, 0.0F ); 00804 rgba[i][GCOMP] = MAX2( g, 0.0F ); 00805 rgba[i][BCOMP] = MAX2( b, 0.0F ); 00806 rgba[i][ACOMP] = CLAMP( a, 0.0F, 1.0F ); 00807 #else 00808 ASSIGN_4V(rgba[i], r, g, b, a); 00809 #endif 00810 } 00811 } 00812 } 00813 00814 00818 static void 00819 blend_general(GLcontext *ctx, GLuint n, const GLubyte mask[], 00820 void *src, const void *dst, GLenum chanType) 00821 { 00822 GLfloat rgbaF[MAX_WIDTH][4], destF[MAX_WIDTH][4]; 00823 00824 if (chanType == GL_UNSIGNED_BYTE) { 00825 GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; 00826 const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; 00827 GLuint i; 00828 /* convert ubytes to floats */ 00829 for (i = 0; i < n; i++) { 00830 if (mask[i]) { 00831 rgbaF[i][RCOMP] = UBYTE_TO_FLOAT(rgba[i][RCOMP]); 00832 rgbaF[i][GCOMP] = UBYTE_TO_FLOAT(rgba[i][GCOMP]); 00833 rgbaF[i][BCOMP] = UBYTE_TO_FLOAT(rgba[i][BCOMP]); 00834 rgbaF[i][ACOMP] = UBYTE_TO_FLOAT(rgba[i][ACOMP]); 00835 destF[i][RCOMP] = UBYTE_TO_FLOAT(dest[i][RCOMP]); 00836 destF[i][GCOMP] = UBYTE_TO_FLOAT(dest[i][GCOMP]); 00837 destF[i][BCOMP] = UBYTE_TO_FLOAT(dest[i][BCOMP]); 00838 destF[i][ACOMP] = UBYTE_TO_FLOAT(dest[i][ACOMP]); 00839 } 00840 } 00841 /* do blend */ 00842 blend_general_float(ctx, n, mask, rgbaF, destF, chanType); 00843 /* convert back to ubytes */ 00844 for (i = 0; i < n; i++) { 00845 if (mask[i]) { 00846 UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][RCOMP], rgbaF[i][RCOMP]); 00847 UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][GCOMP], rgbaF[i][GCOMP]); 00848 UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][BCOMP], rgbaF[i][BCOMP]); 00849 UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][ACOMP], rgbaF[i][ACOMP]); 00850 } 00851 } 00852 } 00853 else if (chanType == GL_UNSIGNED_SHORT) { 00854 GLushort (*rgba)[4] = (GLushort (*)[4]) src; 00855 const GLushort (*dest)[4] = (const GLushort (*)[4]) dst; 00856 GLuint i; 00857 /* convert ushorts to floats */ 00858 for (i = 0; i < n; i++) { 00859 if (mask[i]) { 00860 rgbaF[i][RCOMP] = USHORT_TO_FLOAT(rgba[i][RCOMP]); 00861 rgbaF[i][GCOMP] = USHORT_TO_FLOAT(rgba[i][GCOMP]); 00862 rgbaF[i][BCOMP] = USHORT_TO_FLOAT(rgba[i][BCOMP]); 00863 rgbaF[i][ACOMP] = USHORT_TO_FLOAT(rgba[i][ACOMP]); 00864 destF[i][RCOMP] = USHORT_TO_FLOAT(dest[i][RCOMP]); 00865 destF[i][GCOMP] = USHORT_TO_FLOAT(dest[i][GCOMP]); 00866 destF[i][BCOMP] = USHORT_TO_FLOAT(dest[i][BCOMP]); 00867 destF[i][ACOMP] = USHORT_TO_FLOAT(dest[i][ACOMP]); 00868 } 00869 } 00870 /* do blend */ 00871 blend_general_float(ctx, n, mask, rgbaF, destF, chanType); 00872 /* convert back to ushorts */ 00873 for (i = 0; i < n; i++) { 00874 if (mask[i]) { 00875 UNCLAMPED_FLOAT_TO_USHORT(rgba[i][RCOMP], rgbaF[i][RCOMP]); 00876 UNCLAMPED_FLOAT_TO_USHORT(rgba[i][GCOMP], rgbaF[i][GCOMP]); 00877 UNCLAMPED_FLOAT_TO_USHORT(rgba[i][BCOMP], rgbaF[i][BCOMP]); 00878 UNCLAMPED_FLOAT_TO_USHORT(rgba[i][ACOMP], rgbaF[i][ACOMP]); 00879 } 00880 } 00881 } 00882 else { 00883 blend_general_float(ctx, n, mask, (GLfloat (*)[4]) src, 00884 (GLfloat (*)[4]) dst, chanType); 00885 } 00886 } 00887 00888 00889 00894 void 00895 _swrast_choose_blend_func(GLcontext *ctx, GLenum chanType) 00896 { 00897 SWcontext *swrast = SWRAST_CONTEXT(ctx); 00898 const GLenum eq = ctx->Color.BlendEquationRGB; 00899 const GLenum srcRGB = ctx->Color.BlendSrcRGB; 00900 const GLenum dstRGB = ctx->Color.BlendDstRGB; 00901 const GLenum srcA = ctx->Color.BlendSrcA; 00902 const GLenum dstA = ctx->Color.BlendDstA; 00903 00904 if (ctx->Color.BlendEquationRGB != ctx->Color.BlendEquationA) { 00905 swrast->BlendFunc = blend_general; 00906 } 00907 else if (eq == GL_MIN) { 00908 /* Note: GL_MIN ignores the blending weight factors */ 00909 #if defined(USE_MMX_ASM) 00910 if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) { 00911 swrast->BlendFunc = _mesa_mmx_blend_min; 00912 } 00913 else 00914 #endif 00915 swrast->BlendFunc = blend_min; 00916 } 00917 else if (eq == GL_MAX) { 00918 /* Note: GL_MAX ignores the blending weight factors */ 00919 #if defined(USE_MMX_ASM) 00920 if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) { 00921 swrast->BlendFunc = _mesa_mmx_blend_max; 00922 } 00923 else 00924 #endif 00925 swrast->BlendFunc = blend_max; 00926 } 00927 else if (srcRGB != srcA || dstRGB != dstA) { 00928 swrast->BlendFunc = blend_general; 00929 } 00930 else if (eq == GL_FUNC_ADD && srcRGB == GL_SRC_ALPHA 00931 && dstRGB == GL_ONE_MINUS_SRC_ALPHA) { 00932 #if defined(USE_MMX_ASM) 00933 if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) { 00934 swrast->BlendFunc = _mesa_mmx_blend_transparency; 00935 } 00936 else 00937 #endif 00938 { 00939 if (chanType == GL_UNSIGNED_BYTE) 00940 swrast->BlendFunc = blend_transparency_ubyte; 00941 else if (chanType == GL_UNSIGNED_SHORT) 00942 swrast->BlendFunc = blend_transparency_ushort; 00943 else 00944 swrast->BlendFunc = blend_transparency_float; 00945 } 00946 } 00947 else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ONE) { 00948 #if defined(USE_MMX_ASM) 00949 if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) { 00950 swrast->BlendFunc = _mesa_mmx_blend_add; 00951 } 00952 else 00953 #endif 00954 swrast->BlendFunc = blend_add; 00955 } 00956 else if (((eq == GL_FUNC_ADD || eq == GL_FUNC_REVERSE_SUBTRACT) 00957 && (srcRGB == GL_ZERO && dstRGB == GL_SRC_COLOR)) 00958 || 00959 ((eq == GL_FUNC_ADD || eq == GL_FUNC_SUBTRACT) 00960 && (srcRGB == GL_DST_COLOR && dstRGB == GL_ZERO))) { 00961 #if defined(USE_MMX_ASM) 00962 if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) { 00963 swrast->BlendFunc = _mesa_mmx_blend_modulate; 00964 } 00965 else 00966 #endif 00967 swrast->BlendFunc = blend_modulate; 00968 } 00969 else if (eq == GL_FUNC_ADD && srcRGB == GL_ZERO && dstRGB == GL_ONE) { 00970 swrast->BlendFunc = blend_noop; 00971 } 00972 else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ZERO) { 00973 swrast->BlendFunc = blend_replace; 00974 } 00975 else { 00976 swrast->BlendFunc = blend_general; 00977 } 00978 } 00979 00980 00981 00987 void 00988 _swrast_blend_span(GLcontext *ctx, struct gl_renderbuffer *rb, SWspan *span) 00989 { 00990 SWcontext *swrast = SWRAST_CONTEXT(ctx); 00991 void *rbPixels; 00992 00993 ASSERT(span->end <= MAX_WIDTH); 00994 ASSERT(span->arrayMask & SPAN_RGBA); 00995 ASSERT(rb->DataType == span->array->ChanType); 00996 ASSERT(!ctx->Color._LogicOpEnabled); 00997 00998 rbPixels = _swrast_get_dest_rgba(ctx, rb, span); 00999 01000 swrast->BlendFunc(ctx, span->end, span->array->mask, 01001 span->array->rgba, rbPixels, span->array->ChanType); 01002 } Generated on Sat May 26 2012 04:19:30 for ReactOS by
1.7.6.1
|