OGRE全面分析三

1: 設計初衷
它設計初衷是完全跨平臺的。抽象的接口隱藏了平臺相關的細節。
它設計初衷是大幅度支持擴展的。支持多種場景類型,獨立出平臺和3D接口限制。
2: 基本類結構關係
Roo:對象爲一切的入口,它負責創建Ogre的所有基礎元素,三大基礎元素大致包括:場景管理器,繪製系統,資源管理器。
場景管理器:場景節點,動態對象。
資源管理器:資源組管理,資源管理
渲染模塊:硬件緩衝區管理,渲染系統,渲染窗口
3:關鍵詞
Root::Ogre系統入口,程序一開始就應當創建,最後釋放,它幫助我們獲得其他元素的指針。甚至包括StartRender()
RenderSystem::渲染系統。是對3D渲染API的一個封裝。一般來說無需手工調用,場景管理器對對其進行控制,只有在實現一些特殊需要的時候,可以獲取使用。
SceneManager:負責對整個場景中內容的創建和管理。包括靜態地形場景,攝象機,動態對象,光線,材質等都歸屬其管理。場景管理器根據室內室外等渲染管理進行了不同類型的優化,在創建時可以傳參進行選擇。
ResourceGroupManager:資源組管理器包含多種的資源管理器,例如紋理,網格Mesh等的資源加載管理器,他們各司其職管理其所負責的資源數據對象。和渲染系統一樣,大多數情況下他們會被自動調用的進行資源加載,我們僅需要做的就是 Root::getSingleton().addRessourceLocation()告訴Ogre從哪兒加載資源即可,除非個別特殊需求,我們動態的手工控制時候可以TextureManager::getSingleton()獲取相應的資源管理器進行處理。
Mesh對象:就是一個具體的模型,而在一些情況下,Mesh對象僅指那些能夠移動的對象,那些靜態對象即不屬於Mesh對象之列。Ogre有自己的一套定義的Mesh結構,即.mesh,該文件格式可以被網格工具編輯。
Entity實體:是一個可移動的對象實例。和Mesh的不同是,實體包括網格,但若網格未和場景結點綁定起來,則不可使用該實體。我們可以修改場景結點來獲得實體的修改,但此時Mesh實際是沒有變化的。注意:實體是允許有子實體的,網格也一樣有子網格。每一個子網格可以有自己的材質。相關函數如下:SceneManager::CreateEntity()由場景管理器去創建實體對象,Entity::GetSubEntity()獲取子實體指針,再SetMaterialName()修改材質。
材質:它是由資源管理器管理,但在場景管理器中也保存着一份材質的列表。它的屬性有默認的,SceneManager::GetDefaultMaterialSetting()函數可以獲取其默認屬性,當然也可以修改。值得注意的是,OGRE允許在程序運行時,通過材質腳本對材質進行設置。
Overlays:一般是拿來做一些不接收用戶交互信息的UI面層的。當然遊戲中也可以設置一些層元素作爲遊戲內容,例如飛機駕駛艙,不接受任何用戶交互信息,並且要求最前端顯示。層有一個專門的層管理器,它負責層的創建釋放等工作。每個層有自己的一個Z深度信息,通過它進行遮擋關係的計算。另外,每幾個層可以分爲一個小組進行統一控制,這個在Ogre中被稱爲層容器 OverlayContainer。每個層可以進行獨立的旋轉縮放等功能。它允許是2D或3D。 OverlayManager::getSingleton().createOverlayElement(“Panel”, “myNewPanel”)。
4:Ogre的腳本
1:材質腳本。在資源組管理器初始化完畢時,裝載材質腳本,OGRE會自動的在組相關的資源位置查找”.materal”擴展名的文件,並對這些腳本進行語法解析。手動解析也可以MaterialSerializer::parseScript()但是注意的是:解析腳本時並沒有對腳本中定義的全部紋理等資源進行加載。所以,在我們訪問一個材質的時候,一定要確保它已經裝載,或者,我們手動將此材質Load()一次再進行訪問。另外,材質名必須唯一,且不可有”:”號。
格式:以{},空格,//作爲標識符。
// 後跟註釋,不支持多行註釋。
{} 之間代表爲一個解析單元
每一個material XXX 代表是一個材質單元。其中,每一個technique代表一個材質渲染手法,pass是每個渲染通路模式,texture_unit則是一個紋理單元。
一個材質腳本允許有多個渲染手法技術,一個渲染手法技術中允許有多個渲染通路模式,一個渲染通道允許有多個紋理單元。
 
渲染手法技術Techinique
一個“渲染手法技術”就是一個單獨的渲染物體的方法。多個技術的存在原因是爲適用不同的顯卡以及根據遠近關係對一個物體進行不同的渲染。
技術的排列需要一定順序,一般來說,最常用最的技術放在腳本最前面,
格式爲:        Techinique 技術名
不命名的技術默認會以其序列號進行命名,注意,技術名不可重複。
 
方案技術scheme
因爲我們對不同的顯卡標準或根據某中不同的需求,設計出不同的技術,每種技術所適用的環境方案需要我們指出。
格式爲:             scheme 方案名
默認的方案是default,若我們某一個技術適用於開啓hdr,Shader3.0的方案,我們只需對該技術設置方案爲 scheme hdr_open_shader_3_0 即可。
 
細節層次索引 lod_index
每一個技術都必須對應一個細節層次索引。一般來說,默認的都是0,即最近最優秀的渲染技術,當我們需要對遠處細節進行渲染時,則設置這個值吧。
格式爲:              lod_index 數值層級
雖說lod的數值層級是從0-65535,一般設置2-4層就差不多了吧。因爲技術有一定的排列順序,所以,我們一般是將index大的技術放在後面。
 
細節層次距離 lod_distances
這裏指定使用不同的細節層次的距離值,注意,該屬性必須在所有的技術塊外面進行聲明指定。
如例子中所標識:lod_distance 200 就代表,在0-200這個距離內,我們使用細節層次爲0的技術,在200以上的則使用細節層次爲1的技術
Lod_distance 200 700.5 則表示在0-200時我們使用細節0,200-700.5這段距離使用細節1的材質技術,700.5以上使用細節2的材質技術。200和700.5間使用空格間隔。
 
所以技術的排列順序通常爲這樣
Material MyTestMaterial
{
lod_distances 200
       Technique Lod_0_Hdr_Open_Shader_3_0
       {
Lod_index 0
              Pass 0
{
       Texture_unit
       {
              //…..
}
       Texture_unit
       {
              //…..
}
              }
Pass 1
{
       Texture unit
{
       // ….
}
}
}
       Technique Lod_0_Hdr_Close_Shader_1_0
       {
Lod_index 0
              Pass
{
       Texture_unit
       {
              //…..
}
       Texture_unit
       {
              //…..
}
              }
}
       Technique Lod_1_Hdr_Open_Shader_3_0
       {
Lod_index 1
              Pass
{
       Texture_unit
       {
              //…..
}
       Texture_unit
       {
              //…..
}
              }
}
       Technique Lod_1_Hdr_Close_Shader_1_0
       {
Lod_index 1
              Pass
{
       Texture_unit
       {
              //…..
}
       Texture_unit
       {
              //…..
}
              }
}
}
 
