![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
#include <queue>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif) class BaseQueue {
public:
virtual void push( void *newItem ) = 0;
};
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif) class e_Object {
public:
// attributes:
float max_displace;
};
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif) class GeoPrim {
public:
virtual void bound() = 0;
virtual bool on_screen() = 0;
virtual bool projectable() = 0;
virtual void project() = 0;
virtual bool on_bucket() = 0;
virtual bool diceable() = 0;
virtual void dice() = 0;
virtual void split( BaseQueue *queue ) = 0;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public:
e_Object *obj;
Bound6f box;
};
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif) class RasterObject {
public:
bool is_grid();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public:
GeoPrim *object; // the geometric primitive
int flags; // the object flags
float zmin; // the minimum z coordinate of the object (used for occlusion culling)
};
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif) class ShadingGrid : public RasterObject {
public:
void shade();
void sample();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public:
float *vertices; // array of vertices
int *bounds; // the bound of the primitive (4 numbers per primitive)
float *sizes; // the size of the primitive (only makes sense for points)
float umin, umax, vmin, vmax; // the parametric range
int udiv, vdiv; // the number of division
int numVertices; // the number of vertices
int flags; // the primitive flags
};
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif) class GeoPrimQueue : public BaseQueue {
public:
// implemented for BaseQueue
void push( void *newItem )
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
gp_queue.push( (GeoPrim *) newItem );
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
GeoPrim *get()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
GeoPrim *gprim = NULL;
if( !gp_queue.empty() )
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
gprim = gp_queue.front();
gp_queue.pop();
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return gprim;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private:
std::queue< GeoPrim * > gp_queue;
};
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
// priority queue
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif) class RasterObjectQueue : public BaseQueue {
public:
RasterObjectQueue( int ss = 100 )
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
stepSize = ss;
maxItems = stepSize;
numItems = 1;
allItems = new RasterObject* [maxItems];
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
~RasterObjectQueue()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
delete [] allItems;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// implemented for BaseQueue
void push( void *newItem )
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
insert( (RasterObject *) newItem );
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void insert( RasterObject *cObject )
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
int i,j;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// expand the buffer
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if (numItems >= maxItems) {
RasterObject **newItems;
maxItems += stepSize;
newItems = new RasterObject* [maxItems+1];
memcpy( newItems, allItems, numItems * sizeof(RasterObject*) );
delete [] allItems;
allItems = newItems;
stepSize *= 2;
}
// insert the item
i = numItems++;
j = i >> 1;
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) while ((i > 1) && (cObject->zmin < allItems[j]->zmin)) {
allItems[i] = allItems[j];
i = j;
j = i >> 1;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
allItems[i] = cObject;
}
RasterObject *get()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
int i = 1, j;
RasterObject *lItem,*cItem;
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if (numItems <= 1) {
cItem = NULL;
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) } else {
cItem = allItems[1];
numItems--;
lItem = allItems[numItems];
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) while (i <= numItems / 2) {
j = 2 * i;
if (j >= numItems) break;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if ((j < (numItems-1)) && (allItems[j]->zmin > allItems[j+1]->zmin))
j++;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (allItems[j]->zmin > lItem->zmin)
break;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
allItems[i] = allItems[j];
i = j;
}
allItems[i] = lItem;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return cItem;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
RasterObject **allItems; // array of the heap
int numItems, maxItems, stepSize; // misc junk
};
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif) class Reyes {
public:
void render();
};
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
void Reyes::render()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif) {
GeoPrimQueue gp_queue;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
GeoPrim *gprim = NULL;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
while( (gprim = gp_queue.get()) != NULL )
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
// bound in camera space
// (including displacement and motion blur)
gprim->bound();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// frustum culling and backface culling
if( gprim->on_screen() )
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
// the bound can be transformed into screen space
if( gprim->projectable() )
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
// transform the bound into screen space
// (including depth of field)
// sort the gprim into buckets which its bound covers
gprim->project();
}
else
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
// too large, divide and conquer
// add back to the queue
gprim->split( &gp_queue );
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
delete gprim;
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
void Bucket::render()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif) {
RasterObjectQueue gp_queue;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
RasterObject *gprim = NULL;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
while( (gprim = gp_queue.get()) != NULL )
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
// bound in camera space
// (including displacement and motion blur)
gprim->bound();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// frustum culling and backface culling
// occlusion culling
// transform the bound into screen space
// (including depth of field)
if( gprim->on_bucket() )
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
// is a grid, draw it
if( gprim->is_grid() )
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
ShadingGrid *grid = (ShadingGrid *) gprim;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// evaluate
// displacement shader
// surface shader
// light shader
// atmosphere shader
grid->shade();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// stitch cracks between micropolygon grids
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// bust into individual micropolygons
// bound each micropolygon
// frustum culling and backface culling
// occlusion culling
// determine which pixels the micropolygons
// cover and stochastic sampling in pixels
grid->sample();
}
else
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
// small enough to dice
if( gprim->diceable() )
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
// dice into grids
gprim->dice();
}
else
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
// too large, divide and conquer
// add back to the queue
gprim->split( &gp_queue );
}
}
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// reconstruct the image portion of this bucket
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
|