//***********************************************************************//
//																		 //
//		- "Talk to me like a 3 year old!" Programming Lessons -			 //
//                                                                       //
//		$Author:		DigiBen			DigiBen@GameTutorials.com		 //
//																		 //
//		$Program:		HeightMap3										 //
//																		 //
//		$Description:	Show how to apply a detail texture to a terrain  //
//																		 //
//		$Date:			5/28/02											 //
//																		 //
//***********************************************************************//

// This is a compiler directive that includes libraries (For Visual Studio)
// You can manually include the libraries in the "Project->settings" menu under
// the "Link" tab.  You need these libraries to compile this program.
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glaux.lib")

#include "main.h"								// This includes our main header file
#include "camera.h"								// This includes our camera's header file

bool  g_bFullScreen = true;						// Set full screen as default
HWND  g_hWnd;									// This is the handle for the window
RECT  g_rRect;									// This holds the window dimensions
HDC   g_hDC;									// General HDC - (handle to device context)
HGLRC g_hRC;									// General OpenGL_DC - Our Rendering Context for OpenGL
HINSTANCE g_hInstance;							// This holds the global hInstance for UnregisterClass() in DeInit()

/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
//
// Now that you most likely know and understand how to create a terrain from a
// height map and texture it, we move on to the next step.  We get to apply a
// second texture on top of our current texture to give a fake detail and/or almost
// fony bump mapping to it.  This technique is done by blending and tiling a
// second texture over top of our current terrain texture with multitexturing.  Just
// so the detail texture doesn't over power the terrain texture, we increase the
// gamma on the detail texture to produce a nice blend between the two.
// 
// It is assumed that you have looked over the multitexturing and previous height
// map tutorials before attempting to tackle this one.  If you are just interested
// in the detail texturing, you can skip over to Terrain.cpp and look at all the
// code between the * NEW * blocks.
// 
// If for some reason your video card can't support textures over 256 x 256, you
// can easily just shrink the textures to this tutorial down with any paint program.
//
//

// Our function pointers for the ARB multitexturing functions
PFNGLMULTITEXCOORD2FARBPROC		glMultiTexCoord2fARB	 = NULL;
PFNGLACTIVETEXTUREARBPROC		glActiveTextureARB		 = NULL;

// This controls if we have detail texturing on or off
bool g_bDetail = true;

// This handles the current scale for the texture matrix for the detail texture
int g_DetailScale = 16;

/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

tBoundingBox bbArray[MAXBOX];

GLUquadricObj *quad;

float angle=0.0f;

// This is our global camera object
CCamera g_Camera;								

// This holds the height map data
BYTE g_HeightMap[MAP_SIZE*MAP_SIZE];			

// This tells us if we want lines or fill mode
bool  g_bRenderMode = true;						

// This holds the texture info by an ID
UINT g_Texture[MAX_TEXTURES] = {0};				

#define BACK_ID		11		// The texture ID for the back side of the cube
#define FRONT_ID	12		// The texture ID for the front side of the cube
#define BOTTOM_ID	13		// The texture ID for the bottom side of the cube
#define TOP_ID		14		// The texture ID for the top side of the cube
#define LEFT_ID		15		// The texture ID for the left side of the cube
#define RIGHT_ID	16		// The texture ID for the right side of the cube


