Index: branches/terrain/src/lib/graphics/importer/material.h
===================================================================
--- branches/terrain/src/lib/graphics/importer/material.h	(revision 8349)
+++ branches/terrain/src/lib/graphics/importer/material.h	(revision 8548)
@@ -63,5 +63,4 @@
     void setBump(const std::string& bump);
     GLuint getDiffuseTexture(unsigned int i = 0) const { return (this->textures.size() > i)? this->textures[i].getTexture() : 0; };
-
     static void addTexturePath(const std::string& pathName);
 
Index: branches/terrain/src/lib/graphics/importer/terrain/terrain.cc
===================================================================
--- branches/terrain/src/lib/graphics/importer/terrain/terrain.cc	(revision 8349)
+++ branches/terrain/src/lib/graphics/importer/terrain/terrain.cc	(revision 8548)
@@ -5,5 +5,5 @@
 #include "util/loading/resource_manager.h"
 #include "debug.h"
-
+#include <math.h>
 #ifdef HAVE_SDL_SDL_IMAGE_H
 #include <SDL/SDL_image.h>
@@ -32,7 +32,10 @@
 	pagesX = (heightfield.width/(pageSize-1) );
 	pagesZ = (heightfield.height/(pageSize-1) );
-	tex = (Texture*)MANAGER->load( lightmapSource );
-	
-	//TODO: Determine layer visibility!
+	//tex = (Texture*)MANAGER->load( lightmapSource );
+	//TODO: Determine layer visibility!	
+	for ( int i = 0; i < materials.size(); ++i ) {
+		
+	}
+
 	printf( " * creating terrain pages ( %d, %d )...", pagesX, pagesZ );
 	pages = new pTerrainPage[pagesX*pagesZ];	
@@ -126,22 +129,34 @@
 void Terrain::draw( )
 {
+	static float s = 0.0f, x = 0.0f;
 	glGetError();
 	pTerrainPage page = NULL;
 	frustum->extractPlanes();
-	glEnableClientState( GL_VERTEX_ARRAY );
-
-	glEnableClientState( GL_TEXTURE_COORD_ARRAY ); 
-	glEnable( GL_TEXTURE_2D );
-	glEnable( GL_DEPTH_TEST );
-	glDisable( GL_CULL_FACE );
-	glBindTexture( GL_TEXTURE_2D, tex->getTexture() );
+	
+	/**
+	 * Enable texture and vertex arrays for the first and the second texture
+	 * units and disable the normal arrays.
+	 */
+	glClientActiveTextureARB( GL_TEXTURE0_ARB );	
+		glEnableClientState( GL_VERTEX_ARRAY );
+		glEnableClientState( GL_TEXTURE_COORD_ARRAY ); 
+		glDisableClientState( GL_NORMAL_ARRAY );
+				
+	glClientActiveTextureARB( GL_TEXTURE1_ARB );	
+		glEnableClientState( GL_VERTEX_ARRAY );
+		glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+		glDisableClientState( GL_NORMAL_ARRAY ); 
+		
 	glDisable( GL_LIGHTING );
-	glEnable( GL_COLOR_MATERIAL );
 	glColor3f( 1.0f, 1.0f, 1.0f );
+	//glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
 	cullCount = 0;
+	
 	// Lets see which pages are visible.
 	determineVisiblePages( root );
-		
-	page = activePages;	
+	int wantedLeft, wantedRight, wantedBottom, wantedTop, minLOD;
+	pTerrainPage neighbor = NULL;
+	page = activePages;
+	
 	while ( page ) {
 		if ( !page->isActive() ) {
@@ -150,14 +165,53 @@
 			tmp->setVisibility( false );
 			continue;
-		}	
-		page->updateTesselation();
-		//Draw the page. TODO: It would be nice if all the pages with an LOD of 4 could be merged
-		//in one index buffer. This would give us a speed boost for sure...
-		page->draw();
+		}
+		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 = page->getNext();
 	}
