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

            麒麟子

            ~~

            導(dǎo)航

            <2009年2月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            1234567

            統(tǒng)計(jì)

            常用鏈接

            留言簿(12)

            隨筆分類

            隨筆檔案

            Friends

            WebSites

            積分與排名

            最新隨筆

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            魔獸世界客戶端數(shù)據(jù)研究(三)

            終于決定,還是通過wow model viewer起手,研究一下WOW的數(shù)據(jù)類型,從另一個(gè)角度,體驗(yàn)一把這個(gè)唯一讓我充過值的游戲。

            這將是一系列隨筆,即在讀代碼的時(shí)候,順便記錄,以理清思路和加深映象。 其中會(huì)有很多讓人費(fèi)解的地方,如果有幸被某位兄弟看見

            ,請(qǐng)勿見笑。

             

            今天來說一下M2中的LOD的數(shù)據(jù)

            WOW中,為了降低遠(yuǎn)處模型的渲染開銷,為模型做了LOD,即遠(yuǎn)處的模型,使用更少的頂點(diǎn),更粗略的材質(zhì)。 比如遠(yuǎn)處的模型在渲染的時(shí)

            候,面片數(shù)量減少,關(guān)閉光照,不渲染掛接的特效等等。

            因此,不用證明也知道,M2中,材質(zhì)是存在每一個(gè)LOD信息中的。
            哎,也就寫這幾句的時(shí)候順手些,其實(shí)不用分析,也是這個(gè)結(jié)果。因?yàn)槲覀冏约旱囊婢褪沁@樣做的,何況是WOW這種大師級(jí)的作品呢。

            從WMV的解析代碼下手,看看它是如何解析的吧。
            首先,它使用了這樣一行代碼
            int16 *transLookup = (int16*)(f.getBuffer() + header.ofsTransparencyLookup);
            讀取了一串用于透明值的查找數(shù)組。 不過暫時(shí)沒有使用,后面材質(zhì)構(gòu)建的地方才會(huì)用到。
            接下來,就是讀取相關(guān)數(shù)據(jù)了。 在WLK以后,所有的這些數(shù)據(jù),被分離到了.skin文件里面,不知道是咱想的,以后再來作討論。 但是在

            WLK之前,這個(gè)數(shù)據(jù)還是被放在了一起的。

            通過模型的名字我們組合上.skin,就是當(dāng)前所要的渲染數(shù)據(jù)了。
            這個(gè)組合是這樣的。
            假如我們一個(gè)模型是 humanmale.m2
            那么它的四個(gè)LOD數(shù)據(jù)分別就是 humanmale01.skin humanmale02.skin humanmale03.skin humanmale04.skin

            當(dāng)我們得到了這個(gè)數(shù)據(jù)后,就可以通過MPQFile加載想要的數(shù)據(jù)了。

            OK,假設(shè)上面的過程,我們已經(jīng)完全搞定了,此時(shí),我們就得到了一個(gè)skin的數(shù)據(jù)。有了這個(gè)數(shù)據(jù),我們就可以為所欲為了,嘿嘿。有點(diǎn)

            夸張了。 在這個(gè)數(shù)據(jù)的最前面,肯定是數(shù)據(jù)頭了。 數(shù)據(jù)頭在WMV中本來一直是以xxxxHeader來定義的,不過在這里,它一改風(fēng)格,定義

            了一個(gè)叫ModelView的東西。

            我們來看看這貨的定義
            struct ModelView
            {
            #ifdef WotLK
                char id[4]; //巫妖王版本新增的一個(gè)標(biāo)記位,必須是 'S' 'K' 'I' 'N'
            #endif
                uint32 nIndex; //這個(gè)表示此LOD有多少個(gè)INDEX
                uint32 ofsIndex; //這個(gè)表示此LOD的INDEX從模型的哪里開始數(shù)
                uint32 nTris; //這個(gè)表示此LOD有多少個(gè)構(gòu)建成三角形的索引
                uint32 ofsTris;     //三角形個(gè)數(shù)
                uint32 nProps; //額外的頂點(diǎn)屬性
                uint32 ofsProps; //頂點(diǎn)屬性讀取
                uint32 nSub; //有多少個(gè)子部件 后面定義的ModelGeoset表示一個(gè)子部件,其包括了MESH數(shù)據(jù),材質(zhì),渲染狀態(tài)等內(nèi)容
                uint32 ofsSub;     //
                uint32 nTex;  //紋理
                uint32 ofsTex;     // ModelTexUnit, material properties/textures
                int32 lod;                 // LOD bias?  WMV作者也打了問號(hào)。
            };

            有了這個(gè)數(shù)據(jù)頭以后,我們就可以無腦的先讀取上面的數(shù)據(jù),然后再進(jìn)行構(gòu)建。

            索引數(shù)據(jù)
            uint16 *indexLookup = (uint16*)(g.getBuffer() + view->ofsIndex);
            構(gòu)成三角形的頂點(diǎn)索引序列
            uint16 *triangles = (uint16*)(g.getBuffer() + view->ofsTris);

            當(dāng)前模型在渲染時(shí)候的索引數(shù)目
            nIndices = view->nTris;
            重新分配索引
            wxDELETEA(indices);
            indices = new uint16[nIndices];

            將本地索引轉(zhuǎn)換成全局索引
            for (size_t i = 0; i<nIndices; i++)
            {
                    indices[i] = indexLookup[triangles[i]];
            }

            索引數(shù)據(jù)總算是完了,下面就得準(zhǔn)備子模型和材質(zhì)相關(guān)的事情。
            大家都知道,在渲染管線中,一次渲染提交只能提交具有相同渲染狀態(tài)和紋理的模型。 于是,我們的模型如果具有不同的材質(zhì),就需要

            先做分割處理。 這是所有WOW這樣的3D MMORPG引擎都需要處理的問題。

            在WMV中,模型渲染狀態(tài)相關(guān)的數(shù)據(jù),使用了ModelGeoset來表示,紋理相關(guān)的,使用了ModelTexUnit來表示
            先看看ModelGeoset的定義
            /// Lod part, One material + render operation
            struct ModelGeoset
            {
                uint32 id;        // mesh part id?
                uint16 vstart;    // first vertex, Starting vertex number.
                uint16 vcount;    // num vertices, Number of vertices.
                uint16 istart;    // first index, Starting triangle index (that's 3* the number of triangles drawn so far).
                uint16 icount;    // num indices, Number of triangle indices.
                uint16 nSkinnedBones;    // number of bone indices, Number of elements in the bone lookup table.
                uint16 StartBones;        // ? always 1 to 4, Starting index in the bone lookup table.
                uint16 rootBone;        // root bone?
                uint16 nBones;        //
                Vec3D BoundingBox[2];
                float radius;
            };

            由上可知,它定義了渲染相關(guān)的頂點(diǎn),以及骨骼,和包圍盒信息,最后一個(gè)是作為構(gòu)建包圍球用的。

            /// Lod part, A texture unit (sub of material)
            struct ModelTexUnit
            {
                // probably the texture units
                // size always >=number of materials it seems
                uint16 flags;        // Usually 16 for static textures, and 0 for animated textures.
                uint16 shading;        // If set to 0x8000: shaders. Used in skyboxes to ditch the need for depth buffering.

            See below.
                uint16 op;            // Material this texture is part of (index into mat)
                uint16 op2;            // Always same as above?
                int16 colorIndex;    // A Color out of the Colors-Block or -1 if none.
                uint16 flagsIndex;    // RenderFlags (index into render flags, TexFlags)
                uint16 texunit;        // Index into the texture unit lookup table.
                uint16 mode;        // See below.
                uint16 textureid;    // Index into Texture lookup table
                uint16 texunit2;    // copy of texture unit value?
                uint16 transid;        // Index into transparency lookup table.
                uint16 texanimid;    // Index into uvanimation lookup table.
            };
            而上面這個(gè)結(jié)構(gòu),是紋理相關(guān)的信息。

            上面的信息,都是一些索引和ID值,真正的數(shù)據(jù)是放在全局信息中的。

            讀取完上面的數(shù)據(jù)后,LOD信息基本上就大功造成了。 而這些索引是如何使用的,只有下一次再研究了。今天又很晚了。

            由此可知,WOW中的數(shù)據(jù)組織和一般的引擎沒有太多區(qū)別。 即HEADER信息用于分割數(shù)據(jù)區(qū)域。
            整個(gè)模型要使用的數(shù)據(jù),放在了最上層,然后,不同的LOD和子MESH要使用數(shù)據(jù)的時(shí)候,只需要保存一些索引值,再到全局?jǐn)?shù)據(jù)里去查詢就可以了。

            暫時(shí)到此吧,下次繼續(xù)。。。。

            posted on 2013-04-26 01:11 麒麟子 閱讀(2061) 評(píng)論(2)  編輯 收藏 引用 所屬分類: BLIZZARD

            評(píng)論

            # re: 魔獸世界客戶端數(shù)據(jù)研究(三) 2013-04-26 08:03 rosan

            LZ加油,呵呵,我會(huì)繼續(xù)關(guān)注的。希望最后能夠?qū)懸恍┐a來說明你的文章  回復(fù)  更多評(píng)論   

            # re: 魔獸世界客戶端數(shù)據(jù)研究(三) 2013-05-04 03:57 monn

            謝謝樓主,,期待下一篇~  回復(fù)  更多評(píng)論   

            色青青草原桃花久久综合| 成人a毛片久久免费播放| 色妞色综合久久夜夜| 一本色综合网久久| 久久亚洲国产午夜精品理论片| 久久精品不卡| 久久精品国产久精国产思思| 久久久久久国产a免费观看不卡| 大香伊人久久精品一区二区| 精品国产一区二区三区久久| 性高朝久久久久久久久久| 99re久久精品国产首页2020| 人人妻久久人人澡人人爽人人精品| 久久精品www人人爽人人| 亚洲国产综合久久天堂| 国产精品久久久久久福利漫画| 久久人人青草97香蕉| 国产精品99久久久久久www| 久久ww精品w免费人成| 亚洲伊人久久综合中文成人网| 99热成人精品免费久久| 久久精品国产亚洲AV香蕉| 久久精品一本到99热免费| 久久精品国产福利国产琪琪| 欧美一区二区精品久久| 无码人妻少妇久久中文字幕蜜桃| 性高朝久久久久久久久久| 国产精品美女久久久网AV| 国产三级久久久精品麻豆三级| 亚洲日本va中文字幕久久| 久久久高清免费视频| 亚洲欧美日韩精品久久亚洲区| 久久影视综合亚洲| 久久久久无码国产精品不卡| 久久精品成人免费观看97| 精品久久久久中文字| 久久国产免费| 亚洲精品第一综合99久久| 久久伊人五月丁香狠狠色| 国产偷久久久精品专区| 亚洲国产美女精品久久久久∴|