青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

永遠(yuǎn)也不完美的程序

不斷學(xué)習(xí),不斷實(shí)踐,不斷的重構(gòu)……

常用鏈接

統(tǒng)計(jì)

積分與排名

好友鏈接

最新評論

修改ETM,用Ogre實(shí)現(xiàn)《天龍八部》地形與部分場景詳解(轉(zhuǎn))

本文主要講的是《天龍八部》游戲的地形和一部分場景的具體實(shí)現(xiàn),使用C++, Ogre1.6,我摸索了段時(shí)間,可能方法用的并不是最好的,但好歹實(shí)現(xiàn)了。文章可能講得有點(diǎn)羅嗦,很多簡單的東西都講了。我是修改了ETM(Editable Terrain Manager)實(shí)現(xiàn)的地形,其實(shí)單單實(shí)現(xiàn)天龍八部的地形場景等的載入根本不需要使用ETM,直接用Ogre的頂點(diǎn)->索引->紋理就可以搞定地形,但我要做的是可以實(shí)時(shí)編輯的,所以用了ETM,場景其由于很重要的粒子和model等部分我還沒去看,所以等以后看了再詳細(xì)寫關(guān)于場景的部分,但這個(gè)Demo已經(jīng)實(shí)現(xiàn)了基本的場景的載入。光,霧,環(huán)境,靜態(tài)物等都能載入。

修改過的ETM和這個(gè)場景的Demo代碼可以通過文章底下的鏈接下載。

Demo截圖如下:(少林)

這個(gè)Demo比較簡單,只能移動攝像機(jī)看看場景。

我研究這些的動機(jī)是當(dāng)前在學(xué)校做一個(gè)網(wǎng)游項(xiàng)目,想做得類似于《Second Life》,苦于沒有游戲美工,最近有馬上要二期驗(yàn)收了,為了讓游戲看上去光鮮一點(diǎn),無奈之下只好借《天龍八部》的資源來用了。看了不少大牛的博客,將得感覺都有點(diǎn)不是很詳細(xì),只是大概把文件格式講了一下而已,具體怎么實(shí)現(xiàn)說得不多(可能是覺得實(shí)現(xiàn)太容易,懶得多說了吧...)最主要的是,似乎沒看到有人發(fā)完整的代碼。

實(shí)際項(xiàng)目中用的程序代碼我就不放出來了,場景部分差不多,只是多了個(gè)內(nèi)建的編輯器,人物移動和網(wǎng)絡(luò)通信部分等。

編輯器的截圖曬一下,功能還不全 :-)

 

言歸正傳,先簡單地說一下載入一個(gè)天龍八部場景的大致過程:

  • 讀取.Scene文件
  • 根據(jù)<Texture>讀取.Terrain文件
  • 讀取地磚大小(<tileSize>) 地形大小(xsize, ysize),縮放值(<scale>),地圖中心坐標(biāo)(<center>)。
  • 讀取所有要用的地形貼圖(<textures>中各項(xiàng))。
  • 讀取.gridinfo 文件,此文件中存放著每個(gè)格子對應(yīng)的紋理坐標(biāo)。
  • 根據(jù)3,4,5步的信息用修改過的ETM創(chuàng)建Terrain。
  • 讀取lightmap, 是png格式的預(yù)處理的場景陰影圖。
  • 讀取場景中的各種模型等,并插入到場景Root中。

(注:天龍八部的場景包含很多個(gè)文件,用“劒蚩”的資源提取工具提取出來,文件夾下的基本都是,但我暫時(shí)不考慮尋路,碰撞等,所以就地形來講只研究.Terrain文件,.Gridinfo文件。 資源提取的問題可訪問http://www.cnitblog.com/sword/category/5167.htmlScene )

 

下面我分幾個(gè)部分來具體講如何實(shí)現(xiàn)天龍八部的場景Demo。

讀取高度圖

做地形首先肯定是要讀取高度圖,《天龍八部》的高度圖是保存在.Heightmap文件中,讀取的方法是跳過前面8個(gè)字節(jié),讀地形的width和height,然后讀取width*height個(gè)float型數(shù)據(jù),上面說到.Terrain文件中有地形大小(xsize, ysize),縮放值(<scale>),地圖中心坐標(biāo)(<center>),<scale>中有xyz 3個(gè)值(一般情況下是100,100,100),分別是x,y,z軸的放大系數(shù),用ETM創(chuàng)建地形的時(shí)候,直接用讀取到的float型數(shù)據(jù)作為高度圖數(shù)據(jù),然后再用上面那些值作為參數(shù),定義地形的大小,縮放值,和偏移。

這是讀取高度圖的代碼,heightMapData是float型的數(shù)組,存放原始的高度圖信息。

void TileTerrainInfo::LoadHightMap( const char* fileName, const char* type )
{
FILE* pf = fopen( fileName, "rb" );
fseek( pf, 8, SEEK_SET );
int height, width;
fread( &width, 4,1, pf );
fread( &height, 4,1, pf );
assert( height = this->height+1 );
assert( width == this->width+1 );
if( heightMapData )
delete []heightMapData;
heightMapData = new float[height*width];
for( int i = 0; i < height; ++i )
{
for( int j  = 0; j < width; ++j )
{
float data;
fread( &data, 4,1,pf );
heightMapData[i*width+j] = data;
}
}
fclose( pf );
}
 

材質(zhì)文件的分析

我想先講一下地形的材質(zhì),因?yàn)橛脛e人的資源,首先要知道怎么用這些資源,一般情況下材質(zhì)信息可以明顯地反映出如何使用紋理資源(不排除有可能用代碼動態(tài)生成材質(zhì))。

