//-----------------------------------------------------------------------
    void RenderSystem::_setTextureUnitSettings(size_t texUnit, TextureUnitState& tl)
    {
        // This method is only ever called to set a texture unit to valid details
        // The method _disableTextureUnit is called to turn a unit off

        const TexturePtr& tex = tl._getTexturePtr();
		// Vertex texture binding?
		if (mCurrentCapabilities->hasCapability(RSC_VERTEX_TEXTURE_FETCH) &&
			!mCurrentCapabilities->getVertexTextureUnitsShared())
		{
			if (tl.getBindingType() == TextureUnitState::BT_VERTEX)
			{
				// Bind vertex texture
				_setVertexTexture(texUnit, tex);
				// bind nothing to fragment unit (hardware isn't shared but fragment
				// unit can't be using the same index
				_setTexture(texUnit, true, sNullTexPtr);
			}
			else
			{
				// vice versa
				_setVertexTexture(texUnit, sNullTexPtr);
				_setTexture(texUnit, true, tex);
			}
		}
		else
		{
			// Shared vertex / fragment textures or no vertex texture support
			// Bind texture (may be blank)
			_setTexture(texUnit, true, tex);
		}

        // Set texture coordinate set
        _setTextureCoordSet(texUnit, tl.getTextureCoordSet());

        // Set texture layer filtering
        _setTextureUnitFiltering(texUnit, 
            tl.getTextureFiltering(FT_MIN), 
            tl.getTextureFiltering(FT_MAG), 
            tl.getTextureFiltering(FT_MIP));

        // Set texture layer filtering
        _setTextureLayerAnisotropy(texUnit, tl.getTextureAnisotropy());

		// Set mipmap biasing
		_setTextureMipmapBias(texUnit, tl.getTextureMipmapBias());

		// Set blend modes
		// Note, colour before alpha is important
        _setTextureBlendMode(texUnit, tl.getColourBlendMode());
        _setTextureBlendMode(texUnit, tl.getAlphaBlendMode());

        // Texture addressing mode
        const TextureUnitState::UVWAddressingMode& uvw = tl.getTextureAddressingMode();
        _setTextureAddressingMode(texUnit, uvw);
        // Set texture border colour only if required
        if (uvw.u == TextureUnitState::TAM_BORDER ||
            uvw.v == TextureUnitState::TAM_BORDER ||
            uvw.w == TextureUnitState::TAM_BORDER)
        {
            _setTextureBorderColour(texUnit, tl.getTextureBorderColour());
        }

        // Set texture effects
        TextureUnitState::EffectMap::iterator effi;
        // Iterate over new effects
        bool anyCalcs = false;
        for (effi = tl.mEffects.begin(); effi != tl.mEffects.end(); ++effi)
        {
            switch (effi->second.type)
            {
            case TextureUnitState::ET_ENVIRONMENT_MAP:
                if (effi->second.subtype == TextureUnitState::ENV_CURVED)
                {
                    _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP);
                    anyCalcs = true;
                }
                else if (effi->second.subtype == TextureUnitState::ENV_PLANAR)
                {
                    _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_PLANAR);
                    anyCalcs = true;
                }
                else if (effi->second.subtype == TextureUnitState::ENV_REFLECTION)
                {
                    _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_REFLECTION);
                    anyCalcs = true;
                }
                else if (effi->second.subtype == TextureUnitState::ENV_NORMAL)
                {
                    _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_NORMAL);
                    anyCalcs = true;
                }
                break;
            case TextureUnitState::ET_UVSCROLL:
			case TextureUnitState::ET_USCROLL:
			case TextureUnitState::ET_VSCROLL:
            case TextureUnitState::ET_ROTATE:
            case TextureUnitState::ET_TRANSFORM:
                break;
            case TextureUnitState::ET_PROJECTIVE_TEXTURE:
                _setTextureCoordCalculation(texUnit, TEXCALC_PROJECTIVE_TEXTURE, 
                    effi->second.frustum);
                anyCalcs = true;
                break;
            }
        }
        // Ensure any previous texcoord calc settings are reset if there are now none
        if (!anyCalcs)
        {
            _setTextureCoordCalculation(texUnit, TEXCALC_NONE);
        }

        // Change tetxure matrix 
        _setTextureMatrix(texUnit, tl.getTextureTransform());


    }