Pass渲染通路:
再次強調一個概念:一個材質腳本,爲了適應不同的顯卡和LOD細節層次技術,我們允許有多個技術,爲了加速充分的使用GPU,每個技術中同時又支持多通道的渲染,每個渲染通道內,同時又允許有多個紋理單元。首先這個改變必須明確理解才能順利的進行材質腳本的設計。
我們在“渲染通路”這層可以設置以下屬性:
·   ambient       材質的環境光反射係數
格式是 ambient red green blue alpha
每個值要求爲0.0-1.0之間,例如ambient 0.2 0.2 1.0 1.0代表每個頂點對環境光的反射係數。注意:若關閉了動態光照和紋理層的光照色彩混合的話,該項就不起作用了。默認值爲全白
·   diffuse       材質的漫反射係數
格式是 diffuse red green blue alpha 其他同上。
·   specular      材質的鏡面反射係數
格式是 specular red green blue alpha Shininess ,最後多了一個參數,是閃耀值,該值處於1-128之間。注意:若該值較大則會令人感到耀眼的反射。
·   emissive      材質自發光係數
格式是 emissive red green blue alpha
·   scene_blend
設置渲染通道和現有的渲染層內容混合方式。有預設的四種方式
格式爲scene_blend add或scene_blend modulate/alpha_blend/colour_blend
Add 是將渲染出的顏色和亮度一起疊加到渲染場景中,相當於“scene_blend one one”
Modulate 是將渲染輸出的顏色疊加到渲染場景中,相當於”scene_blend dest_colour zero”
alpha_blend 是將渲染輸出的亮度疊加到渲染場景中,相當於”scene_blend src_colour one_minus_src_colour”
colour_blend 是將渲染輸出的alpha值進行遮罩緩和。相當於”scene_blend src_alpha one_minus_src_alpha”
當然,我們也可以不使用預設的方式,進行自定義源和目標的混合因數
格式爲 scene_blend src_factor dest_factor
這樣最終渲染出的顏色就是 (渲染通道的結果 * src_factor) + (渲染場景的顏色 * dest_factor),其中src_factor dest_factor兩個參數可選以下值
one
常數值1.0
zero
常數值0.0
dest_colour
已存在的像素顏色
src_colour
紋理像素顏色
one_minus_dest_colour
1 -(dest_colour)
one_minus_src_colour
1 -(src_colour)
dest_alpha
已存在的像素alpha值
src_alpha
紋理像素alpha值
one_minus_dest_alpha
1 -(dest_alpha)
one_minus_src_alpha
1 -(src_alpha)
例如:scene_blend one zero (代表渲染出的紋理完全覆蓋其後的渲染場景,即渲染管道出來的紋理是完全不透明的) ß默認的混合模式也正是這種。
·   depth_check
是否開啓深度緩衝檢測 格式爲 depth_check on 或 depth_check off
·   depth_write
是否打開深度緩衝寫入。 格式爲 depth_write on 或 depth_write off
默認的時候深度緩衝是打開的,個別時候我們需要渲染一系列透明物體的關係時候,則將其關閉。
·   depth_func
寫入象素前的深度比較函數。 格式爲 depth_func compareFun
其中compareFun可以取下面值之一。
always_fail
永遠不向渲染目標寫入像素
always_pass
總是將像素寫入渲染目標
less
如果將要寫入的像素的深度小於現在緩衝區內容的深度,則寫入
less_equal
如果將要寫入的像素的深度小於等於現在緩衝區內容的深度,則寫入
equal
如果將要寫入的像素的深度等於現在緩衝區內容的深度,則寫入
not_equal
如果將要寫入的像素的深度不等於現在緩衝區內容的深度,則寫入
greater_equal
如果將要寫入的像素的深度大於等於現在緩衝區內容的深度,則寫入
greater
如果將要寫入的像素的深度大於現在緩衝區內容的深度,則寫入
默認值是 depth_func less_equal ,注意:當我們關閉深入緩衝檢測的話,該函數無效。
·   depth_bias
無法理解。不會用。
·   alpha_rejection
對渲染管道的材質紋理進行alpha信息剪裁。 格式爲 alpha_rejection compareFun value
其中value取值範圍是0-255,例如 alpha_rejection less_equal 122 則代表拋棄渲染管道中alpha值大於等於122的象素。附註:考慮到硬件兼容,Value最好是0-128之間。
·   cull_hardware
硬件剪裁方式。 格式爲 cull_hardware HCutFun
HCutFun枚舉下列三種方式:clockwise / anticlockwise/ none
clockwise將逆時針的三角型都cut掉(即CUT鏡頭反面)
anticlockwise將順時針的三角型都cut掉(即CUT鏡頭正面)
none 不做任何剪切。
默認爲 clockwise
·   cull_software
軟件剪裁方式。 格式爲 cull_software SCutFun
SCutFun 枚舉以下三種格式:back / front / none
實際上,這個和硬件裁減是類似的,不過,對於一些動態的物件建議不要開啓該項,消耗很大。默認是 back 剪裁。
·   lighting
是否開啓動態光照。 格式爲 lighting on / off
注意:使用了頂點程序,此屬性無效。動態光照一旦關閉,環境光反射,鏡面反射光,放射光,陰影等屬性均無效。默認爲on
·   shading
Ogre陰影模式。 格式爲 shading flat/ gouraud/ phong
Flat不進行插值,每個平面的陰影都由該平面的第一個頂點色決定。
Gouraud 對平面上每個頂點顏色進行線形插入計算。
Phong 全平面使用頂點法線向量。效果好,代價高,部份硬件無法支持此屬性。
默認爲 : gouraud
·   polygon_mode
柵格化方式。   格式爲 polygon_mode solid/ wireframe/ points
面,線,點的柵格化。默認當然是面solid模式。
·   fog_override
是否開啓霧化。 fog_override true/false
當fog_override true的時候就需要順序跟出以下參數
霧的type: none 無霧。 相當於fog_override false
           Linear 線性霧。 從 start到end之間有霧
           Exp 幾何方次性霧。 受濃度 density 影響
           Exp2 幾何二次方增加。 受濃度 density 影響
霧的顏色 color: RGB三種顏色值。0.0-1.0之間
霧的濃度 density:設置幾何方次性霧的濃度。對線形霧不影響,但也必須寫上進行佔位。
霧的起始位置 start :對非線性霧無效,但必須寫上佔位。
霧的結束位置 end : 對非線性霧無效,但必須寫上佔位。
例如:fog_override true exp 1 1 1 0.002 100 10000 開啓幾何次方霧。顏色爲1,1,1白色,濃度爲0.002(若是線性則代表,離鏡頭100至10000之間的距離有霧)
·   colour_write
是否關閉渲染通路的顏色寫入功能。 colour_write on/off
該功能一旦關閉,則代表渲染通路不可輸入任何的顏色渲染。僅在初期初始化深度緩衝區時個別時間有用。默認爲開on
·   max_lights
此渲染通路最大光源數量。一般使用默認爲8 格式爲 max_lights 8
·   start_light
·   iteration
是否對渲染通路進行迭代渲染。 默認爲僅渲染一次,格式爲Iteration once
Iteration 5 代表本渲染通路將被重複執行5次渲染。
Iteration once per_light point 則代表本渲染通道將每個光源點進行一次渲染。
Iteration 5 per_light point則代表本渲染通道將每個光源點進行5次渲染。
·   point_size
·   point_sprites
·   point_size_attenuation
·   point_size_min
·   point_size_max
 
