Index: branches/terrain/src/lib/graphics/importer/Makefile.am
===================================================================
--- branches/terrain/src/lib/graphics/importer/Makefile.am	(revision 8548)
+++ branches/terrain/src/lib/graphics/importer/Makefile.am	(revision 8569)
@@ -25,5 +25,6 @@
                            terrain/terrain_quad.cc \
                            terrain/terrain_page.cc \
-                           terrain/frustum.cc
+                           terrain/frustum.cc \
+                           terrain/buffer_broker.cc
 
 libtc_a_SOURCES  = tc.cc
@@ -56,3 +57,4 @@
 		terrain/terrain_quad.h \
 		terrain/frustum.h \
-		terrain/types.h
+		terrain/types.h \
+      terrain/buffer_broker.h
Index: branches/terrain/src/lib/graphics/importer/terrain/frustum.h
===================================================================
--- branches/terrain/src/lib/graphics/importer/terrain/frustum.h	(revision 8548)
+++ branches/terrain/src/lib/graphics/importer/terrain/frustum.h	(revision 8569)
@@ -28,5 +28,5 @@
 	
 /** 
- * Code borrowed from Lighthouse 3D 
+ * Code borrowed from Lighthouse 3D. Its a very good tutorial on culling.
  */
 class Frustum;
