⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s_blend.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Mesa 3-D graphics library * Version:  7.1 * * Copyright (C) 1999-2008  Brian Paul   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"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *//** * \file swrast/s_blend.c * \brief software blending. * \author Brian Paul * * Only a few blend modes have been optimized (min, max, transparency, add) * more optimized cases can easily be added if needed. * Celestia uses glBlendFunc(GL_SRC_ALPHA, GL_ONE), for example. */#include "glheader.h"#include "context.h"#include "colormac.h"#include "macros.h"#include "s_blend.h"#include "s_context.h"#include "s_span.h"#if defined(USE_MMX_ASM)#include "x86/mmx.h"#include "x86/common_x86_asm.h"#define _BLENDAPI _ASMAPI#else#define _BLENDAPI#endif/** * Integer divide by 255 * Declare "int divtemp" before using. * This satisfies Glean and should be reasonably fast. * Contributed by Nathan Hand. */#define DIV255(X)  (divtemp = (X), ((divtemp << 8) + divtemp + 256) >> 16)/** * Special case for glBlendFunc(GL_ZERO, GL_ONE). * No-op means the framebuffer values remain unchanged. * Any chanType ok. */static void _BLENDAPIblend_noop(GLcontext *ctx, GLuint n, const GLubyte mask[],           GLvoid *src, const GLvoid *dst, GLenum chanType){   GLint bytes;   ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);   ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);   ASSERT(ctx->Color.BlendSrcRGB == GL_ZERO);   ASSERT(ctx->Color.BlendDstRGB == GL_ONE);   (void) ctx;   /* just memcpy */   if (chanType == GL_UNSIGNED_BYTE)      bytes = 4 * n * sizeof(GLubyte);   else if (chanType == GL_UNSIGNED_SHORT)      bytes = 4 * n * sizeof(GLushort);   else      bytes = 4 * n * sizeof(GLfloat);   _mesa_memcpy(src, dst, bytes);}/** * Special case for glBlendFunc(GL_ONE, GL_ZERO) * Any chanType ok. */static void _BLENDAPIblend_replace(GLcontext *ctx, GLuint n, const GLubyte mask[],              GLvoid *src, const GLvoid *dst, GLenum chanType){   ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);   ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);   ASSERT(ctx->Color.BlendSrcRGB == GL_ONE);   ASSERT(ctx->Color.BlendDstRGB == GL_ZERO);   (void) ctx;   (void) n;   (void) mask;   (void) src;   (void) dst;}/** * Common transparency blending mode: * glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA). */static void _BLENDAPIblend_transparency_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[],                         GLvoid *src, const GLvoid *dst, GLenum chanType){   GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;   const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;   GLuint i;   ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);   ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);   ASSERT(ctx->Color.BlendSrcRGB == GL_SRC_ALPHA);   ASSERT(ctx->Color.BlendSrcA == GL_SRC_ALPHA);   ASSERT(ctx->Color.BlendDstRGB == GL_ONE_MINUS_SRC_ALPHA);   ASSERT(ctx->Color.BlendDstA == GL_ONE_MINUS_SRC_ALPHA);   ASSERT(chanType == GL_UNSIGNED_BYTE);   (void) ctx;   for (i = 0; i < n; i++) {      if (mask[i]) {         const GLint t = rgba[i][ACOMP];  /* t is in [0, 255] */         if (t == 0) {            /* 0% alpha */            COPY_4UBV(rgba[i], dest[i]);         }         else if (t != 255) {	    GLint divtemp;            const GLint r = DIV255((rgba[i][RCOMP] - dest[i][RCOMP]) * t) + dest[i][RCOMP];            const GLint g = DIV255((rgba[i][GCOMP] - dest[i][GCOMP]) * t) + dest[i][GCOMP];            const GLint b = DIV255((rgba[i][BCOMP] - dest[i][BCOMP]) * t) + dest[i][BCOMP];            const GLint a = DIV255((rgba[i][ACOMP] - dest[i][ACOMP]) * t) + dest[i][ACOMP];             ASSERT(r <= 255);            ASSERT(g <= 255);            ASSERT(b <= 255);            ASSERT(a <= 255);            rgba[i][RCOMP] = (GLubyte) r;            rgba[i][GCOMP] = (GLubyte) g;            rgba[i][BCOMP] = (GLubyte) b;            rgba[i][ACOMP] = (GLubyte) a;         }      }   }}static void _BLENDAPIblend_transparency_ushort(GLcontext *ctx, GLuint n, const GLubyte mask[],                          GLvoid *src, const GLvoid *dst, GLenum chanType){   GLushort (*rgba)[4] = (GLushort (*)[4]) src;   const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;   GLuint i;   ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);   ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);   ASSERT(ctx->Color.BlendSrcRGB == GL_SRC_ALPHA);   ASSERT(ctx->Color.BlendSrcA == GL_SRC_ALPHA);   ASSERT(ctx->Color.BlendDstRGB == GL_ONE_MINUS_SRC_ALPHA);   ASSERT(ctx->Color.BlendDstA == GL_ONE_MINUS_SRC_ALPHA);   ASSERT(chanType == GL_UNSIGNED_SHORT);   (void) ctx;   for (i = 0; i < n; i++) {      if (mask[i]) {         const GLint t = rgba[i][ACOMP];         if (t == 0) {            /* 0% alpha */            COPY_4V(rgba[i], dest[i]);         }         else if (t != 65535) {            const GLfloat tt = (GLfloat) t / 65535.0F;            GLushort r = (GLushort) ((rgba[i][RCOMP] - dest[i][RCOMP]) * tt + dest[i][RCOMP]);            GLushort g = (GLushort) ((rgba[i][GCOMP] - dest[i][GCOMP]) * tt + dest[i][GCOMP]);            GLushort b = (GLushort) ((rgba[i][BCOMP] - dest[i][BCOMP]) * tt + dest[i][BCOMP]);            GLushort a = (GLushort) ((rgba[i][ACOMP] - dest[i][ACOMP]) * tt + dest[i][ACOMP]);            ASSIGN_4V(rgba[i], r, g, b, a);         }      }   }}static void _BLENDAPIblend_transparency_float(GLcontext *ctx, GLuint n, const GLubyte mask[],                         GLvoid *src, const GLvoid *dst, GLenum chanType){   GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;   const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;   GLuint i;   ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);   ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);   ASSERT(ctx->Color.BlendSrcRGB == GL_SRC_ALPHA);   ASSERT(ctx->Color.BlendSrcA == GL_SRC_ALPHA);   ASSERT(ctx->Color.BlendDstRGB == GL_ONE_MINUS_SRC_ALPHA);   ASSERT(ctx->Color.BlendDstA == GL_ONE_MINUS_SRC_ALPHA);   ASSERT(chanType == GL_FLOAT);   (void) ctx;   for (i = 0; i < n; i++) {      if (mask[i]) {         const GLfloat t = rgba[i][ACOMP];  /* t in [0, 1] */         if (t == 0.0F) {            /* 0% alpha */            COPY_4V(rgba[i], dest[i]);         }         else if (t != 1.0F) {            GLfloat r = (rgba[i][RCOMP] - dest[i][RCOMP]) * t + dest[i][RCOMP];            GLfloat g = (rgba[i][GCOMP] - dest[i][GCOMP]) * t + dest[i][GCOMP];            GLfloat b = (rgba[i][BCOMP] - dest[i][BCOMP]) * t + dest[i][BCOMP];            GLfloat a = (rgba[i][ACOMP] - dest[i][ACOMP]) * t + dest[i][ACOMP];            ASSIGN_4V(rgba[i], r, g, b, a);         }      }   }}/** * Add src and dest: glBlendFunc(GL_ONE, GL_ONE). * Any chanType ok. */static void _BLENDAPIblend_add(GLcontext *ctx, GLuint n, const GLubyte mask[],          GLvoid *src, const GLvoid *dst, GLenum chanType){   GLuint i;   ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);   ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);   ASSERT(ctx->Color.BlendSrcRGB == GL_ONE);   ASSERT(ctx->Color.BlendDstRGB == GL_ONE);   (void) ctx;   if (chanType == GL_UNSIGNED_BYTE) {      GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;      const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;      for (i=0;i<n;i++) {         if (mask[i]) {            GLint r = rgba[i][RCOMP] + dest[i][RCOMP];            GLint g = rgba[i][GCOMP] + dest[i][GCOMP];            GLint b = rgba[i][BCOMP] + dest[i][BCOMP];            GLint a = rgba[i][ACOMP] + dest[i][ACOMP];            rgba[i][RCOMP] = (GLubyte) MIN2( r, 255 );            rgba[i][GCOMP] = (GLubyte) MIN2( g, 255 );            rgba[i][BCOMP] = (GLubyte) MIN2( b, 255 );            rgba[i][ACOMP] = (GLubyte) MIN2( a, 255 );         }      }   }   else if (chanType == GL_UNSIGNED_SHORT) {      GLushort (*rgba)[4] = (GLushort (*)[4]) src;      const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;      for (i=0;i<n;i++) {         if (mask[i]) {            GLint r = rgba[i][RCOMP] + dest[i][RCOMP];            GLint g = rgba[i][GCOMP] + dest[i][GCOMP];            GLint b = rgba[i][BCOMP] + dest[i][BCOMP];            GLint a = rgba[i][ACOMP] + dest[i][ACOMP];            rgba[i][RCOMP] = (GLshort) MIN2( r, 255 );            rgba[i][GCOMP] = (GLshort) MIN2( g, 255 );            rgba[i][BCOMP] = (GLshort) MIN2( b, 255 );            rgba[i][ACOMP] = (GLshort) MIN2( a, 255 );         }      }   }   else {      GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;      const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;      ASSERT(chanType == GL_FLOAT);      for (i=0;i<n;i++) {         if (mask[i]) {            /* don't RGB clamp to max */            rgba[i][RCOMP] += dest[i][RCOMP];            rgba[i][GCOMP] += dest[i][GCOMP];            rgba[i][BCOMP] += dest[i][BCOMP];            rgba[i][ACOMP] += dest[i][ACOMP];         }      }   }}/** * Blend min function. * Any chanType ok. */static void _BLENDAPIblend_min(GLcontext *ctx, GLuint n, const GLubyte mask[],          GLvoid *src, const GLvoid *dst, GLenum chanType){   GLuint i;   ASSERT(ctx->Color.BlendEquationRGB == GL_MIN);   ASSERT(ctx->Color.BlendEquationA == GL_MIN);   (void) ctx;   if (chanType == GL_UNSIGNED_BYTE) {      GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;      const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;      for (i=0;i<n;i++) {         if (mask[i]) {            rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] );            rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] );            rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] );            rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] );         }      }   }   else if (chanType == GL_UNSIGNED_SHORT) {      GLushort (*rgba)[4] = (GLushort (*)[4]) src;      const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;      for (i=0;i<n;i++) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -