清源游民 gameogre@gmail.com
布告板(Billboard)
Ogre中的布告板簡單的來講就是場景中的一個四邊形,但它的朝向與相機有關。通常布告板隨著相機的視方向旋轉以便與相機的視線方向對齊。把布告板放在場景的任何地方,它將會朝向相機。為了效率考慮,布告板與相機的視線方向對齊,而不是與從布告板到相機的向量對齊。大部分情況下兩者沒有明顯的區別。如果想使用后一種的對齊形式,也可以辦到,但在性能會有所降低。
布告板集(Billboard Sets)
布告板不能獨立存在,他們也不能自我渲染。他們必須屬于某個布告板集。布告板集可認為是一組布告板
的管理器,布告板集內的所有布告板有相同的尺寸,使用相同的材質。相同的尺寸,相同的紋理會帶來計算與渲染效率的提升??梢栽谝粋€布告板集內單獨改變某個公告板的尺寸,但這樣做會導致性能下降ogre
認為一個布告板集是一個操作的單位,它們要么都不渲染,要么全部進行渲染,換句話說,它們以同樣的
方式進行剔除處理,也可以對集合的個體進行單獨剔除,但最好不要這么做,同樣這也是出于效率的慮。在大范圍的應用布告板集來模擬草的例子中,就有可能出現在布告板集內的許多布告板落在視角之外的情況,在這種情況下也許會想到用單獨剔除的方式,但這樣做同樣不可避免地會影響性能。更好的做法是使用多個布告板集而不是在一個巨大的布告板集進行單獨剔除。布告板集內的布告板是相對于布告板集attached到的場景結點進行定位的。既然,布告板集內的布告板使用相同的材質,那么它們會在同一batch進行渲染。
布告板創建
布告板可以用與本布告板集的中心的偏移與尺寸(寬,高)來描述。它的方向是它到相機向量的函數。缺省,創建的布告板是所謂的point布告板。這種布告板總是完全地面對相機而且垂直。布告板的原點缺省位置是它的中心,可以在九個規范的位置范圍內改變原點位置。第二種類型的布告板是oriented布告板,它即可以沿各自的Y軸旋轉,也可沿共同的軸(通常是Y軸)旋轉。第三種是perpendicular布告板,它與方向向量(布告板與相機之間的向量)垂直。這個方向向量可以是共享的向量(通常是Z軸),也可以是各自的Z軸。這種類型的布告板也需要一個上方向輔助定位。
point布告板相對于其他類型的布告板有一些優點。一般,ogre為每個布告板產生一個quad(四個頂點,每個
頂點都有位置,紋理坐標),并把生成的幾何體送入GPU進行渲染。對于point 布告板,可以廢除其中的三個,讓GPU挑選,以及決定如何進行基于點繪制紋理屬性的渲染。進行硬件點渲染有一些限制:只支持
point布告板,其中只限于以中心為原點的那一類。尺寸與外觀在材質中定義,不在布告板集,尺寸是有限
的,不可能與軟件創建的一樣大。不支持單獨的布告板旋轉與改變大小,但可以對紋理單元旋轉。
布告板池
創建布告板時需要告訴布告板集中布告板的數量。布告板被分別放在active與free列表中,這使得定位非常快。當創建的布告板的數量超過了布告板池的尺寸,池的尺寸會增加一倍。最好事先確定池的大小,避免在使用中使池的大小不合理地增長。
布告板紋理坐標
支持非全范圍的紋理坐標分配。舉個例子,假如你有個紋理,它包含幾個子紋理。每個紋理都包含一個
英文字母。這時,你想創建幾個公告板,每個公告板上顯示不同的字母,當然它們都來自同一個紋理。
可以先創建一個包含紋理坐標的數組,然后把這個數組提供給布告板集。當利用布告板集創建布告板時,
可以給這個布告板一個存放紋理坐標的數組的索引。圖片與代碼如下:

