Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 9421 in orxonox.OLD for branches/terrain/src/lib/graphics


Ignore:
Timestamp:
Jul 24, 2006, 1:46:23 PM (18 years ago)
Author:
bensch
Message:

renamings

File:
1 edited

Legend:

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

    r9414 r9421  
    1212#endif
    1313
    14 bool validateSize( int _s ) {
    15         _s-=1;
    16         int s = 16;
    17         while ( s <= _s ) {
    18                 if (s == _s )
    19                         return true;
    20                 s*=2;
    21         }
    22         return false;
     14bool validateSize( int _s )
     15{
     16  _s-=1;
     17  int s = 16;
     18  while ( s <= _s )
     19  {
     20    if (s == _s )
     21      return true;
     22    s*=2;
     23  }
     24  return false;
    2325}
    2426void Terrain::build()
    2527{
    26         ResourceManager *MANAGER = ResourceManager::getInstance();
    27         std::string full = MANAGER->getFullName( heightmapSource );
    28         SDL_Surface *tmpData = IMG_Load( full.c_str() );
    29         if ( !tmpData ) {
    30                 PRINT(0)( "I' sorry, I can't load %s\n", full.c_str() );
    31                 return;
    32         }               
    33         if ( !validateSize( tmpData->h ) || !validateSize( tmpData->w ) ) {
    34                 PRINT(0)( "The size of the elevation map must be 2^n+1x2^m+1. and at least 17x17" );
    35                 return;
    36         }
    37         if ( tmpData->format->BytesPerPixel != 1 ) {
    38                 PRINT(0)( "The elevetation map must be an 8bit image not %d",
    39                         tmpData->format->BytesPerPixel*8 );
    40                 return;
    41         }
    42         PRINTF(2)( "Loaded the elevation map\n" );
    43         heightfield.height = tmpData->h;
    44         heightfield.width = tmpData->w;
    45         heightfield.pitch = tmpData->pitch;
    46         int dataSize = heightfield.pitch*heightfield.height;
    47         heightfield.data = new Uint8[dataSize];
    48         memcpy( heightfield.data, tmpData->pixels, sizeof(Uint8)*dataSize );
    49         SDL_FreeSurface( tmpData );
    50         pagesX = (heightfield.width/(pageSize-1) );
    51         pagesZ = (heightfield.height/(pageSize-1) );
    52        
    53        
    54         pages = new pTerrainPage[pagesX*pagesZ];       
    55         for ( int x = 0; x < pagesX; ++x )
    56                 for ( int z = 0; z < pagesZ; ++z )
    57                         pages[z*pagesX+x] = createPage( x, z );
    58         //Inform each page about its neighbors.
    59         for ( int x = 0; x < pagesX; ++x )
    60                 for ( int z = 0; z < pagesZ; ++z )
    61                         pages[z*pagesX+x]->setNeighbors(
    62                                 x > 0                   ? getPage( x-1, z+0 ) : NULL,
    63                                 x < pagesX-1    ? getPage( x+1, z+0 ) : NULL,
    64                                 z < pagesZ-1    ? getPage( x+0, z+1 ) : NULL,
    65                                 z > 0                   ? getPage( x+0, z-1 ) : NULL );
    66        
    67         root = createQuadTree( 0, 0, pagesX, pagesZ );
    68        
    69         for ( unsigned int i = 0; i < layers.size(); ++i ) {
    70                 determineLayerVisibility( i );
    71         }       
    72         activePages = NULL;
     28
     29  printf("SHOULD GET LOADED :)\n");
     30
     31  ResourceManager *MANAGER = ResourceManager::getInstance();
     32  std::string full = MANAGER->getFullName( heightmapSource );
     33  SDL_Surface *tmpData = IMG_Load( full.c_str() );
     34  if ( !tmpData )
     35  {
     36    PRINT(0)( "I' sorry, I can't load %s\n", full.c_str() );
     37    return;
     38  }
     39  if ( !validateSize( tmpData->h ) || !validateSize( tmpData->w ) )
     40  {
     41    PRINT(0)( "The size of the elevation map must be 2^n+1x2^m+1. and at least 17x17" );
     42    return;
     43  }
     44  if ( tmpData->format->BytesPerPixel != 1 )
     45  {
     46    PRINT(0)( "The elevetation map must be an 8bit image not %d",
     47              tmpData->format->BytesPerPixel*8 );
     48    return;
     49  }
     50  PRINTF(2)( "Loaded the elevation map\n" );
     51  heightfield.height = tmpData->h;
     52  heightfield.width = tmpData->w;
     53  heightfield.pitch = tmpData->pitch;
     54  int dataSize = heightfield.pitch*heightfield.height;
     55  heightfield.data = new Uint8[dataSize];
     56  memcpy( heightfield.data, tmpData->pixels, sizeof(Uint8)*dataSize );
     57  SDL_FreeSurface( tmpData );
     58  pagesX = (heightfield.width/(pageSize-1) );
     59  pagesZ = (heightfield.height/(pageSize-1) );
     60
     61
     62  pages = new pTerrainPage[pagesX*pagesZ];
     63  for ( int x = 0; x < pagesX; ++x )
     64    for ( int z = 0; z < pagesZ; ++z )
     65      pages[z*pagesX+x] = createPage( x, z );
     66  //Inform each page about its neighbors.
     67  for ( int x = 0; x < pagesX; ++x )
     68    for ( int z = 0; z < pagesZ; ++z )
     69      pages[z*pagesX+x]->setNeighbors(
     70        x > 0                   ? getPage( x-1, z+0 ) : NULL,
     71        x < pagesX-1    ? getPage( x+1, z+0 ) : NULL,
     72        z < pagesZ-1    ? getPage( x+0, z+1 ) : NULL,
     73        z > 0                   ? getPage( x+0, z-1 ) : NULL );
     74
     75  root = createQuadTree( 0, 0, pagesX, pagesZ );
     76
     77  for ( unsigned int i = 0; i < layers.size(); ++i )
     78  {
     79    determineLayerVisibility( i );
     80  }
     81  activePages = NULL;
    7382}
    7483
    7584pTerrainQuad Terrain::createQuadTree( int _x0, int _z0, int _x1, int _z1, int _depth )
    7685{
    77         int _x01 = (_x1+_x0)/2; int _z01 = (_z1+_z0)/2;
    78         pTerrainQuad node;
    79         if ( _x1-_x0 == 1 ) {
    80                 node = getPage( _x0, _z0 );
    81                 node->setChildren( NULL, NULL, NULL, NULL );
    82         }
    83         else { 
    84                 node = new TerrainQuad( this, _x0, _z0, _x1, _z1 );
    85                 node->setChildren(
    86                         createQuadTree( _x0, _z0, _x01, _z01, _depth+1 ),
    87                         createQuadTree( _x01, _z0, _x1, _z01, _depth+1 ),
    88                         createQuadTree( _x0, _z01, _x01, _z1, _depth+1 ),
    89                         createQuadTree( _x01, _z01, _x1, _z1, _depth+1 ) );
    90         }
    91         node->calculateBounds();
    92         return node;
     86  int _x01 = (_x1+_x0)/2; int _z01 = (_z1+_z0)/2;
     87  pTerrainQuad node;
     88  if ( _x1-_x0 == 1 )
     89  {
     90    node = getPage( _x0, _z0 );
     91    node->setChildren( NULL, NULL, NULL, NULL );
     92  }
     93  else
     94  {
     95    node = new TerrainQuad( this, _x0, _z0, _x1, _z1 );
     96    node->setChildren(
     97      createQuadTree( _x0, _z0, _x01, _z01, _depth+1 ),
     98      createQuadTree( _x01, _z0, _x1, _z01, _depth+1 ),
     99      createQuadTree( _x0, _z01, _x01, _z1, _depth+1 ),
     100      createQuadTree( _x01, _z01, _x1, _z1, _depth+1 ) );
     101  }
     102  node->calculateBounds();
     103  return node;
    93104}
    94105
    95106pTerrainPage Terrain::createPage( int _xOffset, int _zOffset ) const
    96107{
    97         pTerrainPage newPage = new TerrainPage( const_cast<Terrain*>( this ), _xOffset, _zOffset );
    98         newPage->setScale( scale );     
    99         newPage->setPosition( Vector( scale.x*_xOffset, 0.0f, scale.z*_zOffset ) );
    100         newPage->calculateErrors();
    101         return newPage;
    102 }
    103 
    104 void Terrain::addLevelFourPage( int _numVertices, Vertex *_vertices,
    105         int _numIndices, unsigned short *_indices )
    106 {
    107         assert( indices ); assert( vertices );
    108         BufferInfo bi = buffers[current];       
    109         if ( ( MAX_VERTICES < _numVertices+bi.numVertices ) ||
    110                 ( MAX_INDICES < _numIndices+bi.numIndices+2 ) ) {
    111                 //So, we need the next vb and ib. Lets put the old into vram...
    112                 glBindBufferARB( GL_ARRAY_BUFFER_ARB, bi.vbIdentifier );
    113                 glBufferDataARB( GL_ARRAY_BUFFER_ARB, MAX_VERTICES*sizeof( Vertex ),
    114                         vertices, GL_DYNAMIC_DRAW_ARB );
    115                 glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, bi.ibIdentifier );
    116                 glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, MAX_INDICES*sizeof( short ),
    117                         indices, GL_DYNAMIC_DRAW_ARB );
    118                 BufferInfo newInfo;
    119                 broker->acquire( newInfo.vbIdentifier, newInfo.ibIdentifier );                 
    120                 current++;     
    121                 buffers.push_back( newInfo );   
    122                 bi = newInfo;
    123         }
    124         //For the vertex data, a simple copy operation is sufficient...
    125         memcpy( &vertices[bi.numVertices], _vertices,
    126                 _numVertices*sizeof( Vertex ) );
    127         //The indices need to be updated with an offset :(
    128         unsigned short *dst= &indices[bi.numIndices];
    129         unsigned short offset = bi.numVertices;
    130         unsigned short *src= _indices;
    131         unsigned short *end= src+_numIndices;
    132         bi.numVertices+=_numVertices;           
    133         if ( bi.numIndices ) {
    134                 dst[0] = *(dst-1);
    135                 dst[1] = *src+offset;
    136                 dst+=2; bi.numIndices+=2;
    137         }
    138         while ( src < end ) {
    139                 *dst= *src+offset;
    140                 dst++;
    141                 src++;
    142         }
    143         bi.numIndices+=_numIndices;
    144         buffers[current] = bi;
     108  pTerrainPage newPage = new TerrainPage( const_cast<Terrain*>( this ), _xOffset, _zOffset );
     109  newPage->setScale( scale );
     110  newPage->setPosition( Vector( scale.x*_xOffset, 0.0f, scale.z*_zOffset ) );
     111  newPage->calculateErrors();
     112  return newPage;
     113}
     114
     115void Terrain::addLevelFourPage( int _numVertices, Vertex *_vertices,
     116                                int _numIndices, unsigned short *_indices )
     117{
     118  assert( indices ); assert( vertices );
     119  BufferInfo bi = buffers[current];
     120  if ( ( MAX_VERTICES < _numVertices+bi.numVertices ) ||
     121       ( MAX_INDICES < _numIndices+bi.numIndices+2 ) )
     122  {
     123    //So, we need the next vb and ib. Lets put the old into vram...
     124    glBindBufferARB( GL_ARRAY_BUFFER_ARB, bi.vbIdentifier );
     125    glBufferDataARB( GL_ARRAY_BUFFER_ARB, MAX_VERTICES*sizeof( Vertex ),
     126                     vertices, GL_DYNAMIC_DRAW_ARB );
     127    glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, bi.ibIdentifier );
     128    glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, MAX_INDICES*sizeof( short ),
     129                     indices, GL_DYNAMIC_DRAW_ARB );
     130    BufferInfo newInfo;
     131    broker->acquire( newInfo.vbIdentifier, newInfo.ibIdentifier );
     132    current++;
     133    buffers.push_back( newInfo );
     134    bi = newInfo;
     135  }
     136  //For the vertex data, a simple copy operation is sufficient...
     137  memcpy( &vertices[bi.numVertices], _vertices,
     138          _numVertices*sizeof( Vertex ) );
     139  //The indices need to be updated with an offset :(
     140  unsigned short *dst= &indices[bi.numIndices];
     141  unsigned short offset = bi.numVertices;
     142  unsigned short *src= _indices;
     143  unsigned short *end= src+_numIndices;
     144  bi.numVertices+=_numVertices;
     145  if ( bi.numIndices )
     146  {
     147    dst[0] = *(dst-1);
     148    dst[1] = *src+offset;
     149    dst+=2; bi.numIndices+=2;
     150  }
     151  while ( src < end )
     152  {
     153    *dst= *src+offset;
     154    dst++;
     155    src++;
     156  }
     157  bi.numIndices+=_numIndices;
     158  buffers[current] = bi;
    145159}
    146160
    147161void Terrain::determineVisiblePages( pTerrainQuad _node )
    148162{
    149         switch( _node->cull() ) {
    150                 case Frustum::INTERSECT:
    151                         if ( !_node->isChildless() ) {
    152                                 pTerrainQuad *children = _node->getChildren();
    153                                 for ( int i = 0; i < 4; ++i, ++children )
    154                                         determineVisiblePages( *children );
    155                         }
    156                         else {
    157                                 showPages( _node->getXOffset(),
    158                                                    _node->getZOffset(), 1, 1 );
    159                         }
    160                         break;
    161                 case Frustum::INSIDE:
    162                         showPages( _node->getXOffset(),
    163                                            _node->getZOffset(),
    164                                            _node->getWidth() ,
    165                                            _node->getHeight() );
    166                         break;
    167                 case Frustum::OUTSIDE:
    168                         break;
    169         }
     163  switch( _node->cull() )
     164  {
     165    case Frustum::INTERSECT:
     166      if ( !_node->isChildless() )
     167      {
     168        pTerrainQuad *children = _node->getChildren();
     169        for ( int i = 0; i < 4; ++i, ++children )
     170          determineVisiblePages( *children );
     171      }
     172      else
     173      {
     174        showPages( _node->getXOffset(),
     175                   _node->getZOffset(), 1, 1 );
     176      }
     177      break;
     178    case Frustum::INSIDE:
     179      showPages( _node->getXOffset(),
     180                 _node->getZOffset(),
     181                 _node->getWidth() ,
     182                 _node->getHeight() );
     183      break;
     184    case Frustum::OUTSIDE:
     185      break;
     186  }
    170187}
    171188
    172189void Terrain::tick( float _dt )
    173190{
    174         for ( unsigned int i = 0; i < buffers.size(); ++i )
    175                 broker->release( buffers[i].vbIdentifier, buffers[i].ibIdentifier );
    176         buffers.clear();       
    177         pTerrainPage page = NULL;
    178         //Extract the frustum planes out of the modelview matrix.
    179         frustum->extractPlanes();       
    180         // Lets see which pages are visible.
    181         determineVisiblePages( root );
    182         int wantedLeft, wantedRight, wantedBottom, wantedTop, minLOD;
    183         pTerrainPage neighbor = NULL;
    184         page = activePages;
    185         bool dirty;
    186         current = 0;
    187         BufferInfo bi;
    188         broker->acquire( bi.vbIdentifier, bi.ibIdentifier );
    189         buffers.push_back( bi );
    190         int dirtyRounds = 0;
    191         do {
    192                 dirtyRounds++;
    193                 dirty = false;
    194                 page = activePages;
    195                 while ( page ) {
    196                         if ( !page->isActive() ) {
    197                                 pTerrainPage tmp = page;
    198                                 page = tmp->getNext();
    199                                 tmp->setVisibility( false );
    200                                 continue;
    201                         }
    202                         wantedLeft = wantedRight = wantedBottom = wantedTop = page->getWantedLOD();
    203                         if ( ( neighbor = page->getLeft() ) && ( neighbor->isActive() ) )
    204                                 wantedLeft = neighbor->getWantedLOD();
    205                         if ( ( neighbor = page->getRight() ) && ( neighbor->isActive() ) )
    206                                 wantedRight = neighbor->getWantedLOD();
    207                         if ( ( neighbor = page->getTop() ) && ( neighbor->isActive() ) )
    208                                 wantedTop = neighbor->getWantedLOD();
    209                         if ( ( neighbor = page->getBottom() ) && ( neighbor->isActive() ) )
    210                                 wantedBottom = neighbor->getWantedLOD();                       
    211                
    212                         minLOD = std::min( std::min( wantedBottom, wantedTop ),
    213                                 std::min( wantedLeft, wantedRight ) ); 
    214                         if ( minLOD < page->getWantedLOD()-1 ) {
    215                                 page->setWantedLOD( minLOD+1 );
    216                                 dirty = true;
    217                         }       
    218                         page = page->getNext();
    219                 }
    220         } while ( dirty );
    221        
    222         page = activePages;
    223         while ( page ) {
    224                 assert( page->isActive() );
    225                 page->updateTesselation();
    226                 page = page->getNext();
    227         }
    228         //If there is some data in the buffer, we need to upload the data
    229         //into the vram...
    230         if ( buffers[current].numIndices != 0 ) {
    231                 BufferInfo bi = buffers[current];       
    232                 glBindBufferARB( GL_ARRAY_BUFFER_ARB, bi.vbIdentifier );
    233                 glBufferDataARB( GL_ARRAY_BUFFER_ARB, MAX_VERTICES*sizeof( Vertex ),
    234                         vertices, GL_DYNAMIC_DRAW_ARB );
    235                 glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, bi.ibIdentifier );
    236                 glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, MAX_INDICES*sizeof( short ),
    237                         indices, GL_DYNAMIC_DRAW_ARB );
    238         }       
     191  for ( unsigned int i = 0; i < buffers.size(); ++i )
     192    broker->release( buffers[i].vbIdentifier, buffers[i].ibIdentifier );
     193  buffers.clear();
     194  pTerrainPage page = NULL;
     195  //Extract the frustum planes out of the modelview matrix.
     196  frustum->extractPlanes();
     197  // Lets see which pages are visible.
     198  determineVisiblePages( root );
     199  int wantedLeft, wantedRight, wantedBottom, wantedTop, minLOD;
     200  pTerrainPage neighbor = NULL;
     201  page = activePages;
     202  bool dirty;
     203  current = 0;
     204  BufferInfo bi;
     205  broker->acquire( bi.vbIdentifier, bi.ibIdentifier );
     206  buffers.push_back( bi );
     207  int dirtyRounds = 0;
     208  do
     209  {
     210    dirtyRounds++;
     211    dirty = false;
     212    page = activePages;
     213    while ( page )
     214    {
     215      if ( !page->isActive() )
     216      {
     217        pTerrainPage tmp = page;
     218        page = tmp->getNext();
     219        tmp->setVisibility( false );
     220        continue;
     221      }
     222      wantedLeft = wantedRight = wantedBottom = wantedTop = page->getWantedLOD();
     223      if ( ( neighbor = page->getLeft() ) && ( neighbor->isActive() ) )
     224        wantedLeft = neighbor->getWantedLOD();
     225      if ( ( neighbor = page->getRight() ) && ( neighbor->isActive() ) )
     226        wantedRight = neighbor->getWantedLOD();
     227      if ( ( neighbor = page->getTop() ) && ( neighbor->isActive() ) )
     228        wantedTop = neighbor->getWantedLOD();
     229      if ( ( neighbor = page->getBottom() ) && ( neighbor->isActive() ) )
     230        wantedBottom = neighbor->getWantedLOD();
     231
     232      minLOD = std::min( std::min( wantedBottom, wantedTop ),
     233                         std::min( wantedLeft, wantedRight ) );
     234      if ( minLOD < page->getWantedLOD()-1 )
     235      {
     236        page->setWantedLOD( minLOD+1 );
     237        dirty = true;
     238      }
     239      page = page->getNext();
     240    }
     241  }
     242  while ( dirty );
     243
     244  page = activePages;
     245  while ( page )
     246  {
     247    assert( page->isActive() );
     248    page->updateTesselation();
     249    page = page->getNext();
     250  }
     251  //If there is some data in the buffer, we need to upload the data
     252  //into the vram...
     253  if ( buffers[current].numIndices != 0 )
     254  {
     255    BufferInfo bi = buffers[current];
     256    glBindBufferARB( GL_ARRAY_BUFFER_ARB, bi.vbIdentifier );
     257    glBufferDataARB( GL_ARRAY_BUFFER_ARB, MAX_VERTICES*sizeof( Vertex ),
     258                     vertices, GL_DYNAMIC_DRAW_ARB );
     259    glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, bi.ibIdentifier );
     260    glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, MAX_INDICES*sizeof( short ),
     261                     indices, GL_DYNAMIC_DRAW_ARB );
     262  }
    239263}
    240264
    241265void Terrain::draw( )
    242266{
    243         pTerrainPage page = NULL;
    244         glGetError();
    245         /*pTerrainPage page = NULL;
    246         frustum->extractPlanes();*/
    247         Plane far = frustum->getPlane( Frustum::FAR );
    248         //Due to some reason, the OpenGL implementors chose the plane equation
    249         //to an array of doubles. So we will make them happy.
    250         double farPlane[] = { far.n.x, far.n.y, far.n.z, far.k };
    251         glEnable( GL_CLIP_PLANE0 );
    252         glClipPlane( GL_CLIP_PLANE0, farPlane );
    253         glPushAttrib( GL_ALL_ATTRIB_BITS );
    254         glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
    255         /*
    256          * Enable texture and vertex arrays for the first and the second texture
    257          * units and disable the normal arrays.
    258          */
    259         glClientActiveTextureARB( GL_TEXTURE0_ARB );   
    260                 glEnableClientState( GL_VERTEX_ARRAY );
    261                 glEnableClientState( GL_TEXTURE_COORD_ARRAY );
    262                 glDisableClientState( GL_NORMAL_ARRAY );
    263                                
    264         glClientActiveTextureARB( GL_TEXTURE1_ARB );   
    265                 glEnableClientState( GL_VERTEX_ARRAY );
    266                 glEnableClientState( GL_TEXTURE_COORD_ARRAY );
    267                 glDisableClientState( GL_NORMAL_ARRAY );
    268         glDisable( GL_CULL_FACE );
    269         glDisable( GL_LIGHTING );
    270         glColor3f( 1.0f, 1.0f, 1.0f );
    271         //glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
    272         cullCount = 0;
    273         glEnable( GL_BLEND );
    274         glDepthFunc( GL_LEQUAL );
    275         glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    276         for ( unsigned int i = 0; i < layers.size(); ++i ) {
    277                 LayerInfo* layer= layers[i];
    278                 page = activePages;     
    279                                
    280                 glActiveTextureARB( GL_TEXTURE1_ARB );
    281                 glClientActiveTextureARB( GL_TEXTURE1_ARB );
    282                 if ( layer->detail ) {
    283                         //glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND );
    284                         glEnable( GL_TEXTURE_2D );
    285                         glBindTexture( GL_TEXTURE_2D, layer->detail->getTexture() );
    286                         glMatrixMode( GL_TEXTURE );
    287                         glLoadIdentity();
    288                         glScalef( layer->repeatX, layer->repeatZ, 1.0f );
    289                 }       
    290                 else {
    291                         glDisable( GL_TEXTURE_2D );
    292                 }
    293                 glEnable( GL_CULL_FACE );
    294                 glCullFace( GL_BACK );
    295                 glClientActiveTextureARB( GL_TEXTURE0_ARB );
    296                 glActiveTextureARB( GL_TEXTURE0_ARB );
    297                 glEnable( GL_TEXTURE_2D );
    298                 if ( layer->alpha ) {
    299                         //glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND );                   
    300                         glBindTexture( GL_TEXTURE_2D, layer->alpha->getTexture() );
    301                 }
    302                 else {
    303                
    304                         glBindTexture( GL_TEXTURE_2D, lightmap->getTexture() );                 
    305                 }
    306                 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );                         
    307                 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
    308                
    309                 for ( unsigned j = 0; j < buffers.size(); ++j ) {
    310                         BufferInfo bi = buffers[j];
    311                         glBindBufferARB( GL_ARRAY_BUFFER_ARB, bi.vbIdentifier );
    312                         glClientActiveTextureARB( GL_TEXTURE0_ARB );
    313                         glInterleavedArrays( GL_T2F_V3F, 0, NULL );
    314 
    315                         glClientActiveTextureARB( GL_TEXTURE1_ARB );
    316                         glInterleavedArrays( GL_T2F_V3F, 0, NULL );
    317 
    318                         glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB,
    319                                 bi.ibIdentifier );     
    320 
    321                         glDrawElements( GL_TRIANGLE_STRIP, bi.numIndices,
    322                                                         GL_UNSIGNED_SHORT, NULL );
    323                 }
    324                 while ( page ) {
    325                         if ( page->hasMaterial( i ) )
    326                                 page->draw();
    327                         page = page->getNext();
    328                 }
    329         }
    330         glClientActiveTextureARB( GL_TEXTURE1_ARB );   
    331         glActiveTextureARB( GL_TEXTURE1_ARB );
    332         glDisable( GL_TEXTURE_2D );
    333         glActiveTextureARB( GL_TEXTURE0_ARB );
    334         glEnable( GL_LIGHTING );
    335         glMatrixMode( GL_TEXTURE );
    336         glLoadIdentity();
    337         glPopAttrib();
    338         glPopClientAttrib();
    339         glCullFace( GL_FRONT );
    340         glDisable( GL_CLIP_PLANE0 );
     267  pTerrainPage page = NULL;
     268  glGetError();
     269  /*pTerrainPage page = NULL;
     270  frustum->extractPlanes();*/
     271  Plane far = frustum->getPlane( Frustum::FAR );
     272  //Due to some reason, the OpenGL implementors chose the plane equation
     273  //to an array of doubles. So we will make them happy.
     274  double farPlane[] = { far.n.x, far.n.y, far.n.z, far.k };
     275  glEnable( GL_CLIP_PLANE0 );
     276  glClipPlane( GL_CLIP_PLANE0, farPlane );
     277  glPushAttrib( GL_ALL_ATTRIB_BITS );
     278  glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
     279  /*
     280   * Enable texture and vertex arrays for the first and the second texture
     281   * units and disable the normal arrays.
     282   */
     283  glClientActiveTextureARB( GL_TEXTURE0_ARB );
     284  glEnableClientState( GL_VERTEX_ARRAY );
     285  glEnableClientState( GL_TEXTURE_COORD_ARRAY );
     286  glDisableClientState( GL_NORMAL_ARRAY );
     287
     288  glClientActiveTextureARB( GL_TEXTURE1_ARB );
     289  glEnableClientState( GL_VERTEX_ARRAY );
     290  glEnableClientState( GL_TEXTURE_COORD_ARRAY );
     291  glDisableClientState( GL_NORMAL_ARRAY );
     292  glDisable( GL_CULL_FACE );
     293  glDisable( GL_LIGHTING );
     294  glColor3f( 1.0f, 1.0f, 1.0f );
     295  //glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
     296  cullCount = 0;
     297  glEnable( GL_BLEND );
     298  glDepthFunc( GL_LEQUAL );
     299  glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
     300  for ( unsigned int i = 0; i < layers.size(); ++i )
     301  {
     302    LayerInfo* layer= layers[i];
     303    page = activePages;
     304
     305    glActiveTextureARB( GL_TEXTURE1_ARB );
     306    glClientActiveTextureARB( GL_TEXTURE1_ARB );
     307    if ( layer->detail )
     308    {
     309      //glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND );
     310      glEnable( GL_TEXTURE_2D );
     311      glBindTexture( GL_TEXTURE_2D, layer->detail->getTexture() );
     312      glMatrixMode( GL_TEXTURE );
     313      glLoadIdentity();
     314      glScalef( layer->repeatX, layer->repeatZ, 1.0f );
     315    }
     316    else
     317    {
     318      glDisable( GL_TEXTURE_2D );
     319    }
     320    glEnable( GL_CULL_FACE );
     321    glCullFace( GL_BACK );
     322    glClientActiveTextureARB( GL_TEXTURE0_ARB );
     323    glActiveTextureARB( GL_TEXTURE0_ARB );
     324    glEnable( GL_TEXTURE_2D );
     325    if ( layer->alpha )
     326    {
     327      //glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND );
     328      glBindTexture( GL_TEXTURE_2D, layer->alpha->getTexture() );
     329    }
     330    else
     331    {
     332
     333      glBindTexture( GL_TEXTURE_2D, lightmap->getTexture() );
     334    }
     335    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
     336    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
     337
     338    for ( unsigned j = 0; j < buffers.size(); ++j )
     339    {
     340      BufferInfo bi = buffers[j];
     341      glBindBufferARB( GL_ARRAY_BUFFER_ARB, bi.vbIdentifier );
     342      glClientActiveTextureARB( GL_TEXTURE0_ARB );
     343      glInterleavedArrays( GL_T2F_V3F, 0, NULL );
     344
     345      glClientActiveTextureARB( GL_TEXTURE1_ARB );
     346      glInterleavedArrays( GL_T2F_V3F, 0, NULL );
     347
     348      glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB,
     349                       bi.ibIdentifier );
     350
     351      glDrawElements( GL_TRIANGLE_STRIP, bi.numIndices,
     352                      GL_UNSIGNED_SHORT, NULL );
     353    }
     354    while ( page )
     355    {
     356      if ( page->hasMaterial( i ) )
     357        page->draw();
     358      page = page->getNext();
     359    }
     360  }
     361  glClientActiveTextureARB( GL_TEXTURE1_ARB );
     362  glActiveTextureARB( GL_TEXTURE1_ARB );
     363  glDisable( GL_TEXTURE_2D );
     364  glActiveTextureARB( GL_TEXTURE0_ARB );
     365  glEnable( GL_LIGHTING );
     366  glMatrixMode( GL_TEXTURE );
     367  glLoadIdentity();
     368  glPopAttrib();
     369  glPopClientAttrib();
     370  glCullFace( GL_FRONT );
     371  glDisable( GL_CLIP_PLANE0 );
    341372}
    342373
    343374inline Uint8 getAlpha( const SDL_Surface *_s, int _x, int _y )
    344375{
    345     int bpp = _s->format->BytesPerPixel;
    346     Uint8 *p = (Uint8 *)_s->pixels + _y*_s->pitch + _x * bpp;
    347         Uint32 pixel = 0;
    348     switch( bpp ) {
     376  int bpp = _s->format->BytesPerPixel;
     377  Uint8 *p = (Uint8 *)_s->pixels + _y*_s->pitch + _x * bpp;
     378  Uint32 pixel = 0;
     379  switch( bpp )
     380  {
    349381    case 1:
    350         pixel = *p;
    351                 break;
     382      pixel = *p;
     383      break;
    352384    case 2:
    353                 if ( SDL_BYTEORDER == SDL_BIG_ENDIAN )
    354                         pixel = p[0] << 8 | p[1];
    355                 else
    356                 pixel = *(Uint16 *)p;
    357                 break;
     385      if ( SDL_BYTEORDER == SDL_BIG_ENDIAN )
     386        pixel = p[0] << 8 | p[1];
     387      else
     388        pixel = *(Uint16 *)p;
     389      break;
    358390    case 3:
    359         if( SDL_BYTEORDER == SDL_BIG_ENDIAN )
    360             pixel = p[0] << 16 | p[1] << 8 | p[2];
     391      if( SDL_BYTEORDER == SDL_BIG_ENDIAN )
     392        pixel = p[0] << 16 | p[1] << 8 | p[2];
     393      else
     394        pixel = p[0] | p[1] << 8 | p[2] << 16;
     395      break;
     396    case 4:
     397      pixel = *(Uint32 *)p;
     398      break;
     399    default:
     400      return 255; /* shouldn't happen, but avoids warnings */
     401  }
     402  Uint8 r,g,b,a;
     403  SDL_GetRGBA( pixel, _s->format, &r, &g, &b, &a );
     404  return a;
     405}
     406
     407void Terrain::determineLayerVisibility( int _layer )
     408{
     409  LayerInfo * layer = layers[_layer];
     410  if ( !layer->alpha )
     411  {
     412    int numPages = pagesX*pagesZ;
     413    for ( int i = 0; i < numPages; ++i )
     414      pages[i]->setLayerVisibility( _layer, LV_FULL );
     415
     416    return;
     417  }
     418  SDL_Surface *alpha = const_cast<SDL_Surface*>( layer->alpha->getStoredImage() );
     419  SDL_LockSurface( alpha );
     420  float du = ( (float)alpha->w)/pagesX;
     421  float dv = ( (float)alpha->h)/pagesZ;
     422  float u = 0.0f, v = 0.0f;
     423  for ( int pageX = 0; pageX < pagesX; ++pageX )
     424  {
     425    v = 0.0f;
     426    for ( int pageZ = 0; pageZ < pagesZ; ++pageZ )
     427    {
     428      bool full = true; bool has = false;
     429      for ( int x = 0; x < (int)PAGE_SIZE; ++x )
     430      {
     431        for ( int z = 0; z < (int)PAGE_SIZE; ++z )
     432        {
     433          Uint8 a = getAlpha( alpha, (int)u, (int)v );
     434          if ( a )
     435            has = true;
     436          if ( a < 255 )
     437            full = false;
     438        }
     439      }
     440      LayerVisibility lv;
     441      if ( has )
     442      {
     443        if ( full )
     444          lv = LV_FULL;
    361445        else
    362             pixel = p[0] | p[1] << 8 | p[2] << 16;
    363                 break;
    364     case 4:
    365         pixel = *(Uint32 *)p;
    366                 break;
    367     default:
    368         return 255; /* shouldn't happen, but avoids warnings */
    369     }
    370         Uint8 r,g,b,a;
    371         SDL_GetRGBA( pixel, _s->format, &r, &g, &b, &a );
    372         return a;
    373 }
    374 
    375 void Terrain::determineLayerVisibility( int _layer )
    376 {
    377         LayerInfo * layer = layers[_layer];
    378         if ( !layer->alpha ) {
    379                 int numPages = pagesX*pagesZ;
    380                 for ( int i = 0; i < numPages; ++i )
    381                         pages[i]->setLayerVisibility( _layer, LV_FULL );
    382                        
    383                 return;
    384         }
    385         SDL_Surface *alpha = const_cast<SDL_Surface*>( layer->alpha->getStoredImage() );       
    386         SDL_LockSurface( alpha );
    387         float du = ( (float)alpha->w)/pagesX;
    388         float dv = ( (float)alpha->h)/pagesZ;
    389         float u = 0.0f, v = 0.0f;
    390         for ( int pageX = 0; pageX < pagesX; ++pageX ) {
    391                 v = 0.0f;
    392                 for ( int pageZ = 0; pageZ < pagesZ; ++pageZ ) {
    393                         bool full = true; bool has = false;
    394                         for ( int x = 0; x < (int)PAGE_SIZE; ++x ) {
    395                                 for ( int z = 0; z < (int)PAGE_SIZE; ++z ) {
    396                                         Uint8 a = getAlpha( alpha, (int)u, (int)v );
    397                                         if ( a )
    398                                                 has = true;
    399                                         if ( a < 255 )
    400                                                 full = false;
    401                                 }
    402                         }
    403                         LayerVisibility lv;
    404                         if ( has ) {
    405                                 if ( full )
    406                                         lv = LV_FULL;
    407                                 else
    408                                         lv = LV_PARTIAL;
    409                         }
    410                         else {
    411                                 lv = LV_NO;
    412                         }
    413                         getPage( pageX, pageZ )->setLayerVisibility( _layer, lv );
    414                         v+= dv;
    415                 }
    416                 u+= du;
    417         }
    418         SDL_UnlockSurface( alpha );
     446          lv = LV_PARTIAL;
     447      }
     448      else
     449      {
     450        lv = LV_NO;
     451      }
     452      getPage( pageX, pageZ )->setLayerVisibility( _layer, lv );
     453      v+= dv;
     454    }
     455    u+= du;
     456  }
     457  SDL_UnlockSurface( alpha );
    419458}
    420459
    421460void Terrain::getAltitude( Vector& _alt, Vector& _normal )
    422461{
    423         float xScaled = _alt.x / scale.x, zScaled = _alt.z / scale.z;
    424         //The offset on the map
    425         int xOff =  (int)xScaled, zOff = (int)zScaled;
    426         //The interpolation values.
    427         float u = xScaled-xOff, v = zScaled-zOff;
    428        
    429         float dX = scale.x / ( pageSize-1 );
    430         float dZ = scale.z / ( pageSize-1 );
    431        
    432         //If u is bigger than v, we are on the lower triangle...
    433         if ( u > v ) {
    434                
    435                 float alt[] = {
    436                         getAltitude( xOff+0, zOff+0 )*scale.y,
    437                         getAltitude( xOff+1, zOff+0 )*scale.y,
    438                         getAltitude( xOff+1, zOff+1 )*scale.y };
    439                 _alt.y = (1.0f-u-v)*alt[0]+u*alt[1]+v*alt[2];
    440                
    441                 //Since we know about the directions of some x and z-coordinates,
    442                 //not the whole cross products needs to be calculated. Grab yourself
    443                 //pen and paper :)
    444                 _normal.x =  dZ*( alt[0] - alt[1] );                           
    445                 _normal.y =  dZ*dX;
    446                 _normal.z = -dX*( alt[2] - alt[1] );
    447         }
    448         else {
    449                 float alt[] = {
    450                         getAltitude( xOff+0, zOff+0 )*scale.y,
    451                         getAltitude( xOff+0, zOff+1 )*scale.y,
    452                         getAltitude( xOff+1, zOff+1 )*scale.y };                       
    453                 _alt.y = (1.0f-u-v)*alt[0]+v*alt[1]+u*alt[2];
    454                 //Since we know about the directions of some x and z-coordinates,
    455                 //not the whole cross products needs to be calculated. Grab yourself
    456                 //pen and paper :)
    457                 _normal.x = -dZ*( alt[2] - alt[1] );                           
    458                 _normal.y =  dZ*dX;
    459                 _normal.z =  dX*( alt[0] - alt[1] );
    460         }
     462  float xScaled = _alt.x / scale.x, zScaled = _alt.z / scale.z;
     463  //The offset on the map
     464  int xOff =  (int)xScaled, zOff = (int)zScaled;
     465  //The interpolation values.
     466  float u = xScaled-xOff, v = zScaled-zOff;
     467
     468  float dX = scale.x / ( pageSize-1 );
     469  float dZ = scale.z / ( pageSize-1 );
     470
     471  //If u is bigger than v, we are on the lower triangle...
     472  if ( u > v )
     473  {
     474
     475    float alt[] = {
     476                    getAltitude( xOff+0, zOff+0 )*scale.y,
     477                    getAltitude( xOff+1, zOff+0 )*scale.y,
     478                    getAltitude( xOff+1, zOff+1 )*scale.y };
     479    _alt.y = (1.0f-u-v)*alt[0]+u*alt[1]+v*alt[2];
     480
     481    //Since we know about the directions of some x and z-coordinates,
     482    //not the whole cross products needs to be calculated. Grab yourself
     483    //pen and paper :)
     484    _normal.x =  dZ*( alt[0] - alt[1] );
     485    _normal.y =  dZ*dX;
     486    _normal.z = -dX*( alt[2] - alt[1] );
     487  }
     488  else
     489  {
     490    float alt[] = {
     491                    getAltitude( xOff+0, zOff+0 )*scale.y,
     492                    getAltitude( xOff+0, zOff+1 )*scale.y,
     493                    getAltitude( xOff+1, zOff+1 )*scale.y };
     494    _alt.y = (1.0f-u-v)*alt[0]+v*alt[1]+u*alt[2];
     495    //Since we know about the directions of some x and z-coordinates,
     496    //not the whole cross products needs to be calculated. Grab yourself
     497    //pen and paper :)
     498    _normal.x = -dZ*( alt[2] - alt[1] );
     499    _normal.y =  dZ*dX;
     500    _normal.z =  dX*( alt[0] - alt[1] );
     501  }
    461502}
    462503
    463504void Terrain::showPages( int _x0, int _z0, int _width, int _height )
    464505{
    465         for ( int x = 0; x < _width; ++x ) {
    466                 for ( int z = 0; z < _height; ++z ) {
    467                         pTerrainPage page = getPage( _x0+x, _z0+z );
    468                         page->setVisibility( true );                   
    469                         page->chooseLOD();
    470 
    471                 }
    472         }
    473 }
     506  for ( int x = 0; x < _width; ++x )
     507  {
     508    for ( int z = 0; z < _height; ++z )
     509    {
     510      pTerrainPage page = getPage( _x0+x, _z0+z );
     511      page->setVisibility( true );
     512      page->chooseLOD();
     513
     514    }
     515  }
     516}
Note: See TracChangeset for help on using the changeset viewer.