//----------------------------------------------------------------------- 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()); }
//----------------------------------------------------------------------- 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; }