在每個(gè).Terrain文件的最下面,有這些內(nèi)容。

  <materials>
    <template material="Terrain/OneLayer" name="OneLayer"/>
    <template material="Terrain/OneLayerLightmap" name="OneLayerLightmap"/>
    <template material="Terrain/TwoLayer" name="TwoLayer"/>
    <template material="Terrain/TwoLayerLightmap" name="TwoLayerLightmap"/>
    <fog_replacement exp="Terrain/OneLayer_ps%fog_exp" exp2="Terrain/OneLayer_ps%fog_exp2" linear="Terrain/OneLayer_ps%fog_linear" none="Terrain/OneLayer_ps"/>
    <fog_replacement exp="Terrain/TwoLayer_ps%fog_exp" exp2="Terrain/TwoLayer_ps%fog_exp2" linear="Terrain/TwoLayer_ps%fog_linear" none="Terrain/TwoLayer_ps"/>
    <fog_replacement exp="Terrain/OneLayerLightmap_ps%fog_exp" exp2="Terrain/OneLayerLightmap_ps%fog_exp2" linear="Terrain/OneLayerLightmap_ps%fog_linear" none="Terrain/OneLayerLightmap_ps"/>
    <fog_replacement exp="Terrain/TwoLayerLightmap_ps%fog_exp" exp2="Terrain/TwoLayerLightmap_ps%fog_exp2" linear="Terrain/TwoLayerLightmap_ps%fog_linear" none="Terrain/TwoLayerLightmap_ps"/>
  </materials>

定義了一些材質(zhì)模板。

我沒有深究其他的,只考慮TwoLayerLightmap這個(gè)材質(zhì)。

不記得是在哪個(gè)文件夾下,有一個(gè)文件FairyTerrain.material,其中就是地形的材質(zhì)。

我修改了一些內(nèi)容,將<lightmap>設(shè)tex_coord = 0. <layer0>設(shè)tex_coord=1,<layer1>設(shè)tex_coord=2。這是因?yàn)槲蚁胱孍TM原有的地形和天龍八部的地形共存,而原有地形紋理坐標(biāo)剛好和<lightmap>紋理坐標(biāo)相符合,所以設(shè)為同一層。

這是我改過的材質(zhì)

material Terrain/TwoLayerLightmap

   technique
    {
        pass
        {
            fragment_program_ref Terrain/TwoLayerLightmap_ps
            {
            }

            texture_unit
            {
                texture_alias <layer0>
                texture <layer0>
                tex_address_mode clamp
     tex_coord_set 1
            }

            texture_unit
            {
                texture_alias <layer1>
                texture <layer1>
                tex_address_mode clamp
                tex_coord_set 2
            }

            texture_unit
            {
                texture_alias <lightmap>
                texture <lightmap>
                tex_address_mode clamp
                tex_coord_set 0

            }
        }
    }

}

<layer0>,<layer1>,<lightmap>是一個(gè)pass中的3個(gè)texture_unit.也就是3層紋理。顧名思義<layer0>是第一層紋理,<layer1>是第二層紋理,<lightmap>是光照圖紋理(陰影圖),具體如何使用,如何使天龍八部的地形貼圖資源對應(yīng)到layer0,layer1,我下面會講到。

從FairyTerrain.cg中我們可以找到對應(yīng)的shader。
void TwoLayerLightmap_ps(
    in float2 uv0 : TEXCOORD0,
    in float2 uv1 : TEXCOORD1,
    in float2 uvLightmap : TEXCOORD2,
    in uniform sampler2D layer0,
    in uniform sampler2D layer1,
    in uniform sampler2D lightmap,
    in float4 diffuse : COLOR0,
    in float4 specular : COLOR1,
    out float4 oColour : COLOR)
{
    float4 c0 = tex2D(layer0, uv0);
    float4 c1 = tex2D(layer1, uv1);
    float3 texturedColour = lerp(c0.rgb, c1.rgb, c1.a);
    float4 lightmapColour = tex2D(lightmap, uvLightmap);
    float4 baseColour = diffuse * lightmapColour;
    float3 finalColour = baseColour.rgb * texturedColour + specular.rgb * (1-c0.a) * (1-c1.a) * lightmapColour.a;
    float3 resultColour = Fogging(finalColour);
    oColour = float4(finalColour, baseColour.a);
}

