• <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>

            永遠也不完美的程序

            不斷學習,不斷實踐,不斷的重構……

            常用鏈接

            統計

            積分與排名

            好友鏈接

            最新評論

            修改ETM,用Ogre實現《天龍八部》地形與部分場景詳解(轉)

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

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

            Demo截圖如下:(少林)

            這個Demo比較簡單,只能移動攝像機看看場景。

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

            實際項目中用的程序代碼我就不放出來了,場景部分差不多,只是多了個內建的編輯器,人物移動和網絡通信部分等。

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

             

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

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

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

             

            下面我分幾個部分來具體講如何實現天龍八部的場景Demo。

            讀取高度圖

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

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

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

            材質文件的分析

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

            在每個.Terrain文件的最下面,有這些內容。

              <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>

            定義了一些材質模板。

            我沒有深究其他的,只考慮TwoLayerLightmap這個材質。

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

            我修改了一些內容,將<lightmap>設tex_coord = 0. <layer0>設tex_coord=1,<layer1>設tex_coord=2。這是因為我想讓ETM原有的地形和天龍八部的地形共存,而原有地形紋理坐標剛好和<lightmap>紋理坐標相符合,所以設為同一層。

            這是我改過的材質

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

            從FairyTerrain.cg中我們可以找到對應的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>進行混合。

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

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

             

            地形紋理的實現

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

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

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

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

            2.在程序中手動創建<layer0>,<layer1>。

             

            先說兩種不能實現的方法:

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

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

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

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

            我最后實現地形貼圖用的是texture atlas,手動創建一張紋理,將所有要用到的地形紋理組合成一張大紋理,然后每一個頂點設基于這張大紋理的UV坐標,texture atlas比每個格子設材質更好的原因很顯而易見,具體可以參考附件中所帶的文章,《“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武當/褐色土地底層.jpg" type="image"/>

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

                <texture filename="05武當/青磚地底層.tga" type="image"/>

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

                ... ...

              </textures>

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

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

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

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

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

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

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

            再根據pixmap中的信息left ,right, top, bottom 可以計算出小貼圖四個點的坐標。在創建頂點時將紋理坐標附上即可。

            具體的過程應該是

            1.手動創建名字為<layer0>的texture

            代碼如下:

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

            2. 將材質中的texture_unit <layer1>中的texture_name 由<layer1>改為<layer0>,因為我們兩層用的是同一張紋理,沒必要復制一遍,直接改名指向同一張紋理就行了。

            代碼如下:

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

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

             

            地形的頂點與索引

             

            若地圖為192x192,它就是應該有192*192個格子。一般情況下的做法下,它應該有193*193個頂點,織成一個網狀,但由于我用的atlas,

            可以知道,每一個非邊緣的頂點將會有4個紋理坐標(左上,右上,左下,右下 )

            如下圖

            中間的頂點要同時負責A塊的右下,B塊的左下,C塊的右上,D塊的左上。

            話說一個頂點確實是同時又多個紋理坐標的,只要設置不同的tex_coord。但天龍八部地形貼圖一般有3層,<layer0>,<layer1>,<lightmap>,分別是兩層地形,一層預處理的陰影。

            一層<lightmap>不用多說的,就是一張大紋理,每個頂點的坐標是u=col/terrainColSize, v=row/terrainRowSize.

            另外兩層就是我們需要考慮的,因為有兩層,這樣每個點不止同時負責4塊,要同時負責兩層共8塊,這樣這個pass的8個texture_unit都滿了,必須再用一個pass來做<lightmap>那一層,效率不行。

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

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

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

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

            一個192x192的地形實際游戲中的大小應該為19200*19200,而天龍的坐標系是正中間坐標為.Terrain文件中的<center>的值,若不存在則中心為(0,0), 正方向為正,負方向為負,所以當<center>值為(0,0),192x192的地形實際坐標范圍應該是 (-9600,-9600)到(9600,9600)。

            要注意的是不是將所有頂點作為一個mesh,而是應該根據.Terrain文件中的<tileSize>規定每一個TerrainTile的大小,每個TerrainTile中包含tileSize x tileSize 個地形網格,一個TerrainTile作為一個Entity插入到一個場景節點。

            頂點位置和索引考慮完了,該是要考慮每個頂點的紋理坐標的問題了。

            要給每個頂點設UV必須用到.Gridinfo文件中的信息,該文件中定義了每一個格子對應的紋理信息。

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

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

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

            如圖1應該是將左上角的頂點紋理坐標復制到右下角

            圖2應該是將右上角的紋理坐標復制到左下角。         

                    圖1                   圖2

            但還有一處我有不同,op=4的時候,我覺得應該是順時針轉90度,測試下來似乎沒問題。

            這是我的根據op操作UV坐標的代碼,op=4的時候我貌似確實是在順時針轉吧……

            void changeGridInfoUV( AutoTexCoord& leftTop, AutoTexCoord& rightTop, AutoTexCoord& leftBottom, AutoTexCoord& rightBottom, uchar state, bool bIndex )
            {
            //0 不變
            //1 圖片水平翻轉
            //2 圖片垂直翻轉
            //4 順時針旋轉度
            //8 對角線上方頂點紋理坐標復制到對角線下方頂點。(與對角線垂直的兩個頂點)
            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() );
            }
            }
            }

            讀取場景環境與模型

             

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

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

             

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

             

             

            地形裂縫問題

            問了一下我的一個學長,自己也思考些時間。估計是由于是用的atlas texture, 然后一定距離后的mipmap和texture filtering,產生了裂縫的問題。

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

            我最后的解決方案是

            1,手動創建紋理的時候,設置其mipmap的級別最多為3,這樣就不會有更高級別的mipmap,導致更嚴重的失真。

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

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

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

            所以讀取紋理坐標的時候加上了一個fixFloat的過程,這個過程很不科學,但我試了一下似乎有點用處就用上了。

            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;
            }

             

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

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

             

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


             

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

            評論

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

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

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

            大哥牛人~小弟剛剛開始學習OGRE不久,想參考一下你的游戲場景。
            能否傳一份完整版的到我的QQ郵箱~萬分感謝!
            369806514@qq.com  回復  更多評論   

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

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

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

            370865225@qq.com  回復  更多評論   

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

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

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

            幫忙傳一份學習喔,謝謝  回復  更多評論   

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

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

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

            10189471@qq.com  回復  更多評論   

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

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

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

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

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

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

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

            dsf  回復  更多評論   

            日本道色综合久久影院| 亚洲va久久久噜噜噜久久天堂| 久久99热国产这有精品| 99久久精品九九亚洲精品| 亚洲国产精品综合久久网络| 久久久久久综合网天天| 久久狠狠高潮亚洲精品| 久久青青草原精品国产软件| 久久精品成人欧美大片| 91精品国产91热久久久久福利| 久久婷婷五月综合国产尤物app | 精品无码久久久久久久动漫| 国内精品久久国产| 91性高湖久久久久| 无码人妻少妇久久中文字幕蜜桃| 久久免费视频观看| 囯产精品久久久久久久久蜜桃| 亚洲国产精品人久久| 久久亚洲国产精品成人AV秋霞| 99久久国产综合精品成人影院| 欧美噜噜久久久XXX| 久久综合亚洲色HEZYO国产| 久久精品一区二区| 久久人爽人人爽人人片AV| 国产精品美女久久福利网站| 久久精品国产99久久香蕉| 久久婷婷国产麻豆91天堂| 9久久9久久精品| 久久国产亚洲精品无码| 日日躁夜夜躁狠狠久久AV| 九九精品久久久久久噜噜| 亚洲国产成人精品无码久久久久久综合 | 国产一区二区精品久久 | 99久久婷婷国产综合亚洲| 久久久久久久久久久久久久| 性高湖久久久久久久久AAAAA| 久久久久黑人强伦姧人妻| 精品久久久久久无码免费| 精品久久久久久无码人妻热| 国产精品无码久久四虎| 久久久久国产一区二区三区|