///////////////////////////////// INIT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function initializes the application
/////
///////////////////////////////// INIT  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void Init(HWND hWnd)
{
	g_hWnd = hWnd;										// Assign the window handle to a global window handle
	GetClientRect(g_hWnd, &g_rRect);					// Assign the windows rectangle to a global RECT
	InitializeOpenGL(g_rRect.right, g_rRect.bottom);	// Init OpenGL with the global rect
	quad = gluNewQuadric();					// Create A Pointer To The Quadric Object ( NEW )

	
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

	// Here we initialize our multitexturing functions
	glActiveTextureARB		= (PFNGLACTIVETEXTUREARBPROC)		wglGetProcAddress("glActiveTextureARB");
	glMultiTexCoord2fARB	= (PFNGLMULTITEXCOORD2FARBPROC)		wglGetProcAddress("glMultiTexCoord2fARB");

	// We should have our multitexturing functions defined and ready to go now, but let's make sure
	// that the current version of OpenGL is installed on the machine.  If the extension functions
	// could not be found, our function pointers will be NULL.
	if(!glActiveTextureARB || !glMultiTexCoord2fARB)
	{
		// Print a error message and quit.
		MessageBox(g_hWnd, "Your current setups does not support multitexturing", "Error", MB_OK);
		PostQuitMessage(0);
	}

/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *


	// Here we read read in the height map from the .raw file and put it in our
	// g_HeightMap array.  We also pass in the size of the .raw file (1024).
	LoadRawFile("texture3/Terrain.raw", MAP_SIZE * MAP_SIZE, g_HeightMap);	

	glEnable(GL_DEPTH_TEST);							// Enables depth testing
	glEnable(GL_TEXTURE_2D);							// Enable texture mapping
//	glEnable(GL_CULL_FACE);								// Turn on back face culling

	CreateTexture(g_Texture[0],			"texture3/Terrain.bmp"); // Load the terrain texture
	CreateTexture(g_Texture[1],			"texture3/Detail.bmp");
	CreateTexture(g_Texture[BACK_ID],	"texture3/Back.bmp");	// Load the Sky box Back texture
	CreateTexture(g_Texture[FRONT_ID],	"texture3/Front.bmp");	// Load the Sky box Front texture
	CreateTexture(g_Texture[BOTTOM_ID], "texture3/Bottom.bmp");	// Load the Sky box Bottom texture
	CreateTexture(g_Texture[TOP_ID],	"texture3/Top.bmp");		// Load the Sky box Top texture
	CreateTexture(g_Texture[LEFT_ID],	"texture3/Left.bmp");	// Load the Sky box Left texture
	CreateTexture(g_Texture[RIGHT_ID],	"texture3/Right.bmp");	// Load the Sky box Right texture
	CreateTexture(g_Texture[2],			"texture3/NSXtop.bmp");	// Load the Sky box Right texture
	CreateTexture(g_Texture[3],			"texture3/NSXback.bmp");	// Load the Sky box Right texture
	// Give our camera a decent starting point in the world
	g_Camera.PositionCamera( 490, 35, 275,  491, 34.5f, 275,  0, 1, 0);
	float posY1 = (float)Height(g_HeightMap, 500, 272) + 2;
	float posY2 = (float)Height(g_HeightMap, 500, 277) + 2;
	float posY3 = (float)Height(g_HeightMap, 505, 277) + 2;
	float posY4 = (float)Height(g_HeightMap, 505, 272) + 2;
	g_Camera.PositionGoKart(500, posY1, 272.5, 500, posY2, 277.5, 505, posY3, 277.5, 505, posY4, 272.5);
	Init_BoundingBox();
}


///////////////////////////////// MAIN GAME LOOP \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function handles the main game loop
/////
///////////////////////////////// MAIN GAME LOOP \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

WPARAM MainLoop()
{
	MSG msg;

	while(1)											// Do our infinite loop
	{													// Check if there was a message
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
        { 
			if(msg.message == WM_QUIT)					// If the message wasn't to quit
				break;
            TranslateMessage(&msg);						// Find out what the message does
            DispatchMessage(&msg);						// Execute the message
        }
		else											// if there wasn't a message
		{ 
			g_Camera.Update();							// Update the camera data
			RenderScene();								// Render the scene every frame
        } 
	}
	
	DeInit();											// Clean up and free all allocated memory

	return(msg.wParam);									// Return from the program
}