很容易看出其大致思路是<layer1>的alpha值控制<layer0>和<layer1>進(jìn)行混合。

可見,天龍八部的地形應(yīng)該是部分像魔獸一樣的格子式地形,部分權(quán)重圖地形,也就是ETM原有的那種貼圖模式,很多層紋理,然后又1-2層手動生成的紋理數(shù)據(jù)控制各層紋理的alpha值,達(dá)到混合的效果,只不過這里是只有一個(gè)alpha通道來控制紋理混合。

兩層紋理的效果比單獨(dú)一層紋理好的多,我用OneLayerLightmap材質(zhì)試過,效果比較赫人...

 

地形紋理的實(shí)現(xiàn)

<lightmap>紋理很明顯,是一整張紋理貼到整個(gè)地形,沒什么好說的。

但<layer0> <layer1>這兩層地形紋理應(yīng)該怎么貼上去呢?

對于材質(zhì)中的這兩層紋理,有兩種可能。

1.<layer0>,<layer1>本身只是材質(zhì)模板中紋理的名字,沒有實(shí)際意義,在實(shí)際的程序中會為每一塊地形從材質(zhì)模板繼承一個(gè)模板,然后修改材質(zhì)中紋理的名稱。

2.在程序中手動創(chuàng)建<layer0>,<layer1>。

 

先說兩種不能實(shí)現(xiàn)的方法:

1. 在程序中手動創(chuàng)建<layer0>,<layer1>, 為極大極大的貼圖(和真實(shí)的地形一樣大),該貼圖根據(jù).Terrain和.Gridinfo中的信息來組成,和lightmap一樣,整個(gè)貼到地形上。

在小游戲,只有可能一個(gè)屏幕那么大的地形,也許可以用,而且效果可能不錯(cuò),但在這種地形相對較大的游戲中是不可能的,首先,極大的浪費(fèi)資源,一個(gè)地磚的紋理,可能被用到幾十次幾百次,那么在這個(gè)大紋理中,就會有幾百個(gè)地磚紋理的拷貝,其次,不可能創(chuàng)建這么大的紋理(硬件不支持?反正我試過創(chuàng)建不出來..)

2. 像ETM一樣,將所有要用到的紋理(假設(shè)有n張)一個(gè)一個(gè)作為texture_unit放在材質(zhì)里面,然后用n/4張手動生成的紋理去控制這些紋理的alpha值。這個(gè)方法不是對于天龍八部的地形不是很現(xiàn)實(shí),一般每個(gè)天龍八部的地形有大概十幾個(gè)不同的紋理,如果用這個(gè)方法,每個(gè)pass一般支持8個(gè)texture_unit,十幾個(gè)紋理,加n/4張控制紋理需要3-4個(gè)pass,效率似乎... 而且我們通過天龍的材質(zhì)文件可以看出,游戲應(yīng)該不是用的這個(gè)方法來實(shí)現(xiàn)的。

3. 每一個(gè)格子都有自己獨(dú)自的材質(zhì),修改每個(gè)格子材質(zhì)中的<layer0>, <layer1>, 改為它需要的材質(zhì)文件,如 "05武當(dāng)\褐色土地底層.jpg” 相當(dāng)于將每一個(gè)格子作為單獨(dú)的mesh。這個(gè)是可以實(shí)現(xiàn)的,我試過,將ETM的TileSize設(shè)為1,然后生成每個(gè)Tile的時(shí)候修改其材質(zhì),成功了,地形也顯示出來了,完全正確,但幀率..... 呵呵,debug模式下fps 大于0小于1... 到release也許可以到十幾吧,我沒試,顯然是不能這樣搞的... 

我最后實(shí)現(xiàn)地形貼圖用的是texture atlas,手動創(chuàng)建一張紋理,將所有要用到的地形紋理組合成一張大紋理,然后每一個(gè)頂點(diǎn)設(shè)基于這張大紋理的UV坐標(biāo),texture atlas比每個(gè)格子設(shè)材質(zhì)更好的原因很顯而易見,具體可以參考附件中所帶的文章,《“Batch, Batch, Batch:”What Does It Really Mean?》中的第30頁:Batch Breaker: Texture Change.

下圖就是將wudang.Terrain中

<textures>

  <textures>

    <texture filename="03南海/巖石海礁01.jpg" type="image"/>

    <texture filename="03南海/巖石海礁03.jpg" type="image"/>

    <texture filename="05武當(dāng)/褐色土地底層.jpg" type="image"/>

    <texture filename="05武當(dāng)/褐色土地上層.tga" type="image"/>

    <texture filename="05武當(dāng)/青磚地底層.tga" type="image"/>

    <texture filename="13鏡湖/鏡湖桃花瓣.tga" type="image"/>

    ... ...

  </textures>