@@ -64,12 +64,15 @@
 		{
 			int result = INSIDE;
-			for(int i=0; i < 6; i++) {
+			//for each plane do ...
+			for( int i = 0; i < 6; ++i ) {
 
+				// is the positive vertex outside?
 				if ( planes[i].distance( _box.vertexP( planes[i].n ) ) < 0 )
 					return OUTSIDE;
-				if ( planes[i].distance( _box.vertexN( planes[i].n) ) < 0 )
-					result =  INTERSECT;
+				// is the negative vertex outside?	
+				else if ( planes[i].distance( _box.vertexN( planes[i].n ) ) < 0 )
+					result = INTERSECT;
 			}
-			return result;		
+			return result;
 		}
 		
@@ -78,5 +81,4 @@
 			int result = INSIDE;
 			for(int i=0; i < 6; i++) {
-
 				if (planes[i].distance( _point ) < 0)
 					return OUTSIDE;
Index: branches/terrain/src/lib/graphics/importer/terrain/terrain.cc
===================================================================
--- branches/terrain/src/lib/graphics/importer/terrain/terrain.cc	(revision 8548)
+++ branches/terrain/src/lib/graphics/importer/terrain/terrain.cc	(revision 8569)
@@ -129,5 +129,5 @@
 void Terrain::draw( )
 {
-	static float s = 0.0f, x = 0.0f;
+	static float s = 0.0f;
 	glGetError();
 	pTerrainPage page = NULL;
@@ -158,30 +158,41 @@
 	pTerrainPage neighbor = NULL;
 	page = activePages;
+	bool dirty;
+	do {
+		dirty = false;
+		page = activePages;
+		while ( page ) {
+			if ( !page->isActive() ) {
+				pTerrainPage tmp = page;
+				page = tmp->getNext();
+				tmp->setVisibility( false );
+				continue;
+			}
+			wantedLeft = wantedRight = wantedBottom = wantedTop = page->getWantedLOD();
+			if ( ( neighbor = page->getLeft() ) ) 
+				wantedLeft = neighbor->getWantedLOD();
+			if ( ( neighbor = page->getRight() ) ) 
+				wantedRight = neighbor->getWantedLOD();
+			if ( ( neighbor = page->getTop() ) ) 
+				wantedTop = neighbor->getWantedLOD();
+			if ( ( neighbor = page->getBottom() ) ) 
+				wantedBottom = neighbor->getWantedLOD();			
+		
+			minLOD = std::min( std::min( wantedBottom, wantedTop ), std::min( wantedLeft, wantedRight ) );	
+			if ( minLOD < page->getWantedLOD()-1 ) {
+				page->setWantedLOD( minLOD+1 );
+				dirty = true;
+			}	
+			page = page->getNext();
+		}
+	} while ( dirty );
+	page = activePages;
 	
 	while ( page ) {
-		if ( !page->isActive() ) {
-			pTerrainPage tmp = page;
-			page = tmp->getNext();
-			tmp->setVisibility( false );
-			continue;
-		}
-		wantedLeft = wantedRight = wantedBottom = wantedTop = page->getWantedLOD();
-		if ( ( neighbor = page->getLeft() ) ) 
-			wantedLeft = neighbor->getWantedLOD();
-		if ( ( neighbor = page->getRight() ) ) 
-			wantedRight = neighbor->getWantedLOD();
-		if ( ( neighbor = page->getTop() ) ) 
-			wantedTop = neighbor->getWantedLOD();
-		if ( ( neighbor = page->getBottom() ) ) 
-			wantedBottom = neighbor->getWantedLOD();			
-		
-		minLOD = std::min( std::min( wantedBottom, wantedTop ), std::min( wantedLeft, wantedRight ) );	
-		/*if ( minLOD < page->getWantedLOD()-1 )
-			page->setWantedLOD( minLOD+1 );*/
-		
-		page->updateTesselation();	
+		page->updateTesselation();
 		page = page->getNext();
 	}
-	s = 50.0f;
+	
+	s = 500.0f;
 	for ( int i = 0; i < materials.size(); ++i ) {
 		page = activePages;	
@@ -189,5 +200,4 @@
 		//This is a hack! Remove this as soon as possible
 		materials[i]->unselect();
-		
 		materials[i]->select();
 		
@@ -214,4 +224,15 @@
 		//printf( "culled %f%% terrain pages away\n",  percentage );
 	}
+	glClientActiveTextureARB( GL_TEXTURE1_ARB );	
+	glDisableClientState( GL_VERTEX_ARRAY );
+	glDisableClientState( GL_TEXTURE_COORD_ARRAY );	
+	glDisableClientState( GL_VERTEX_ARRAY );
+	glDisableClientState( GL_TEXTURE_COORD_ARRAY );	
+	materials[0]->unselect();
+	glActiveTextureARB( GL_TEXTURE0_ARB );
+	glClientActiveTextureARB( GL_TEXTURE0_ARB );	
+	glDisableClientState( GL_VERTEX_ARRAY );
+	glDisableClientState( GL_TEXTURE_COORD_ARRAY );	
+	glEnable( GL_LIGHTING );
 }
 
Index: branches/terrain/src/lib/graphics/importer/terrain/terrain.h
===================================================================
--- branches/terrain/src/lib/graphics/importer/terrain/terrain.h	(revision 8548)
+++ branches/terrain/src/lib/graphics/importer/terrain/terrain.h	(revision 8569)
@@ -17,4 +17,8 @@
 #define _TERRAIN_H
 
+#define USE_VBO
+#ifdef USE_VBO
+#include "buffer_broker.h"
+#endif
 #include "types.h"
 #include "terrain_page.h"
@@ -82,4 +86,8 @@
 			frustum = new Frustum();
 			activatedCount = deactivatedCount = 0;
+#ifdef USE_VBO
+			broker = new BufferBroker( 200, pageSize*pageSize*sizeof( Vertex ), 
+				pageSize*pageSize*sizeof( short )*3 );
+#endif			
 		}
 		
@@ -146,5 +154,7 @@
 			scale = _scale;
 		}
