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

月下的博客

  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 月下圓舞曲 閱讀(4152) 評論(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>
            国产精品毛片大码女人| 欧美久久一级| 国产日韩欧美夫妻视频在线观看| 亚洲无玛一区| 亚洲精品影院在线观看| 欧美日韩日本国产亚洲在线 | 一区二区三区日韩欧美| 欧美精品麻豆| 亚洲欧美日韩国产精品| 亚洲嫩草精品久久| 国产综合色一区二区三区| 久久视频一区| 欧美成人免费va影院高清| 夜色激情一区二区| 亚洲午夜激情网页| 国产一区观看| 亚洲精品乱码久久久久久久久 | 久久成人av少妇免费| 一区二区在线免费观看| 亚洲第一视频| 国产精品热久久久久夜色精品三区 | 免费视频一区| 亚洲小说欧美另类婷婷| 小嫩嫩精品导航| 最新成人av在线| 亚洲性感激情| 亚洲黄一区二区三区| 一本大道久久精品懂色aⅴ| 国产日本欧美一区二区三区在线| 欧美电影免费观看大全| 欧美日韩一区二区三区免费| 久久久久亚洲综合| 欧美激情精品久久久久久| 久久国产日韩| 欧美日韩美女在线| 久久综合99re88久久爱| 欧美性大战久久久久久久| 美女久久一区| 欧美手机在线视频| 麻豆精品在线视频| 欧美午夜宅男影院在线观看| 麻豆九一精品爱看视频在线观看免费| 欧美伦理一区二区| 久久综合伊人77777蜜臀| 国产精品jvid在线观看蜜臀| 男女视频一区二区| 国产精品日本欧美一区二区三区| 欧美激情网友自拍| 国产亚洲精品aa午夜观看| 99精品热视频| 亚洲日本成人| 久久人91精品久久久久久不卡| 亚洲欧美日本视频在线观看| 欧美精品成人一区二区在线观看| 久久三级福利| 国产三级精品三级| 亚洲一区在线免费| 亚洲一区二区三区在线视频| 欧美精品久久一区| 欧美激情久久久久| 1024成人网色www| 久久九九免费| 美女国产精品| 影音先锋久久久| 久久国产精品一区二区| 久久久久久久久久久久久9999 | 欧美在线视频观看| 久久精品国产一区二区三| 欧美日韩专区| 一区二区三区欧美在线观看| 一区二区高清在线观看| 欧美片在线播放| 99视频国产精品免费观看| 9色精品在线| 欧美午夜激情视频| 一区二区三区四区国产| 亚洲欧美日本国产专区一区| 国产精品毛片a∨一区二区三区|国 | 久久久久久黄| 激情小说另类小说亚洲欧美| 久久乐国产精品| 欧美 日韩 国产一区二区在线视频 | 1024亚洲| 欧美极品在线视频| 99re这里只有精品6| 亚洲午夜精品| 国产日韩精品在线观看| 久久高清福利视频| 欧美韩日高清| 亚洲午夜久久久久久尤物| 国产精品久久国产三级国电话系列| 亚洲色诱最新| 久久精品在线播放| 在线播放中文字幕一区| 欧美精品 国产精品| 在线综合亚洲| 久久永久免费| 在线一区二区三区做爰视频网站 | 久久福利资源站| 欧美大片在线影院| 制服丝袜激情欧洲亚洲| 国产精品亚洲人在线观看| 久久久一区二区三区| 亚洲精品国产精品国产自| 午夜在线一区二区| 亚洲欧洲综合| 国产夜色精品一区二区av| 久热国产精品| 午夜精品久久| 亚洲三级免费观看| 久久爱91午夜羞羞| 日韩香蕉视频| 激情久久五月| 国产精品毛片一区二区三区| 久久这里有精品15一区二区三区| 亚洲伦理在线免费看| 久久久久一区二区三区四区| 一区二区三区视频免费在线观看| 国产欧美在线视频| 欧美激情综合网| 久久久久国产精品麻豆ai换脸| 亚洲美女毛片| 欧美1区2区3区| 久久精品九九| 亚洲欧美日韩国产成人精品影院| 伊人夜夜躁av伊人久久| 国产精品色婷婷久久58| 欧美日韩另类丝袜其他| 久久免费高清| 久久九九全国免费精品观看| 亚洲性色视频| 亚洲欧洲一区二区在线播放 | 亚洲香蕉在线观看| 亚洲电影在线看| 精品91在线| 国产亚洲毛片在线| 国产农村妇女精品| 国产精品区免费视频| 欧美性开放视频| 欧美日韩亚洲综合在线| 欧美国产精品久久| 噜噜噜躁狠狠躁狠狠精品视频| 久久成人18免费观看| 亚洲已满18点击进入久久| 亚洲视频在线观看| 亚洲深夜福利视频| 一区二区日韩精品| 亚洲视频香蕉人妖| 亚洲社区在线观看| 亚洲在线网站| 午夜精品久久久久久久久久久久久| av成人免费在线| 一区二区激情视频| 一本色道久久精品| 亚洲一级二级| 欧美一进一出视频| 久久精品视频在线观看| 麻豆久久婷婷| 欧美精品成人一区二区在线观看| 欧美精品激情| 国产精品露脸自拍| 国产欧美一区二区三区沐欲| 国内精品久久久久影院优| 国产综合婷婷| 亚洲国产另类久久精品| 亚洲精品一区二区三区在线观看| 日韩一二在线观看| 在线亚洲电影| 久久av最新网址| 欧美大香线蕉线伊人久久国产精品| 欧美国产一区二区| 亚洲精品一区二| 亚洲欧美在线观看| 久久久久久久综合狠狠综合| 欧美黑人国产人伦爽爽爽| 欧美性大战久久久久久久蜜臀| 国产农村妇女精品| 亚洲高清免费在线| 亚洲欧美日韩精品久久亚洲区| 久久婷婷久久| 亚洲三级观看| 久久国产免费看| 欧美日韩视频在线第一区| 国产伦精品一区二区三区四区免费 | 久久综合激情| 国产精品户外野外| 精品1区2区3区4区| 亚洲一区精品视频| 欧美福利电影网| 亚洲男人第一网站| 欧美国产日本在线| 国产一区二区黄色| av不卡在线| 久久综合久久综合久久综合| 99伊人成综合| 麻豆久久久9性大片| 国产亚洲成av人在线观看导航| 日韩午夜在线电影| 免费成年人欧美视频| 亚洲在线观看免费|