所定義的所有紋理組合成的一張大紋理。

可以發(fā)現(xiàn),天龍八部中的地形貼圖大小是不同的,但最大是256x256(就我目前所知),所以我干脆將每一格劃為256x256,共可容納有ROW_SIZExCOL_SIZE張小貼圖,這樣大貼圖的大小應(yīng)該是256*COL_SIZE x 256*ROW_SIZE。 

我這臺機(jī)器支持的最大紋理大小似乎為4096x4096,那么理論上因該可以最多容納16*16張小貼圖,綽綽有余了。這樣雖然浪費(fèi)一點(diǎn)空間,但可以很方便地通過ID索引貼圖坐標(biāo)。

比如 <pixmap bottom="0.2480469" left="0.00390625" right="0.4960938" textureId="2" top="0.001953125"/> 通過這樣一塊pixmap的定義,我們可以根據(jù)textureId=2找到它所所在的位置。

其所在行為textureId/COL_SIZE,所在列為textureId%COL_SIZE。如上面那張大紋理的COLE_SIZE = 8(一行有8張小貼圖)

所以textureId=2的這張小貼圖所在行row=0,坐在列col=2.

我們知道紋理坐標(biāo)范圍為0.0f-1.0f,所以textureId=2的小貼圖左上角的UV坐標(biāo)為U = (float)col/COL_SIZE = 0.25f , V = (float)row/ROW_SIZE = 0.0f.

再根據(jù)pixmap中的信息left ,right, top, bottom 可以計(jì)算出小貼圖四個(gè)點(diǎn)的坐標(biāo)。在創(chuàng)建頂點(diǎn)時(shí)將紋理坐標(biāo)附上即可。

具體的過程應(yīng)該是

1.手動創(chuàng)建名字為<layer0>的texture

代碼如下:

TexturePtr layer0 = TextureManager::getSingletonPtr()->createManual(
   "<layer0>", "General",TEX_TYPE_2D,
   layerTextureWidth,layerTextureHeight, 1, 3, PF_BYTE_RGBA, TU_WRITE_ONLY );

2. 將材質(zhì)中的texture_unit <layer1>中的texture_name 由<layer1>改為<layer0>,因?yàn)槲覀儍蓪佑玫氖峭粡埣y理,沒必要復(fù)制一遍,直接改名指向同一張紋理就行了。

代碼如下:

MaterialPtr material (MaterialManager::getSingleton().getByName("Terrain/TwoLayerLightmap"));
material->getTechnique(0)->getPass(0)->getTextureUnitState( 1 )->setTextureName( "<layer0>");

3.讀取.Texture文件,將要用到的紋理拼接為大紋理,如上面那張圖。

 

地形的頂點(diǎn)與索引

 

若地圖為192x192,它就是應(yīng)該有192*192個(gè)格子。一般情況下的做法下,它應(yīng)該有193*193個(gè)頂點(diǎn),織成一個(gè)網(wǎng)狀,但由于我用的atlas,

可以知道,每一個(gè)非邊緣的頂點(diǎn)將會有4個(gè)紋理坐標(biāo)(左上,右上,左下,右下 )

如下圖

中間的頂點(diǎn)要同時(shí)負(fù)責(zé)A塊的右下,B塊的左下,C塊的右上,D塊的左上。

話說一個(gè)頂點(diǎn)確實(shí)是同時(shí)又多個(gè)紋理坐標(biāo)的,只要設(shè)置不同的tex_coord。但天龍八部地形貼圖一般有3層,<layer0>,<layer1>,<lightmap>,分別是兩層地形,一層預(yù)處理的陰影。

一層<lightmap>不用多說的,就是一張大紋理,每個(gè)頂點(diǎn)的坐標(biāo)是u=col/terrainColSize, v=row/terrainRowSize.

另外兩層就是我們需要考慮的,因?yàn)橛袃蓪樱@樣每個(gè)點(diǎn)不止同時(shí)負(fù)責(zé)4塊,要同時(shí)負(fù)責(zé)兩層共8塊,這樣這個(gè)pass的8個(gè)texture_unit都滿了,必須再用一個(gè)pass來做<lightmap>那一層,效率不行。

所以只好用另一方法,就是在非邊緣的每一個(gè)位置,將4個(gè)頂點(diǎn)重合在一起,這4個(gè)頂點(diǎn)的紋理坐標(biāo)不同,但位置相同,即每一個(gè)格子都有四個(gè)獨(dú)立的頂點(diǎn),相鄰的兩個(gè)格子有兩個(gè)點(diǎn)重合。

也就是說192x192的地圖,需要有192*192*4個(gè)頂點(diǎn)。索引方式還是差不多,每一個(gè)格子需要6個(gè)索引,所以一共要192*192*6個(gè)索引。