// create a new billboard set with a pool of 4 billboards
BillboardSet* bbset = sceneMgr->createBillboardSet("BBSet", 4);
// create a texture coordinate array to address the texture
FloatRect texCoordArray[] = {
FloatRect(0.0, 0.0, 0.5, 0.5), // address the "A"
FloatRect(0.5, 0.0, 1.0, 0.5), // address the "B"
FloatRect(0.0, 0.5, 0.5, 1.0), // address the "C"
FloatRect(0.5, 0.5, 1.0, 1.0), // address the "D"
};
// provide this array to the billboard set
bbset->setTextureCoords(texCoordArray, 4);
// now create a billboard to display the "D"; this
// is the fourth entry in the array, index=3
Billboard* bb = bbset->createBillboard(Vector3(0, 0, 0));
bb->setTexcoordIndex(3);
也可以直接對紋理坐標進行賦值
FloatRect coords(0.5, 0.5, 1.0, 1.0);
bb->setTexcoordRect(coords);
布告板使用的材質腳本與可以包括正常材質腳本中的所有東西,而且可以使用布告板與點紋理特有的一些
指令與參數。
布告板鏈與絲帶跟蹤(Ribbon Trails)
布告板鏈一組前后相聯結的一組布告板(可以聯想“老鷹抓小雞”的游戲中小雞們的組織結構)。ogre
提供了一個ribbon-trail引用類,它使用了布告板鏈,可以追逐場景中的結點,并留下一條尾巴。布告板鏈可以分多個節,因此可以很好來模擬燈的效果 。布告板鏈的缺點是必須手動更新??梢詾椴几姘彐湹拿總€節的尾部添加項,每個節有最大的長度,假如超過了那個長度,尾部項被移除,重新做為節的頭。
ribbon trail有類似的行為,從尾部移除項作為頭來增長,從頭到尾顏色逐漸褪化。圖片與代碼如下:

void setupTrailLights(void)
{
NameValuePairList pairList;
pairList["numberOfChains"] = "2";
pairList["maxElements"] = "80";
RibbonTrail* trail = static_cast<RibbonTrail*>(
mSceneMgr->createMovableObject("1", "RibbonTrail", &pairList));
trail->setMaterialName("Examples/LightRibbonTrail");
trail->setTrailLength(400);
mSceneMgr->getRootSceneNode()->
createChildSceneNode()->attachObject(trail);
// Create nodes for trail to follow
SceneNode* animNode = mSceneMgr->getRootSceneNode()->
createChildSceneNode();
animNode->setPosition(50,30,0);
Animation* anim = mSceneMgr->createAnimation("an1", 14);
anim->setInterpolationMode(Animation::IM_SPLINE);
NodeAnimationTrack* track = anim->createNodeTrack(1, animNode);
TransformKeyFrame* kf = track->createNodeKeyFrame(0);
kf->setTranslate(Vector3(50,30,0));
kf = track->createNodeKeyFrame(2);
kf->setTranslate(Vector3(100, -30, 0));
kf = track->createNodeKeyFrame(4);
kf->setTranslate(Vector3(120, -100, 150));
kf = track->createNodeKeyFrame(6);
kf->setTranslate(Vector3(30, -100, 50));
kf = track->createNodeKeyFrame(8);
kf->setTranslate(Vector3(-50, 30, -50));
kf = track->createNodeKeyFrame(10);
kf->setTranslate(Vector3(-150, -20, -100));
kf = track->createNodeKeyFrame(12);
kf->setTranslate(Vector3(-50, -30, 0));
kf = track->createNodeKeyFrame(14);
kf->setTranslate(Vector3(50,30,0));
AnimationState* animState = mSceneMgr->createAnimationState("an1");
animState->setEnabled(true);
mAnimStateList.push_back(animState);
trail->setInitialColour(0, 1.0, 0.8, 0);
trail->setColourChange(0, 0.5, 0.5, 0.5, 0.5);
trail->setInitialWidth(0, 5);
trail->addNode(animNode);
// Add light
Light* l2 = mSceneMgr->createLight("l2");
l2->setDiffuseColour(trail->getInitialColour(0));
animNode->attachObject(l2);
// Add billboard
BillboardSet* bbs = mSceneMgr->createBillboardSet("bb", 1);
bbs->createBillboard(Vector3::ZERO, trail->getInitialColour(0));
bbs->setMaterialName("Examples/Flare");
animNode->attachObject(bbs);
}
首先,RibbonTrail創建了兩個鏈,每個最多包括80個元素,尾巴長400個世界單位。創建了一個結點animNoade。為這個結點創建了一個動畫,使得這個結點可以根據關鍵幀的設計在場景中不斷變化位置。并把一個RibbonTrail與這個結點聯結起來,于是RibbonTrail可與animNode一起運動。又創建了一個燈,并聯結到這個結點,燈隨結點也一起運動,于是怪物頭會有明暗變化。最后用一個布告板來形象表示剛創建的燈,因為燈在場景中是不可見的。因為燈被掛到animNode結點上,所以布告板bbs也掛到同樣的結點上。當然別忘了使用了動畫狀態來推進動畫。
posted on 2007-03-20 15:31
清源游民 閱讀(3726)
評論(0) 編輯 收藏 引用 所屬分類:
OGRE