-	activatedCount = 0; deactivatedCount = 0;
-	//float percentage = (float)cullCount/(float)(pagesX*pagesZ)*100.0f;
-	//printf( "culled %f%% terrain pages away\n",  percentage );
+	s = 50.0f;
+	for ( int i = 0; i < materials.size(); ++i ) {
+		page = activePages;	
+		
+		//This is a hack! Remove this as soon as possible
+		materials[i]->unselect();
+		
+		materials[i]->select();
+		
+		glActiveTextureARB( GL_TEXTURE1_ARB );
+		glClientActiveTextureARB( GL_TEXTURE1_ARB );
+		glMatrixMode( GL_TEXTURE );
+		glLoadIdentity();
+		glScalef( s, s, s );
+		
+		glClientActiveTextureARB( GL_TEXTURE0_ARB );
+		glActiveTextureARB( GL_TEXTURE0_ARB );
+		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );				
+		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
+		while ( page ) {
+			//Draw the page. TODO: It would be nice if all the pages with an LOD of 4 could be merged
+			//in one index buffer. This would give us a speed boost for sure...
+			if ( page->hasMaterial( i ) )
+				page->draw();
+			page = page->getNext();
+		}
+		activatedCount = 0; deactivatedCount = 0;
+		//printf( "%d of %d pages drawn\n", pagesX*pagesZ-cullCount, pagesX*pagesZ );
+		//float percentage = (float)cullCount/(float)(pagesX*pagesZ)*100.0f;
+		//printf( "culled %f%% terrain pages away\n",  percentage );
+	}
 }
 
@@ -182,5 +236,5 @@
 			getAltitude( xOff+1, zOff+0 )*scale.y,
 			getAltitude( xOff+1, zOff+1 )*scale.y };
-		_alt.y = (1.0f-u)*(1.0-v)*alt[0]+u*(1.0f-v)*alt[1]+u*v*alt[2];
+		_alt.y = (1.0f-u-v)*alt[0]+u*alt[1]+v*alt[2];
 		
 		//Since we know about the directions of some x and z-coordinates, 
@@ -196,5 +250,5 @@
 			getAltitude( xOff+0, zOff+1 )*scale.y,
 			getAltitude( xOff+1, zOff+1 )*scale.y };			
-		_alt.y = (1.0f-u)*(1.0-v)*alt[0]+(1.0f-u)*v*alt[1]+u*v*alt[2];
+		_alt.y = (1.0f-u-v)*alt[0]+v*alt[1]+u*alt[2];
 		//Since we know about the directions of some x and z-coordinates, 
 		//not the whole cross products needs to be calculated. Grab yourself
Index: branches/terrain/src/lib/graphics/importer/terrain/terrain.h
===================================================================
--- branches/terrain/src/lib/graphics/importer/terrain/terrain.h	(revision 8349)
+++ branches/terrain/src/lib/graphics/importer/terrain/terrain.h	(revision 8548)
@@ -22,4 +22,6 @@
 #include <cstdlib>
 #include <string>
+#include <list>
+#include "material.h"
 #include "texture.h"
 #include "frustum.h"
@@ -34,4 +36,5 @@
 
 class Terrain;
+
 typedef Terrain *pTerrain;
 
@@ -107,8 +110,13 @@
 		inline float getAltitude( int _x, int _z ) const;
 		