Texture_unit 紋理單元
我們在PASS渲染通道處已經進行了一次整體的渲染環境設置,然而,在每個紋理單元,我們還可以對單獨的紋理進行渲染屬性設置。
·   texture_alias
設置一個紋理的別名。類似於技術的別名。格式: texture_alias 紋理別名
默認該別名就是紋理單元的名字。
·   texture
本層要使用的靜態紋理圖象名字。可以簡單的格式爲
Texture xxx.jpg (注意:紋理文件名禁止有空格)也可對其屬性進行詳細的設置。如下
Texture xxx.jpg 2d 8 none PF_A8R8G8B8
2d是裝載的紋理類型,類型實際上包括1d(1象素的紋理點),2d(紋理面,默認也是該項),3d(3D帶深度的紋理),cubic(有些類似天空盒式的貼在立方體內側6個2D紋理,但是僅可貼同一種紋理,不如使用cubic_texture)
8 是MipMap的層級,默認是unlinited,代表可以無限的對紋理進行mipmap,我們這裏設置爲8代表生成8個層級遞減的MIPMAP。注意:若多個材質腳本中使用同一個紋理,切記他們的mipmap數量必須一致。
None 這項是我們指定的單獨的透明通道做爲alpha進行裝載,默認的爲 none,表示以紅色作爲alpha通道。
PF_A8R8G8B8紋理格式,常用的有PF_R5G6B5,PF_A4R4G4B4,PF_A8R8G8B8,PF_X8R8G8B8等。
·   anim_texture
與上面的texture對應,是用於活動的紋理層,即動態圖象。注意,這裏不是使用默認的保存好的.gif動畫,而是導入多楨圖,設置好楨之間的間隔時間。這裏我們有兩種方法。
一種是按照Ogre內部規定對動畫的紋理命名:xxx_0.jpg xxx_1.jpg xxx_2.jpg這樣以0爲首,加下劃線遞增命名,這樣我們調用時會比較方便,這樣便可以了
Anim_texture xxx.jpg 3 2.2 即代表xxx_0.jpg這樣命名的紋理有3張,間隔時間爲2.2秒。
另一種是非標準的紋理命名,則需要我們如下寫:
Anim_texture 1.jpg flame2.jpg xxx_3.png hit4.tga 2.2 直接以空格間隔標示逐個標示出每一楨的紋理即可。
注意:2.2是每楨間的間隔時間,若設置爲0,則不會自動進行楨畫面切換,需要我們代碼中手工控制了。
·   cubic_texture
創建一個立方體紋理。這個一般用於反射映射和天空盒中。其格式和動態紋理一樣,有兩種方式,一種是Ogre制定的規範,我們調用就更加簡單,如下
Cubic_texture skybox.jpg combinedUVW
我們僅提供一個基礎的紋理名,此時OGRE會默認的去查找skybox_fr.jpg, skybox_bk.jpg, skybox_up.jpg, skybox_dn.jpg, skybox_lf.jpg, skybox_rt.jpg這些紋理。
第二中方式則是按照“前後上下左右”的順序將這些紋理羅列出來。
最後一個參數需要設置爲combinedUVW或separateUV, combinedUVW會將紋理組合到一個立方體紋理映射中,帶有UVW三維紋理座標,適合做反射映射。而separateUV僅僅保存2D的UV座標,適用於天空盒。
·   tex_coord_set
因爲一個Mesh網格允許有多套紋理座標集,我們在這裏設置使用哪套座標集。格式爲 tex_coord_set 3 (使用編號爲3的座標集)
默認爲 tex_coord_set 0
·   tex_address_mode
紋理尋址模式。即當紋理UV值大於1.0時的紋理處理方法。參數有以下幾種枚舉選擇:
Wrap 會將所有UV值大於1.0的值設置爲0.0,紋理會被重複連續繪製。
Clamp 會將所有UV值大於1.0的值設置爲1.0,這樣的話就相當於在模糊邊界。
Mirror 會當UV值等於1.0的時候,將紋理反轉後連續繪製。
Border 超過1.0的UV都會被設置爲邊界色,就是描邊效果。此項可設置tex_border_colour屬性。
·   tex_border_colour
和上一屬性對應,設置紋理邊界色,僅對Border紋理尋址有效。
格式 : tex_border_colour RGBA(0.0 – 1.0取值)
·   filtering
紋理過濾形式:我們可以使用其預定的四種基本類型,包括
None 不進行紋理過濾
Bilinear 進行雙線性紋理過濾。就是對mipmap進行挑選過濾,但是不對mipmap各個級別之間進行過濾
Trilinear 進行三線性紋理過濾。將最近的兩個mipmap一起進行過濾。
Anisotropic 各向異性紋理過濾。使用該項,則你必須設置其max_anisotropy值。
默認爲bilinear。
·   max_anisotropy
最大各相異性程度偏差值。根據硬件不同一般限制爲8或者16
默認爲 max_anisotropy 1
·   mipmap_bias
我們在Pass通道時已經允許設置mipmap紋理Lod運用層級以及適用的距離。在紋理單元這層級我們可以重新對其進行調整。格式爲
Mipmap_bias -3 後面的整數代表在所有的範圍內強制使用增大或縮小的mip級別。-3代表,在所有範圍內強制使用更大3級的mip紋理。
默認是不進行層級偏移:mipmap_bias 0
·   colour_op
簡單的紋理混合方式,我們可以使用預定義的4項枚舉:
Replace 不處理,用當前的紋理直接替換掉後面的所有顏色。覆蓋式。
Add 將當前紋理色和後面的渲染顏色進行加法處理。
Modulate 將當前紋理色和後面的渲染顏色進行乘法處理。
Alpha_blend 將當前紋理和後面的紋理進行alpha顏色混合。
默認爲 colour_op modulate 當前紋理色和後面顏色進行乘法混合。
·   colour_op_ex
高級的紋理混合模式,可以詳細的指定混合係數和效果,但個人不推薦使用。效率消耗較大,且受不用的硬件限制性大,使用默認支持的4種混合模式可以了。
·   colour_op_multipass_fallback
當上面一個colour_op_ex設置要求過高,硬件無法支持多紋理混合時,則不得不調用該項進行多通路混合渲染。若我們使用的是colour_op預設置的4種紋理混合模式,則無需在此處理,OGRE底層已經做了完善的處理。
·   alpha_op_ex
同colour_op_ex,不推薦使用。
·   env_map
設置環境映射效果。該項可以使用預定義的五個選項
Off 關閉環境映射反射。 默認即本項。
Spherical 開啓球面環境映射。 它需要一個單獨的紋理,該紋理進行周圍反射的記錄。
Cubic_reflection 開啓平面環境映射。
·   scroll
靜態紋理偏移。 個人感覺這個函數的存在意義完全是拿來彌補美術的小BUG。或者是個別情況下,事件響應時調用對紋理的修改?
格式如下:scroll x y
·   scroll_anim
動態紋理偏移。 ……針對上一功能的補足。給紋理層一個移動速度進行偏移。
格式爲 scroll_anim xspeed yspeed
·   rotate
以固定角度靜態旋轉一個紋理。和scroll沒什麼區別。格式如下 rotate angle
注: angle是逆時針旋轉的角度數
·   rotate_anim
動態旋轉一個紋理。 格式爲 rotate_anim 3 代表每秒旋轉3次360度。
·   scale
靜態縮放一個紋理。 格式爲 scale x_scale y_scale。
·   wave_xform
製作類似於水面波紋性質的專用函數。可以製造出一個類似於波狀的動態紋理變化形式。
格式: wave_xform <xform_type> <wave_type> <base> <frequency> <phase> <amplitude>
示例: wave_xform scale_x sine 1.0 0.2 0.0 5.0
xform_type
scroll_x
變動x滾動值
scroll_y
變動y滾動值
rotate
變動旋轉值
scale_x
變動x比例值
scale_y
變動y比例值
wave_type
sine
典型的正弦波,在最小值和最大值之間平穩地循環。
triangle
以恆定的速度增加減少的有角度的波,在極值時立即改變。
square
最大是波長的一半,最小是瞬時轉換之間的停止時間。
sawtooth
經過一段時間,從最小逐漸持續增加到最大,最後立即回到最小。
inverse_sawtooth
經過一段時間,從最大逐漸持續減少到最小,最後又立即返回最大。::base
基值,如果amplitude > 0就是指最小值,amplitdue < 0就是指最大值。
frequency
波每秒重複的次數,即速度。
phase
波開始的偏移量。
amplitude
波的大小。
波的輸出範圍在{base, base+amplitude}。所以,以在x方向調整紋理爲例,沿正弦波方向從1(標準值)調整到5,即表示每5秒一個週期(每秒0.2個波)。
 