///////////////////////////////// RENDER SCENE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function renders the entire scene.
/////
///////////////////////////////// RENDER SCENE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void RenderScene() 
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear The Screen And The Depth Buffer
	glLoadIdentity();									// Reset The matrix

	// Give OpenGL our camera position
	g_Camera.Look();

	// Render the height map
	RenderHeightMap(g_HeightMap);						

	// Create the sky box and center it around the terrain
	glPushMatrix();	
		glTranslatef(500.0f, 0.0f, 500.0f);			
		angle=angle+0.1f;
		if (angle>360)
			angle=0.0f;
		glRotatef(angle, 0.0f, 1.0f, 0.0f);
		CreateSkyBox(500, 578.5, 500, 4000, 1000, 4000);
	glPopMatrix();		

	g_Camera.kartPosTL.y = Height(g_HeightMap, (int)g_Camera.kartPosTL.x, (int)g_Camera.kartPosTL.z) + 2;
	g_Camera.kartPosTR.y = Height(g_HeightMap, (int)g_Camera.kartPosTR.x, (int)g_Camera.kartPosTR.z) + 2;
	//g_Camera.kartPosTR.y = g_Camera.kartPosTL.y;
	//g_Camera.kartPosBL.y = Height(g_HeightMap, (int)g_Camera.kartPosBL.x, (int)g_Camera.kartPosBL.z) + 2;
	//g_Camera.kartPosBR.y = Height(g_HeightMap, (int)g_Camera.kartPosBR.x, (int)g_Camera.kartPosBR.z) + 2;
	g_Camera.kartPosBR.y = g_Camera.kartPosTL.y;
	g_Camera.kartPosBL.y = g_Camera.kartPosTR.y;

	CVector3 vPos		= g_Camera.Position();
	CVector3 vNewPos    = vPos;

	// Check if the camera is below the height of the terrain at x and z,
	// but we add 10 to make it so the camera isn't on the floor.
	if(vPos.y < Height(g_HeightMap, (int)vPos.x, (int)vPos.z ) + 10)
	{
		// Set the new position of the camera so it's above the terrain + 10
		vNewPos.y = (float)Height(g_HeightMap, (int)vPos.x, (int)vPos.z ) + 10;

		// Get the difference of the y that the camera was pushed back up
		float temp = vNewPos.y - vPos.y;

		//  Get the current view and increase it by the different the position was moved
		CVector3 vView = g_Camera.View();
		vView.y += temp;

		// Set the new camera position.
		g_Camera.PositionCamera(vNewPos.x,  vNewPos.y,  vNewPos.z,
								vView.x,	vView.y,	vView.z,	0, 1, 0);
	}
	// Create GoKart
	CreateGoKart(g_Camera.kartPosTL, g_Camera.kartPosTR, g_Camera.kartPosBL, g_Camera.kartPosBR);

	// Swap the backbuffers to the foreground
	SwapBuffers(g_hDC);									
}

///////////////////////////////// WIN PROC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function handles the window messages.
/////
///////////////////////////////// WIN PROC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

