Ogre中g(shù)rass渲染動(dòng)態(tài)草體
Ogre中grass渲染動(dòng)態(tài)草體
關(guān)鍵詞:
StaticGeometry、靜態(tài)幾何體
“看起來似乎靜態(tài)幾何體是活動(dòng)物體(Moveable Object)的反義詞,但事實(shí)上也不全是:通常來說靜態(tài)幾何體會由很多不再活動(dòng)的活動(dòng)物體來構(gòu)成。”(Pro OGRE 3D Programming
中文翻譯版本0.2.0)
靜態(tài)物體的幾個(gè)缺點(diǎn)(Pro OGRE 3D Programming中文翻譯版本0.2.0):
•巨大的靜態(tài)物體需要在使用前被構(gòu)建,通常這是一個(gè)緩慢的過程,所以不能在每一幀都執(zhí)行。
• 靜態(tài)幾何體將按著放入物體的材質(zhì)來進(jìn)行分類,并且把材質(zhì)相同的集合體放置到同一個(gè)渲染設(shè)置當(dāng)中(換句話說,也就是放到同一個(gè)簇中)。但這并不表示只要把一組幾何體打包成一個(gè)靜態(tài)物體就能神奇的把它們捆綁到一個(gè)渲染設(shè)置中。
•在靜態(tài)幾何體中“靜態(tài)”的含義是:一旦物體被放入靜態(tài)幾何體中,你就不能在單獨(dú)移動(dòng)它了。任何對靜態(tài)幾何體的世界變換都會應(yīng)用到所有里面包含的物體上。
•靜態(tài)幾何體會比同樣大小的活動(dòng)物體占用更多的內(nèi)存。靜態(tài)幾何體會為每一個(gè)實(shí)體創(chuàng)建一個(gè)網(wǎng)格模型數(shù)據(jù)的拷貝。
•就算在你的視野里(視截體)中看到了整個(gè)靜態(tài)幾何體的一小部分,甚至包括在你身后的整個(gè)數(shù)據(jù)都會傳到圖形硬件中渲染。
ogre_src_v1-7-2\Samples\Grass\include\Grass.h
這個(gè)注釋很機(jī)械,夠參考用了:http://xmchang.bokee.com/4277630.html
StaticGeometry的數(shù)據(jù)分析見后面的“底層數(shù)據(jù)結(jié)構(gòu)分析”。
StaticGeometry對象作為動(dòng)態(tài)草坪,然后在上面附加手繪的grass mesh
步驟:
1. 創(chuàng)建手繪mesh,命名為“grass”,并加載到Etity中。這是一個(gè)創(chuàng)建用戶自定義mesh的方法,稍后再說。
2. 構(gòu)造靜態(tài)幾何體,并設(shè)置它的參數(shù)。
StaticGeometry* mField = mSceneMgr->createStaticGeometry("Field");
3. 將草體Entity加到StaticGeometry靜態(tài)幾何體中,也就是往field中種草
mField->addEntity(grass, pos, ori, scale);
4. 執(zhí)行創(chuàng)建。烘焙草體?
mField->build(); // build our static geometry (bake the grass into it)
5. 草體隨風(fēng)搖擺。幀循環(huán)中
waveGrass(evt.timeSinceLastFrame); // wave the grass around slowly to simulate wind
手動(dòng)創(chuàng)建mesh(需補(bǔ)充。。。)
草體搖動(dòng)的代碼不是很懂。不是很熟悉靜態(tài)幾何體的結(jié)構(gòu)。(需補(bǔ)充。。。)
PagedGeometry中的草體
奧米格得,那不是2句話就能說清楚的,還用了cg。靜止的樹如下渲染:
1. 創(chuàng)建PagedGeometry對象
PagedGeometry* trees = new PagedGeometry();
2. 創(chuàng)建TreeLoader3D對象,用于加載樹,并加載到PG中。
TreeLoader3D *treeLoader = new TreeLoader3D(trees, TBounds(0, 0, 1500, 1500));
trees->setPageLoader(treeLoader); //Assign the "treeLoader" to be used to load geometry for the PagedGeometry instance
3. 準(zhǔn)備好地形高度表,方便種樹嘛
//Setup the height function (so the Y values of trees can be calculated when they are placed on the terrain)
HeightFunction::initialize(sceneMgr);
4. 種樹了。隨機(jī)在一個(gè)區(qū)域種樹,世界里沒有一顆相同的樹。
for (int i = 0; i < 20000; i++){
yaw = Degree(Math::RangeRandom(0, 360));
position.x = Math::RangeRandom(0, 1500);
position.z = Math::RangeRandom(0, 1500);
position.y = HeightFunction::getTerrainHeight(position.x, position.z);
scale = Math::RangeRandom(0.5f, 0.6f);
treeLoader->addTree(myEntity, position, yaw, scale);
}
5. 幀循環(huán)中更新LOD
//[NOTE] PagedGeometry::update() is called every frame to keep LODs, etc. up-to-date
trees->update();
類關(guān)系
class BatchedGeometry: public Ogre::MovableObject
class WindBatchedGeometry: public BatchedGeometry
總結(jié):
很迷惑,似乎是用的MovableObject,為什么不用StaticGeometry?PG實(shí)現(xiàn)了一套完整的樹木森林渲染方式,得單獨(dú)理解。暫且放下,看看ogitor如何實(shí)現(xiàn)的。
Ogitor中的草體
Ogitor 0.4中也是是用的pagedgeometry 1.1.0,和上面分析時(shí)使用的一個(gè)版本。
#define PAGEDGEOMETRY_VERSION "1.1.0"
Ogitor中還用到了moc,暫記之。
CPGInstanceManager
用于管理pagedgeometry
class CBaseEditor: public Ogre::GeneralAllocatedObject
class CPGInstanceManager : public CBaseEditor, public MouseListener
class CPGInstanceEditor : public CBaseEditor
加載樹的代碼和上面的介紹一樣,這里找
bool CPGInstanceManager::load(bool async)
update在這里
bool CPGInstanceManager::update(float timePassed)
總之還是可以借鑒的。
底層數(shù)據(jù)結(jié)構(gòu)分析
---------------------------------------------------------------------------------------------------------------
內(nèi)存種類
enum MemoryCategory
{
/// General purpose
MEMCATEGORY_GENERAL = 0,
/// Geometry held in main memory
MEMCATEGORY_GEOMETRY = 1,
/// Animation data like tracks, bone matrices
MEMCATEGORY_ANIMATION = 2,
/// Nodes, control data
MEMCATEGORY_SCENE_CONTROL = 3,
/// Scene object instances
MEMCATEGORY_SCENE_OBJECTS = 4,
/// Other resources
MEMCATEGORY_RESOURCE = 5,
/// Scripting
MEMCATEGORY_SCRIPTING = 6,
/// Rendersystem structures
MEMCATEGORY_RENDERSYS = 7,
// sentinel value, do not use
MEMCATEGORY_COUNT = 8
};
This allocation policy uses nedmalloc
(http://nedprod.com/programs/portable/nedmalloc/index.html).
class NedPoolingPolicy
template <MemoryCategory Cat> class CategorisedAllocPolicy : public NedPoolingPolicy{};
typedef CategorisedAllocPolicy<Ogre::MEMCATEGORY_GEOMETRY> GeometryAllocPolicy;
|
typedef AllocatedObject<GeometryAllocPolicy> GeometryAllocatedObject;
|
typedef GeometryAllocatedObject BatchedGeometryAlloc;
值得注意的是,nedprod宣稱: there is no faster portable memory allocator out there!
Ned似乎是作者的名字。
Policy模式
PagedGeometry插件分析
http://sxoo0305.blog.163.com/blog/static/10132887201061154455372/