·   transform
爲紋理提供一個4*4矩陣以直接替代上面的旋轉,縮放,移動等一系列變化。
格式爲 transform m00 m01 m02 m03 m10 m11 m12 m13 m20 m21 m22 m23 m30 m31 m32 m33
·   binding_type
設置綁定類型。該紋理是綁定到片斷處理單元還是頂點處理單元。格式爲:
Binding_type fragment / vertex
默認爲綁定片斷處理單元。
·   content_type
設置紋理內容的來源類型。格式爲 content_type named / shadow
默認是爲named,表示紋理單元圖片來源於texture,cubic_texture,anim_texture之一,但個別時候我們需要使用陰影紋理,則此時可以設置爲shadow
注: 除去上面的紋理屬性設置之外,假若我們需要更高級的紋理屬性支持,可以使用外部紋理源。
頂點程序和片斷程序聲明:
假設我們在材質腳本中需要使用頂點程序或者片段程序,那麼,類似於函數聲明調用一樣,我們必須在調用它之前先對其進行聲明定義。
假若調用點都在一個.meterial腳本內還好,我們只需要在調用處的上面進行聲明定義,但,假若多個腳本都調用一段頂點程序,我們就需要將這段頂點片斷程序獨立出任何的.meterial腳本之外,獨立編寫一個 .program 格式的腳本,在這個腳本中進行定義,這樣的話,這個外部定義的頂點片斷程序就會順利的在任何位置上被調用讀取。
個人推薦所有的頂點程序都獨立爲一個腳本,可以更大程度上方便我們整理。
 
頂點程序本身既可以是一些低級語言,例如vs_1_1語法規格寫的彙編代碼,也可以是HLSL,GLSL,CG,個人更推薦使用後者。
 
一個最基本的片斷程序要求有以下幾個要點說明:
 vertex_program myVertexProgram asm
{
    source myVertexProgram.asm 
    syntax vs_1_1
}
1:在頭部給出程序名字,之後說明程序類型。“asm”
2:指示出資源來自何處。” source
3:指示出語法規則。“vs_1_1”
我們可以通過Ogre的GPU管理器來獲取當前顯卡支持的語法列表。
GpuProgramManager::GetSingleton().getSupportedSyntax()來獲得。
一般顯卡支持的語法規則如下:
vs_1_1
這是一種DirectX頂點渲染器彙編語法。
支持顯卡有:ATI Radeon 8500,nVidia GeForce 3。
vs_2_0
另一種DirectX頂點渲染器彙編語法。
支持顯卡有:ATI Radeon 9600,nVidia GeForce FX 5系列。
vs_2_x
另一種DirectX頂點渲染器彙編語法。
支持顯卡有:ATI Radeon X系列,nVidia GeForce FX 6系列。
vs_3_0
另一種DirectX頂點渲染器彙編語法。
支持顯卡有:nVidia GeForce FX 6系列。
arbvp1
這是OpenGL標準頂點程序彙編格式。大體上相當於DirectX vs_1_1。
vp20
這是一種nVidia特有的OpenGL頂點渲染器語法,是vs 1.1的一個超集。
vp30
另一種nVidia特有的OpenGL頂點渲染器語法。它是vs 2.0的一個超集,被nVidia GeForce FX 5系及以上系列支持。
vp40
另一種nVidia特有的OpenGL頂點渲染器語法。它是vs 3.0的一個超集,被nVidia GeForce FX 6系及以上系列支持。
ps_1_1, ps_1_2, ps_1_3
DirectX像素渲染器(例如片斷程序)彙編語法。
支持顯卡:ATI Radeon 8500,nVidia GeForce 3。
註解:對於ATI 8500,9000,9100,9200硬件,也可用於OpenGL。ATI 8500到9200不支持arbfp1但是確實支持OpenGL的atifs擴展,非常類似DirectX的ps_1_4。OGRE有針對atifs編譯器的ps_1_x模塊,當在ATI硬件上使用ps_1_x時,它會自動執行。
ps_1_4
DirectX像素渲染器(片斷程序)彙編語法。
支持顯卡有:ATI Radeon 8500,nVidia GeForce FX 5系列。
註解:對於ATI 8500,9000,9100,9200硬件,此項也可用於OpenGL。ATI 8500到9200不支持arbfp1但是支持OpenGL的atifs擴展,功能上非常類似於DirectX中的ps_1_4。OGRE有針對 atifs編譯器的ps_1_x模塊,當在ATI硬件上使用ps_1_x時,它會自動執行。
ps_2_0
DirectX像素渲染器(片斷程序)彙編語法。
支持顯卡有:ATI Radeon 9600,nVidia GeForce FX 5系列。
ps_2_x
DirectX像素渲染器(片斷程序)彙編語法。基本上是帶有更多指令的ps_2_0。
支持顯卡有:ATI Radeon X系列,nVidia GeForce FX 6系列。
ps_3_0
DirectX像素渲染器(片斷程序)彙編語法。
支持顯卡有:nVidia GeForce FX 6系列。
ps_3_x
DirectX像素渲染器(片斷程序)彙編語法。
支持顯卡有:nVidia GeForce FX 7系列。
arbfp1
這是OpenGL標準片斷程序彙編格式。大體上相當於ps_2_0,意味着不是所有支持DirectX下的基本像素渲染器都支持arbfp1(例如GeForce3和GeForce4就都不支持arbfp1,但是它們都支持ps_1_1)。
fp20
這是一個nVidia特有的OpenGL片斷程序語法,是ps 1.3的一個超集。它允許你爲基本片斷程序使用'nvparse'格式。實際上,它使用NV_texture_shader和 NV_register_combiners在GL下提供相當於DirectX's ps_1_1的功能,但是僅限於nVidia顯卡。然而,因爲ATI顯卡比nVidia早一步採用arbfp1,所以它主要用於像GeForce3和 GeForce4系列的nVidia顯卡。你可以在http://developer.nvidia.com/object/nvparse.html找到更多有關nvparse的信息。
fp30
另一種nVidia特有的OpenGL片斷渲染語法。它是ps 2.0的一個超集,被nVidia GeForce FX 5系列或更高級的顯卡支持。
fp40
另一種nVidia特有的OpenGL片斷渲染語法。它是ps 3.0的一個超集,被nVidia GeForce FX 6系列或更高級的顯卡支持。
 