Esempio n. 2
0
//-----------------------------------------------------------------------
void RenderSystem::_setTextureUnitSettings(int texUnit, Material::TextureLayer& tl) {
  // This method is only ever called to set a texture unit to valid details
  // The method _disableTextureUnit is called to turn a unit off

  Material::TextureLayer& curr = mTextureUnits[texUnit];
  bool currIsBlank = curr.isBlank();

  // Texture name
  String texName = tl.getTextureName();
  if (currIsBlank || curr.getTextureName() != texName) {
    _setTexture(texUnit, true, texName);
  }

  // Set texture coordinate set
  int coordSet = tl.getTextureCoordSet();
  if (currIsBlank || curr.getTextureCoordSet() != coordSet) {
    _setTextureCoordSet(texUnit, coordSet);
  }

  // Set texture layer filtering
  TextureFilterOptions texLayerFilterOps = tl.getTextureLayerFiltering();
  if (currIsBlank || curr.getTextureLayerFiltering() != texLayerFilterOps) {
    _setTextureLayerFiltering(texUnit, texLayerFilterOps);
  }

  // Set texture layer filtering
  int tMaxAniso = tl.getTextureAnisotropy();
  if (currIsBlank || curr.getTextureAnisotropy() != tMaxAniso) {
    _setTextureLayerAnisotropy(texUnit, tMaxAniso);
  }

  // Set blend modes
  LayerBlendModeEx newBlend = tl.getColourBlendMode();
  if (currIsBlank || curr.getColourBlendMode() != newBlend) {
    _setTextureBlendMode(texUnit, newBlend);
  }
  newBlend = tl.getAlphaBlendMode();
  if (currIsBlank || curr.getAlphaBlendMode() != newBlend) {
    _setTextureBlendMode(texUnit, newBlend);
  }

  Material::TextureLayer::TextureAddressingMode addr = tl.getTextureAddressingMode();
  // Fix: GL requires addressing mode to be set in ALL cases
  // If the extra state changes in D3D become problematic, refactor this
  //if (currIsBlank || curr.getTextureAddressingMode() != addr)
  //{
  _setTextureAddressingMode(texUnit, addr );
  //}

  // Set texture effects
  Material::TextureLayer::EffectMap::iterator effi;
  bool currEnv = false;
  bool currEnvPlanar = false;
  bool currEnvReflection = false;
  bool currEnvNormal = false;
  // bool currTexMod = false;
  // Iterate over current effects
  for (effi = curr.mEffects.begin(); effi != curr.mEffects.end(); ++effi) {
    switch (effi->second.type) {
    case Material::TextureLayer::ET_ENVIRONMENT_MAP:
      if (effi->second.subtype == Material::TextureLayer::ENV_CURVED) {
        currEnv = true;
      } else if (effi->second.subtype == Material::TextureLayer::ENV_PLANAR) {
        currEnvPlanar = true;
      } else if (effi->second.subtype == Material::TextureLayer::ENV_REFLECTION) {
        currEnvReflection = true;
      } else if (effi->second.subtype == Material::TextureLayer::ENV_NORMAL) {
        currEnvNormal = true;
      }
      break;
    case Material::TextureLayer::ET_BUMP_MAP:
    case Material::TextureLayer::ET_SCROLL:
    case Material::TextureLayer::ET_ROTATE:
    case Material::TextureLayer::ET_TRANSFORM:
      break;
    }
  }
  // Iterate over new effects
  bool anyCalcs = false;
  for (effi = tl.mEffects.begin(); effi != tl.mEffects.end(); ++effi) {
    switch (effi->second.type) {
    case Material::TextureLayer::ET_ENVIRONMENT_MAP:
      if (effi->second.subtype == Material::TextureLayer::ENV_CURVED) {
        if (currIsBlank || !currEnv) {
          _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP);
        }
        anyCalcs = true;
      } else if (effi->second.subtype == Material::TextureLayer::ENV_PLANAR) {
        if (currIsBlank || !currEnvPlanar) {
          _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_PLANAR);
        }
        anyCalcs = true;
      } else if (effi->second.subtype == Material::TextureLayer::ENV_REFLECTION) {
        if (currIsBlank || !currEnvReflection) {
          _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_REFLECTION);
        }
        anyCalcs = true;
      } else if (effi->second.subtype == Material::TextureLayer::ENV_NORMAL) {
        if (currIsBlank || !currEnvNormal) {
          _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_NORMAL);
        }
        anyCalcs = true;
      }
      break;
    case Material::TextureLayer::ET_BUMP_MAP:
    case Material::TextureLayer::ET_SCROLL:
    case Material::TextureLayer::ET_ROTATE:
    case Material::TextureLayer::ET_TRANSFORM:
      break;
    }
  }
  // Ensure any previous texcoord calc settings are reset if there are now none
  if ((!anyCalcs) &&
      (currEnv || currEnvPlanar || currEnvReflection || currEnvNormal)) {
    _setTextureCoordCalculation(texUnit, TEXCALC_NONE);
    _setTextureCoordSet(texUnit, tl.getTextureCoordSet());
  }


  // Change tetxure matrix if required
  // NB concatenate with any existing texture matrix created for generate
  const Matrix4& xform = tl.getTextureTransform();
  if( !(curr.getTextureTransform() == xform )) {
    _setTextureMatrix(texUnit, xform);
  }

  // Set alpha rejection
  unsigned char alphaVal = tl.getAlphaRejectValue();
  CompareFunction alphaFunc = tl.getAlphaRejectFunction();
  if (currIsBlank ||
      (curr.getAlphaRejectFunction() != alphaFunc) ||
      (curr.getAlphaRejectValue() != alphaVal)) {
    _setAlphaRejectSettings(alphaFunc, alphaVal);
  }

  // Now that the changes have been made, update the record of current texture unit settings
  curr = tl;

}