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

月下的博客

  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則是對應于vs,fs以及新的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類型(named,auto_named,index,auto_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取出對應的logicalIndex,dataPointer,vector4ofCount,然后調用SetVertex/PixelShaderConstantF/I即可。



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

posted on 2011-04-18 23:32 月下圓舞曲 閱讀(4151) 評論(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>
            国产精品美女视频网站| 在线看国产日韩| 国产精品亚洲综合| 亚洲精品美女久久7777777| 亚洲欧美日韩在线观看a三区| 亚洲第一主播视频| 欧美亚洲专区| 国产亚洲毛片| 久久青草福利网站| 欧美中文字幕在线视频| 国产欧美亚洲一区| 欧美与欧洲交xxxx免费观看| 亚洲综合三区| 国产九色精品成人porny| 亚洲影院高清在线| 亚洲欧美色一区| 国产在线一区二区三区四区| 久久精品国产999大香线蕉| 午夜影院日韩| 一区二区视频免费完整版观看| 久久亚洲精选| 麻豆成人av| 浪潮色综合久久天堂| 亚洲成色精品| 亚洲第一黄色| 欧美精品免费观看二区| av成人手机在线| 一区二区三区四区蜜桃| 国产女人aaa级久久久级| 久久久久久久久久看片| 久久天天躁狠狠躁夜夜av| 在线看视频不卡| 亚洲国产日韩欧美在线99| 欧美日韩喷水| 久久国产手机看片| 美女脱光内衣内裤视频久久网站| 99国内精品久久| 亚洲午夜国产一区99re久久| 狠狠色狠狠色综合日日91app| 欧美成人精品在线视频| 欧美成人精品不卡视频在线观看 | 农村妇女精品| 亚洲精品自在久久| 亚洲一品av免费观看| 国产一区视频在线看| 欧美激情一区二区三区在线视频观看| 欧美激情免费在线| 久久久久高清| 欧美日韩免费观看一区三区| 久久av二区| 欧美sm视频| 欧美在线首页| 欧美日韩国产经典色站一区二区三区| 久久国产精品一区二区三区| 欧美激情中文字幕一区二区| 久久精品人人做人人爽电影蜜月 | 在线视频日韩| 久久精品一区| 午夜精品电影| 欧美福利电影在线观看| 久久精品国产亚洲一区二区| 欧美日韩国产精品| 欧美激情1区2区3区| 国模一区二区三区| 亚洲综合色丁香婷婷六月图片| 亚洲区国产区| 久久精品人人做人人综合| 午夜精品久久| 欧美视频中文字幕在线| 亚洲国产日韩欧美| 亚洲国产成人午夜在线一区| 小黄鸭精品aⅴ导航网站入口| av成人免费在线| 美女精品一区| 久久免费视频在线观看| 国产精品视频九色porn| 日韩视频一区二区三区在线播放免费观看 | 裸体一区二区| 性一交一乱一区二区洋洋av| 欧美激情va永久在线播放| 久久久夜精品| 国产欧美日本一区二区三区| 99视频超级精品| 99精品热6080yy久久| 老巨人导航500精品| 久久噜噜噜精品国产亚洲综合| 国产精品入口尤物| 亚洲先锋成人| 亚洲欧美日韩国产| 欧美四级在线观看| 中文av一区特黄| 亚洲自拍另类| 国产精品久久久久永久免费观看| 日韩一区二区精品在线观看| 一个色综合av| 欧美三区不卡| 亚洲一区二区黄色| 欧美伊人久久久久久午夜久久久久| 欧美性猛交xxxx乱大交蜜桃 | 99国产精品国产精品久久| 亚洲三级视频| 欧美日韩福利在线观看| 亚洲精品欧美一区二区三区| 夜夜嗨av一区二区三区网站四季av | 亚洲国产精品久久91精品| 久久三级福利| 亚洲国产精品一区二区尤物区| 亚洲国产欧美另类丝袜| 欧美成人午夜激情视频| 亚洲日本va午夜在线电影| 日韩写真视频在线观看| 欧美日韩中文字幕在线| 亚洲自拍偷拍网址| 久久综合九色99| 日韩视频不卡中文| 国产精品美女主播在线观看纯欲| 亚洲欧美资源在线| 欧美96在线丨欧| 亚洲一区二区免费| 国产视频在线观看一区二区| 久久久久久噜噜噜久久久精品| 欧美成人国产一区二区| a4yy欧美一区二区三区| 国产精品视频一区二区三区| 欧美在线啊v一区| 欧美黄色影院| 欧美一区二区免费观在线| 亚洲成人自拍视频| 欧美午夜欧美| 另类天堂av| 亚洲一区二区三区在线播放| 欧美a级在线| 午夜一级久久| 日韩视频亚洲视频| 国产亚洲欧美另类一区二区三区| 老司机精品视频一区二区三区| 日韩一区二区精品| 女主播福利一区| 欧美一区二区成人6969| 日韩午夜电影在线观看| 国产一级揄自揄精品视频| 一区二区三区精品在线| 能在线观看的日韩av| 亚洲在线视频观看| 1000部精品久久久久久久久| 国产精品久久久免费| 欧美成人中文| 久久国产精品黑丝| 亚洲天堂男人| 亚洲激情成人网| 久久这里有精品视频| 午夜精彩国产免费不卡不顿大片| 91久久精品国产91性色| 国内精品久久久久久久影视麻豆 | 欧美大香线蕉线伊人久久国产精品| 亚洲一区在线观看视频| 亚洲精品久久7777| 欧美成人高清视频| 久久夜色精品国产欧美乱极品| 亚洲欧美日韩电影| 夜夜夜久久久| 亚洲日本免费| 亚洲国产精品福利| 一区二区三区在线免费视频| 国产精品亚洲人在线观看| 欧美视频在线观看免费| 欧美日韩亚洲一区二区三区在线| 免费欧美网站| 欧美14一18处毛片| 麻豆亚洲精品| 蜜臀av一级做a爰片久久| 久久天天躁狠狠躁夜夜爽蜜月| 久久精品一区二区| 久久香蕉国产线看观看av| 久久九九免费视频| 久久久视频精品| 久久久噜久噜久久综合| 久久综合九色综合久99| 麻豆freexxxx性91精品| 欧美成人日本| 欧美区亚洲区| 午夜影视日本亚洲欧洲精品| 亚洲美女黄色片| 91久久综合亚洲鲁鲁五月天| 最新69国产成人精品视频免费| 欧美福利视频| 91久久精品www人人做人人爽| 亚洲第一级黄色片| 亚洲欧洲日本在线| 一二三四社区欧美黄| 亚洲欧美日韩精品一区二区| 性色av一区二区三区在线观看| 久久精品视频播放| 欧美成人免费一级人片100| 欧美日韩国产一区二区| 国产精品视频你懂的| 伊人久久成人| 99热这里只有成人精品国产| 一区二区三区视频在线看| 欧美在线视频不卡|