詳細的語法編寫,實在沒有興趣詳細研究下去了。所以這裏略過,我們需要知道的是,除了HLSL,GLSL,CG以外,還有一個Ogre自動識別處理的類型,unified可以統一的對程序定義,這樣就可以依賴於渲染系統和硬件支持自動的選擇渲染程序。
 
另外,材質拷貝技巧。
一般來說,我們遊戲中大量的材質是雷同性很強的,假若大段的複製材質渲染模式,實在是非常不值得的體力勞動,所以對於一些只有微小改變的材質設置,推薦使用材質拷貝。
 
材質拷貝技巧1:
當兩個材質完全一致時。直接類似於C++的繼承的寫法即可:
 
Material met1
{
Technique
{
              Pass 0
{ … }
Pass 1
{ … }
}
}
 
Material met2 : met1
{
      
}
我們不需要做任何事情,met2就已經過去了met1的材質屬性。
 
材質拷貝技巧2:
當我們向一個拷貝材質中添加新技術時。直接在新的材質腳本中聲明新的技術即可。例:
Material met2 : met1
{
       Technique new
{
      
}
}
此時new這個技術就會默認的在其父類的默認命名爲0的技術之後產生。不過值得注意的是,新創建的這個技術儘量命名,避免與父源類的技術名稱發生衝突。
 
材質拷貝技巧3:
當我們想對拷貝材質已有的屬性做一點點的改動時候,需要聲明原有技術和通道,直接聲明需要改動的屬性即可。例:
Material met2 : met1
{
       Technique 0    // 父類的技術並沒有命名,默認是以索引爲名,索引爲0,所以這裏填0,但是注意的是,一定要把這個0表示說明出來
       {
              Pass 1     // 父類中的0號技術中的命名爲0的一個通道
              {
                     max_lights 2 //修改該Pass中的最大光源屬性爲2
}
}
}
最常用的是修改一個渲染材質中的某一個紋理文件。我們可以這麼做
Material met2 : met1
{
       Technique 0    // 父類的技術並沒有命名,默認是以索引爲名,索引爲0,所以這裏填0,但是注意的是,一定要把這個0表示說明出來
       {
              Pass 1     // 父類中的0號技術中的命名爲0的一個通道
              {
                     Texture_unit TreeTexture
            {
                Texture NewTreeTexture.png
}
}
}
}
這樣我們就將treetexture紋理單元中的紋理圖片替換了,而其他的一切渲染屬性都沒有更改。
 
材質拷貝技巧4:
記得我們之前說紋理單元時候有強調過紋理有一個屬性叫紋理別名吧。texture_alias。
我們看上面的例子,假若我們材質met1,和met2僅差一個紋理的區別的話,那麼上面的寫法也比較麻煩,我們有個更簡單的方法,就是,在初次定義的時候,爲紋理定義一個別名,之後我們假若需要換紋理,僅告訴Ogre腳本解釋器,別名現在代表另一張紋理便可以了。
例如:我們要渲染一張“漂亮的圖“,在材質1中,“漂亮的圖”代表 1.png,材質2中,“漂亮的圖”代表2.png,我們只要告訴Ogre,“漂亮的圖”是哪張便可以了。例子如下:
Material met1
{
       Pass 0
       {
              Texture_unit testTex
              {
         texture_alias DiffuseMap
         texture defaultDiff.png
        filtering trilinear
        tex_coord_set 1
}
}
}
那麼我們假若需要使用同樣的技術和通道,僅修改紋理圖片,我們可以簡單到如下:
Material met2
{
       Set_texture_alias DiffuseMap NewChangedDiff.png
}
一句話便更換了別名DiffuseMap所指代的對象。直接達到更換紋理貼圖的效果。
 
所以,我們儘量可能的爲技術,通道,紋理單元手動設置名字,紋理資源儘量設置別名。
 
合成器Compositor
雖然在Ogre說明書上佔了一定篇幅來說明他,很遺憾的是依舊無法理解這個概念名詞,它的作用也很值得斟酌,在現有的資料來看,它的使用率極低,故不再加以研究。暫時,放棄。
 
粒子腳本
非常熟悉,不贅述。格式完全類似材質腳本,僅修改了屬性關鍵字。
注意的是,Ogre中的粒子腳本中允許設置一些力學信息。
 
字體定義腳本
Ogre中字體最終就是一個Meterial對象,我們要獲得這個對象可以有2種方法:
1:利用一個字體生成工具自己設計字體紋理
2:讓Ogre生成一個基於trueType字體的字體紋理
無論使用哪種,都需要在 .fontdef 文件中對字體進行定義。
 
當我們使用現有的一個字體紋理,那麼該腳本聲明格式爲:
MyFont          // 字體名稱,程序中調用時使用,自定義
{
       Type image                   // 告知Ogre,我們使用的是字體紋理,不是tureType
       Source XXX.png          // 字體紋理文件名
       Glyph A 1 3 14 14         // 告知Ogre,A這個字符在紋理中的位置是(1,3)到(14,14)之間。
       ……                            // 對我們所需要的每一個字符都進行紋理位置的通知
}
從上面可以看出……對中文適用性之低。
 
當我們使用truetype生成一個字體紋理,那麼腳本聲明格式爲
MyNewFont // 字體名稱,程序中調用時使用,自定義
{
       Type truetype                // 告知Ogre我們將從一個字體中生成紋理
       Source XXX.ttf            // 要加載的. ttf文件名
       Size 16                        // 生成字體紋理的大小,若過小,則貼到大的面上就顯示很粗糙,若過大,則貼到小的面上就會模糊不清。
       Resolution 96                // 每英寸計算的清晰度,一般是72或96
       Antialias_colour true      // 關閉默認的字體抗鋸齒,這樣的話我們就會在渲染時手動的對字體邊進行抗鋸齒處理。該項默認爲false, 即不使用手動的抗鋸齒,使用Ogre默認的抗鋸齒功能。一般,false即可。
       Code_pionts 33-166       // 該項是表示哪一段的unicode編碼應當被生成字體紋理,默認是33-166的字符。
}
 