這樣,ETM中生成頂點(diǎn)和索引的部分代碼都需要改,生成頂點(diǎn)的代碼在void Tile::createVertexData(size_t startx, size_t startz)中,生成索引的代碼在void Tile::createIndexData()中。

天龍八部的.Terrain文件一般有這么一行<scale x="100" y="100" z="100"/>,說明地形在3個(gè)方向都是放大100倍,x,z本是一格大小為1x1為單位的,放大后即為100x100,

一個(gè)192x192的地形實(shí)際游戲中的大小應(yīng)該為19200*19200,而天龍的坐標(biāo)系是正中間坐標(biāo)為.Terrain文件中的<center>的值,若不存在則中心為(0,0), 正方向?yàn)檎?fù)方向?yàn)樨?fù),所以當(dāng)<center>值為(0,0),192x192的地形實(shí)際坐標(biāo)范圍應(yīng)該是 (-9600,-9600)到(9600,9600)。

要注意的是不是將所有頂點(diǎn)作為一個(gè)mesh,而是應(yīng)該根據(jù).Terrain文件中的<tileSize>規(guī)定每一個(gè)TerrainTile的大小,每個(gè)TerrainTile中包含tileSize x tileSize 個(gè)地形網(wǎng)格,一個(gè)TerrainTile作為一個(gè)Entity插入到一個(gè)場景節(jié)點(diǎn)。

頂點(diǎn)位置和索引考慮完了,該是要考慮每個(gè)頂點(diǎn)的紋理坐標(biāo)的問題了。

要給每個(gè)頂點(diǎn)設(shè)UV必須用到.Gridinfo文件中的信息,該文件中定義了每一個(gè)格子對應(yīng)的紋理信息。

具體的文件格式可參考,我在這就不贅述了。

http://m.shnenglu.com/mybios/archive/2009/07/26/91267.html

此處是正解,其他地方似乎多多少少都有錯(cuò),特別是op=8的時(shí)候,要注意是與對角線兩邊的兩個(gè)點(diǎn)(不是對角線上的點(diǎn))從上面復(fù)制到下面。

如圖1應(yīng)該是將左上角的頂點(diǎn)紋理坐標(biāo)復(fù)制到右下角

圖2應(yīng)該是將右上角的紋理坐標(biāo)復(fù)制到左下角。         

        圖1                   圖2

但還有一處我有不同,op=4的時(shí)候,我覺得應(yīng)該是順時(shí)針轉(zhuǎn)90度,測試下來似乎沒問題。

這是我的根據(jù)op操作UV坐標(biāo)的代碼,op=4的時(shí)候我貌似確實(shí)是在順時(shí)針轉(zhuǎn)吧……

void changeGridInfoUV( AutoTexCoord& leftTop, AutoTexCoord& rightTop, AutoTexCoord& leftBottom, AutoTexCoord& rightBottom, uchar state, bool bIndex )
{
//0 不變
//1 圖片水平翻轉(zhuǎn)
//2 圖片垂直翻轉(zhuǎn)
//4 順時(shí)針旋轉(zhuǎn)度
//8 對角線上方頂點(diǎn)紋理坐標(biāo)復(fù)制到對角線下方頂點(diǎn)。(與對角線垂直的兩個(gè)頂點(diǎn))
uchar res1 = state&1;
uchar res2 = state&2;
uchar res3 = state&4;
uchar res4 = state&8;
if( res1 != 0 )
{
leftTop.Exchange( rightTop );
leftBottom.Exchange( rightBottom );
}
if( res2 != 0 )
{
leftTop.Exchange( leftBottom );
rightTop.Exchange( rightBottom );
}
if( res3 != 0 )
{
leftTop.Exchange( rightTop );
leftBottom.Exchange( rightTop );
rightBottom.Exchange( rightTop );
}
if( res4 != 0 )
{
// 非正常索引
if( bIndex ) {
(leftBottom.setX( rightTop.getX) );
leftBottom.setY( rightTop.getY() );
}
// 正常索引
else {
rightBottom.setX( leftTop.getX() );
rightBottom.setY( leftTop.getY() );
}
}
}

讀取場景環(huán)境與模型

 

先階段我讀取了一部分場景,包括環(huán)境和一些模型,粒子等部分還沒看,所以這個(gè)場景是不完整的,不過大概的輪廓都出來了。

讀取場景其實(shí)就是用TinyXML讀取.Scene中的各種XML項(xiàng),然后根據(jù)讀取的數(shù)據(jù)創(chuàng)建相應(yīng)的場景節(jié)點(diǎn),或設(shè)置相應(yīng)的場景環(huán)境,如霧,skydome等。
具體代碼下載附件看吧,有點(diǎn)無聊,都是switch-case語句。
但有一點(diǎn)一定要注意,在讀取資源前一定要先調(diào)用一個(gè)函數(shù)
setlocale( LC_CTYPE, "" );
不然中文路徑或文件名的.mesh文件是讀不了的。
地形和場景都搞定了,可以看看結(jié)果了!然而,悲劇出現(xiàn)了!
遠(yuǎn)景的效果圖,很明顯,地形一格一格像有裂縫一樣……

 

