Пишем портальный рен'дерер (часть 1)
Ниже приводится описание класса SubScene, реализующего отдельную комнату.
'£!
class SubScene : public Object {
protected:
Array polys;
BoundingBox boundingBox;
public:
SubScene ( const char * theName ) : Object ( theName ), polys ( "Polys" )
{
metaClass = Sclasslnstance;
}
virtual bool isOk () const {
return polys.isOk (),-
}
virtual int init (),-
virtual void render ( View& view, const Cameras,
const Frustrums ) const;
virtual void renderPoly ( Views view, const Cameras,
Polygon3D *, Polygon3DS, const FrustrumS ) const;
virtual int contains ( const Vector3DS pos ) const;
virtual void update ( Controller *,
float systemTime );
void addPoly ( Polygon3D * poly );
void addObject ( VisualObject * object );
void setFog ( Fog * theFog );
void setSky ( Sky * theSky );
const Arrays getPolys () const {
return polys;
}
const BoundingBoxS getBoundingBox () const {
return boundingBox;
}
static MetaClass classlnstance; protected:
void buildFrustrum ( const Vector3D&, const Polygon3D&,
Frustrum&, Transform3D * ) const;
} ;
Главным методом этого класса является метод render, который осуществляет рендеринг комнаты по заданной камере и области отсечения. При этом после вывода всех граней, видимых внутри данной комнаты, он вызывает метод render для комнат, видимых из данной через ее порталы (с учетом области видимости).
Тогда алгоритм, реализующий данный подход, можно представить при помощи следующего фрагмента псевдокода: та
view.lock () ;
view.apply ( camera )
for p in polys:
if not p.isFrontFacing ( camera.pos ): continue
if not viewFrustrum.contains ( camera.pos ): continue
if p.isPortal ():
visPoly = p.clipBy ( viewFrustrum )
newFrustrum = buildFrustrum ( camera.pos, visPoly )
p.adjacentScene.render ( view, camera, newFrustrum )
view.draw ( p ) view.unlock ()
Вызовы методов lock и apply подготавливают объект view к выводу в него и задают преобразование, соответствующее камере.