菜鳥學習OGRE和天龍八部之四: 地表貼圖的實現

來源:互聯網
上載者:User

 

國慶大假,沒耍成,天天寫代碼,悲劇...

地表我已經成功載入,也走了不少彎路...犯了很多低級錯誤...不然半天都可以搞定的事情,鬱悶

 

天龍八部的地表算是比較難搞的了,至少我這樣認為,由於自己沒多少OGRE經驗,不清楚地形的載入過程,於是看TSM源碼,

 

發現TSM真是破,破到無法解釋啊,居然只支援一個地圖一個紋理,看著天龍裡面幾十個紋理,我只有歎氣啊

 

於是打算用ETM,發現ETM用了shade,和天龍的做法完全不同,天龍的地表做法很落後...估計是為了相容老的顯卡吧,

 

沒有現成的管理器可以用,就自己做啦,既然每個網格都可能有不同的材質,那就把材質相同的網格做成一個mesh

 

具體方法有2種:

 

第一種:手動產生網格mesh,把材質相同的做成一個mesh, 注意最好分tile,把一個tile內的相同材質的網格才做出一個mesh,不然會提交整個地型的頂點,關於分tile,不再多說.

 

第二種:每個網格做一個mesh,產生一個實體, 再把材質相同的實體用staticgemety合并成一個實體, staticgemety只對材質相同的實體有效果, staticgemety的劃分tile也十分方便,直接調用sg->setRegionDimensions();這個函數分區就行,

 

對比2種方法,第二種操作要簡單一點點,因為產生單個網格實體和分tile都很容易,

 

至於怎麼產生一個mesh,也有2中方發,手動產生mesh和使用manulObject

 

顯然用manulObject更簡單,都不用自己去操作硬體緩衝,

 

思路就這些,思路有了,做起來就不成問題了

 

-------------------------------------------------------------------------------------

然後是材質問題

 

天龍只提供了一個材質模板,意味著地形的材質要我們去繼承

顯然不適合寫個檔案去繼承,只有在程式中實現了

至於方法,也有4種至少:

第一種: 最囧的,在外部做一個material指令碼....

第二種: 不用模板,直接代碼產生材質,再操作材質的具體資料,麻煩

第三種: 直接用做一個字串拼接成material指令碼那樣的格式,載入materialManager解析

第四種: 直接代碼clone材質模板,再用別名更改紋理即可,小弟用的第4種

 

 

附上源碼:

 

 void TLBBTerrain::createLightMaterial()<br />{<br />int tempIndex = -1;<br />for(int i = 0; i < mXSize*mZSize; ++ i){<br />// 如果此材質已經存在<br />if((tempIndex = findSameMaterial(mGridData[i], i)) >= 0){<br />// 用已有材質存入數組<br />mLightMaterialData.push_back(mLightMaterialData[tempIndex]);<br />}else{</p><p>if(mGridData[i].nSecondLayer >= 0 && mGridData[i].nFirstLayer >= 0){ // 看第二層是否存在,<br />// 拷貝第二層材質<br />MaterialPtr materialTemplate = static_cast<MaterialPtr>(MaterialManager::getSingleton().getByName(mTemplateData[3])); // 先獲得材質模板<br />if(materialTemplate.isNull()){<br />OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Material "+mTemplateData[0]+"doesn't exist!","TLBBTerrain::createMaterial");<br />}else{</p><p>String newMaterialName = "material"+StringConverter::toString(mMaterialNum); // 材質名字<br />MaterialPtr newMaterial = materialTemplate->clone(newMaterialName); // 複製材質<br />AliasTextureNamePairList aliasList; // 儲存紋理別名的二叉樹<br />String textureName1 = mTextureData[mPixMapData[mGridData[i].nFirstLayer].textureId];<br />String textureName2 = mTextureData[mPixMapData[mGridData[i].nSecondLayer].textureId];<br />aliasList["<layer0>"] = textureName1;<br />aliasList["<layer1>"] = textureName2;<br />aliasList["<lightmap>"] = mLightMapName;<br />newMaterial->applyTextureAliases(aliasList); // 用紋理別名更改紋理<br />mLightMaterialData.push_back(newMaterialName); // 存入材質數組<br />}</p><p>}else if(mGridData[i].nFirstLayer >= 0){<br />// 拷貝第一層材質<br />MaterialPtr materialTemplate = static_cast<MaterialPtr>(MaterialManager::getSingleton().getByName(mTemplateData[1])); // 先獲得材質模板<br />if(materialTemplate.isNull()){<br />OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Material "+mTemplateData[0]+"doesn't exist!","TLBBTerrain::createMaterial");<br />}else{<br />String newMaterialName = "material"+StringConverter::toString(mMaterialNum); // 材質名字<br />MaterialPtr newMaterial = materialTemplate->clone(newMaterialName); // 複製材質<br />AliasTextureNamePairList aliasList; // 儲存紋理別名的二叉樹<br />String textureName1 = mTextureData[mPixMapData[mGridData[i].nFirstLayer].textureId];<br />aliasList["<layer0>"] = textureName1;<br />aliasList["<lightmap>"] = mLightMapName;<br />newMaterial->applyTextureAliases(aliasList); // 用紋理別名更改紋理<br />mLightMaterialData.push_back(newMaterialName); // 存入材質數組<br />}</p><p>}</p><p>++ mMaterialNum;<br />}<br />}<br />}

-----------------------------------------------------------------------------------------------------------------------------------------------

然後說說圖片的翻轉操作問題

 

enum Operate
{
 FLIP_HORIZINTAL = 1,    // 圖片水平翻轉,即左右翻轉
 FLIP_VERTICAL = 2,       // 圖片垂直翻轉,即上下翻轉
 ANTICLOCKWISE_90 = 4,    // 逆時針旋轉90度
 FLIP_DIAGONAL = 8       // 以三角形的對角線鏡像,IndexOrder==0時就把左上的紋理座標複製到右下,否則把右上的座標複製到左下
};

 

1,2,4,8 這些數位二進位的低位,就是0001   0010  0100  1000 

他們可以疊加, 但是也很容易尋找到具體含有什麼屬性,按位與,就尋找到是否具有某屬性,這是遊戲常用的方法

 

由於可有有多個操作疊加,所以更改紋理座標的時候,一定要相對上一次的座標操作,

 

 ------------------------------------------------------------------------------------------------------------------------------------

 

 

1024*768 32位元模式下.debug版本,由於暫時沒分tile,頂點資料有點多哈~~~

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.