近處的效果圖, 近了以后,就沒地形的裂縫了……

 

 

地形裂縫問題

問了一下我的一個(gè)學(xué)長,自己也思考些時(shí)間。估計(jì)是由于是用的atlas texture, 然后一定距離后的mipmap和texture filtering,產(chǎn)生了裂縫的問題。

通過附件中的《Improve Batching Using Texture Atlases 》在Applying Texture Filtering To Atlases節(jié)可以看討論到texture filtering對texture atlas造成的影響,但是解決方案只是理論上的,并沒有實(shí)現(xiàn),一個(gè)是寫shader,在不同的mipmap下調(diào)整紋理坐標(biāo),另一個(gè)是預(yù)留紋理,就是在已有紋理上加一圈和邊緣相同的像素。文章中還提到:enabling anisotropic filtering minimizes these errors,我試了一下,設(shè)置了filtering anisotropic , 并且將anisotropic_max 設(shè)為最大,結(jié)果卻是略有好轉(zhuǎn),但幀率損失了50fps左右… 也許是我的顯卡太水了?我最后還是沒采用這個(gè)解決方案。

我最后的解決方案是

1,手動創(chuàng)建紋理的時(shí)候,設(shè)置其mipmap的級別最多為3,這樣就不會有更高級別的mipmap,導(dǎo)致更嚴(yán)重的失真。

2,手動創(chuàng)建mipmap,而不是讓其自動生成。比如原來是1024*1024大小的貼圖,1級mipmap的大小應(yīng)該為512*512,默認(rèn)它是自動生成的,我設(shè)為手動生成,先把個(gè)小貼圖縮小為50%,再把他們組成一張512x512的貼圖作為原來的貼圖的mipmap,一次類推手動生成3層mipmap.這樣情況稍微有了點(diǎn)改善。

3,小貼圖合成大貼圖之前,將他們統(tǒng)一resize到256*256的大小,在組合成大貼圖,這樣后感覺裂縫問題好轉(zhuǎn)了不少。

4,預(yù)留紋理坐標(biāo),雖然天龍八部開始就預(yù)留了紋理坐標(biāo),可以.Terrain文件中的紋理坐標(biāo)很多都不是絕對的0.0f 0.25f 0.5f 等,都是一些 0.2480469 ,0.00390625,0.4960938等,我不知道它本是出于什么原因。但我用了這樣的坐標(biāo)還是不行,還是要把它設(shè)地更加靠內(nèi)才能避免裂縫。

所以讀取紋理坐標(biāo)的時(shí)候加上了一個(gè)fixFloat的過程,這個(gè)過程很不科學(xué),但我試了一下似乎有點(diǎn)用處就用上了。

static void fixFloat( float& f )
{
if( f < 0.01f )
f = 0.005f;
else if( f > 0.24f && f < 0.25f )
f = 0.245f;
else if( f > 0.25f && f < 0.26f )
f = 0.255f;
else if( f > 0.49f && f < 0.50f )
f = 0.495f;
else if( f > 0.5f && f < 0.51f )
f = 0.505f;
else if( f > 0.74f && f < 0.75f )
f = 0.745f;
else if( f > 0.75f && f < 0.76f )
f = 0.755f;
else if( f > 0.99f )
f = 0.995f;
}

 

這樣也在一定程度上改善了裂縫的問題,但有的貼圖看上去會不太吻合,但總比裂縫好。

隨后地形基本上看不出有裂縫了,但還是有一點(diǎn)痕跡。

 

這個(gè)地形裂縫的問題困擾了我許久,最后的解決方案我也覺得不甚滿意,不知道有哪位有好點(diǎn)的解決方案請告訴我。


 

posted on 2010-02-16 22:15 狂爛球 閱讀(4064) 評論(12)  編輯 收藏 引用 所屬分類: 圖形編程

評論

# re: 修改ETM,用Ogre實(shí)現(xiàn)《天龍八部》地形與部分場景詳解(附源碼)(轉(zhuǎn)) 2010-03-05 23:20 流浪の念楓雪

完整帶資源版本下載( TTLBSceneDemo.rar 162.12M ) 請發(fā)22521973@qq.com,謝謝。  回復(fù)  更多評論   

# re: 修改ETM,用Ogre實(shí)現(xiàn)《天龍八部》地形與部分場景詳解(附源碼)(轉(zhuǎn)) 2010-03-08 13:49 OGRE 小白

大哥牛人~小弟剛剛開始學(xué)習(xí)OGRE不久,想?yún)⒖家幌履愕挠螒驁鼍啊?
能否傳一份完整版的到我的QQ郵箱~萬分感謝!
369806514@qq.com  回復(fù)  更多評論   