-		
+#ifdef USE_VBO
+		inline pBufferBroker getBufferBroker() { return broker; }
+#endif		
 		inline TerrainPage *getPage( int _x, int _z )
 		{
@@ -170,4 +180,7 @@
 		void determineVisiblePages( pTerrainQuad _node );						
 		
+#ifdef USE_VBO
+		pBufferBroker			broker;
+#endif
 		pTerrainQuad			root;		// The quad-tree root node.
 		pTerrainPage			*pages;		// the references to all pages
Index: branches/terrain/src/lib/graphics/importer/terrain/terrain_page.cc
===================================================================
--- branches/terrain/src/lib/graphics/importer/terrain/terrain_page.cc	(revision 8548)
+++ branches/terrain/src/lib/graphics/importer/terrain/terrain_page.cc	(revision 8569)
@@ -18,5 +18,5 @@
 #include <stdio.h>
 #include <math.h>
-
+#define USE_VBO
 
 #define CHECK_GL_ERROR( _d ) do { \
@@ -33,5 +33,5 @@
 	numVertices = numIndices = 0;
 	errors = new LODError[TerrainPage::MAX_LODS];
-	vertices = NULL; indices = NULL; coords = NULL;
+	vertices = NULL; indices = NULL;
 	position = Triple( scale.x*_xOffset, 0.0f, scale.z*_zOffset );
 	isVisible = false;
@@ -45,9 +45,7 @@
 void TerrainPage::tesselateRow( int _z, int _xStride, int _zStride, bool _adaptLeft, bool _adaptRight )
 {
-	int xStart = 0, xEnd = owner->getPageSize();
-	
+	
+	int xStart = 0, xEnd = owner->getPageSize();	
 	int halfStride = _zStride >> 1;
-
-
 	if ( _z ) {
 		addAgain( );
@@ -454,4 +452,31 @@
 	determineBorderAdaption( adapt );
 	assert( isVisible );
+#ifdef USE_VBO
+	
+	glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbIdentifier );
+	
+	// The call to glBufferDataARB with a null argument for data is to tell the GPU, that the
+	// old data is invalid. Then calling call glMapBuffer() tells the driver that the previous 
+	// data aren’t valid. As a consequence, if the GPU is still working on them, there won’t 
+	// be a conflict because we invalidated these data. The function glMapBuffer() returns a 
+	// new pointer that we can use while the GPU is working on the previous set of data.. 
+	
+	glBufferDataARB( GL_ARRAY_BUFFER_ARB, count*sizeof( Vertex ), NULL, GL_DYNAMIC_DRAW_ARB );
+	
+	vertices = (Vertex*)glMapBufferARB( GL_ARRAY_BUFFER_ARB, 
+		GL_WRITE_ONLY_ARB );
+	
+	glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, ibIdentifier );
+	
+	glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 
+		count*3*sizeof( short ), NULL, GL_DYNAMIC_DRAW_ARB );	
+		
+	indices = (unsigned short*)glMapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 
+		GL_WRITE_ONLY_ARB );
+	
+	assert( indices ); 
+	assert( vertices );
+	
+#endif	
 	if ( _lod == TerrainPage::MAX_LODS-1 ) {
 		tesselateLevelFourPatch( adapt );
@@ -473,6 +498,5 @@
 	
 
-	if ( !adapt[TP_BOTTOM] )
-		return;
+	if ( adapt[TP_BOTTOM] ) {
 		
 	addAgain( );
@@ -480,4 +504,10 @@
 	
 	tesselateRow( owner->getPageSize()-1-stride, stride / 2, stride, adapt[TP_LEFT], adapt[TP_RIGHT] );
+	}
+	
+#ifdef USE_VBO
+	glUnmapBufferARB( GL_ARRAY_BUFFER_ARB );
+	glUnmapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB );
+#endif
 
 }
@@ -488,21 +518,30 @@
 	int count = owner->getPageSize()*owner->getPageSize();
 	
-	vertices = new Triple[count];
+#ifdef USE_VBO	
+	owner->getBufferBroker()->acquire( vbIdentifier, ibIdentifier );
+	vertices = NULL;
+	indices = NULL;
+#else
+	vertices = new Vertex[count];
 	// Not the economical way, but we just want to have space for all indices.
 	indices = new unsigned short[count*3];
+#endif	
+
 	indexHash = new unsigned short[count];	
-	coords = new TexCoord[count];
 	forceTesselation = true;
 	activate();
 	active = true;
