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

📄 mga_texcombine.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2003 Ville Syrjala * * 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 * THE AUTHORS OR COPYRIGHT HOLDERS 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. * * Authors: *    Ville Syrjala <syrjala@sci.fi> */#include "glheader.h"#include "mgacontext.h"#include "mgatex.h"#include "mgaregs.h"/* * GL_ARB_texture_env_combine * GL_EXT_texture_env_combine * GL_ARB_texture_env_crossbar * GL_ATI_texture_env_combine3 */#define ARG_DISABLE 0xffffffff#define MGA_ARG1  0#define MGA_ARG2  1#define MGA_ALPHA 2GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit ){   mgaContextPtr mmesa = MGA_CONTEXT(ctx);   const int source = mmesa->tmu_source[unit];   const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];   GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit);   GLuint numColorArgs = 0, numAlphaArgs = 0;   GLuint arg1[3], arg2[3], alpha[3];   int args[3];   int i;   switch (texUnit->Combine.ModeRGB) {   case GL_REPLACE:      numColorArgs = 1;      break;   case GL_MODULATE:   case GL_ADD:   case GL_ADD_SIGNED:   case GL_SUBTRACT:      numColorArgs = 2;      break;   case GL_INTERPOLATE:   case GL_MODULATE_ADD_ATI:   case GL_MODULATE_SIGNED_ADD_ATI:   case GL_MODULATE_SUBTRACT_ATI:      numColorArgs = 3;      break;   default:      return GL_FALSE;   }   switch (texUnit->Combine.ModeA) {   case GL_REPLACE:      numAlphaArgs = 1;      break;   case GL_MODULATE:   case GL_ADD:   case GL_ADD_SIGNED:   case GL_SUBTRACT:      numAlphaArgs = 2;      break;   default:      return GL_FALSE;   }   /* Start fresh :) */   *reg = 0;   /* COLOR */   for (i = 0; i < 3; i++) {      arg1[i] = 0;      arg2[i] = 0;      alpha[i] = 0;   }   for (i = 0;i < numColorArgs; i++) {      switch (texUnit->Combine.SourceRGB[i]) {      case GL_TEXTURE:         arg1[i] |= 0;         arg2[i] |= ARG_DISABLE;         alpha[i] |= TD0_color_alpha_currtex;         break;      case GL_TEXTURE0:         if (source == 0) {            arg1[i] |= 0;            arg2[i] |= ARG_DISABLE;            alpha[i] |= TD0_color_alpha_currtex;         } else {            if (ctx->Texture._EnabledUnits != 0x03) {               /* disable texturing */               mmesa->setup.dwgctl &= DC_opcod_MASK;               mmesa->setup.dwgctl |= DC_opcod_trap;               mmesa->hw.alpha_sel = AC_alphasel_diffused;               /* return GL_TRUE since we don't need a fallback */               return GL_TRUE;            }            arg1[i] |= ARG_DISABLE;            arg2[i] |= ARG_DISABLE;            alpha[i] |= TD0_color_alpha_prevtex;         }         break;      case GL_TEXTURE1:         if (source == 0) {            if (ctx->Texture._EnabledUnits != 0x03) {               /* disable texturing */               mmesa->setup.dwgctl &= DC_opcod_MASK;               mmesa->setup.dwgctl |= DC_opcod_trap;               mmesa->hw.alpha_sel = AC_alphasel_diffused;               /* return GL_TRUE since we don't need a fallback */               return GL_TRUE;            }            arg1[i] |= ARG_DISABLE;            /* G400 specs (TDUALSTAGE0) */            arg2[i] |= TD0_color_arg2_prevstage;            alpha[i] |= TD0_color_alpha_prevstage;         } else {            arg1[i] |= 0;            arg2[i] |= ARG_DISABLE;            alpha[i] |= TD0_color_alpha_currtex;         }         break;      case GL_CONSTANT:         if (mmesa->fcol_used &&             mmesa->envcolor[source] != mmesa->envcolor[!source])            return GL_FALSE;         arg1[i] |= ARG_DISABLE;         arg2[i] |= TD0_color_arg2_fcol;         alpha[i] |= TD0_color_alpha_fcol;         mmesa->setup.fcol = mmesa->envcolor[source];         mmesa->fcol_used = GL_TRUE;         break;      case GL_PRIMARY_COLOR:         arg1[i] |= ARG_DISABLE;         /* G400 specs (TDUALSTAGE1) */         if (unit == 0 || (mmesa->setup.tdualstage0 &                           ((TD0_color_sel_mul & TD0_color_sel_add) |                            (TD0_alpha_sel_mul & TD0_alpha_sel_add)))) {            arg2[i] |= TD0_color_arg2_diffuse;            alpha[i] |= TD0_color_alpha_diffuse;         } else {            arg2[i] |= ARG_DISABLE;            alpha[i] |= ARG_DISABLE;         }         break;      case GL_PREVIOUS:         arg1[i] |= ARG_DISABLE;         if (unit == 0) {            arg2[i] |= TD0_color_arg2_diffuse;            alpha[i] |= TD0_color_alpha_diffuse;         } else {            arg2[i] |= TD0_color_arg2_prevstage;            alpha[i] |= TD0_color_alpha_prevstage;         }         break;      default:         return GL_FALSE;      }      switch (texUnit->Combine.OperandRGB[i]) {      case GL_SRC_COLOR:         arg1[i] |= 0;         arg2[i] |= 0;         if (texUnit->Combine.SourceRGB[i] == GL_CONSTANT &&             RGBA_EQUAL( mmesa->envcolor[source] )) {            alpha[i] |= 0;         } else {            alpha[i] |= ARG_DISABLE;         }         break;      case GL_ONE_MINUS_SRC_COLOR:         arg1[i] |= TD0_color_arg1_inv_enable;         arg2[i] |= TD0_color_arg2_inv_enable;         if (texUnit->Combine.SourceRGB[i] == GL_CONSTANT &&             RGBA_EQUAL( mmesa->envcolor[source] )) {            alpha[i] |= (TD0_color_alpha1inv_enable |                         TD0_color_alpha2inv_enable);         } else {            alpha[i] |= ARG_DISABLE;         }         break;      case GL_SRC_ALPHA:         arg1[i] |= TD0_color_arg1_replicatealpha_enable;         arg2[i] |= TD0_color_arg2_replicatealpha_enable;         alpha[i] |= 0;         break;      case GL_ONE_MINUS_SRC_ALPHA:         arg1[i] |= (TD0_color_arg1_replicatealpha_enable |                     TD0_color_arg1_inv_enable);         arg2[i] |= (TD0_color_arg2_replicatealpha_enable |                     TD0_color_arg2_inv_enable);         alpha[i] |= (TD0_color_alpha1inv_enable |                      TD0_color_alpha2inv_enable);         break;      }   }   switch (texUnit->Combine.ModeRGB) {   case GL_MODULATE_ADD_ATI:   case GL_MODULATE_SIGNED_ADD_ATI:      /* Special handling for ATI_texture_env_combine3.       * If Arg1 == Arg0 or Arg1 == Arg2 we can use arg1 or arg2 as input for       * both multiplier and adder.       */      /* Arg1 == arg1 */      if (arg1[1] == arg1[0]) {         if ((arg1[1] | arg2[2]) != ARG_DISABLE) {            *reg |= arg1[1] | arg2[2];            args[0] = MGA_ARG1; args[1] = MGA_ARG1; args[2] = MGA_ARG2;            break;         } else         if ((arg1[1] | alpha[2]) != ARG_DISABLE) {            *reg |= arg1[1] | alpha[2];            args[0] = MGA_ARG1; args[1] = MGA_ARG1; args[2] = MGA_ALPHA;            break;         }      }      if (arg1[1] == arg1[2]) {         if ((arg1[1] | arg2[0]) != ARG_DISABLE) {            *reg |= arg1[1] | arg2[0];            args[0] = MGA_ARG2; args[1] = MGA_ARG1; args[2] = MGA_ARG1;            break;         } else         if ((arg1[1] | alpha[0]) != ARG_DISABLE) {            *reg |= arg1[1] | alpha[0];            args[0] = MGA_ALPHA; args[1] = MGA_ARG1; args[2] = MGA_ARG1;            break;         }      }      /* fallthrough */   case GL_MODULATE_SUBTRACT_ATI:      /* Arg1 == arg2 */      if (arg2[1] == arg2[0]) {         if ((arg2[1] | arg1[2]) != ARG_DISABLE) {            *reg |= arg2[1] | arg1[2];            args[0] = MGA_ARG2; args[1] = MGA_ARG2; args[2] = MGA_ARG1;            break;         } else         if ((arg2[1] | alpha[2]) != ARG_DISABLE) {            *reg |= arg2[1] | alpha[2];            args[0] = MGA_ARG2; args[1] = MGA_ARG2; args[2] = MGA_ALPHA;            break;         }      }      if (arg2[1] == arg2[2]) {         if ((arg2[1] | arg1[0]) != ARG_DISABLE) {            *reg |= arg2[1] | arg1[0];            args[0] = MGA_ARG1; args[1] = MGA_ARG2; args[2] = MGA_ARG2;            break;         } else         if ((arg2[1] | alpha[0]) != ARG_DISABLE) {            *reg |= arg2[1] | alpha[0];            args[0] = MGA_ALPHA; args[1] = MGA_ARG2; args[2] = MGA_ARG2;            break;         }      }      /* fallthrough */   default:      /* Find working combo of arg1, arg2 and alpha.       *       * Keep the Arg0 != alpha cases first since there's       * no way to get alpha out by itself (GL_REPLACE).       *       * Keep the Arg2 == alpha cases first because only alpha has the       * capabilities to function as Arg2 (GL_INTERPOLATE). Also good for        * GL_ADD, GL_ADD_SIGNED, GL_SUBTRACT since we can't get alpha to the       * adder.       *       * Keep the Arg1 == alpha cases last for GL_MODULATE_ADD_ATI,       * GL_MODULATE_SIGNED_ADD_ATI. Again because we can't get alpha to the       * adder.       *       * GL_MODULATE_SUBTRACT_ATI needs special treatment since it requires       * that Arg1 == arg2. This requirement clashes with those of other modes.       */      if ((arg1[0] | arg2[1] | alpha[2]) != ARG_DISABLE) {         *reg |= arg1[0] | arg2[1] | alpha[2];         args[0] = MGA_ARG1; args[1] = MGA_ARG2; args[2] = MGA_ALPHA;      } else      if ((arg1[1] | arg2[0] | alpha[2]) != ARG_DISABLE &&          texUnit->Combine.ModeRGB != GL_MODULATE_SUBTRACT_ATI) {         *reg |= arg1[1] | arg2[0] | alpha[2];         args[0] = MGA_ARG2; args[1] = MGA_ARG1; args[2] = MGA_ALPHA;      } else      if ((arg1[1] | arg2[2] | alpha[0]) != ARG_DISABLE &&          texUnit->Combine.ModeRGB != GL_MODULATE_SUBTRACT_ATI) {         *reg |= arg1[1] | arg2[2] | alpha[0];         args[0] = MGA_ALPHA; args[1] = MGA_ARG1; args[2] = MGA_ARG2;      } else      if ((arg1[2] | arg2[1] | alpha[0]) != ARG_DISABLE) {         *reg |= arg1[2] | arg2[1] | alpha[0];         args[0] = MGA_ALPHA; args[1] = MGA_ARG2; args[2] = MGA_ARG1;      } else      if ((arg1[0] | arg2[2] | alpha[1]) != ARG_DISABLE) {         *reg |= arg1[0] | arg2[2] | alpha[1];         args[0] = MGA_ARG1; args[1] = MGA_ALPHA; args[2] = MGA_ARG2;      } else      if ((arg1[2] | arg2[0] | alpha[1]) != ARG_DISABLE) {         *reg |= arg1[2] | arg2[0] | alpha[1];         args[0] = MGA_ARG2; args[1] = MGA_ALPHA; args[2] = MGA_ARG1;      } else {         /* nothing suitable */         return GL_FALSE;      }   }   switch (texUnit->Combine.ModeRGB) {   case GL_REPLACE:      if (texUnit->Combine.ScaleShiftRGB) {         return GL_FALSE;      }      if (args[0] == MGA_ARG1) {

⌨️ 快捷键说明

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