// 功能: 替换某块序号为index的着色纹理
void TerrainTile::ReplaceTexture(size_t index, const std::string& texName)
{
m_pOwner->ReplaceTileTexture(this, index, texName);
}
//***************************************************************************************
// 功能: 替换某块序号为index的着色纹理 index为纹理的序号 [0,textures.size()-1]
void TerrainManager::ReplaceTileTexture(TerrainTile* pTile, size_t index, const std::string& texName)
{
std::list<std::string>& textures = m_pInfo->m_TileInfos[pTile->GetIdX()][pTile->GetIdZ()].textures;
ASSERT (index < textures.size());//纹理序号必须要小于textures.size
std::list<std::string>::iterator itr = textures.begin();
for (int i = 0; i != index; ++i, ++itr){}//找到当前纹理的指针
if (*itr == texName)//如果当前的纹理名字不变 则返回
return;
*itr = texName;//得到替换纹理的名字
m_pMaterialHandler->ReplaceTileTexture(pTile->GetIdX(), pTile->GetIdZ(), index, texName);
}
//***************************************************************************************
// 功能: 替换某块序号为index的着色纹理 i j为tile在Terrain的编号 index为当前纹理的编号 texName为纹理的名字
void TerrainMaterialHandler::ReplaceTileTexture(size_t i, size_t j, size_t index, const std::string& texName)
{
Ogre::Material::TechniqueIterator ti = m_MaterialTiles[i][j].materialPtr->getTechniqueIterator();
while (ti.hasMoreElements())
{
Ogre::Technique* technique = ti.getNext();
UINT num = 0;
Ogre::Technique::PassIterator pi = technique->getPassIterator();
while (pi.hasMoreElements())
pi.getNext()->getTextureUnitState(index)->setTextureName(texName);
}
}
// 功能: 移除某块序号为index的着色纹理
void TerrainTile::RemoveTexture(UINT index)
{
m_pOwner->RemoveTileTexture(this, index);
}
//***************************************************************************************
// 功能: 移除某块序号为index的着色纹理
void TerrainManager::RemoveTileTexture(TerrainTile* pTile, UINT index)
{
m_pMaterialHandler->RemoveTileTexture(pTile->GetIdX(), pTile->GetIdZ(), index);
}
//***************************************************************************************
// 清除tile[i][j]块的第index个纹理texture
void TerrainMaterialHandler::RemoveTileTexture(size_t i, size_t j, UINT index)
{
std::list<std::string>& textures = m_pOwner->GetTileTextures(i,j);//得到Tile[i][j]包含的纹理数组
if (textures.size() == 1)//如果当前的纹理只有1个 则立即返回
return;
if (textures.size() == 2)//如果只有两个纹理 则可以随便删除一个
{
if (index == 0)
textures.pop_front();
else
textures.pop_back();
MakeMaterial(i, j);
return;
}
//如果当前的Tile包含了多个texture
MaterialTile& matTile = m_MaterialTiles[i][j];//找到当前Tile对应的MaterialTile
int y = matTile.coverageMaps.size() - 1;//当前Tile所需要的混合纹理数目-1
int x = matTile.coverageMaps[y]->GetChannelCount() - 1; //当前Tile最后一张混合纹理的通道数-1
UINT m = index /4; //m为Tile包含的混合图的张数
UINT n = index % 4;//n为index在索引图中的通道
unsigned short tileSize = m_pOwner->GetTileSize()-1;//Tile包含的顶点数目大小 为一个固定值 tileSize
// 拷贝最后一个纹理到该序号 将最后一张纹理在BlendMap中对应的通道值 复制到将要删除的序号为index纹理对应的通道处,然后将最后一张纹理覆盖当前纹理就行了
for(unsigned short b = 0; b < tileSize; ++b)
for(unsigned short a = 0; a < tileSize; ++a)
{//遍历Tile的所有节点,逐个替换通道值
matTile.coverageMaps[m]->SetValue(a,b,n,matTile.coverageMaps[y]->GetValue(a,b,x));
}
std::list<std::string>::iterator itr = textures.begin();
for (UINT k = 0; k < index; ++k, ++itr){}
*itr = *(textures.rbegin());
textures.pop_back();
MakeMaterial(i,j);
}
地形Tile中纹理删除以及替换模块分析,所有源码转自Ogrese
最新推荐文章于 2024-06-07 10:46:12 发布