Writing REYES



#include 
<queue>

class BaseQueue {
public:
    
virtual void    push( void *newItem ) = 0;
}
;

class e_Object {
public:
    
//    attributes:
    float            max_displace;
}
;

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;

public:
    e_Object        
*obj;
    Bound6f            box;
}
;

class RasterObject {
public:
    
bool    is_grid();

public:
    GeoPrim        
*object;    //    the geometric primitive
    int            flags;        //    the object flags
    float        zmin;        //    the minimum z coordinate of the object (used for occlusion culling)
}
;

class ShadingGrid : public RasterObject {
public:
    
void    shade();
    
void    sample();

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
}
;

class GeoPrimQueue : public BaseQueue {
public:
    
//    implemented for BaseQueue
    void    push( void *newItem )
    
{
        gp_queue.push( (GeoPrim 
*) newItem );
    }


    GeoPrim    
*get()
    
{
        GeoPrim        
*gprim = NULL;
        
        
if!gp_queue.empty() )
        
{
            gprim 
= gp_queue.front();
            gp_queue.pop();
        }


        
return gprim;
    }


private:
    std::queue
< GeoPrim * >    gp_queue;
}
;

//    priority queue

class RasterObjectQueue : public BaseQueue {
public:
    RasterObjectQueue( 
int ss = 100 )
    
{
        stepSize    
=    ss;
        maxItems    
=    stepSize;
        numItems    
=    1;
        allItems    
=    new RasterObject* [maxItems];
    }


    
~RasterObjectQueue()
    
{
        delete [] allItems;
    }


    
//    implemented for BaseQueue
    void    push( void *newItem )
    
{
        insert( (RasterObject 
*) newItem );
    }


    
void    insert( RasterObject *cObject )
    
{
        
int i,j;

        
//    expand the buffer
        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;
        
while ((i > 1&& (cObject->zmin < allItems[j]->zmin)) {
            allItems[i]    
=    allItems[j];
            i            
=    j;
            j            
=    i >> 1;
        }


        allItems[i]        
=    cObject;
    }

                    
    RasterObject    
*get()
    
{
        
int                i = 1, j;
        RasterObject    
*lItem,*cItem;
        
        
if (numItems <= 1{
            cItem    
=    NULL;
        }
 else {
            cItem    
=    allItems[1];
                                    
            numItems
--;
            lItem    
=    allItems[numItems];

            
while (i <= numItems / 2{
                j 
= 2 * i;
                
if (j >= numItems) break;

                
if ((j < (numItems-1)) && (allItems[j]->zmin > allItems[j+1]->zmin))
                    j
++;

                
if (allItems[j]->zmin > lItem->zmin)
                    
break;

                allItems[i]    
=    allItems[j];
                i            
=    j;
            }

            allItems[i]                
=    lItem;
        }


        
return cItem;
    }


    RasterObject            
**allItems;                        //    array of the heap
    int                        numItems, maxItems, stepSize;    //    misc junk
}
;

class Reyes {
public:
    
void    render();
}
;

void    Reyes::render()
{
    GeoPrimQueue        gp_queue;

    GeoPrim                
*gprim = NULL;

    
while( (gprim = gp_queue.get()) != NULL )
    
{
        
//    bound in camera space
        
//    (including displacement and motion blur)
        gprim->bound();

        
//    frustum culling and backface culling
        if( gprim->on_screen() )
        
{
            
//    the bound can be transformed into screen space
            if( gprim->projectable() )
            
{
                
//    transform the bound into screen space
                
//    (including depth of field)
                
//    sort the gprim into buckets which its bound covers
                gprim->project();
            }

            
else
            
{
                
//    too large, divide and conquer
                
//    add back to the queue
                gprim->split( &gp_queue );
            }

        }


        delete gprim;
    }

}


void    Bucket::render()
{
    RasterObjectQueue    gp_queue;

    RasterObject        
*gprim = NULL;

    
while( (gprim = gp_queue.get()) != NULL )
    
{
        
//    bound in camera space
        
//    (including displacement and motion blur)
        gprim->bound();

        
//    frustum culling and backface culling
        
//    occlusion culling
        
//    transform the bound into screen space
        
//    (including depth of field)
        if( gprim->on_bucket() )
        
{
            
//    is a grid, draw it
            if( gprim->is_grid() )
            
{
                ShadingGrid    
*grid = (ShadingGrid *) gprim;

                
//    evaluate
                
//    displacement shader
                
//    surface shader
                
//    light shader
                
//    atmosphere shader
                grid->shade();

                
//    stitch cracks between micropolygon grids

                
//    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
            
{
                
//    small enough to dice
                if( gprim->diceable() )
                
{
                    
//    dice into grids
                    gprim->dice();
                }

                
else
                
{
                    
//    too large, divide and conquer
                    
//    add back to the queue
                    gprim->split( &gp_queue );
                }

            }

        }

    }


    
//    reconstruct the image portion of this bucket
}


原文地址:https://www.cnblogs.com/len3d/p/1197217.html