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

月下的博客

  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 月下圓舞曲 閱讀(4143) 評論(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)  回復  更多評論
  

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            国产免费成人在线视频| 亚洲国产精品成人久久综合一区| 欧美99在线视频观看| 久久久国产成人精品| 亚洲电影免费观看高清完整版在线| 麻豆精品传媒视频| 米奇777在线欧美播放| 99精品久久免费看蜜臀剧情介绍| 亚洲日本免费| 国产欧美一区二区白浆黑人| 久久精品免费| 欧美成人亚洲成人日韩成人| 在线亚洲美日韩| 亚洲欧美激情视频| 在线精品高清中文字幕| 日韩一区二区精品| 国产一区二区中文字幕免费看| 蜜桃av综合| 国产精品v欧美精品∨日韩| 久久久久99| 欧美日韩精品三区| 看欧美日韩国产| 国产精品v欧美精品v日韩| 久久久久www| 国产精品二区在线| 亚洲丁香婷深爱综合| 国产精品视频精品| 亚洲黄色大片| 国产午夜精品美女视频明星a级| 欧美激情一区二区三区四区| 国产精品美女主播| 亚洲国产精品成人综合| 国产一区二区福利| 中文成人激情娱乐网| 亚洲国产高清一区二区三区| 亚洲欧美日本国产专区一区| 日韩视频专区| 久久综合色婷婷| 欧美在线不卡| 欧美性色综合| 亚洲精品婷婷| 亚洲国产日韩在线| 久久精品国产亚洲5555| 国内不卡一区二区三区| 激情综合久久| 亚洲欧美视频在线| 亚洲图片欧美午夜| 欧美成人精品在线| 欧美国产日韩精品| 国内久久精品| 欧美一级片久久久久久久| 亚洲一区激情| 欧美午夜精品电影| 亚洲国产老妈| 亚洲精品一级| 欧美二区在线看| 欧美成人免费全部| 亚洲国产精品一区二区三区| 久久久国产成人精品| 狂野欧美一区| 亚洲第一天堂av| 米奇777在线欧美播放| 欧美激情免费观看| 亚洲美女精品久久| 欧美岛国激情| 99精品免费视频| 亚洲免费视频网站| 国产日本精品| 久久久精品一区| 欧美国产精品v| 亚洲美女黄网| 国产精品国产三级国产aⅴ9色| 亚洲视频一起| 久久久久久亚洲精品中文字幕| 黄色小说综合网站| 免费在线看成人av| 亚洲精品视频在线观看网站 | 欧美日韩国产综合久久| 亚洲免费av片| 亚洲一区二区在线播放| 国产欧美日韩伦理| 久久久免费av| 亚洲青色在线| 亚洲欧美激情诱惑| 国内久久精品| 欧美激情一区| 亚洲一区三区电影在线观看| 久久久久久久久久久久久女国产乱| 一区二区三区自拍| 欧美精品激情| 午夜在线电影亚洲一区| 欧美成人一区二区三区在线观看| 99ri日韩精品视频| 国产区日韩欧美| 欧美成人午夜视频| 亚洲免费视频观看| 亚洲福利国产| 欧美一区高清| 亚洲精品一区二区在线观看| 国产精品老牛| 欧美电影在线播放| 欧美一区二区三区另类 | 性色av香蕉一区二区| 在线看成人片| 国产精品免费在线| 欧美r片在线| 亚洲欧美国产日韩中文字幕| 亚洲区国产区| 美女在线一区二区| 欧美亚洲日本一区| 亚洲精品一区二| 黄色精品一区| 国产欧美一区二区三区视频| 一区二区三区视频在线| 亚洲美女在线一区| 国内偷自视频区视频综合| 欧美精品色网| 久久一区二区三区超碰国产精品| 99国产精品| 亚洲国产一区在线| 蜜臀av性久久久久蜜臀aⅴ四虎 | 国内偷自视频区视频综合| 欧美日韩在线免费| 欧美电影打屁股sp| 久久婷婷色综合| 久久精品人人爽| 欧美亚洲一区三区| 亚洲自拍偷拍视频| 亚洲校园激情| 亚洲尤物视频在线| 亚洲一区三区视频在线观看| 日韩一级视频免费观看在线| 亚洲精品一区在线观看香蕉| 亚洲高清av| 欧美xx视频| 欧美风情在线观看| 欧美黄免费看| 亚洲高清二区| 亚洲欧洲综合另类在线| 亚洲电影激情视频网站| 欧美激情乱人伦| 亚洲国产一区二区a毛片| 欧美顶级艳妇交换群宴| 亚洲第一视频网站| 亚洲国产精品专区久久| 亚洲精品在线三区| 99视频国产精品免费观看| 亚洲网站在线播放| 亚洲欧美激情一区二区| 欧美一区二区三区四区在线 | 欧美日韩不卡在线| 欧美四级电影网站| 国产日韩av在线播放| 国产日韩在线看| 精品动漫3d一区二区三区免费版| 亚洲第一伊人| 一区二区冒白浆视频| 欧美一级视频免费在线观看| 久久久久久久一区二区| 欧美韩国日本一区| 日韩一级二级三级| 小处雏高清一区二区三区| 久久人人爽人人| 欧美二区乱c少妇| 国产精品久久97| 一区二区在线观看av| 亚洲精品美女91| 午夜精品久久久久久久99樱桃| 久久九九免费视频| 亚洲国产综合在线看不卡| 亚洲线精品一区二区三区八戒| 久久精品视频在线| 欧美女同视频| 国内精品免费在线观看| 日韩视频二区| 久久久久久伊人| 91久久国产自产拍夜夜嗨| 亚洲在线播放| 欧美激情一级片一区二区| 国产欧美69| 一本色道久久88综合亚洲精品ⅰ| 欧美在线播放高清精品| 亚洲国产精品福利| 欧美一区二区三区啪啪| 欧美日韩亚洲一区三区| 一区在线观看视频| 亚洲欧美日韩精品| 亚洲国产精品久久人人爱蜜臀| 亚洲欧美成aⅴ人在线观看| 欧美激情精品久久久久久变态| 国产无遮挡一区二区三区毛片日本| 这里只有精品视频| 欧美日韩一卡| 亚洲高清成人| 久久久久久九九九九| a91a精品视频在线观看| 蜜桃av一区二区| 国产一区久久久| 欧美一区日韩一区| 一区二区激情视频|