Overlay覆蓋層腳本
這個的作用重點表現在UI方面了,它就是將3D的按Z軸深度進行分割出的層平面,這個腳本默認在Root初始化時會自動搜尋所有的 .overlay 層腳本並且裝載分析。當然我們也可以手動去加載OverlayManager::GetSingleton().parseAllSource()或者手動加載單獨一個腳本OverlayManager::GetSingleton().parseSource().
 
我們看一個樣板式的層腳本
MyNewOverlays    // 該層的唯一標識命名
{
       Zorder 200     // 該層的Z軸深度,越大代表越接近屏幕
       Container Panel (MyNewOverlays/FirstPanel)      // Container對應的是element,這兩者都是對Panel的修飾詞,當該面上有新的子面時就使用Container,若是一個完全無子面的面,則可使用 element進行修飾。Panel是註冊過的本面板元素的類型,Ogre提供了三種基本類型Panel,BorderPanel,TextArea.    括號中的是該元素的唯一識別名稱。我們在程序中就可以使用OverlayManager::GetSingleton().getOverlayElement(唯一識別名稱);來獲得此元素的指針。在該句最後我們還可以加入繼承模版,接下來再說。
{
              Left 0
              Top 0
              Width 0.02
              Height 0.3
              Material ThisPanelMaterial     // 這些都是該面板元素的屬性
}
}
 
這裏我們遺留了三個問題:
1:Ogre提供的三個基本元素類型有什麼區別和作用?
2:什麼是面版元素繼承的模版,作用有什麼?
3:面板元素都有什麼屬性有什麼作用?
 
答1:Ogre提供了三個基本表層元素類型。包括Panel,BorderPanel,TextArea。實際上,一般來說,這三種是完全不夠的,是需要我們進行擴展的。擴展後的類型擁有獨特的功能和屬性。
例如:
Panel 面版
它就是一個矩形的區域,重點作用就是做一個其他元素的容器。所以一般來說,它更多時候是沒有背景的透明的。他的專有屬性有:
Transparent true / false 是否透明,若爲true則代表本面板透明,自己是不參與渲染的。
Tiling 0 1 2 實現多重貼圖。本例說明使用第0層材質紋理在面板上X軸方向重複貼一次,Y軸方向上重複貼兩次。
Uv_coords topleft_u topleft_v bottomright_u bottomright_v 設置這個面版上的紋理UV座標。
這三個屬性是Panel專屬的,這意味着其他的表層元素是不具有這些功能和屬性的。
 
BorderPanel邊框面版
它和Panel區別僅有一個,就是多個一套邊框。這個邊框會隨着BorderPanel的大小自動的調節其紋理大小。它的構成由9部分:一箇中心區,4個角,4個邊。它的專屬屬性是
       Border_size left right top bottom 邊框按屏幕大小的比例尺寸。我們可以發現到Ogre在記錄UI大小時是很喜歡記錄UI與屏幕長度之間的比例,而非實際的象素大小。這樣做的好處是,當屏幕大小有變換時,是很容易實現縮放功能的。
       Border_material materialName 因爲邊框面板有獨特的邊框,所以,我們需要對它指示出其邊框使用的材質紋理。
       Border_topleft_uv topleft_U uv_topleft_V buttomRight_U buttomRight_V
Border_top_uv topleft_U uv_topleft_V buttomRight_U buttomRight_V
       …… 總共八塊邊緣都需要指定其UV信息。這裏我們需要注意,我們美術資源製作時,要求左右兩邊的材質紋理應該允許被垂直拉伸,上下兩塊的材質紋理應該允許被水平拉伸。
 
TextArea文本區
用來渲染文本的一個表層元素。它轉有屬性包括:
Font_name name 要使用的渲染字體名,我們必須保證這個字體在 .fontdef 裏面並且可用。
Char_height 字母高度佔用整個屏幕告訴的百分比。
Colour RGB 渲染字體的顏色,默認是使用一般的黑白字體。RGB是0.0-1.0之間的浮點數。
Colour_bottom RGB / colour_top RGB 實現文本從上到下的顏色漸變。
 
答2:
模板實際上就是類似於材質拷貝時的那個父類,實際作用是當幾個比較類似屬性的表層元素,我們可以直接定義一個模板,其他元素繼承於該模板就節約了一些複製粘貼的操作而已。
我們看下例:
Template container BordPanel ( MyTemplate/BasicBorderPanel ) // template表示該Panle是模板面版,本身它是不進行渲染的,類似於C++的抽象父類,制定一套屬性樣版提供其他渲染面板直接套用使用。Container也是Panel的一個屬性,表明它是允許有子表層元素的。後面括號裏是模板面板名稱。
{
       Left 0
       ……
       Material MyPanelMaterialName
       Border_size 0.05 0.05 0.06 0.06
       Border_material MyBorderPanelMaterialName
       ……
}
 
Template container Button (MyTemplate/BasicButton) : MyTemplate/BasicBorderPanel
// 表明該Button是上面的層的子層,Button是開發人員註冊的一個層元素類型
{
       Font_name BlackStyle
       Char_height 0.09
       Color_top 1 1 0
       Color_bottom 1 0.5 0.5
}
 
上面定義了一套模板邊框面和一套模板按鈕,下面我們將對其實現
MyOverlays           // 層名稱
{
       Zorder 490     // 層深度
       Container BorderPanel (ChatBackPanel ) : MyTemplate/BasicBorderPanel         // 實現一個進行渲染的背景面層元素,它套用模板邊框面
       {
              Container Button (JionButton) : MyTemplate/BasicButton           // 實現一個進行渲染的按鈕,它套用模板按鈕的各項屬性
              {
                     Left 0.8
                     Top 0.4
}
              Container Button (ExitButton) : MyTemplate/BasicButton           // 實現另一個進行渲染的按鈕,它套用模板按鈕的各項屬性
              {
                     Left 0.6
                     Top 0.4
}
 
}
}
這樣,我們就得到了一個渲染出來的邊框面板和上面的兩個按鈕,我們新創建的按鈕就可以省去很多屬性的設置了,僅對部分獨特的屬性進行設置即可。
可見,模板的作用和抽象Pass通道,技術,紋理單元 是一樣的作用,減少我們屬性設置而創建的。
 
答3:
層元素屬性是對層的各項渲染指數進行調整的東西。我們也看到了,不同的元素因功能特性不同,會有獨特的屬性,但下列通用屬性是每個元素必須有的:
Metrics_mode pixels / relative 屬性參數解釋方式。默認是relative相對模式,這就意味着之後我們設置top 0.8 代表着這個0.8是針對屏幕寬高得到的比例值。若我們設置爲pixels則代表我們設置 top 8 是從第8個象素開始的,是一個絕對的象素偏移量。顯而易見,我們再設置爲top 0.8 這樣明顯是不合理的了。
默認該項爲 metrics_mode relative
Horz_align left/center/right 設置此元素水平起點位置。例如,horz_align left 則代表本元素會自動的居左對齊,當然我們再設置left xxx可以再次對其位置進行調整。
默認該項爲 horz_align left
       Vert_align top/center.button 同上不再解釋。
默認該項爲 vert_align top
       Left 0.3 設置元素相對於它上一層的水平位置。後面的參數跟metrics_mode屬性參數解釋方式掛鉤。
默認該項爲 left 0
       Top 同上不再解釋。