# re: 修改ETM,用Ogre實(shí)現(xiàn)《天龍八部》地形與部分場景詳解(附源碼)(轉(zhuǎn)) 2010-03-12 22:19 活著的木乃伊

@OGRE 小白
124740523@qq.com幫忙傳一份,謝謝了  回復(fù)  更多評論   

# re: 修改ETM,用Ogre實(shí)現(xiàn)《天龍八部》地形與部分場景詳解(附源碼)(轉(zhuǎn)) 2010-03-19 21:40 壞壞

370865225@qq.com  回復(fù)  更多評論   

# re: 修改ETM,用Ogre實(shí)現(xiàn)《天龍八部》地形與部分場景詳解(附源碼)(轉(zhuǎn)) 2010-03-21 20:16 梁藹然

各位,這篇文章是轉(zhuǎn)載的,代碼我沒有,要的話去原作者那里問。  回復(fù)  更多評論   

# re: 修改ETM,用Ogre實(shí)現(xiàn)《天龍八部》地形與部分場景詳解(附源碼)(轉(zhuǎn)) 2010-05-06 11:56 lzhkpt

幫忙傳一份學(xué)習(xí)喔,謝謝  回復(fù)  更多評論   

# re: 修改ETM,用Ogre實(shí)現(xiàn)《天龍八部》地形與部分場景詳解(附源碼)(轉(zhuǎn)) 2010-05-06 11:56 lzhkpt

@lzhkpt
額,剛才忘了留mail了。。。lzhkpt@gmail.com  回復(fù)  更多評論   

# re: 修改ETM,用Ogre實(shí)現(xiàn)《天龍八部》地形與部分場景詳解(附源碼)(轉(zhuǎn)) 2010-05-22 16:44 zyo

10189471@qq.com  回復(fù)  更多評論   

# re: 修改ETM,用Ogre實(shí)現(xiàn)《天龍八部》地形與部分場景詳解(附源碼)(轉(zhuǎn)) 2010-05-25 08:23 aliu

大俠,傳一份~~aliu927@126.com  回復(fù)  更多評論   

# re: 修改ETM,用Ogre實(shí)現(xiàn)《天龍八部》地形與部分場景詳解(轉(zhuǎn)) 2011-08-04 01:11 OlegIsakov33

раскрутка сайта, <a href="http://top5.com.ua">оптимизация</a>, продвижение  回復(fù)  更多評論   

# re: 修改ETM,用Ogre實(shí)現(xiàn)《天龍八部》地形與部分場景詳解(轉(zhuǎn)) 2012-06-01 20:24 os

您好,我也在做地形,麻煩給我也發(fā)一份資源加源碼完整版,向高手學(xué)習(xí)一下~
348732178@qq.com  回復(fù)  更多評論   

# re: 修改ETM,用Ogre實(shí)現(xiàn)《天龍八部》地形與部分場景詳解(轉(zhuǎn))[未登錄] 2012-08-04 22:59 ds