LRESULT CALLBACK WinProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT    ps;

    switch (uMsg)
	{ 
    case WM_SIZE:										// If the window is resized
		if(!g_bFullScreen)								// Do this only if we are NOT in full screen
		{
			SizeOpenGLScreen(LOWORD(lParam),HIWORD(lParam));// LoWord=Width, HiWord=Height
			GetClientRect(hWnd, &g_rRect);				// Get the window rectangle
		}
        break; 
 
	case WM_PAINT:										// If we need to repaint the scene
		BeginPaint(hWnd, &ps);							// Init the paint struct		
		EndPaint(hWnd, &ps);							// EndPaint, Clean up
		break;


	case WM_LBUTTONDOWN:
	
		g_bDetail = !g_bDetail;
		break;

	case WM_RBUTTONDOWN:								// If the left mouse button was clicked
		
		g_bRenderMode = !g_bRenderMode;

		// Change the rendering mode to and from lines or triangles
		if(g_bRenderMode) 				
		{
			// Render the triangles in fill mode		
			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);	
		}
		else 
		{
			// Render the triangles in wire frame mode
			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);	
		}
		break;

	case WM_KEYDOWN:
		switch(wParam) 
		{
			case VK_ESCAPE:								// Check if we hit the ESCAPE key.
				PostQuitMessage(0);						// Tell windows we want to quit
				break;


/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

			case VK_SPACE:								// Check if we hit the SPACE bar

				// To get a few different ideas of what a detail texture
				// could look like, we want to change it's scale value.

				// Times the current scale value by 2 and loop when it get's to 128
				g_DetailScale = (g_DetailScale * 2) % 128;

				// If the scale value is 0, set it to 1 again
				if(g_DetailScale == 0)
					g_DetailScale = 1;

				break;

/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *


		}
		break;
 
    case WM_CLOSE:										// If the window is closed
        PostQuitMessage(0);								// Tell windows we want to quit
        break; 
    } 
 
    return DefWindowProc (hWnd, uMsg, wParam, lParam); 	// Return the default
}

///////////////////////////////// CREATE SKY BOX \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This creates a sky box centered around X Y Z with a width, height and length
/////
///////////////////////////////// CREATE SKY BOX \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void CreateSkyBox(float x, float y, float z, float width, float height, float length)
{
	// Turn on texture mapping if it's not already
	glEnable(GL_TEXTURE_2D);

	// Bind the BACK texture of the sky map to the BACK side of the cube
	glBindTexture(GL_TEXTURE_2D, g_Texture[BACK_ID]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	// This centers the sky box around (x, y, z)
	x = x - width  / 2;
	y = y - height / 2;
	z = z - length / 2;

	// Start drawing the side as a QUAD
	glBegin(GL_QUADS);		
		
		// Assign the texture coordinates and vertices for the BACK Side
		glTexCoord2f(1.0f, 0.0f); glVertex3f(x + width, y,			z);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(x + width, y + height, z); 
		glTexCoord2f(0.0f, 1.0f); glVertex3f(x,			y + height, z);
		glTexCoord2f(0.0f, 0.0f); glVertex3f(x,			y,			z);
		
	glEnd();

	// boundingbox for skybox BACK Side
	bbArray[0].min.x = x - DELTABOX;
	bbArray[0].max.x = x + width + DELTABOX;
	bbArray[0].min.y = y - DELTABOX;
	bbArray[0].max.y = y + height + DELTABOX;
	bbArray[0].min.z = z - DELTABOX;
	bbArray[0].max.z = z + DELTABOX;

	// Bind the FRONT texture of the sky map to the FRONT side of the box
	glBindTexture(GL_TEXTURE_2D, g_Texture[FRONT_ID]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);


	// Start drawing the side as a QUAD
	glBegin(GL_QUADS);	
	
		// Assign the texture coordinates and vertices for the FRONT Side
		glTexCoord2f(1.0f, 0.0f); glVertex3f(x,			y,			z + length);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(x,			y + height, z + length);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y + height, z + length); 
		glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y,			z + length);
	glEnd();

	// boundingbox for skybox Front Side
	bbArray[1].min.x = x - DELTABOX;
	bbArray[1].max.x = x + width + DELTABOX;
	bbArray[1].min.y = y - DELTABOX;
	bbArray[1].max.y = y + height + DELTABOX;
	bbArray[1].min.z = z + length - DELTABOX;
	bbArray[1].max.z = z + length + DELTABOX;

	// Bind the BOTTOM texture of the sky map to the BOTTOM side of the box
	glBindTexture(GL_TEXTURE_2D, g_Texture[BOTTOM_ID]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	// Start drawing the side as a QUAD
	glBegin(GL_QUADS);		
	
		// Assign the texture coordinates and vertices for the BOTTOM Side
		glTexCoord2f(1.0f, 0.0f); glVertex3f(x,			y,			z);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(x,			y,			z + length);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y,			z + length); 
		glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y,			z);
	glEnd();

	// Bind the TOP texture of the sky map to the TOP side of the box
	glBindTexture(GL_TEXTURE_2D, g_Texture[TOP_ID]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	// Start drawing the side as a QUAD
	glBegin(GL_QUADS);		
		
		// Assign the texture coordinates and vertices for the TOP Side
		glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y + height, z);
		glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y + height, z + length); 
		glTexCoord2f(1.0f, 0.0f); glVertex3f(x,			y + height,	z + length);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(x,			y + height,	z);
		
	glEnd();

	// Bind the LEFT texture of the sky map to the LEFT side of the box
	glBindTexture(GL_TEXTURE_2D, g_Texture[LEFT_ID]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	// Start drawing the side as a QUAD
	glBegin(GL_QUADS);		
		
		// Assign the texture coordinates and vertices for the LEFT Side
		glTexCoord2f(1.0f, 1.0f); glVertex3f(x,			y + height,	z);	
		glTexCoord2f(0.0f, 1.0f); glVertex3f(x,			y + height,	z + length); 
		glTexCoord2f(0.0f, 0.0f); glVertex3f(x,			y,			z + length);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(x,			y,			z);		
		
	glEnd();

	// boundingbox for skybox Left Side
	bbArray[2].min.x = x - DELTABOX;
	bbArray[2].max.x = x + DELTABOX;
	bbArray[2].min.y = y - DELTABOX;
	bbArray[2].max.y = y + height + DELTABOX;
	bbArray[2].min.z = z - DELTABOX;
	bbArray[2].max.z = z + length + DELTABOX;

	// Bind the RIGHT texture of the sky map to the RIGHT side of the box
	glBindTexture(GL_TEXTURE_2D, g_Texture[RIGHT_ID]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	// Start drawing the side as a QUAD
	glBegin(GL_QUADS);		

		// Assign the texture coordinates and vertices for the RIGHT Side
		glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y,			z);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(x + width, y,			z + length);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(x + width, y + height,	z + length); 
		glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y + height,	z);
	glEnd();

	// boundingbox for skybox Right Side
	bbArray[3].min.x = x + width - DELTABOX;
	bbArray[3].max.x = x + width + DELTABOX;
	bbArray[3].min.y = y - DELTABOX;
	bbArray[3].max.y = y + height + DELTABOX;
	bbArray[3].min.z = z - DELTABOX;
	bbArray[3].max.z = z + length + DELTABOX;
}