+	
 }
 
 void TerrainPage::hide( )
 {
+#ifdef USE_VBO
+	owner->getBufferBroker()->release( vbIdentifier, ibIdentifier );
+#else	
 	if ( vertices ) {
 		delete[] vertices;
 		vertices = NULL;
 	}
-	delete[] coords;	
 	if ( indices ) {
 		delete[] indices;
@@ -510,4 +549,5 @@
 		numIndices = 0;
 	}
+#endif
 	deactivate();
 }
@@ -552,13 +592,29 @@
 	CHECK_GL_ERROR( "1" );	
 	
-	glVertexPointer( 3, GL_FLOAT, 0, vertices );
-	glTexCoordPointer( 2, GL_FLOAT, 0, coords );	
+#ifdef USE_VBO
+	
+	glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbIdentifier );
+	glClientActiveTextureARB( GL_TEXTURE0_ARB );
+	glInterleavedArrays( GL_T2F_V3F, 0, NULL );
 	
 	glClientActiveTextureARB( GL_TEXTURE1_ARB );
-	glVertexPointer( 3, GL_FLOAT, 0, vertices );
-	glTexCoordPointer( 2, GL_FLOAT, 0, coords );
+	glInterleavedArrays( GL_T2F_V3F, 0, NULL );
+	
+	glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, ibIdentifier );	
 	
 	glDrawElements( GL_TRIANGLE_STRIP, numIndices, 
-					GL_UNSIGNED_SHORT, indices );
+					GL_UNSIGNED_SHORT, NULL );	
+#else	
+	glClientActiveTextureARB( GL_TEXTURE0_ARB );
+	glInterleavedArrays( GL_T2F_V3F, 0, vertices );
+	
+	glClientActiveTextureARB( GL_TEXTURE1_ARB );
+	glInterleavedArrays( GL_T2F_V3F, 0, vertices );
+	
+	glDrawElements( GL_TRIANGLE_STRIP, numIndices, 
+					GL_UNSIGNED_SHORT, indices );	
+#endif
+	
+
 	
 	if ( owner->debug() )
@@ -574,6 +630,6 @@
 		//The vertex didn't exists before, lets create it.
 		indexHash[index] = numVertices;
-		getVertex( _x, _z, vertices[numVertices] );
-		getCoord( _x, _z, coords[numVertices] );
+		getVertex( _x, _z, vertices[numVertices].p );
+		getCoord( _x, _z, vertices[numVertices].t );
 		numVertices++;
 	}
Index: branches/terrain/src/lib/graphics/importer/terrain/terrain_page.h
===================================================================
--- branches/terrain/src/lib/graphics/importer/terrain/terrain_page.h	(revision 8548)
+++ branches/terrain/src/lib/graphics/importer/terrain/terrain_page.h	(revision 8569)
@@ -17,5 +17,5 @@
 #ifndef TERRAIN_PAGE_H
 #define TERRAIN_PAGE_H
-
+#define USE_VBO
 #include "terrain_quad.h"
 #include <stdio.h>
@@ -26,4 +26,11 @@
 
 typedef TerrainPage *pTerrainPage;
+
+struct Vertex {
+	TexCoord 	t;	
+	Triple 		p;
+};
+
+typedef Vertex *pVertex;
 
 typedef struct {
@@ -208,4 +215,6 @@
 			if ( wantedLOD >= TerrainPage::MAX_LODS )
 				wantedLOD = 4;
+			else if ( wantedLOD < 0 )
+				wantedLOD = 0;
 			else
 				wantedLOD = _lod;
@@ -271,10 +280,14 @@
 		bool						forceTesselation;
 		bool						active;
-		Triple						*vertices;
+		pVertex						vertices;
 		unsigned short				*indices;
 		unsigned short				*indexHash;
-		TexCoord					*coords;
 		int							numIndices;
 		int							numVertices;
+		
+#ifdef	USE_VBO
+		GLuint						ibIdentifier,
+									vbIdentifier;
+#endif		
 		bool						isVisible;
 		pTerrainPage				next;