dsf  回復(fù)  更多評論   

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲精品少妇| 久久久久88色偷偷免费| 亚洲免费在线精品一区| 日韩视频免费大全中文字幕| 亚洲高清视频中文字幕| 在线看无码的免费网站| 韩日在线一区| 最新高清无码专区| 一区二区三区视频观看| 午夜亚洲福利| 美女啪啪无遮挡免费久久网站| 欧美与黑人午夜性猛交久久久| 欧美在线观看天堂一区二区三区| 久久嫩草精品久久久精品一| 欧美大尺度在线观看| 亚洲麻豆av| 午夜免费在线观看精品视频| 久久久久久久999精品视频| 久久久久成人网| 欧美日韩午夜在线| 国产综合在线看| 亚洲日韩欧美视频| 欧美一区二区日韩一区二区| 欧美777四色影视在线| 亚洲精品国产精品乱码不99按摩| 亚洲精品乱码久久久久久久久 | 欧美韩国日本综合| 一区二区不卡在线视频 午夜欧美不卡在 | 久久精品国产第一区二区三区| 久久影视精品| 韩国欧美一区| 欧美三区美女| 在线观看国产欧美| 一本色道久久综合亚洲精品小说| 欧美中文字幕精品| 亚洲免费观看高清完整版在线观看熊 | 老司机精品导航| 国产精品久久久久久久久借妻 | 亚洲风情亚aⅴ在线发布| 亚洲视频图片小说| 六月婷婷一区| 韩国欧美一区| 久久精品国产清自在天天线| 日韩视频一区二区三区| 欧美va亚洲va香蕉在线| 国内视频精品| 欧美一区日韩一区| 亚洲视频在线观看| 欧美日韩亚洲一区二| 亚洲激情第一页| 蜜桃av噜噜一区二区三区| 亚洲欧美日韩成人高清在线一区| 欧美日韩一级大片网址| 日韩亚洲欧美一区二区三区| 欧美国产免费| 国内视频精品| 香蕉久久久久久久av网站| 欧美gay视频激情| 欧美一级大片在线免费观看| 欧美先锋影音| 亚洲调教视频在线观看| 亚洲精品123区| 欧美a级一区二区| 亚洲国产欧美一区二区三区同亚洲 | 国产精品一二三四| 在线观看成人av| 欧美专区日韩视频| 午夜国产精品视频免费体验区| 欧美日韩一区二区免费在线观看| 亚洲第一天堂无码专区| 亚洲一区二区三区四区中文| 欧美插天视频在线播放| 亚洲精品国产精品国自产观看| 欧美护士18xxxxhd| 老司机成人网| 日韩视频在线观看| 中文在线资源观看网站视频免费不卡| 国产精品porn| 久色成人在线| 裸体女人亚洲精品一区| 亚洲一级在线观看| 国产精品久久精品日日| 亚洲综合国产| 亚洲一区成人| 国产在线视频欧美一区二区三区| 欧美主播一区二区三区美女 久久精品人| 亚洲色无码播放| 国产精品电影网站| 久久精品国内一区二区三区| 久久都是精品| 亚洲精品色图| 亚洲欧美国产日韩中文字幕| 黑人巨大精品欧美一区二区| 欧美69视频| 亚洲电影毛片| 亚洲人成在线观看网站高清| 久久女同互慰一区二区三区| 久久一区精品| 99av国产精品欲麻豆| av72成人在线| 黄色小说综合网站| 日韩视频在线播放| 国产一区久久| 亚洲精品在线三区| 国产在线精品二区| 亚洲欧洲一区| 国产一区二区欧美| 日韩一区二区精品视频| 一区福利视频| 午夜精品久久久久久99热软件| 亚洲福利一区| 午夜一区在线| 亚洲国产小视频| 亚洲美女少妇无套啪啪呻吟| 亚洲国产欧美一区二区三区同亚洲 | 亚洲精品综合精品自拍| 亚洲欧美日韩中文在线制服| 亚洲高清视频在线| 欧美一区精品| 日韩亚洲一区在线播放| 欧美在线3区| 亚洲欧美日韩国产一区二区三区| 你懂的亚洲视频| 嫩草影视亚洲| 国产视频在线观看一区二区| 久久一区激情| 国内精品久久久久影院色| 亚洲午夜av电影| 亚洲视频一二区| 欧美日韩三级视频| 亚洲国产精品日韩| 亚洲全部视频| 欧美va天堂在线| 亚洲国产黄色| 亚洲人成在线观看网站高清| 久久久亚洲国产天美传媒修理工| 久久久www免费人成黑人精品| 国产精品久久一卡二卡| 日韩一级视频免费观看在线| 99视频超级精品| 欧美日韩综合不卡| 亚洲靠逼com| 亚洲综合清纯丝袜自拍| 国产精品久久久久久久久借妻 | 欧美精品日本| 亚洲精品久久久久久久久久久久 | 欧美日韩国内| 国语自产精品视频在线看抢先版结局 | 一区二区三区波多野结衣在线观看| 亚洲精品欧美日韩专区| 欧美区日韩区| 亚洲在线视频一区| 久久久久高清| 亚洲激情亚洲| 欧美日韩亚洲一区二| 亚洲先锋成人| 快射av在线播放一区| 亚洲大胆人体在线| 欧美日本一区二区三区| 亚洲欧美日韩中文播放| 欧美 日韩 国产在线| 99精品国产在热久久婷婷| 国产精品久久久久久av下载红粉| 午夜久久tv| 最新日韩精品| 久久不射2019中文字幕| 亚洲破处大片| 国产日韩精品在线| 欧美激情欧美激情在线五月| 亚洲一区中文字幕在线观看| 狂野欧美激情性xxxx欧美| 亚洲最新视频在线播放| 国产精品美女在线| 久久综合色天天久久综合图片| 久久中文在线| 一区二区黄色| 欧美日韩系列| 亚洲精品五月天| 性刺激综合网| 日韩西西人体444www| 国产精品国产精品国产专区不蜜| 亚洲综合电影| 亚洲国产成人91精品 | 99精品国产福利在线观看免费| 国产精品久久久久9999高清| 久久久av水蜜桃| 一本大道久久a久久精品综合| 久久精品国产一区二区电影| 亚洲毛片一区| 伊人久久大香线蕉av超碰演员| 欧美久久九九| 老巨人导航500精品| 性色av一区二区三区红粉影视| 亚洲乱码日产精品bd| 欧美顶级少妇做爰| 久久久久www| 久久精品国产精品亚洲| 亚洲欧美成人| 亚洲欧美日韩在线观看a三区| 亚洲精品中文字幕女同|