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

            月下的博客

              C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
              34 Posts :: 0 Stories :: 59 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(5)

            我參與的團隊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

             

            自從以前看了clayman博客后,就很想把自己代碼里dxeffect框架替代掉。如今實習結束正好有短暫的自由時間,所以就ogrematerial開刀吧。

              山寨代碼也是有學問的,如果你想搞明白這些代碼的含義的話,最后之前就對這些已經有了一定的使用經歷和認知,第一步先得自己想一下material系統的組成:
            material
            應該包含的:1Material->n Techinque->(n Pass + extra params)->(n TextureUnit + m or 0 shaderUnit + n RenderStates(部分)),Pass里的TextureUnit又包含了這一組texture的相關信息和設置,TexcoordSet, AddressMode, FilterSetting等等, ShaderUnit則是對應于vsfs以及新的gs,普通點也就最多兩組。shaderUnit包含了具體的shader和其shaderParams,為何要把shadershaderParams分開呢,不說設計優雅的考慮,簡單的說就是方便,很多時候params可能會需要共享,譬如shaderA里用到mvpMat,和eyePos diffuse,specular,可能shaderB也只用到這些,但是兩個shader的內部計算并不相同。到此我們只分析了作為程序中的材質的結構,還需要考慮如果編寫一個類似fx格式的material script,這也是另外一個大頭,簡單的說就是要做個腳本解釋,然后給shader參數加上語義,減少大部分需要手動更新的shaderParams。鑒于我如今還沒把這塊扒完,等下次再寫這塊吧。


               當你至少能閉著眼睛想透這些了,那就可以開始看ogrematerial system了,先說句題外話,我讀ogre的代碼其實讀挺久了。一直覺得很難讀,開始覺得是自己水平不夠,但后來實習才發現很多人都有這想法,甚至wolfgang對此也有批評,而自己曾經寫了個olong引擎,接觸過ipad編程的人應該對這些代碼都比較熟悉~ogre里用了大量的設計模式,使得整個渲染流程從不同類里跳來跳去(SceneMgr這塊看著最累了。。其實有很多地方看著都很累。。)個人覺得應該把renderSceneMgr里抽離出來做個RenderMgr,(記住這里的RenderMgr的概念和ogreRenderSystem,后者是提供底層渲染API的接口,而前者是管理renderData并最終遞交給RenderSystem,以前也見有別人博客講過這個問題)讓SceneMgr專門管理Scene。。
             
            打住打住。。我是來寫material的。。咳咳。。相當于渲染來說,ogrematerial system還是相當易讀的,也是因為這些模塊相互關系幾乎都是單向的,我們開始編寫的時候可以先不考慮Technique,就是直接1 Material->n Pass->...當然甚至你都可以把multi pass去掉,就等同于1pass,當然由于pass都代碼實際也沒多少,我們還是加上好了。

            原始渲染的偽代碼就是:

             1for each pass
             2{
             3  setRenderStates(like alphe belnd, depth..)
             4  for each texture unit
             5    setTexSettings();
             6  if(hasVertexShader())
             7  {
             8    bindVertexShader();
             9    setShaderParams(vs);
            10  }

            11  if(hasFragmentShader())
            12  {
            13    bindFragmentShader();
            14    setShaderParams(fs);
            15  }

            16  drawPrimitives();
            17}

            加入的RenderQueue也是一樣,只是pass和對應的renderData我們是從renderqueue里取。

            看到這里你會覺得,嘿,很簡單嘛,但如果你看了ogre里關于shader參數的細節,你就知道這塊還是比較復雜的。我們剛只說了一個運行過程,而建立params到constant registers的關系,以及如何編寫autoConstants的代碼都是魔鬼的細節~~對于dx,我們可以簡單點,直接使用ID3DXConstantTable,它提供了set接口。但ogre則是直接從ID3DXConstantTable中解析參數。

               設計這塊的時候,腦子里先要對我整個過程有個清晰的認識:一方面是從shader里(我們這里假設是hlsl,asm先不考慮),另一方面則是解析參數讀入材質腳本里定義的參數(named,autoNamed,或者index),最后將兩者對應上。

            0.類型解釋
            看過OgreGpuProgramParams.cpp/h的人都知道:GpuConstantDefinition,GpuNamedConstants,GpuLogicalIndexUse,GpuSharedParameters,GpuSharedParametersUsage,一堆的struct和class。。其實按照我們上面這個思路逐步加斷點分析,代碼也沒那么繁瑣。暫時不看GpuSharedParameters這塊,大概看下GpuConstantDefinition,重點變成員是physicalIndex和logicalIndex,前者的解釋是buffer中的起始地址,每個GpuProgramParameters里都包含了vector<int>和vector<float>兩個buffer,他們存儲了shader變量的值,而physicalIndex就是對應vector的索引。而logicalIndex則是我們后面將hlsl編譯成asm后這些變量所綁定的寄存器id,而由于constant reg的size都是4,即一個register為4個float的大小,所以這些logicalIndex則不一定連續,譬如第一個uniform為float1那么第二個uniform的logicalIndex雖然是1,但實際跨過了4個float,而實際內存中我們的float(int同) buffer里,兩個變量之間的則就空了3個float,這就是physicalIndex的作用,所以我們還需要建立一個從logicalIndex到physicalIndex的map,也就是兩個GpuLogicalBuffersStructPtr對象(這兩個對象和GpuNamedConstantsPtr在GpuProgram類和GpuProgramParameters是共享的,都是sharedPtr)

            1.解析shader的變量
              
            我們從再具體的讀取代碼來看,假設我們已經從腳本里讀入了對應的shader,經過一堆調用后(略。。)在D3D9HLSLProgram的函數buildConstantDefinitions->processParamElement將每個參數的registerIndex,physicalIndex, type(原子類型,即float, int,),size都寫入GpuLogicalBuffersStructPtrGpuNamedConstantsPtr對象里(后者當然是只有highLevelShader里才有),并會為這個定義同樣在插入帶下標的一對鍵值,以便于如果我們傳入的參數是數組(譬如float4x4[5]),則在程序里可以通過數組下標訪問對應的數組變量。再constantDef建立好之后,將GpuNamedConstantsPtr傳入到GpuProgramParameters對象里,然后向其中的兩個vector添加上述對象大小的空間,在將兩個LogicalToPhysicalMap的指針也傳到shaderParams里,這樣整個GpuProgramParameters幾乎就完工了。

            2.解析材質里定義的params,并將其與前者對應上
              如今就差再把material script定義的param解析出來并與之前shader里的變量進行對應。材質腳本讀出的每個變量的信息包含了param類型(namedauto_namedindexauto_index),name,type(float,int..),autoType(auto的才有),初始值等。我們根據其autoType在全局變量AutoConstantDictionary中查找是否有定義,然后調用set[Named]AutoConstant,在這里我們在會在我們之前從hlsl里解析出的GpuNamedConstantsPtr里查找是否有該名字的變量(畢竟shader里的變量才是最終有用的,甚至由于編譯器優化的關系,由于shader編寫者可能定義了一個變量而未實際使用,在編譯shader后,這個變量實際是會被省略的,這樣在GpuNamedConstantsPtr也就找不到了)然后調用_setRawAutoConstant將這個變量加入到這個GpuProgramParameters對象所持有的autoConstant中。

            (ps:關于_getFloatConstantLogicalIndexUse的用途我沒看懂,為何需要去在mFloatLogicalToPhysical里去查找這個logicalIndex是否存在呢,我覺得如果走到這一步肯定shader里肯定就是定義了的,因為這個logicalIndex是由mNamedConstants里取出,我覺得是沒必要的。。)

            3,更新autoParamsbuffer并最終在DP前進行更新

            把上面的過程看懂了,下面就很好理解了。GpuProgramParameters::_updateAutoParams里就是對GpuProgramParameters對象所持有的autoConstant值進行更新,當然這是我們只是對GpuProgramParameters持有的buffer里的值做更新,最終在文章開頭的偽代碼中的setShaderParamsogre里叫bindGpuProgramParamters而這里的更新就輕而易舉了,我們遍歷logicalToPhysicalMap對每個param取出對應的logicalIndexdataPointervector4ofCount,然后調用SetVertex/PixelShaderConstantF/I即可。



            呼。。終于把這塊寫完了。。上述只是一個實現自己的material的基本思路。關于優化的話,我開頭推薦的clayman的文章里有很多敘述。關于怎么寫ogre script translator,等下一篇再說。。

            posted on 2011-04-18 23:32 月下圓舞曲 閱讀(4109) 評論(1)  編輯 收藏 引用 所屬分類: 開發

            Feedback

            # re: 沿著ogre來實現material system(一) 2012-08-20 09:09 sxx
            09:03:57: OGRE EXCEPTION(2:InvalidParametersException): Parameter called worldVeiwMatrix does not exist. in GpuProgramParameters::_findNamedConstantDefinition at ..\..\..\..\OgreMain\src\OgreGpuProgramParams.cpp (line 1435)  回復  更多評論
              

            中文字幕精品久久久久人妻| 欧美午夜精品久久久久久浪潮| 久久亚洲私人国产精品| 日本强好片久久久久久AAA| 中文字幕日本人妻久久久免费| .精品久久久麻豆国产精品| 国产ww久久久久久久久久| 四虎国产精品成人免费久久| 久久国产高潮流白浆免费观看| 国产精品嫩草影院久久| 免费无码国产欧美久久18| 亚洲国产二区三区久久| 久久国语露脸国产精品电影 | 91久久成人免费| 欧美久久久久久| 精品久久久久久无码国产| 亚洲国产另类久久久精品小说| 久久精品国产精品亜洲毛片| 久久精品国产亚洲av日韩| 久久久噜噜噜久久中文字幕色伊伊| 成人亚洲欧美久久久久| 久久婷婷五月综合色奶水99啪| 亚洲?V乱码久久精品蜜桃| 国内精品伊人久久久久影院对白| 狠狠色丁香久久婷婷综合五月 | 久久97久久97精品免视看| 久久国产色AV免费观看| 久久人人爽爽爽人久久久| 一本色道久久88综合日韩精品| 精品久久久久久无码中文野结衣 | 中文字幕热久久久久久久| 亚洲国产天堂久久久久久| 久久久精品视频免费观看| 久久久久亚洲精品中文字幕| 99久久久久| 久久这里只有精品视频99| 青青久久精品国产免费看| 中文字幕久久精品| 久久妇女高潮几次MBA| 久久精品国产99久久无毒不卡| 久久亚洲AV成人无码电影|