void CreateGoKart(CVector3 p1, CVector3 p2, CVector3 p3, CVector3 p4) // This object will symbolize our character
{
	glPushMatrix();		
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, g_Texture[2]);

	glBegin(GL_QUADS);		// Top
		glTexCoord2f(0.0f, 0.0f); glVertex3f(p1.x, p1.y+1, p1.z);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(p2.x, p2.y+1, p2.z);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(p3.x, p3.y+1, p3.z); 
		glTexCoord2f(0.0f, 1.0f); glVertex3f(p4.x, p4.y+1, p4.z);
	glEnd();

	glBindTexture(GL_TEXTURE_2D, g_Texture[3]);
	glBegin(GL_QUADS);		// Back
		glTexCoord2f(0.0f, 0.0f); glVertex3f(p1.x, p1.y, p1.z);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(p2.x, p2.y, p2.z);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(p2.x, p3.y+1, p2.z); 
		glTexCoord2f(0.0f, 1.0f); glVertex3f(p1.x, p4.y+1, p1.z);
	glEnd();
	
	glDisable(GL_TEXTURE_2D);	
	glBegin(GL_QUADS);		// Bottom
		glTexCoord2f(0.0f, 0.0f); glVertex3f(p1.x, p1.y, p1.z);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(p2.x, p2.y, p2.z);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(p3.x, p3.y, p3.z); 
		glTexCoord2f(0.0f, 1.0f); glVertex3f(p4.x, p4.y, p4.z);
	glEnd();
	glColor3f(1.0f,1.0f,1.0f);				

	glPopMatrix();

}