默認該項爲 top 0
       Width 0.2 設置元素大小。這裏0.2是針對整個屏幕的大小而言,並非針對其父元素的大小。所以當我們設置width 0.5時則意味着這個元素會佔屏幕的一半寬。
默認該項爲 width 1
       Height 同上不再解釋
默認該項爲height 1
       Material XXX 設置該層元素使用的基本材質。值得注意的是:一個表層元素的材質會默認的禁止其上材質的光照和深度檢測。所以,我們不應當在表層上使用與3D物體相同的材質。另外,該項在不同的元素中解釋意義也是不同的,在Panel中他是整個面版的背景材質,但是在BorderPanel中它僅僅是中心區域的材質。
       Caption XXX 設置該層元素的標題。因爲部分元素是沒有標題屬性的,所以有些元素可以忽略掉該元素。
       Rotation 30 0 0 1 設置該層的旋轉角度,第一個參數是旋轉的角度,第2,3,4屬性分別表示在x,y,z軸的旋轉。本例就說明是該層元素需要圍繞z軸旋轉30度。
 
4Mesh網格工具
Ogre自帶的網格工具包括三種:
1:導出器Exporters    用於從繪圖軟件中導出固定格式的數據提供Ogre使用
       Ogre這個導出插件能夠導出兩個文件,一個 .mesh 結尾的網格模型,一個是 .skeleton 後綴的骨骼模型。值得注意的是,當我們需要創建一個模型動畫時候請注意:
·每個頂點必須沒有超過4的加權骨骼賦值。
·所有的頂點都必須被分配到至少一個骨骼點上,靜態頂點就分配到根部骨骼點上
·動畫開始和結束時候每個骨骼點上最少要有一個關鍵楨
2:Xml轉換器             能夠將xml格式的數據轉換爲Mesh數據和骨骼數據
       ·因爲很多模型工具導出的Mesh都是xml格式的,這時使用該轉換器就可以直接將 xml格式的mesh網格轉換爲 .mesh 文件。其中的語法非常簡單。
格式爲: OgreXMLConverter 文件名    
這樣就可以了。不過在轉換時,你可以有一次機會對Mesh中的Lod信息進行處理。
3:Mesh網格更新器    能夠對網格的數據進行更新修改功能。
       未能順利使用。故不做介紹。
 
5:硬件緩衝區(硬件緩存)
·定義
實際上這個緩衝區就是一塊malloc出來的存儲區域,不過它不如malloc是在內存中申請的區域,而這個緩衝區是在gpu/agp中,它的寫讀速度更快。通常硬件緩衝區作用有拿來做頂點緩衝區,索引緩衝區,和象素緩衝區。
 
·使用
硬件緩衝區的管理是交由一個硬件緩存管理器負責的HardwareBufferManager,他負責緩衝區的創建和釋放,它是幾何體創建工廠,單鍵在Root初始化時就會被創建,所以,當我們需要一塊內存的時候,一定不要直接New或malloc操作,而應當是這樣
VerBuf = HardwareBufferManager::GetSingleton().CreateVertexBuffer()
 
·類型
       我們在分配一塊硬件緩衝區時,需要傳一個參數,來指明這塊緩衝區的類型,是否需要頻繁讀寫?這樣對底層的硬件緩存區域分配管理提供很大的便利。我們來看一下硬件緩衝區的類型有哪些,我們分配它的時候應該做何選擇。(HBU是HarewareBufferUsage簡寫)
       HBU_STATIC 靜態硬件緩衝區,它意味着我們很少寫入更新緩衝區,偶爾會從中進行數據讀取。
       HBU_STATIC_WRITE_ONLY 只寫靜態硬件緩衝區。它意味着我們很少更新緩衝區,並且絕對不從該緩衝區進行數據讀取。但是,當我們創建了一個備份緩衝的話,我們依舊可以對其讀取。
       HBU_DYNAMIC 動態硬件緩衝區。它意味着我們會經常性的更新緩衝區中的數據,並且也希望能從其中讀取數據,這一個效率最低的緩衝區使用方法。
       HBU­_DYNAMIC_WRITE_ONLY 只寫動態硬件緩衝區,這個是個只許寫入的硬件緩衝區,但當我們創建了一個備份緩衝的話,還是允許讀取的。
       HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE 這個參數指明這個硬件緩衝區是一個需要頻繁更新的緩衝區,大多數是每楨更新的數據存放在這裏。但是需要注意的是,向該數據緩衝寫入數據時記得加緩存鎖。
 
建議:多使用WRITE_ONLY爲後綴的緩衝區類型。即使必須進行讀取,也建議使用備份緩衝,而非時刻可寫的緩衝。
 
·備份緩衝
當我們創建一個WRITE_ONLY的硬件緩衝區後,我們有些時候假若非要從中讀取數據,我們可以在創建緩衝區時傳參,這樣我們在內存中就會創建一個備份的緩衝區。每當我們向顯存中寫入一份數據的時候,Ogre會自動的先將這份數據拷貝到內存緩衝區後,再將其更新到顯存中的硬件緩衝區。當然,這個技術會帶來更多的開銷,所以,非必要時不要用它。
 
·緩存鎖
當我們更新寫入緩衝或者在讀取緩衝的時候,都應該先“鎖”住它,以免它被修改。當然,之後記得解鎖。pBuffer->Lock(begin , length , lockType)一般來說,鎖的範圍越小越便捷快速。但是鎖的類型lockType也可以對讀取的效率產生影響。
鎖的類型包括:
·HBL_NORMAL 這種鎖支持從緩衝區讀取數據,但是效率很低下,因爲它允許我們從硬件緩衝區進行數據讀取。但是,當我們使用備份緩衝的話,這種影響會得到一些改善。
·HBL_READ_ONLY 這種鎖意味着我們只能從緩衝區中進行內容的讀取,禁止寫入。此時建議我們使用備份緩衝,會提高我們效率。而且,此時我們實際上讀取到的並非硬件緩衝區,而是內存中的數據。
·HBL_DISCARD 這種鎖意味着我們每次操作都會將硬件緩衝區中的所有內容丟棄,一般這種操作也是會在每楨都處理的環境下才會使用,它是禁止讀出的。但是一旦我們如此聲明,也就基本上是向引擎宣稱我們不會對硬件緩衝區的內容感興趣,那麼就不應當創建備份緩衝區。在我們沒有使用備份緩衝區時儘量使用這種鎖,它的效率很高,但若有了內存備份緩衝區的話,它就沒有必要了。
·HBL_NO_OVERWRITE 當我們有些時候需要更新部分緩衝區而非全部緩衝區時,使用HBL_DISCARD就顯的不適合了。此時我們就需要使用這種鎖了,它的效率依舊很高,但是也僅是沒有備份緩衝的時候纔有作用。
 
