地形Tile中纹理删除以及替换模块分析,所有源码转自Ogrese

// 功能:	替换某块序号为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);
}











  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值