Changeset 9415 in orxonox.OLD for branches/terrain/src/lib/graphics/importer/terrain/terrain_page.cc
- Timestamp:
- Jul 24, 2006, 12:59:44 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/terrain/src/lib/graphics/importer/terrain/terrain_page.cc
r9414 r9415 1 1 /* 2 2 orxonox - the future of 3D-vertical-scrollers 3 3 4 4 Copyright (C) 2006 orx 5 5 6 6 This program is free software; you can redistribute it and/or modify 7 7 it under the terms of the GNU General Public License as published by 8 8 the Free Software Foundation; either version 2, or (at your option) 9 9 any later version. 10 10 11 11 ### File Specific: 12 12 main-programmer: Marco Biasini 13 13 14 14 */ 15 15 #include "terrain_page.h" … … 26 26 }\ 27 27 while ( 0 ) 28 28 29 29 TerrainPage::~TerrainPage( ) 30 { 30 { 31 31 SAVE_DELETE_ARRAY( indices ); 32 32 SAVE_DELETE_ARRAY( vertices ); 33 SAVE_DELETE_ARRAY( indexHash ); 34 SAVE_DELETE_ARRAY( errors ); 33 SAVE_DELETE_ARRAY( indexHash ); 34 SAVE_DELETE_ARRAY( errors ); 35 35 } 36 36 … … 41 41 numVertices = numIndices = 0; 42 42 errors = new LODError[TerrainPage::MAX_LODS]; 43 vertices = NULL; indices = NULL; 43 vertices = NULL; indices = NULL; 44 44 left = top = bottom = right = NULL; 45 45 for ( int i = 0; i < 8; ++i ) 46 layerVisibility[i] = LV_NO; 47 48 position = Vector( scale.x*_xOffset, 46 layerVisibility[i] = LV_NO; 47 48 position = Vector( scale.x*_xOffset, 49 49 0.0f, scale.z*_zOffset ); 50 50 isVisible = false; 51 51 next = NULL; 52 52 active = false; 53 previous = NULL; 53 previous = NULL; 54 54 currentLOD = -1; wantedLOD = -1; 55 55 hasfull = false; … … 58 58 } 59 59 60 void TerrainPage::tesselateRow( int _z, int _xStride, int _zStride, 60 void TerrainPage::tesselateRow( int _z, int _xStride, int _zStride, 61 61 bool _adaptLeft, bool _adaptRight ) 62 62 { 63 64 int xStart = 0, xEnd = owner->getPageSize(); 63 64 int xStart = 0, xEnd = owner->getPageSize(); 65 65 int halfStride = _zStride >> 1; 66 66 assert( _xStride > 0 ); assert( _zStride > 0 ); … … 70 70 } 71 71 if ( _adaptLeft ) { 72 assert( halfStride > 0 ); 72 assert( halfStride > 0 ); 73 73 addIndex( getIndex( 0, _z ) ); 74 74 addIndex( getIndex( 0, _z+halfStride ) ); … … 79 79 xStart = _xStride; 80 80 } 81 81 82 82 if ( _adaptRight ) 83 83 xEnd-=_xStride; 84 84 85 85 for ( int x = xStart; x < xEnd; x+=_xStride ) { 86 86 addIndex( getIndex( x, _z) ); 87 87 addIndex( getIndex( x, _z+_zStride ) ); 88 88 } 89 89 90 90 int w = owner->getPageSize()-1; 91 91 92 92 if ( _adaptRight ) { 93 assert( halfStride > 0 ); 93 assert( halfStride > 0 ); 94 94 addIndex( getIndex( xEnd-1, _z ) ); 95 95 addAgain(); … … 106 106 { 107 107 _adapt[0] = _adapt[1] = _adapt[2] = _adapt[3] = false; 108 108 109 109 if ( left && left->isActive() ) { 110 110 _adapt[TP_LEFT] = ( wantedLOD - left->getWantedLOD() ) > 0; 111 assert( std::abs( wantedLOD - left->wantedLOD ) < 2 ); 112 } 111 assert( std::abs( wantedLOD - left->wantedLOD ) < 2 ); 112 } 113 113 if ( right && right->isActive() ) { 114 114 _adapt[TP_RIGHT] = ( wantedLOD - right->getWantedLOD() ) > 0; 115 assert( std::abs( wantedLOD - right->wantedLOD ) < 2 ); 116 } 117 115 assert( std::abs( wantedLOD - right->wantedLOD ) < 2 ); 116 } 117 118 118 if ( top && top->isActive() ) { 119 _adapt[TP_TOP] = ( wantedLOD - top->getWantedLOD() ) > 0; 120 assert( std::abs( wantedLOD - top->wantedLOD ) < 2 ); 121 } 119 _adapt[TP_TOP] = ( wantedLOD - top->getWantedLOD() ) > 0; 120 assert( std::abs( wantedLOD - top->wantedLOD ) < 2 ); 121 } 122 122 if ( bottom && bottom->isActive() ) { 123 _adapt[TP_BOTTOM] = ( wantedLOD - bottom->getWantedLOD() ) > 0; 123 _adapt[TP_BOTTOM] = ( wantedLOD - bottom->getWantedLOD() ) > 0; 124 124 assert( std::abs( wantedLOD - bottom->wantedLOD ) < 2 ); 125 } 125 } 126 126 } 127 127 … … 130 130 wantedLOD = -1; 131 131 Vector cam( owner->getCameraPosition() ); 132 132 133 133 for ( int i = TerrainPage::MAX_LODS-1; i >= 0; --i ) { 134 134 Vector distance( cam.x-errors[i].correct.x, 135 135 cam.y-errors[i].correct.y, 136 136 cam.z-errors[i].correct.z ); 137 137 138 138 float d = distance.len(); 139 139 140 140 float err = errors[i].diff / d ; 141 141 142 142 if ( err*scale.y < owner->getDetail() ) { 143 143 wantedLOD = i; 144 144 break; 145 } 145 } 146 146 } 147 147 if ( wantedLOD < 0 ) { 148 148 wantedLOD = TerrainPage::MAX_LODS-1; 149 } 149 } 150 150 return wantedLOD; 151 151 } … … 153 153 void TerrainPage::activate() 154 154 { 155 155 156 156 pTerrainPage list = owner->getActiveList(); 157 157 next = list; … … 164 164 { 165 165 pTerrainPage list = owner->getActiveList(); 166 166 167 167 if ( previous ) { 168 168 previous->next = next; … … 175 175 next = NULL; 176 176 previous = NULL; 177 177 178 178 } 179 179 … … 186 186 { 187 187 int stride = 1 << _lod, x0, y0, xi, yi; 188 // Altough these four nested loops look very scary, they're not 189 // that bad and require only about O(n^2). 188 // Altough these four nested loops look very scary, they're not 189 // that bad and require only about O(n^2). 190 190 for( y0 = 0 ; y0 < size-stride; y0 += stride ) { 191 191 for( x0 = 0; x0 < size-stride; x0 += stride ) { … … 197 197 float fx0 = ( float )xi/( float )stride, fx1 = 1.0f-fx0, 198 198 fy0 = ( float )yi/( float )stride, fy1 = 1.0f-fy0; 199 199 200 200 float height00 = getAltitude( x0, y0 ), 201 201 height10 = getAltitude( x0+stride,y0 ), 202 202 height01 = getAltitude( x0,y0+stride ), 203 203 height11 = getAltitude( x0+stride, y0+stride ); 204 204 205 205 float paintHeight = fx1*fy1 * height00 + 206 206 fx0*fy1 * height10 + … … 208 208 fx0*fy0 * height11, 209 209 correctHeight = getAltitude( x, y ); 210 210 211 211 float er = ( float )fabs( correctHeight - paintHeight ); 212 212 213 213 numErrors++; 214 214 sumError += er; … … 229 229 int size = owner->getPageSize(); 230 230 float alt = 0.0f; 231 232 Vector min( xOffset*scale.x ,0.0f, zOffset*scale.z ), 231 232 Vector min( xOffset*scale.x ,0.0f, zOffset*scale.z ), 233 233 max( (xOffset+1)*scale.x, 0.0f, (zOffset+1)*scale.z); 234 234 235 235 min.y = max.y = getAltitude( 0, 0 ); 236 236 for ( int x = 0; x < size; ++x ) { … … 248 248 assert( _x >= 0 && _x < 17 ); 249 249 assert( _z >= 0 && _z < 17 ); 250 return position.y+scale.y*owner->getAltitude( 251 _x+(owner->getPageSize()-1)*xOffset, 250 return position.y+scale.y*owner->getAltitude( 251 _x+(owner->getPageSize()-1)*xOffset, 252 252 _z+(owner->getPageSize()-1)*zOffset ); 253 253 } … … 255 255 bool TerrainPage::needsRetesselation() 256 256 { 257 257 258 258 bool leftChanged = ( left && left->isActive() ) && 259 259 ( left->wantedLOD != left->currentLOD ), 260 rightChanged = ( right && right->isActive() ) && 260 rightChanged = ( right && right->isActive() ) && 261 261 ( right->wantedLOD != right->currentLOD ), 262 topChanged = ( top && top->isActive() ) && 262 topChanged = ( top && top->isActive() ) && 263 263 ( top->wantedLOD != currentLOD ), 264 bottomChanged = ( bottom && bottom->isActive() ) && 264 bottomChanged = ( bottom && bottom->isActive() ) && 265 265 ( bottom->wantedLOD != bottom->currentLOD ), 266 266 iChanged = wantedLOD != currentLOD; 267 268 return ( leftChanged || rightChanged || topChanged || bottomChanged || 267 268 return ( leftChanged || rightChanged || topChanged || bottomChanged || 269 269 forceTesselation || iChanged ); 270 270 } … … 275 275 if ( needsRetesselation() ) { 276 276 tesselate( wantedLOD ); 277 } 277 } 278 278 currentLOD = wantedLOD; 279 280 //Check if the page is a level four page. If yes, copy the vertex and index data into 279 280 //Check if the page is a level four page. If yes, copy the vertex and index data into 281 281 //the shared level four page buffers. 282 282 if ( currentLOD == TerrainPage::MAX_LODS-1 ) { 283 owner->addLevelFourPage( numVertices, vertices, 283 owner->addLevelFourPage( numVertices, vertices, 284 284 numIndices, indices ); 285 285 } … … 287 287 } 288 288 289 void TerrainPage::tesselateTopRow( int _z, int _stride, 289 void TerrainPage::tesselateTopRow( int _z, int _stride, 290 290 bool _adaptLeft, bool _adaptRight ) 291 291 { … … 293 293 int xStart = 0, xEnd= owner->getPageSize()-1; 294 294 int size = xEnd; 295 int z = xEnd-_stride ; 295 int z = xEnd-_stride ; 296 296 addAgain(); 297 297 addIndex( getIndex( 0, z ) ); … … 331 331 332 332 } 333 void TerrainPage::tesselateBottomRow( int _z, int _stride, 333 void TerrainPage::tesselateBottomRow( int _z, int _stride, 334 334 bool _adaptLeft, bool _adaptRight ) 335 335 { … … 380 380 numIndices = numVertices = 0; 381 381 const int halfStride = 8, stride = 16; 382 382 383 383 enum { ADAPT_L = 1, ADAPT_R = 2, ADAPT_B = 4, ADAPT_T = 8, 384 ADAPT_LR = 3, ADAPT_LB = 5, ADAPT_LT = 9, ADAPT_RB = 6, 385 ADAPT_RT = 10, ADAPT_BT = 12, ADAPT_LRB = 7, ADAPT_LBT = 13, ADAPT_LRT = 11, 384 ADAPT_LR = 3, ADAPT_LB = 5, ADAPT_LT = 9, ADAPT_RB = 6, 385 ADAPT_RT = 10, ADAPT_BT = 12, ADAPT_LRB = 7, ADAPT_LBT = 13, ADAPT_LRT = 11, 386 386 ADAPT_RBT = 14, ADAPT_LRBT = 15, ADAPT_NONE = 0 }; 387 388 int code = ( _adapt[TP_LEFT] ? ADAPT_L : 0 ) | 389 ( _adapt[TP_RIGHT] ? ADAPT_R : 0 ) | 390 ( _adapt[TP_BOTTOM] ? ADAPT_B : 0 ) | 387 388 int code = ( _adapt[TP_LEFT] ? ADAPT_L : 0 ) | 389 ( _adapt[TP_RIGHT] ? ADAPT_R : 0 ) | 390 ( _adapt[TP_BOTTOM] ? ADAPT_B : 0 ) | 391 391 ( _adapt[TP_TOP] ? ADAPT_T : 0 ); 392 392 switch( code ) { … … 397 397 addIndex( getIndex( stride, stride ) ); 398 398 break; 399 399 400 400 case ADAPT_L: 401 401 addIndex( getIndex( 0, 0 ) ); … … 406 406 addAgain( ); 407 407 break; 408 408 409 409 case ADAPT_R: 410 410 addIndex( getIndex( stride, stride ) ); … … 556 556 { 557 557 558 memset( indexHash, 0xffff, 558 memset( indexHash, 0xffff, 559 559 sizeof(unsigned short)*Terrain::MAX_VERTICES ); 560 560 561 561 numVertices = 0; numIndices = 0; 562 562 563 563 //Calculate the pace, based on the lod. 564 564 int stride = 1 << _lod; 565 565 566 566 bool adapt[4]; 567 567 determineBorderAdaption( adapt ); … … 573 573 vbIdentifier = ibIdentifier = 0; 574 574 } 575 if ( !vertices ) 576 vertices = new Vertex[8]; 575 if ( !vertices ) 576 vertices = new Vertex[8]; 577 577 if ( !indices ) 578 578 indices = new unsigned short[8]; … … 585 585 if ( indices ) 586 586 delete[] indices; 587 vertices = NULL; indices = NULL; 587 vertices = NULL; indices = NULL; 588 588 } 589 589 assert( vbIdentifier ); assert( ibIdentifier ); … … 591 591 592 592 // The call to glBufferDataARB with a null argument for data is to make things faster. 593 // Then calling call glMapBuffer() tells the driver that the previous 594 // data aren’t valid. As a consequence, if the GPU is still working on them, there won’t 595 // be a conflict because we invalidated these data. The function glMapBuffer() returns a 596 // new pointer that we can use while the GPU is working on the previous set of data.. 597 598 glBufferDataARB( GL_ARRAY_BUFFER_ARB, Terrain::MAX_VERTICES*sizeof( Vertex ), 593 // Then calling call glMapBuffer() tells the driver that the previous 594 // data aren’t valid. As a consequence, if the GPU is still working on them, there won’t 595 // be a conflict because we invalidated these data. The function glMapBuffer() returns a 596 // new pointer that we can use while the GPU is working on the previous set of data.. 597 598 glBufferDataARB( GL_ARRAY_BUFFER_ARB, Terrain::MAX_VERTICES*sizeof( Vertex ), 599 599 NULL, GL_DYNAMIC_DRAW_ARB ); 600 600 601 vertices = (Vertex*)glMapBufferARB( GL_ARRAY_BUFFER_ARB, 601 vertices = (Vertex*)glMapBufferARB( GL_ARRAY_BUFFER_ARB, 602 602 GL_WRITE_ONLY_ARB ); 603 603 604 604 glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, ibIdentifier ); 605 605 606 glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 607 Terrain::MAX_INDICES*sizeof( short ), NULL, GL_DYNAMIC_DRAW_ARB ); 608 609 indices = (unsigned short*)glMapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 606 glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 607 Terrain::MAX_INDICES*sizeof( short ), NULL, GL_DYNAMIC_DRAW_ARB ); 608 609 indices = (unsigned short*)glMapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 610 610 GL_WRITE_ONLY_ARB ); 611 611 612 } 613 614 #endif 612 } 613 614 #endif 615 615 616 616 assert( indices ); assert( vertices ); … … 619 619 return; 620 620 } 621 621 622 622 int zStart = 0, zEnd = owner->getPageSize()-stride; 623 623 624 624 if ( adapt[TP_BOTTOM] ) { 625 625 tesselateBottomRow( 0, stride, adapt[TP_LEFT], adapt[TP_RIGHT] ); 626 626 zStart+= stride; 627 627 } 628 628 629 629 if ( adapt[TP_TOP] ) 630 630 zEnd-= stride; 631 631 632 632 for ( int z = zStart; z < zEnd; z+=stride ) 633 633 tesselateRow( z, stride, stride, adapt[TP_LEFT], adapt[TP_RIGHT] ); 634 634 635 635 636 636 if ( adapt[TP_TOP] ) { 637 tesselateTopRow( owner->getPageSize()-stride-1, 637 tesselateTopRow( owner->getPageSize()-stride-1, 638 638 stride, adapt[TP_LEFT], adapt[TP_RIGHT] ); 639 639 } 640 640 641 641 #ifdef USE_VBO 642 642 if ( vbIdentifier && ibIdentifier ) { … … 645 645 glUnmapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB ); 646 646 vertices = NULL; 647 } 647 } 648 648 #endif 649 649 … … 653 653 void TerrainPage::show( ) 654 654 { 655 656 #ifdef USE_VBO 655 656 #ifdef USE_VBO 657 657 //This is done later on... 658 658 //owner->getBufferBroker()->acquire( vbIdentifier, ibIdentifier ); … … 662 662 vertices = new Vertex[Terrain::MAX_VERTICES]; 663 663 indices = new unsigned short[Terrain::MAX_INDICES]; 664 #endif 664 #endif 665 665 vbIdentifier = 0; ibIdentifier = 0; 666 indexHash = new unsigned short[Terrain::MAX_VERTICES]; 666 indexHash = new unsigned short[Terrain::MAX_VERTICES]; 667 667 forceTesselation = true; 668 668 activate(); … … 673 673 { 674 674 #ifdef USE_VBO 675 owner->getBufferBroker()->release( vbIdentifier, ibIdentifier ); 675 owner->getBufferBroker()->release( vbIdentifier, ibIdentifier ); 676 676 #endif 677 677 SAVE_DELETE_ARRAY( vertices ); … … 692 692 glVertex3f( bounds.x, bounds.y, 0.0f ); 693 693 glVertex3f( 0.0f, bounds.y, 0.0f ); 694 694 695 695 glVertex3f( 0.0f, 0.0f, bounds.z ); 696 696 glVertex3f( bounds.x, 0.0f, bounds.z ); 697 697 glVertex3f( bounds.x, bounds.y, bounds.z ); 698 glVertex3f( 0.0f, bounds.y, bounds.z ); 699 698 glVertex3f( 0.0f, bounds.y, bounds.z ); 699 700 700 glVertex3f( 0.0f, 0.0f, 0.0 ); 701 701 glVertex3f( 0.0, 0.0f, bounds.z ); 702 702 glVertex3f( 0.0f, bounds.y, bounds.z ); 703 glVertex3f( 0.0f, bounds.y, 0.0f ); 704 703 glVertex3f( 0.0f, bounds.y, 0.0f ); 704 705 705 glVertex3f( bounds.x, 0.0f, 0.0 ); 706 706 glVertex3f( bounds.x, 0.0f, bounds.z ); 707 707 glVertex3f( bounds.x, bounds.y, bounds.z ); 708 glVertex3f( bounds.x, bounds.y, 0.0f ); 708 glVertex3f( bounds.x, bounds.y, 0.0f ); 709 709 glEnd(); 710 710 glPopMatrix(); … … 716 716 assert( glIsEnabled( GL_VERTEX_ARRAY ) ); 717 717 assert( !glIsEnabled( GL_NORMAL_ARRAY ) ); 718 718 719 719 if ( currentLOD == TerrainPage::MAX_LODS-1 ) 720 720 return; 721 721 722 722 assert( isVisible ); assert( numIndices > 0 ); 723 723 active = false; 724 CHECK_GL_ERROR( "1" ); 724 CHECK_GL_ERROR( "1" ); 725 725 #ifdef USE_VBO 726 726 727 727 glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbIdentifier ); 728 728 glClientActiveTextureARB( GL_TEXTURE0_ARB ); 729 729 glInterleavedArrays( GL_T2F_V3F, 0, NULL ); 730 730 731 731 glClientActiveTextureARB( GL_TEXTURE1_ARB ); 732 732 glInterleavedArrays( GL_T2F_V3F, 0, NULL ); 733 734 glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, ibIdentifier ); 735 736 glDrawElements( GL_TRIANGLE_STRIP, numIndices, 737 GL_UNSIGNED_SHORT, NULL ); 738 #else 733 734 glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, ibIdentifier ); 735 736 glDrawElements( GL_TRIANGLE_STRIP, numIndices, 737 GL_UNSIGNED_SHORT, NULL ); 738 #else 739 739 glClientActiveTextureARB( GL_TEXTURE0_ARB ); 740 740 glInterleavedArrays( GL_T2F_V3F, 0, vertices ); 741 741 742 742 glClientActiveTextureARB( GL_TEXTURE1_ARB ); 743 743 glInterleavedArrays( GL_T2F_V3F, 0, vertices ); 744 745 glDrawElements( GL_TRIANGLE_STRIP, numIndices, 746 GL_UNSIGNED_SHORT, indices ); 744 745 glDrawElements( GL_TRIANGLE_STRIP, numIndices, 746 GL_UNSIGNED_SHORT, indices ); 747 747 #endif 748 749 750 748 749 750 751 751 if ( owner->debug() ) 752 752 drawBox( ); 753 754 CHECK_GL_ERROR( "2" ); 753 754 CHECK_GL_ERROR( "2" ); 755 755 } 756 756 … … 768 768 } 769 769 770 void TerrainPage::getCoord( int _x, int _z, TexCoord& _coord ) const 771 { 772 owner->getCoord( _x+xOffset*(owner->getPageSize()-1 ), 770 void TerrainPage::getCoord( int _x, int _z, TexCoord& _coord ) const 771 { 772 owner->getCoord( _x+xOffset*(owner->getPageSize()-1 ), 773 773 _z+zOffset*(owner->getPageSize()-1 ), _coord ); 774 774 } … … 789 789 if ( _layer ) 790 790 hasfull = true; 791 } 792 layerVisibility[_layer] = _lv; 791 } 792 layerVisibility[_layer] = _lv; 793 793 } 794 794 795 795 bool TerrainPage::hasMaterial( int _layer ) 796 { 796 { 797 797 return ( layerVisibility[_layer] != LV_NO ); 798 798 }
Note: See TracChangeset
for help on using the changeset viewer.