Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 8641 in orxonox.OLD


Ignore:
Timestamp:
Jun 20, 2006, 5:24:24 PM (18 years ago)
Author:
ponder
Message:

The level four pages are now merged into large buffers. Its not finished, though.

Location:
branches/terrain/src/lib/graphics/importer/terrain
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • branches/terrain/src/lib/graphics/importer/terrain/buffer_broker.h

    r8595 r8641  
    5656                        head = tail = NULL;
    5757                }
    58                
     58                inline int getIBSize() { return ibSize; }
     59                inline int getVBSize() { return vbSize; }               
    5960                inline void acquire( GLuint &_vbName, GLuint &_ibName );
    6061               
     
    7879        pBufferPair bp = head, prev = NULL;
    7980        bool removed = false;
    80        
    8181        while ( bp ) {
    8282
     
    106106inline void BufferBroker::acquire( GLuint &_vbName, GLuint &_ibName )
    107107{
    108 
     108        assert( capacity > lastAcquired );
    109109        int index = capacity-lastAcquired-1;
    110110        _vbName = freeVertexBuffers[index]; _ibName = freeIndexBuffers[index];
  • branches/terrain/src/lib/graphics/importer/terrain/terrain.cc

    r8593 r8641  
    3434        //tex = (Texture*)MANAGER->load( lightmapSource );
    3535        //TODO: Determine layer visibility!     
    36         for ( int i = 0; i < materials.size(); ++i ) {
     36        for ( unsigned int i = 0; i < materials.size(); ++i ) {
    3737               
    3838        }
     
    9292        newPage->calculateErrors();
    9393        return newPage;
     94}
     95
     96void Terrain::addLevelFourPage( int _numVertices, Vertex *_vertices,
     97        int _numIndices, unsigned short *_indices )
     98{
     99        assert( indices ); assert( vertices );
     100        BufferInfo bi = buffers[current];       
     101        if ( ( MAX_VERTICES < _numVertices+bi.numVertices ) ||
     102                ( MAX_INDICES < _numIndices+bi.numIndices+2 ) ) {
     103                //So, we need the next vb and ib. Lets put the old into vram...
     104                glBindBufferARB( GL_ARRAY_BUFFER_ARB, bi.vbIdentifier );
     105                glBufferDataARB( GL_ARRAY_BUFFER_ARB, MAX_VERTICES*sizeof( Vertex ),
     106                        vertices, GL_DYNAMIC_DRAW_ARB );
     107                glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, bi.ibIdentifier );
     108                glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, MAX_INDICES*sizeof( short ),
     109                        indices, GL_DYNAMIC_DRAW_ARB );
     110                //printf( "uploaded %d verts and %d indices\n", bi.numIndices, bi.numVertices );
     111                BufferInfo newInfo;
     112                broker->acquire( newInfo.vbIdentifier, newInfo.ibIdentifier );                 
     113                current++;     
     114                buffers.push_back( newInfo );   
     115                bi = newInfo;
     116        }
     117        //For the vertex data, a simple copy operation is sufficient...
     118        memcpy( &vertices[bi.numVertices], _vertices,
     119                _numVertices*sizeof( Vertex ) );
     120        bi.numVertices+=_numVertices;
     121        //The indices need to be updated with an offset :(
     122        unsigned short *end = _indices+_numIndices;
     123        unsigned short *dst = indices+bi.numIndices;
     124        int offset = bi.numIndices;
     125        if ( bi.numIndices > 0 ) {
     126                indices[bi.numIndices] = indices[bi.numIndices-1];
     127                indices[bi.numIndices+1] = _indices[0]+offset;
     128                dst+=2;
     129                bi.numIndices+=2;
     130        }
     131        for ( unsigned short *i = _indices; i < end; ++i ) {
     132                *indices = *i+offset;
     133        }
     134        bi.numIndices+=_numIndices;
     135        buffers[current] = bi;
    94136}
    95137
     
    154196        page = activePages;
    155197        bool dirty;
     198        current = 0;
     199        BufferInfo bi;
     200        broker->acquire( bi.vbIdentifier, bi.ibIdentifier );
     201        buffers.push_back( bi );
    156202        do {
    157203                dirty = false;
     
    174220                                wantedBottom = neighbor->getWantedLOD();                       
    175221               
    176                         minLOD = std::min( std::min( wantedBottom, wantedTop ), std::min( wantedLeft, wantedRight ) ); 
     222                        minLOD = std::min( std::min( wantedBottom, wantedTop ),
     223                                std::min( wantedLeft, wantedRight ) ); 
    177224                        if ( minLOD < page->getWantedLOD()-1 ) {
    178225                                page->setWantedLOD( minLOD+1 );
     
    188235                page = page->getNext();
    189236        }
    190        
     237        //Finish the last buffer
     238        if ( buffers[current].numIndices != 0 ) {
     239                BufferInfo bi = buffers[current];       
     240                glBindBufferARB( GL_ARRAY_BUFFER_ARB,
     241                        bi.vbIdentifier );
     242                glBufferDataARB( GL_ARRAY_BUFFER_ARB, MAX_VERTICES*sizeof( Vertex ),
     243                        vertices, GL_DYNAMIC_DRAW_ARB );
     244                glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB,
     245                        bi.ibIdentifier );
     246                glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, MAX_INDICES*sizeof( short ),
     247                        indices, GL_DYNAMIC_DRAW_ARB );
     248        }
    191249        s = 500.0f;
    192         for ( int i = 0; i < materials.size(); ++i ) {
     250        for ( unsigned int i = 0; i < materials.size(); ++i ) {
    193251                page = activePages;     
    194252               
     
    202260                glLoadIdentity();
    203261                glScalef( s, s, s );
    204                
     262
    205263                glClientActiveTextureARB( GL_TEXTURE0_ARB );
    206264                glActiveTextureARB( GL_TEXTURE0_ARB );
    207265                glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );                         
    208266                glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
     267                for ( unsigned j = 0; j < buffers.size(); ++j ) {
     268                        BufferInfo bi = buffers[j];
     269                        glBindBufferARB( GL_ARRAY_BUFFER_ARB, bi.vbIdentifier );
     270                        glClientActiveTextureARB( GL_TEXTURE0_ARB );
     271                        glInterleavedArrays( GL_T2F_V3F, 0, NULL );
     272
     273                        glClientActiveTextureARB( GL_TEXTURE1_ARB );
     274                        glInterleavedArrays( GL_T2F_V3F, 0, NULL );
     275
     276                        glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB,
     277                                bi.ibIdentifier );     
     278
     279                        glDrawElements( GL_TRIANGLE_STRIP, bi.numIndices,
     280                                                        GL_UNSIGNED_SHORT, NULL );
     281                }
    209282                while ( page ) {
    210                         //Draw the page. TODO: It would be nice if all the pages with an LOD of 4 could be merged
    211                         //in one index buffer. This would give us a speed boost for sure...
    212283                        if ( page->hasMaterial( i ) )
    213284                                page->draw();
     
    219290                //printf( "culled %f%% terrain pages away\n",  percentage );
    220291        }
     292       
     293        //Get rid of the buffers
     294       
     295        for ( unsigned int i = 0; i < buffers.size(); ++i )
     296                broker->release( buffers[i].vbIdentifier, buffers[i].ibIdentifier );
     297        buffers.clear();
     298               
    221299        glClientActiveTextureARB( GL_TEXTURE1_ARB );   
    222300        glDisableClientState( GL_VERTEX_ARRAY );
  • branches/terrain/src/lib/graphics/importer/terrain/terrain.h

    r8595 r8641  
    3333
    3434typedef struct {
    35         int             width;
    36         int             height;
    37         int                     pitch;
    38         UByte           *data;
     35        int                     width;
     36        int                     height;
     37        int                             pitch;
     38        UByte                   *data;
    3939} Heightfield, *pHeightfield;
     40
     41struct BufferInfo {
     42       
     43        unsigned int    vbIdentifier,
     44                                        ibIdentifier,
     45                                        numIndices,
     46                                        numVertices;
     47       
     48        BufferInfo( unsigned int _vb, unsigned int _ib,
     49                unsigned int _numV, unsigned int _numI )
     50        {
     51                vbIdentifier = _vb; ibIdentifier = _ib;
     52                numIndices = _numI; numVertices =_numV;
     53               
     54        }
     55       
     56        BufferInfo()
     57        {
     58                vbIdentifier = ibIdentifier = numIndices = numVertices = 0;
     59        }
     60};
     61
    4062
    4163class Terrain;
     
    4769class Terrain {
    4870        public:
    49        
     71                const static int PAGE_SIZE                      = 17;
     72                const static int MAX_VERTICES           = PAGE_SIZE*PAGE_SIZE;
     73                const static int MAX_INDICES            = 3*MAX_VERTICES/*2*( PAGE_SIZE*PAGE_SIZE - PAGE_SIZE ) - 2*/;
    5074                /**
    5175                 * The amount of geometry rendered is largely depending on this constant. So chose a
     
    7599                void getAltitude( Triple& _alt, Triple& _normal );
    76100               
     101                //What a bad name: Need to rename that :(
     102                void addLevelFourPage( int _numVertices, Vertex *_vertices,
     103                        int _numIndices, unsigned short *_indices );
    77104                void showPages( int _x0, int _z0, int _width, int _height );
    78105                                       
     
    86113                        frustum = new Frustum();
    87114                        activatedCount = deactivatedCount = 0;
    88 #ifdef USE_VBO
    89                         broker = new BufferBroker( 400, pageSize*pageSize*sizeof( Vertex ),
    90                                 pageSize*pageSize*sizeof( short )*3 );
     115                        vertices = new Vertex[MAX_VERTICES];
     116                        indices = new unsigned short[MAX_INDICES];
     117#ifdef USE_VBO
     118                        broker = new BufferBroker( 200, MAX_VERTICES*sizeof( Vertex ),
     119                                MAX_INDICES*sizeof( short ) );
    91120#endif                 
    92121                }
     
    181210               
    182211#ifdef USE_VBO
    183                 pBufferBroker                   broker;
     212                pBufferBroker                           broker;
    184213#endif
    185                 pTerrainQuad                    root;           // The quad-tree root node.
    186                 pTerrainPage                    *pages;         // the references to all pages
    187                 std::string                             heightmapSource;
    188                 std::string                             lightmapSource;
    189                 Heightfield                             heightfield;
    190                 Triple                                  scale;
    191                 int                                     pagesX,
    192                                                                 pagesZ;
    193                 int                                             pageSize;       
    194                 int                                             cullCount;
    195                
    196                 int                                             activatedCount,
    197                                                                 deactivatedCount; // For debugging and statistics
    198                 Texture                                 *tex;
    199                 Triple                                  cameraPosition;
    200                 pFrustum                                frustum;
    201                 pTerrainPage                    activePages;
    202                 std::vector<Material*>  materials;
     214                pTerrainQuad                            root;           // The quad-tree root node.
     215                pTerrainPage                            *pages;         // the references to all pages
     216                std::string                                     heightmapSource;
     217                std::string                                     lightmapSource;
     218                Heightfield                                     heightfield;
     219                Triple                                          scale;
     220                int                                             pagesX,
     221                                                                        pagesZ;
     222                int                                                     pageSize;       
     223                int                                                     cullCount;
     224               
     225                int                                                     activatedCount,
     226                                                                        deactivatedCount; // For debugging and statistics
     227                                                               
     228                //The next five members are for the level 4 pages.                                             
     229                Vertex                                          *vertices;                                             
     230                unsigned short                          *indices;
     231                int                                                     current;
     232                                                                       
     233                std::vector<BufferInfo>         buffers;                       
     234                       
     235                //Texture                                       *tex;
     236                Triple                                          cameraPosition;
     237                pFrustum                                        frustum;
     238                pTerrainPage                            activePages;
     239                std::vector<Material*>          materials;
    203240};
    204241
  • branches/terrain/src/lib/graphics/importer/terrain/terrain_page.cc

    r8593 r8641  
    3333        numVertices = numIndices = 0;
    3434        errors = new LODError[TerrainPage::MAX_LODS];
    35         vertices = NULL; indices = NULL;
     35        vertices = NULL; indices = NULL; 
    3636        position = Triple( scale.x*_xOffset, 0.0f, scale.z*_zOffset );
    3737        isVisible = false;
     
    4141        currentLOD = -1;
    4242        forceTesselation = true;
     43        vbIdentifier = 0; ibIdentifier = 0;
    4344}
    4445
     
    259260        }       
    260261        currentLOD = wantedLOD;
     262        //Check if the page is a level four page. If yes, copy the vertex and index data into
     263        //
     264        if ( currentLOD == TerrainPage::MAX_LODS-1 ) {
     265                owner->addLevelFourPage( numVertices, vertices,
     266                        numIndices, indices );
     267        }
    261268        forceTesselation = false;
    262269}
    263270
    264 void TerrainPage::tesselateLevelFourPatch( bool _adapt[] )
    265 {
     271void TerrainPage::tesselateLevelFourPage( bool _adapt[] )
     272{
     273        assert( indices ); assert( vertices );
     274        numIndices = numVertices = 0;
    266275        const int       halfStride = 8, stride = 16;
    267276       
     
    434443                        break;
    435444        }
     445        assert( numVertices > 3 );
     446
     447        assert( numIndices % 2 == 0 );
    436448}
    437449
     
    440452{
    441453
    442         int count = owner->getPageSize()*owner->getPageSize(); 
    443 
    444454        memset( indexHash, 0xffff,
    445                         sizeof(unsigned short)*count );
     455                        sizeof(unsigned short)*Terrain::MAX_VERTICES );
    446456       
    447457        numVertices = 0; numIndices = 0;
     
    454464        assert( isVisible );
    455465#ifdef USE_VBO
    456        
    457         glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbIdentifier );
    458        
    459         // The call to glBufferDataARB with a null argument for data is to tell the GPU, that the
    460         // old data is invalid. Then calling call glMapBuffer() tells the driver that the previous
    461         // data aren’t valid. As a consequence, if the GPU is still working on them, there won’t
    462         // be a conflict because we invalidated these data. The function glMapBuffer() returns a
    463         // new pointer that we can use while the GPU is working on the previous set of data..
    464        
    465         glBufferDataARB( GL_ARRAY_BUFFER_ARB, count*sizeof( Vertex ), NULL, GL_DYNAMIC_DRAW_ARB );
    466        
    467         vertices = (Vertex*)glMapBufferARB( GL_ARRAY_BUFFER_ARB,
    468                 GL_WRITE_ONLY_ARB );
    469        
    470         glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, ibIdentifier );
    471        
    472         glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB,
    473                 count*3*sizeof( short ), NULL, GL_DYNAMIC_DRAW_ARB );   
    474                
    475         indices = (unsigned short*)glMapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB,
    476                 GL_WRITE_ONLY_ARB );
    477        
    478         assert( indices );
    479         assert( vertices );
    480        
     466        if ( _lod == TerrainPage::MAX_LODS-1 ) {
     467                if ( vbIdentifier && ibIdentifier ) {
     468                        owner->getBufferBroker()->release( vbIdentifier, ibIdentifier );
     469                        vbIdentifier = ibIdentifier = 0;
     470                }
     471                if ( !vertices )
     472                        vertices =  new Vertex[8];
     473                if ( !indices )
     474                        indices = new unsigned short[8];
     475        }
     476        else {
     477                if ( !vbIdentifier && !ibIdentifier ) {
     478                        owner->getBufferBroker()->acquire( vbIdentifier, ibIdentifier );
     479                        if ( vertices )
     480                                delete[] vertices;
     481                        if ( indices )
     482                                delete[] indices;
     483                        vertices = NULL; indices = NULL;       
     484                }
     485                assert( vbIdentifier ); assert( ibIdentifier );
     486                glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbIdentifier );
     487
     488                // The call to glBufferDataARB with a null argument for data is to make things faster.
     489                // Then calling call glMapBuffer() tells the driver that the previous
     490                // data aren’t valid. As a consequence, if the GPU is still working on them, there won’t
     491                // be a conflict because we invalidated these data. The function glMapBuffer() returns a
     492                // new pointer that we can use while the GPU is working on the previous set of data..
     493
     494                glBufferDataARB( GL_ARRAY_BUFFER_ARB, Terrain::MAX_VERTICES*sizeof( Vertex ),
     495                        NULL, GL_DYNAMIC_DRAW_ARB );
     496
     497                vertices = (Vertex*)glMapBufferARB( GL_ARRAY_BUFFER_ARB,
     498                        GL_WRITE_ONLY_ARB );
     499
     500                glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, ibIdentifier );
     501
     502                glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB,
     503                        Terrain::MAX_INDICES*sizeof( short ), NULL, GL_DYNAMIC_DRAW_ARB );     
     504
     505                indices = (unsigned short*)glMapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB,
     506                        GL_WRITE_ONLY_ARB );
     507
     508        }       
     509
    481510#endif 
     511
     512        assert( indices );      assert( vertices );
    482513        if ( _lod == TerrainPage::MAX_LODS-1 ) {
    483                 tesselateLevelFourPatch( adapt );
     514                tesselateLevelFourPage( adapt );
    484515                return;
    485516        }
     
    508539       
    509540#ifdef USE_VBO
    510         glUnmapBufferARB( GL_ARRAY_BUFFER_ARB );
    511         glUnmapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB );
     541        if ( vbIdentifier && ibIdentifier ) {
     542                glUnmapBufferARB( GL_ARRAY_BUFFER_ARB );
     543                indices = NULL;
     544                glUnmapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB );
     545                vertices = NULL;
     546        }       
    512547#endif
    513548
     
    517552void TerrainPage::show( )
    518553{
    519         int count = owner->getPageSize()*owner->getPageSize();
    520554       
    521555#ifdef USE_VBO 
    522         owner->getBufferBroker()->acquire( vbIdentifier, ibIdentifier );
     556        //This is done later on...
     557        //owner->getBufferBroker()->acquire( vbIdentifier, ibIdentifier );
    523558        vertices = NULL;
    524559        indices = NULL;
    525560#else
    526         vertices = new Vertex[count];
    527         // Not the economical way, but we just want to have space for all indices.
    528         indices = new unsigned short[count*3];
     561        vertices = new Vertex[Terrain::MAX_VERTICES];
     562        indices = new unsigned short[Terrain::MAX_INDICES];
    529563#endif 
    530 
    531         indexHash = new unsigned short[count]; 
     564        vbIdentifier = 0; ibIdentifier = 0;
     565        indexHash = new unsigned short[Terrain::MAX_VERTICES]; 
    532566        forceTesselation = true;
    533567        activate();
    534568        active = true;
    535        
    536569}
    537570
     
    539572{
    540573#ifdef USE_VBO
    541         owner->getBufferBroker()->release( vbIdentifier, ibIdentifier );
    542 #else   
     574        owner->getBufferBroker()->release( vbIdentifier, ibIdentifier );       
     575#endif
    543576        if ( vertices ) {
    544577                delete[] vertices;
     
    550583                numIndices = 0;
    551584        }
    552 #endif
    553585        deactivate();
    554586}
     
    582614        glPopMatrix();
    583615}
    584 
     616//TODO: put all the pages that have a coarses tesselation level than 4 into a
     617//              separate list!
    585618void TerrainPage::draw( )
    586619{
     
    588621        assert( !glIsEnabled( GL_NORMAL_ARRAY ) );
    589622       
     623        if ( currentLOD == TerrainPage::MAX_LODS-1 )
     624                return;
     625               
    590626        assert( isVisible ); assert( numIndices > 0 );
    591627        assert( active );
     
    625661}
    626662
    627 short TerrainPage::getIndex( int _x, int _z )
     663unsigned short TerrainPage::getIndex( int _x, int _z )
    628664{
    629665        unsigned short index = _z*owner->getPageSize()+_x;
  • branches/terrain/src/lib/graphics/importer/terrain/terrain_page.h

    r8593 r8641  
    4343        public:
    4444                enum { TP_LEFT = 0, TP_RIGHT = 1, TP_BOTTOM = 2, TP_TOP = 3 };
    45                 const static int MAX_LODS = 5;
     45                const static int MAX_LODS                       = 5;
    4646                /**
    4747                 * Creates a new terrain page with its lower left corner set
     
    263263                 * created before, this method does that for you.
    264264                 */                     
    265                 short getIndex( int _x, int _z );
    266                 void tesselateLevelFourPatch( bool _adapt[] );
     265                unsigned short getIndex( int _x, int _z );
     266                void tesselateLevelFourPage( bool _adapt[] );
    267267           /**
    268268                * Generates the tesselation for the given level of detail.
Note: See TracChangeset for help on using the changeset viewer.