-		inline void setLightmap( const std::string &_lightmap )
+		inline void addMaterial( Material *_material )
+		{
+			materials.push_back( _material );
+		}
+		
+		/*inline void setLightmap( const std::string &_lightmap )
 		{
 			lightmapSource = _lightmap;
-		}
+		}*/
 		inline void setHeightmap( const std::string &_heightmap ) 
 		{ 
@@ -122,8 +130,10 @@
 		
 		inline const Triple getScale() const { return scale; }
+		
 		inline int getPageSize() const 
 		{
 			return pageSize;
 		}
+		
 		inline void getCoord( int _x, int _z, TexCoord& _coord) const
 		{
@@ -160,21 +170,22 @@
 		void determineVisiblePages( pTerrainQuad _node );						
 		
-		pTerrainQuad		root;		// The quad-tree root node.
-		pTerrainPage		*pages;		// the references to all pages
-		std::string			heightmapSource;
-		std::string			lightmapSource;
-		Heightfield			heightfield;
-		Triple				scale;
-		int 				pagesX, 
-							pagesZ;
-		int					pageSize;	
-		int					cullCount;
+		pTerrainQuad			root;		// The quad-tree root node.
+		pTerrainPage			*pages;		// the references to all pages
+		std::string				heightmapSource;
+		std::string				lightmapSource;
+		Heightfield				heightfield;
+		Triple					scale;
+		int 					pagesX, 
+								pagesZ;
+		int						pageSize;	
+		int						cullCount;
 		
-		int					activatedCount, 
-							deactivatedCount; // For debugging and statistics
-		Texture				*tex;
-		Triple				cameraPosition;
-		pFrustum			frustum;
-		pTerrainPage		activePages;
+		int						activatedCount, 
+								deactivatedCount; // For debugging and statistics
+		Texture					*tex;
+		Triple					cameraPosition;
+		pFrustum				frustum;
+		pTerrainPage			activePages;
+		std::vector<Material*>	materials;
 };
 
Index: branches/terrain/src/lib/graphics/importer/terrain/terrain_page.cc
===================================================================
--- branches/terrain/src/lib/graphics/importer/terrain/terrain_page.cc	(revision 8349)
+++ branches/terrain/src/lib/graphics/importer/terrain/terrain_page.cc	(revision 8548)
@@ -19,4 +19,5 @@
 #include <math.h>
 
+
 #define CHECK_GL_ERROR( _d ) do { \
 	GLenum __err = glGetError(); \
@@ -87,5 +88,4 @@
 //TODO: Perform benchmark to measure if the isVisible test should be included
 //in this method.
-
 void TerrainPage::determineBorderAdaption( bool _adapt[] )
 {
@@ -544,13 +544,19 @@
 void TerrainPage::draw( )
 {
-	//These give an error
 	assert( glIsEnabled( GL_VERTEX_ARRAY ) );
 	assert( !glIsEnabled( GL_NORMAL_ARRAY ) );
+	
 	assert( isVisible ); assert( numIndices > 0 );
 	assert( active );
 	active = false;
 	CHECK_GL_ERROR( "1" );	
+	
 	glVertexPointer( 3, GL_FLOAT, 0, vertices );
 	glTexCoordPointer( 2, GL_FLOAT, 0, coords );	
+	
+	glClientActiveTextureARB( GL_TEXTURE1_ARB );
+	glVertexPointer( 3, GL_FLOAT, 0, vertices );
+	glTexCoordPointer( 2, GL_FLOAT, 0, coords );
+	
 	glDrawElements( GL_TRIANGLE_STRIP, numIndices, 
 					GL_UNSIGNED_SHORT, indices );
Index: branches/terrain/src/lib/graphics/importer/terrain/terrain_page.h
===================================================================
--- branches/terrain/src/lib/graphics/importer/terrain/terrain_page.h	(revision 8349)
+++ branches/terrain/src/lib/graphics/importer/terrain/terrain_page.h	(revision 8548)
@@ -199,76 +199,87 @@
 		 */
 		void activate();		
-		
-		protected:
-			
-			/**
-			 * @brief Tesselates one row of the terrain page.
-			 * @param _z 			The z-offset of the row
-			 * @param _xStride 		Determines the step-size horizontally
-			 * @param _zStride		Determines the step-size vertically.
-			 * @param _adaptRight	True if the right neighbor has a coarser
-			 *						tesselation level.
-			 * @param _adaptLeft	True if the left neighbor has a coarser
-			 *						tesselation level.			
-			 */
-			void tesselateRow( int _z, int _xStride, int _zStride, bool _adaptLeft, bool _adaptRight );
-
-			/** 
-			 * @brief Returns four boolean values in the oder
-			 */
-			void determineBorderAdaption( bool _adapt[] );
-			
-			/**
-			 * @brief Adds the given index to the index-array
-			 */
-			inline void addIndex( unsigned short _index );
-			
-			/**
-			 * @brief We programmers are very lazy :) This method just adds the last added index
-			 * again.
-			 */
-			inline void addAgain();
-			
-			
-			void getCoord( int _x, int _z, TexCoord& _coord) const;
-			
-			/** 
-			 * Fills _vertex with the vertex information at index.
-			 */
-			void getVertex( int _x, int _z, Triple& _vertex ) const;
-			
-		 	/**
-			 * Use this method to safely get a vertex at location ( _x, _z ). If it wasn't
-			 * created before, this method does that for you. 
-			 */			
-			short getIndex( int _x, int _z );
-			void tesselateLevelFourPatch( bool _adapt[] );
-		   /**
-			* Generates the tesselation for the given level of detail.
-			*/
-			void tesselate( int _lod );			
-			
-			float getAltitude( int _x, int _z ) const;
-			
-			int							currentLOD,
-										wantedLOD;
-			float						tween;
-			pTerrainPage 				left, 
-										right,
-										top,
-										bottom;
-			bool						forceTesselation;
-			bool						active;
-			Triple						*vertices;
-			unsigned short				*indices;
-			unsigned short				*indexHash;
-			TexCoord					*coords;
-			int							numIndices;
-			int							numVertices;
-			bool						isVisible;
-			pTerrainPage				next;
-			pTerrainPage				previous;
-			LODError					*errors;
-			Triple						position;
+		inline bool hasMaterial( int _i )
+		{
+			return true;
+		}
+		
+		inline void setWantedLOD( int _lod )
+		{
+			if ( wantedLOD >= TerrainPage::MAX_LODS )
+				wantedLOD = 4;
+			else
+				wantedLOD = _lod;
+		}		
+	protected:
+		
+		/**
+		 * @brief Tesselates one row of the terrain page.
+		 * @param _z 			The z-offset of the row
+		 * @param _xStride 		Determines the step-size horizontally
+		 * @param _zStride		Determines the step-size vertically.
+		 * @param _adaptRight	True if the right neighbor has a coarser
+		 *						tesselation level.
+		 * @param _adaptLeft	True if the left neighbor has a coarser
+		 *						tesselation level.			
+		 */
+		void tesselateRow( int _z, int _xStride, int _zStride, bool _adaptLeft, bool _adaptRight );
+
+		/** 
+		 * @brief Returns four boolean values in the oder
+		 */
+		void determineBorderAdaption( bool _adapt[] );
+		
+		/**
+		 * @brief Adds the given index to the index-array
+		 */
+		inline void addIndex( unsigned short _index );
+		
+		/**
+		 * @brief We programmers are very lazy :) This method just adds the last added index
+		 * again.
+		 */
+		inline void addAgain();
+		
+		
+		void getCoord( int _x, int _z, TexCoord& _coord) const;
+		
+		/** 
+		 * Fills _vertex with the vertex information at index.
+		 */
+		void getVertex( int _x, int _z, Triple& _vertex ) const;
+		
+	 	/**
+		 * Use this method to safely get a vertex at location ( _x, _z ). If it wasn't
+		 * created before, this method does that for you. 
+		 */			
+		short getIndex( int _x, int _z );
+		void tesselateLevelFourPatch( bool _adapt[] );
+	   /**
+		* Generates the tesselation for the given level of detail.
+		*/
+		void tesselate( int _lod );			
+
+		float getAltitude( int _x, int _z ) const;
+		
+		int							currentLOD,
+									wantedLOD;
+		float						tween;
+		pTerrainPage 				left, 
+									right,
+									top,
+									bottom;
+		bool						forceTesselation;
+		bool						active;
+		Triple						*vertices;
+		unsigned short				*indices;
+		unsigned short				*indexHash;
+		TexCoord					*coords;
+		int							numIndices;
+		int							numVertices;
+		bool						isVisible;
+		pTerrainPage				next;
+		pTerrainPage				previous;
+		LODError					*errors;
+		Triple						position;
 };
 