·硬件緩衝區和緩衝鎖使用經驗
       1:因爲最快最優秀的緩衝自然是通過 HBU_STATIC_WRITE_ONLY類型創建,不創建備份緩存,並且僅進行一次HBL_DISCARD的鎖操作永不再額外處理的緩衝。
       2:當我們需要頻繁更新的緩衝,可以用HBU_DYNAMIC_WRITE_ONLY來創建,不創建備份緩存,之後使用HBL_DISCARD加鎖,若不想全部更新,則使用HBL_NO_OVERWRITE進行鎖操作。
       3:若我們必須從緩衝區中讀取數據的話,那麼我們可以創建一個備份緩衝,用HBL_READ_ONLY將其鎖住。可能的話,儘量聲明緩衝區爲靜態的。
       4:在我們對頂點的不同元素需要使用不同模式的時候,我們不要通過指針大量更新緩衝區的全部頂點結構,應該分塊更新。例如,我們假設只需要經常更新紋理座標信息,那麼我們應當將紋理座標信息保存在一個單獨的緩衝區區域,而其他的不經常更新的元素拆分保存在HBU_STATIC_WRITE_ONLY緩衝區中。
 
·頂點緩衝區
       VertexData中有幾個重要成員:
       ·VertexStart                頂點起始位置信息
       ·VertexCount              頂點個數
       ·VertexDeclaration       一個指向頂點數據個數的指針
       ·VertexBufferBinding   一個指向頂點緩衝區綁定的指針
       其中頂點類型描述中我們需要強調一個順序問題,爲了支持DX9以前的版本,我們有必要按如下順序聲明和數據保存:
       1:頂點位置信息
       2:頂點綁定權重
       3:頂點法線信息
       4:頂點環境光顏色信息
       5:頂點鏡面光顏色信息
       6:頂點紋理座標信息
       除了上面的順序需要注意以外,我們還需要注意的是頂點緩衝區中,是絕對不允許有空隙存在的。
       我們創建了一個頂點緩衝區後,我們還需要將起和指定的資源進行綁定。
       格式如下 verterBufferBinding->setBinding(0, vertexBuffer);
       之後,我們在運行時將頂點緩衝區綁定起來,循環的將其信息更新填充進入,Ogre提供了臨接點與點之間的間隔長度和起始點信息,以便我們進行數據更新。
 
·索引緩衝區
       與頂點緩衝區基本都是一致的。創建後更新。唯一的區別就是創建時有些屬性不同而已。
 
·象素緩衝區
       這裏是保存紋理象素信息的。但是和頂點緩衝和索引緩衝不同的是,我們不能手動創建象素緩衝區,只有在我們創建一個紋理的時候,象素緩衝會自動被創建出來。
       象素緩衝區中支持的紋理類型:
              TEX_TYPE_1D 一維的紋理,通過1D紋理座標來索引
              TEX_TYPE_2D 二維的紋理,通過2D文理座標來索引
TEX_TYPE_3D 三維的紋理,通過3D文理座標來索引
TEX_TYPE_CUBE_MAP 一個立方體的六個表面紋理,通過3D紋理進行索引。
象素緩衝區的內存分配格式
       Ogre中的圖象數據的信息都被封裝在一個個的PixelBox對象之中,我們需要注意的是PixelBox本身是保存在GPU中,但是真正的紋理都是保存在內存中,並非讀到GPU中。GPU中的 PixelBox保存着內存中象素的格式位置內容信息的描述,但是PixelBox並沒有內存管理的功能,它只能通過保存的內存指針來操作數據。象素盒中提供了通過深度,高度,寬度來索引象素的方法,若一維紋理沒有高度和深度時,就將其參數補1。如下:(width, 1, 1),二維的紋理(width, height, 1)
象素緩衝區的更新
       Ogre提供了兩種更新象素緩衝區的方法。
1:手動建立一個紋理並將一個圖片放入這個紋理中。我們可以如下代碼Image img; img.load(“xxx.jpg”, “General”); Texture pTex = Texture::getSingleton().createManual( …. ); pTex->GetBuffer(0,0)->blitFromMemory( );
2:對一個象素緩衝區加鎖之後對其進行讀取和寫入。
Buffer->Lock(HarewareBuffer::HBL_DISCARD);
const PixelBox &pb = buffer->getCurrentLock();              // 鎖好了之後進行處理
for (int I = 0; I < pb.GetWindth(); ++I)
{
       For( int j = 0; j < GetHeight(); ++j)
       {
        Static_cast<unit32*>(pb.data) // 數據獲得,隨便處理
}
}
Buffer->unlock(); //最後記得解鎖。
6:外部紋理源
·定義。
       我們讀取一個紋理,通常是從一個.jpg.png.bmp等格式的圖形文件中進行讀取,但有些時候我們需要從avi.mpeg等電影格式文件,flv文件,實時渲染產生的來源中讀取紋理,這些渠道來源就被稱爲外部紋理源。
·處理外部紋理源。
       我們如何處理外部紋理源?本身Ogre是沒有寫的。不過它提供了方法的接口,以便我們寫出需要的插件。
·外部紋理源插件編寫方法
       我們構建的插件必須繼承於ExternalTextureSource類。它提供了一個通用的框架。另外,當我們開始需要獲取外部紋理源的時候可以使用ExternalTextureSourceManager類中的函數來獲得。典型的函數可以如下:AdvanceTextureManager::GetSingleton().GetCurrentPlugIn()
->CreateDefinedTexture(sMaterialName);
·外部紋理源腳本
       Material Example/MyVideoExample
       {
              Technique
              {
                     Pass
                     {
                            Texture_unit
                            {
                                   Texture_source video
                                   {
                                          Filename MyMovie.avi
                                          Play_mode play
                                          Sound_mode Off    // 注意:這些屬性根據插件不同而且不同
}
}
}
}
}
 
7:陰影
·啓動陰影
       1:默認時陰影是被關閉的。我們要使用陰影就必須使陰影有效,而這個操作必須極其優先處理,因爲,是否開啓陰影會影響模型讀取的方式。如:
       M_SceneMgr->SetShadowTechnique( SHADOWTYPE_STENCIL_ADDITIVE ); //開啓一個模板陰影。
2:關閉部分不支持投射陰影的光源。(有些光源並不支持投影)
       Light::SetCastsShadow(false)
3:關閉那些不需要投射陰影的物體。(有些透明物體可能不需要投影)
MovableObject::SetCastsShadow(false)
4:設置投影的最遠距離。(爲了性能考慮,需要設置)
5:關閉那些不需要接受陰影的物體。(透明材質,自發光材質通常是不能接收投影的)
Material::SetReciveShadow(false )
 
8:動畫
       Ogre默認支持四種腳本動畫。
1) 骨骼動畫。使用骨骼結構來定義網格數據。
a)         Ogre的骨骼和動畫信息被保存在 .skeleton 的腳本文件中。
b)        我們進行動畫操作時,需要創建一個叫動畫狀態的對象來控制該動畫的狀態。我們可以通過Entity::getAnimationState()來獲得一個指向動畫狀態的指針,之後我們在frameStarted時間中,通過動畫狀態指針來進行動畫更新。
2) 頂點動畫。保存頂點快照來決定網格數據如何改變。
3) 場景節點動畫。按照預先定義的路徑,來操作場景節點上掛接的實體進行移動產生動畫。
a)         我們可以爲每個SceneNode創建一個對應的NodeAnimationTrack
4) 數值動畫。使用Ogre的接口類AnimableObject來繼承擴展。這樣就可以自定義其對象屬性。

<script type="text/javascript"></script>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章