void Draw_BoundingBox()
{
	for(int i = 0; i < MAXBOX; i++)
	{
	glColor3f(0,0,1.0f);

	glBegin(GL_LINE_LOOP);
	glVertex3f( bbArray[i].min.x, bbArray[i].min.y, bbArray[i].min.z );
	glVertex3f( bbArray[i].max.x, bbArray[i].min.y, bbArray[i].min.z );
	glVertex3f( bbArray[i].max.x, bbArray[i].min.y, bbArray[i].max.z );
	glVertex3f( bbArray[i].min.x, bbArray[i].min.y, bbArray[i].max.z );
	glEnd();

	glBegin(GL_LINE_LOOP);
	glVertex3f( bbArray[i].min.x, bbArray[i].max.y, bbArray[i].min.z );
	glVertex3f( bbArray[i].max.x, bbArray[i].max.y, bbArray[i].min.z );
	glVertex3f( bbArray[i].max.x, bbArray[i].max.y, bbArray[i].max.z );
	glVertex3f( bbArray[i].min.x, bbArray[i].max.y, bbArray[i].max.z );
	glEnd();

	glBegin(GL_LINES);
	glVertex3f( bbArray[i].min.x, bbArray[i].min.y, bbArray[i].min.z );
	glVertex3f( bbArray[i].min.x, bbArray[i].max.y, bbArray[i].min.z );

	glVertex3f( bbArray[i].max.x, bbArray[i].min.y, bbArray[i].min.z );
	glVertex3f( bbArray[i].max.x, bbArray[i].max.y, bbArray[i].min.z );

	glVertex3f( bbArray[i].max.x, bbArray[i].min.y, bbArray[i].max.z );
	glVertex3f( bbArray[i].max.x, bbArray[i].max.y, bbArray[i].max.z );

	glVertex3f( bbArray[i].min.x, bbArray[i].min.y, bbArray[i].max.z );
	glVertex3f( bbArray[i].min.x, bbArray[i].max.y,bbArray[i]. max.z );
	glEnd();
	}
}

void Init_BoundingBox() 
{
	for(int i = 0; i < MAXBOX; i++)
	{
		// init bounding box min/max values
		if (bbArray[i].min.x == 0) bbArray[i].min.x =  999999.9f;
		if (bbArray[i].max.x == 0) bbArray[i].max.x = -999999.9f;
		if (bbArray[i].min.z == 0) bbArray[i].min.z =  999999.9f;
		if (bbArray[i].max.z == 0) bbArray[i].max.z = -999999.9f;
		if (bbArray[i].min.y == 0) bbArray[i].min.y =  999999.9f;
		if (bbArray[i].max.y == 0) bbArray[i].max.y = -999999.9f;
	}
}

int Collision_BoundingBox(int maxbox, CVector3 point)
{
	for (int i = 0; i < maxbox; i++)
	{
		if (Inside_BoundingBox(i,point) == 1) return i;
	}

	return -1;
}

bool Inside_BoundingBox(int box, CVector3 point)
{
	if( bbArray[box].max.x < point.x )
		return false;
	if( bbArray[box].min.x > point.x )
		return false;
	if( bbArray[box].max.z < point.z )
		return false;
	if( bbArray[box].min.z > point.z )
		return false;
	
	return true;	
}

/////////////////////////////////////////////////////////////////////////////////
//
// * QUICK NOTES * 
//
// Nothing was added to this file except the checking for the space bar,
// along with the global variables at the top.
// 
// This concludes the third tutorial in the height map series.
//
//
// Ben Humphrey (DigiBen)
// Game Programmer
// DigiBen@GameTutorials.com
// Co-Web Host of www.GameTutorials.com
// © 2000-2003 GameTutorials
//
     

