void Editor::update( float dt )
{
	vec2f scrollDir( 0.0f, 0.0f );

	// Continuous (key state) keys
	Uint8 *keyState = SDL_GetKeyState( NULL );
	if ((keyState[SDLK_LEFT]) && (!keyState[SDLK_RIGHT]))
	{
		scrollDir.x = -1.0;
	}
	else if ((!keyState[SDLK_LEFT]) && (keyState[SDLK_RIGHT]))
	{
		scrollDir.x = 1.0;
	}
	if ((keyState[SDLK_UP]) && (!keyState[SDLK_DOWN]))
	{
		scrollDir.y = 1.0;
	}
	else if ((!keyState[SDLK_UP]) && (keyState[SDLK_DOWN]))
	{
		scrollDir.y = -1.0;
	}

	// update view
	if (m_useEditView)
	{
		m_viewport += scrollDir * _TV( 0.6f ) * m_viewsize.x * dt;
	}
	else
	{
		m_gameview += scrollDir * _TV( 200.0f ) * dt;
	}

	// update mouse
	int mx, my;
	SDL_GetMouseState( &mx, &my );
	my = 600-my;
	if (m_activeShape)
	{
		if (m_useEditView)
		{
			m_activeShape->pos.x = m_viewport.x + ((float)mx / 800.0)*m_viewsize.x;
			m_activeShape->pos.y = m_viewport.y + ((float)my / 600.0)*m_viewsize.y;			
		}
		else
		{
			m_activeShape->pos.x = mx + m_gameview.x;
			m_activeShape->pos.y = my + m_gameview.y;
		}
		
		// remember this pos for otehr use
		m_mousePos = m_activeShape->pos;

		// offset so active shape is centered
		m_activeShape->pos.x -= m_activeShape->m_size.x/2;
		m_activeShape->pos.y -= m_activeShape->m_size.y/2;
	}
}
void pseudoOrtho2D( double left, double right, double bottom, double top )
{
#if 0
	// for now, real ortho
	gluOrtho2D( left, right, bottom, top );
#else	
	float w2, h2;
	w2 = (right - left) /2;
	h2 = (top - bottom) /2;
	float nv = _TV( 1.0f );
	glFrustum( -w2, w2, -h2, h2, nv, _TV(5.0f) );
	gluLookAt( left + w2, bottom + h2, nv,
			   left + w2, bottom + h2, 0.0,
			   0.0, 1.0, 0.0 );
#endif
}
void	EffectTranslucency::Render( float _Time, float _DeltaTime )
{
	float3	TorusPosition = float3(
		0.8f * sinf( _TV(0.95f) * _Time ) * sinf( _TV(0.7f) * _Time ),
		0.8f * sinf( _TV(0.83f) * _Time ) * sinf( _TV(-0.19f) * _Time ),
		0.2f * cosf( _TV(0.5f) * _Time ) * sinf( _TV(-0.17f) * _Time ) );							// Oscillate within the quiche

	float4	TorusRotation = float4::QuatFromAngleAxis( _TV(1.35f) * _Time, float3::UnitY );	// Rotate, too

	m_EmissivePower = SATURATE( -4.0f * sinf( _TV(0.5f) * _Time ) );

	float4	SphereNoise = float4( _Time * 0.2f * float3( 1.0f, -0.5f, 0.9f ), 0.2f );
	float4	TorusNoise = float4( _Time * 0.2f * float3( 1.0f, -0.5f, 0.9f ), 0.0f );

	//////////////////////////////////////////////////////////////////////////
	// 1] Render the internal & external objects into the RGBA ZBuffer
	gs_Device.ClearRenderTarget( *m_pRTZBuffer, float4( 2.0f, 0.0f, 2.0f, 0.0f ) );
	gs_Device.SetRenderTarget( *m_pRTZBuffer, m_pDepthStencil );

	{	USING_MATERIAL_START( *m_pMatBuildZBuffer )

		// === Render external object ===
		m_pCB_Object->m.Local2World.PRS( float3::Zero, float4::QuatFromAngleAxis( 0.0f, float3::UnitY ), float3::One );
		m_pCB_Object->m.NoiseOffset = SphereNoise;
		m_pCB_Object->UpdateData();

			// Front
		gs_Device.ClearDepthStencil( *m_pDepthStencil, 1.0f, 0 );
 		gs_Device.SetStates( gs_Device.m_pRS_CullBack, gs_Device.m_pDS_ReadWriteLess, gs_Device.m_pBS_Disabled_RedOnly );
		m_pPrimSphereExternal->Render( *m_pMatBuildZBuffer );

			// Back
		gs_Device.ClearDepthStencil( *m_pDepthStencil, 0.0f, 0 );
 		gs_Device.SetStates( gs_Device.m_pRS_CullFront, gs_Device.m_pDS_ReadWriteGreater, gs_Device.m_pBS_Disabled_GreenOnly );
		m_pPrimSphereExternal->Render( *m_pMatBuildZBuffer );

		// === Render rotating internal object ===
		m_pCB_Object->m.Local2World.PRS( TorusPosition, TorusRotation, float3::One );
		m_pCB_Object->m.NoiseOffset = TorusNoise;
		m_pCB_Object->UpdateData();

			// Front
		gs_Device.ClearDepthStencil( *m_pDepthStencil, 1.0f, 0 );
 		gs_Device.SetStates( gs_Device.m_pRS_CullBack, gs_Device.m_pDS_ReadWriteLess, gs_Device.m_pBS_Disabled_BlueOnly );
		m_pPrimTorusInternal->Render( *m_pMatBuildZBuffer );

			// Back
		gs_Device.ClearDepthStencil( *m_pDepthStencil, 0.0f, 0 );
 		gs_Device.SetStates( gs_Device.m_pRS_CullFront, gs_Device.m_pDS_ReadWriteGreater, gs_Device.m_pBS_Disabled_AlphaOnly );
		m_pPrimTorusInternal->Render( *m_pMatBuildZBuffer );

		USING_MATERIAL_END
	}

	//////////////////////////////////////////////////////////////////////////
	// 2] Render the irradiance map ?

	// LATER... Not sure it's necessary

	//////////////////////////////////////////////////////////////////////////
	// 3] Perform diffusion
	gs_Device.SetStates( gs_Device.m_pRS_CullNone, gs_Device.m_pDS_Disabled, gs_Device.m_pBS_Disabled );

	{	USING_MATERIAL_START( *m_pMatDiffusion )

		// Clear original irradiance map
		gs_Device.ClearRenderTarget( *m_ppRTDiffusion[0], float4( 0.0f, 0.0f, 0.0f, 0.0f ) );

		// Setup our global diffusion parameters
		float	BBoxSize = _TV(0.002f);	// Size of the BBox containing our objects, in meter

		m_pCB_Diffusion->m.BBoxSize = BBoxSize;
		m_pCB_Diffusion->m.SliceThickness = BBoxSize / DIFFUSION_PASSES_COUNT;	// Size of a single slice
		m_pCB_Diffusion->m.TexelSize = BBoxSize / DIFFUSION_SIZE;				// Size of a single texel
		m_pCB_Diffusion->m.ExtinctionCoeff = _TV(1000.0f) * float3( 0.8f, 0.85f, 1.0f );
		m_pCB_Diffusion->m.Albedo = _TV(0.8f) * float3::One;

		float3	ScatteringAnisotropy = _TV(0.0f) * float3::One;
		float		PhaseFactor = _TV(4.6f);
		m_pCB_Diffusion->m.Phase0 = PhaseFactor * ComputePhase( ScatteringAnisotropy, 0, 1, m_pCB_Diffusion->m.TexelSize, m_pCB_Diffusion->m.SliceThickness );
		m_pCB_Diffusion->m.Phase1 = PhaseFactor * ComputePhase( ScatteringAnisotropy, 1, 8, m_pCB_Diffusion->m.TexelSize, m_pCB_Diffusion->m.SliceThickness );
		m_pCB_Diffusion->m.Phase2 = PhaseFactor * ComputePhase( ScatteringAnisotropy, 2, 12, m_pCB_Diffusion->m.TexelSize, m_pCB_Diffusion->m.SliceThickness );

//		m_pCB_Diffusion->m.ExternalLight = _TV(2.0f) * NjFloat3( 1.0f, 1.0f, 1.0f );
		m_pCB_Diffusion->m.ExternalLight = _TV(1.4f) * (1.4f - m_EmissivePower) * float3( 1.0f, 1.0f, 1.0f );
		m_pCB_Diffusion->m.InternalEmissive = _TV(10.0f) * m_EmissivePower * float3( 1.0f, 0.8f, 0.2f );

		m_pCB_Diffusion->UpdateData();

gs_Device.SetRenderTarget( gs_Device.DefaultRenderTarget(), NULL );

		m_pRTZBuffer->SetPS( 10 );

		// Diffuse light through multiple passes
		for ( int PassIndex=0; PassIndex <= DIFFUSION_PASSES_COUNT; PassIndex++ )
		{
			gs_Device.SetRenderTarget( *m_ppRTDiffusion[1] );

			m_pCB_Pass->m.PassIndex = float(PassIndex);
			m_pCB_Pass->m.CurrentZ = 2.0f * PassIndex / DIFFUSION_PASSES_COUNT;
			m_pCB_Pass->m.NextZ = 2.0f * (PassIndex+1) / DIFFUSION_PASSES_COUNT;
			m_pCB_Pass->UpdateData();

			m_ppRTDiffusion[0]->SetPS( 11 );
			gs_pPrimQuad->Render( *m_pMatDiffusion );

			// Swap irradiance maps
			Texture2D*	pTemp = m_ppRTDiffusion[0];
			m_ppRTDiffusion[0] = m_ppRTDiffusion[1];
			m_ppRTDiffusion[1] = pTemp;
		}

		USING_MATERIAL_END
	}

	//////////////////////////////////////////////////////////////////////////
	// 4] Finally, render the object with a planar mapping of the irradiance map
	{	USING_MATERIAL_START( *m_pMatDisplay )

		gs_Device.SetRenderTarget( m_RTTarget, &gs_Device.DefaultDepthStencil() );
		gs_Device.SetStates( gs_Device.m_pRS_CullBack, gs_Device.m_pDS_ReadWriteLess, NULL );

		m_ppRTDiffusion[0]->SetPS( 10 );

		// Render the sphere
		m_pCB_Object->m.Local2World.PRS( float3( 0, 1, 0 ), float4::QuatFromAngleAxis( _TV(0.0f) * _Time, float3::UnitY ), float3::One );
		m_pCB_Object->m.EmissiveColor = float4::Zero;
		m_pCB_Object->m.NoiseOffset = SphereNoise;
		m_pCB_Object->UpdateData();

		m_pPrimSphereExternal->Render( *m_pMatDisplay );

		// Render the torus
		m_pCB_Object->m.Local2World.PRS( float3( 0, 1, 0 ) + TorusPosition, TorusRotation, float3::One );
		m_pCB_Object->m.EmissiveColor = float4( 0.0f * float3::One + m_pCB_Diffusion->m.InternalEmissive, 1.0f );
		m_pCB_Object->m.NoiseOffset = TorusNoise;
		m_pCB_Object->UpdateData();

		m_pPrimTorusInternal->Render( *m_pMatDisplay );

		USING_MATERIAL_END
	}
}
void Editor::redraw()
{

	if (!isInit)
	{
		initEditor();
		isInit = true;
	}

	vec3f bgColor, gridColor;
	glColor3f( 1.0, 1.0, 1.0 );
	if (!m_level)
	{
		glClearColor( _TV( 0.2f ), _TV(0.0f), _TV( 0.0f ), 1.0 );
		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

		gfEnableFont( m_fntFontId, 32 );	
		gfBeginText();
		glTranslated( _TV(260), _TV(550), 0 );
		gfDrawString( "No Level Active" );
		gfEndText();
	}
	else
	{
		bgColor = m_level->m_bgColor;
		gridColor = (bgColor + vec3f( 1.0f, 1.0f, 1.0f )) / 2.0f;

		glClearColor( bgColor.r, bgColor.g, bgColor.b, 1.0 );
		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	}


	// at this point we need a level to draw
	if (m_level)
	{
		// reset the view to be map space
		glMatrixMode( GL_PROJECTION );
		glLoadIdentity();

		if (m_useEditView)
		{
			gluOrtho2D( m_viewport.x, m_viewport.x + m_viewsize.x, 
				m_viewport.y, m_viewport.y + m_viewsize.y ) ;
		}
		else
		{
			pseudoOrtho2D( m_gameview.x, m_gameview.x + 800,
				m_gameview.y, m_gameview.y + 600 );
		}

		glMatrixMode( GL_MODELVIEW );
		glLoadIdentity();
		
		// Draw the level grid
		float zval = _TV( -0.5f );
		glColor3f( gridColor.r, gridColor.g, gridColor.b );
		glDisable( GL_TEXTURE );

		glLineWidth( 2.0f );
		glBegin( GL_LINE_LOOP );
		glVertex3f( 0.0, 0.0, zval );
		glVertex3f( m_level->m_mapSize.x, 0.0, zval );
		glVertex3f( m_level->m_mapSize.x, m_level->m_mapSize.y, zval );
		glVertex3f( 0.0, m_level->m_mapSize.y, zval );	
		glEnd();


		// draw grid lines
		glLineWidth( 1.0f );
		glBegin( GL_LINES );
		for (float xpos=800; xpos < m_level->m_mapSize.x; xpos += 800.0)
		{
			glVertex3f( xpos, 0.0, zval );
			glVertex3f( xpos, m_level->m_mapSize.y, zval );
		}

		for (float ypos = 600; ypos < m_level->m_mapSize.y; ypos += 600.0)
		{
			glVertex3f( 0.0, ypos, zval);
			glVertex3f( m_level->m_mapSize.x, ypos, zval );
		}
		glEnd();

		glLineWidth( 1.0f );
		glEnable( GL_LINE_STIPPLE );
		glLineStipple( 1, 0xAAAAAAAA );
		glBegin( GL_LINES );
		for (float xpos=100; xpos < m_level->m_mapSize.x; xpos += 100.0)
		{
			glVertex3f( xpos, 0.0, zval );
			glVertex3f( xpos, m_level->m_mapSize.y, zval );
		}

		for (float ypos = 100; ypos < m_level->m_mapSize.y; ypos += 100.0)
		{
			glVertex3f( 0.0, ypos,zval );
			glVertex3f( m_level->m_mapSize.x, ypos, zval );
		}
		glEnd();
		glDisable( GL_LINE_STIPPLE );		

		// draw the "game view" extents
		if (m_useEditView)
		{
			glLineWidth( 2.0f );
			glColor3f( 0.7f, 0.4f, 0.7f );

			glPushMatrix();
			glTranslated( m_gameview.x, m_gameview.y, 0.0 );

			glBegin( GL_LINE_LOOP );
			glVertex3f( 0.0, 0.0, 0.0 );
			glVertex3f( 800, 0.0, 0.0 );
			glVertex3f( 800, 600, 0.0 );
			glVertex3f( 0.0, 600, 0.0 );			
			glEnd();

			glPopMatrix();
		}

		

		// draw the level
		m_level->draw();
	
		// draw icons		
		glEnable( GL_TEXTURE_2D );
		glDisable( GL_BLEND );
		glEnable( GL_ALPHA_TEST );		
		glAlphaFunc( GL_GREATER, 0.5 );

		iconSpawnPoint->pos = m_level->m_spawnPoint;
		iconSpawnPoint->pos.y += 16.0;
		iconSpawnPoint->drawBraindead();
								
		
		if (drawLine)
		{
			// drawing a line (for collision)
			glDisable( GL_TEXTURE_2D );
			
			vec3f col = segColor( currSegType );
			glColor3f( col.r, col.g, col.b );

			glLineWidth( 5 );
			glBegin( GL_LINES );
			glVertex3f( m_dragStart.x, m_dragStart.y, 0.0 );
			glVertex3f( m_mousePos.x, m_mousePos.y, 0.0 );
			glEnd();

			glColor3f( 1.0f, 1.0f, 1.0f );
		} 
		else if (m_activeShape)
		{
			// draw the active shape (aka "cursor")		
			glEnable( GL_TEXTURE_2D );
			if (m_activeShape->blendMode == Blend_OFF)
			{
				glDisable( GL_BLEND );
				glEnable( GL_ALPHA_TEST );
				glAlphaFunc( GL_GREATER, 0.5 );
			}
			else
			{
				glEnable( GL_BLEND );
				glDisable( GL_ALPHA_TEST );
				glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );		
			}

			m_activeShape->sortNum = m_sort;
			m_activeShape->drawBraindead();			
		}				
	
	}

	// draw regular collision lines
	if (m_level)
	{
		glDisable( GL_TEXTURE_2D );
		glColor3f( 1.0f, 1.0f, 0.5f );
		glLineWidth( 3 );
			
		glBegin( GL_LINES );
		for (int i=0; i < m_level->m_collision.size(); i++)
		{
			Segment &s = m_level->m_collision[i];
			vec3f col = segColor( s.segType );
			glColor3f( col.r, col.g, col.b );

			glVertex3f( s.a.x, s.a.y, 0.0 );
			glVertex3f( s.b.x, s.b.y, 0.0 );		
			
		}		
		glEnd();
	}

	// now draw any text overlay		
	if (m_showHelp)
	{
		glColor3f( 1.0f, 1.0f, 1.0f );
		gfEnableFont( m_fntFontId, 20 );	
		gfBeginText();
		glTranslated( _TV(50), _TV(500), 0 );
		
		gfDrawString( "------[ EDITOR KEYS ]------\n" 
			          "h - toggle this help\n" 
					  "F2 - save level\n"
					  "F3 - load level\n"
	    			  "1,2,3 - New Level (small, med, large)\n" 					  
					  "f - frame view\n" 
					  "<,> - select brush\n" 
					  "TAB - toggle editor/closeup\n" 
					  "ARROWS - move view\n"
					  "a,z,s,x - change sort\n"
					  "o,p,brackets - brush size\n"
					  "k,l - zoom view\n" 
					  "8,9 - segment type\n"
					  "0 - spawn point\n"
					  "mousewheel - rotate brush\n"
					  "SPC, LMB - stamp brush\n"
					  "Drag RMB - draw segment\n"
					  );			
		gfEndText();
	}	

	// draw the active shape info
	if (m_activeShape)
	{
		glEnable( GL_TEXTURE_2D );		

		glColor3f( 1.0f, 1.0f, 1.0f );

		gfEnableFont( m_fntFontId, 20 );	
		gfBeginText();
		glTranslated( _TV(650), _TV(570), 0 );		
		
		gfDrawStringFmt( "%s (%d)",
				m_activeShape->name.c_str(),
				m_sort );
		gfEndText();

		vec3f col = segColor( currSegType );
		glColor3f( col.r, col.g, col.b );
		gfBeginText();
		glTranslated( _TV(650), _TV(550), 0 );		
				
		gfDrawString( SegTypeNames[ currSegType ] );

		gfEndText();
		
		glDisable( GL_TEXTURE_2D );
	}
}
void IslandGame::redraw( )
{
	//static bool gfxInit = false;
	//if (!gfxInit)
	//{
	//	initGraphics();
	//	gfxInit = true;
	//}

	glClearColor( 0.3, 1.0, 1.0, 1.0 );
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

	// 3d stuff
	glEnable( GL_DEPTH_TEST );
	glEnable( GL_TEXTURE_2D );
	glEnable( GL_TEXTURE );

	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();	

	int useOrtho = _TV(1);
	if (!useOrtho)
	{
		gluPerspective( _TV(2.0f), 800.0/600.0, 0.1, 1000.0 );
	}
	else
	{
		float aspect = 800.0 / 600.0;
		float hite = _TV(4.0f);
		glOrtho( -aspect * hite, aspect * hite, -hite, hite, 0.1, 1000.0 );
	}

	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();	
	
	glDisable( GL_LIGHTING );

	// player
	MapSquare &mp = m_map[m_px][m_py];
	vec3f ppos( m_px + 0.5f, 
				(mp.m_elevation+1.0) * 0.3f, 
				m_py + 0.5f );
	
	//gluLookAt( ppos.x, ppos.y + 1, ppos.z + 1,
	//		   ppos.x, ppos.y, ppos.z,
	//		   0.0, 1.0, 0.0 );	
	glRotatef( _TV(29.7f), 1.0, 0.0, 0.0 );
	glTranslatef( _TV(0), _TV(-6), _TV(-8) );
	glRotatef( _TV(45.0f), 0.0, 1.0, 0.0 );

	glTranslatef( m_camPos.x * _TV(-1.0f), 
				  m_camPos.y * _TV( 0.0f), 
				  m_camPos.z  * _TV(-1.0f));
	

	//static float ang = 0;
	//glRotatef( ang, 0.0, 1.0, 0.0 );
	//ang += 1;	

	glDisable( GL_TEXTURE_2D );
#if 0	
	glLineWidth( 4.0 );
	glBegin( GL_LINES );

	glColor3f( 1.0, 0.0, 0.0 );
	glVertex3f( ppos.x-1.0, ppos.y + 0.01, ppos.z );
	glVertex3f( ppos.x+1.0, ppos.y + 0.01, ppos.z );

	glColor3f( 0.0, 1.0, 0.0 );
	glVertex3f( ppos.x, ppos.y -1.0, ppos.z );
	glVertex3f( ppos.x, ppos.y +1.0, ppos.z );

	glColor3f( 0.0, 0.0, 1.0 );
	glVertex3f( ppos.x, ppos.y + 0.01, ppos.z - 1.0 );
	glVertex3f( ppos.x, ppos.y + 0.01, ppos.z + 1.0 );

	glEnd();
#endif

	glColor3f( 1.0, 1.0, 1.0 );
	glEnable( GL_TEXTURE_2D );	

	// draw some stuff the easy way
	glBindTexture( GL_TEXTURE_2D, m_waterTexId );	
	glBegin( GL_QUADS );
	
	glTexCoord2f( 0.0, 0.0 );
	glVertex3f( -2000, 0, -2000 );

	glTexCoord2f( 0.0, 1000.0 );
	glVertex3f( -2000, 0, 2000 );

	glTexCoord2f( 1000.0, 1000.0 );
	glVertex3f( 2000, 0, 2000 );

	glTexCoord2f( 1000.0, 0.0 );
	glVertex3f( 2000, 0, -2000 );

	glEnd();

	glEnable( GL_TEXTURE_2D );	
	//glColor3f( 1.0, 0.0, 1.0 );	

	// draw player
	glPushMatrix();	
	glTranslatef( ppos.x, ppos.y, ppos.z );
	glScalef( 0.4f, 0.4f, 0.4f );
	glRotatef( getRotForDir(m_pdir), 0.0, 1.0, 0.0 );
	glBindTexture( GL_TEXTURE_2D, m_playerTex );
	glCallList( m_personMesh );
	glPopMatrix();

	// draw critters
	for (std::vector<Critter*>::iterator ci = m_critters.begin(); 
		 ci != m_critters.end(); ci++)
	{
		Critter *c = (*ci);
		float elev = (m_map[c->m_x][c->m_y].m_elevation + 1.0) * 0.3;
		glPushMatrix();	
		glTranslatef( c->m_x + 0.5f, elev, c->m_y + 0.5f );
		glScalef( 0.4f, 0.4f, 0.4f );

		if (c->m_behavior == BEHAVIOR_STATIC)
		{
			glRotatef( getRotLookAt( c->m_x, c->m_y ), 0.0, 1.0, 0.0 );
		}
		else
		{
			glRotatef( getRotForDir( c->m_dir ), 0.0, 1.0, 0.0 );
		}

		glBindTexture( GL_TEXTURE_2D, c->m_critterTex );
		glCallList( m_critterMesh );
		glPopMatrix();
	}

	// draw npcs
	for (std::vector<Npc*>::iterator ci = m_npcs.begin(); 
		 ci != m_npcs.end(); ci++)
	{
		Npc *npc = (*ci);
		float elev = (m_map[npc->m_x][npc->m_y].m_elevation + 1.0) * 0.3;
		glPushMatrix();	
		glTranslatef( npc->m_x + 0.5f, elev, npc->m_y + 0.5f );
		glScalef( 0.4f, 0.4f, 0.4f );
		glRotatef( getRotLookAt( npc->m_x, npc->m_y ), 0.0, 1.0, 0.0 );
		glBindTexture( GL_TEXTURE_2D, npc->m_personTex );
		glCallList( m_personMesh );
		glPopMatrix();
	}

	glEnable( GL_LIGHTING );
	glEnable( GL_LIGHT0 );
	glEnable( GL_LIGHT1 );	

	glBindTexture( GL_TEXTURE_2D, m_terrainTilesTexId );

	// Bind the island VBO
	glBindBuffer(GL_ARRAY_BUFFER, m_islandVBO);

	//glEnableVertexAttribArray( MapVert::ATTRIB_VERTEX);
	//glEnableVertexAttribArray( MapVert::ATTRIB_TEXCOORD );
	//glEnableVertexAttribArray( ATTRIB_NORMAL );
	
	//glVertexAttribPointer( MapVert::ATTRIB_VERTEX,   4, GL_FLOAT, GL_FALSE, sizeof(MapVert), 0);
	//glVertexAttribPointer( MapVert::ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(MapVert), (void*)(3*sizeof(GLfloat)) );
	//glVertexAttribPointer( ATTRIB_NORMAL,   3, GL_FLOAT, GL_FALSE, sizeof(MapVert), (void*)(6*sizeof(GLfloat)) );
	
	//glBufferData( GL_ARRAY_BUFFER, sizeof(MapVert) * m_quadSize, 0, GL_STATIC_DRAW );
	//glVertexPointer( 4, GL_FLOAT, sizeof(MapVert), NULL );
	//

	glEnableClientState( GL_VERTEX_ARRAY );
	glVertexPointer( 3, GL_FLOAT, sizeof(MapVert), 0 );
	
	glEnableClientState( GL_TEXTURE_COORD_ARRAY );	
	glTexCoordPointer( 2, GL_FLOAT, sizeof(MapVert), (void*)(4*sizeof(GLfloat)) );

	glEnableClientState( GL_NORMAL_ARRAY );
	glNormalPointer( GL_FLOAT, sizeof(MapVert), (void*)(6*sizeof(GLfloat)) );
	
	glDrawArrays( GL_QUADS, 0, m_quadSize );

	glDisableClientState( GL_TEXTURE_COORD_ARRAY );
	glDisableClientState( GL_NORMAL_ARRAY );
	glDisableClientState( GL_VERTEX_ARRAY );

	// 2D text and GUI stuff
	glDisable( GL_DEPTH_TEST );	
	
	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();

	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();

	glDisable( GL_LIGHTING );		
	

	glColor3f( 1.0, 1.0, 1.0 );
		
	if (m_showHudText)
	{
		gfEnableFont( m_fntFontId, 32 );
		gfBeginText();		

		// draw background box
		glDisable( GL_TEXTURE_2D );
		glColor4f( 0.0, 0.0, 0.0, 0.6 );
		glBegin( GL_QUADS );
		glVertex2f( 0, 0 ); glVertex2f( 0, 210 );
		glVertex2f( 800, 210 ); glVertex2f( 800, 0 );
		glEnd();
		glColor4f( 1.0, 1.0, 0.0, 1.0 );

		glEnable( GL_TEXTURE_2D );

		glTranslated( 20, 170, 0 );		
		gfDrawString( m_hudTitle.c_str() );
		gfEndText();

		glColor4f( 1.0, 1.0, 1.0, 1.0 );
		gfEnableFont( m_fntFontId, 20 );
		gfBeginText();		
		glTranslated( 20, 130, 0 );		
		gfDrawString( m_hudText.c_str() );
		gfEndText();
	}

}