//////////////////////////////////////////////////////////////////////////////////////////////////
// 
// File: teapot.cpp
// 
// Author: Frank Luna (C) All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 
//
// Desc: Renders a teapot in wireframe mode.  Shows how to create a teapot 
//       using the D3DXCreateTeapot function and how to render the teapot
//       using the ID3DXMesh::DrawSubset method.
//          
//////////////////////////////////////////////////////////////////////////////////////////////////

#include "d3dUtility.h"
#include "scene.h"
#include <kLibrary\factory\factory.h>
#include "box.h"
#include "sphere.h"
#include "cylinder.h"
#include "material.h"
#include "light.h"
#include "texture.h"
#include "pivot.h"
#include "objLoader.h"
#include "camera.h"
#include "xLoader.h"
#include "terrain.h"

cbk::Scene& myScene = cbk::Scene::Instance();

//
// Framework Functions
//
bool Setup()
{
	//Setup lights//
	CBK::Light* cLight;

	cLight = new CBK::Light(myScene.getDevice());
	cLight->setDirection(D3DXVECTOR3(1.0f, -1.0f, 0.0f));
	cLight->setColor(d3d::WHITE * 0.6f, d3d::WHITE * 0.8f, d3d::WHITE);
	cLight->setType(D3DLIGHT_DIRECTIONAL);
	myScene.addLight("Sun", cLight);

	cLight = new CBK::Light(myScene.getDevice());
	cLight->setDirection(D3DXVECTOR3(-1.0f, 1.0f, 0.0f));
	cLight->setColor(d3d::BLACK, d3d::WHITE * 0.2f, d3d::WHITE * 0.25f);
	cLight->setType(D3DLIGHT_DIRECTIONAL);
	myScene.addLight("Back", cLight);

	cLight = new CBK::Light(myScene.getDevice());
	cLight->setDirection(D3DXVECTOR3(0.0f, -1.0f, 0.0f));
	cLight->setColor(d3d::BLACK, d3d::WHITE * 0.2f, d3d::WHITE * 0.25f);
	cLight->setType(D3DLIGHT_DIRECTIONAL);
	myScene.addLight("Top", cLight);

	//Setup Objects
	CBK::Shape* cObject;

	cObject = new CBK::Shape(new CBK::Shapes::Sphere(CBK::MeshParam(myScene.getDevice())),myScene.getDevice());
	cObject->load("");
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->setMaterial("0 1 1 1 0 0 1 1 1 1 1 1 0 0 0 0 20");
	cObject->move(0.0f, 0.0f, 200.0f);
	cObject->scale(10.0f, 10.0f, 10.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	myScene.addObject("Sphere1", cObject);

	cObject = new CBK::Shape(new CBK::Shapes::Sphere(CBK::MeshParam(myScene.getDevice())),myScene.getDevice());
	cObject->load("");
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->setMaterial("1 0 1 1 0 0 1 1 1 1 1 1 0 0 0 0 20");
	cObject->move(0.0f, 0.0f, 0.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	cObject->scale(10.0f, 10.0f, 10.0f);
	myScene.addObject("Sphere2", cObject);

	cObject = new CBK::Shape(new CBK::Shapes::Sphere(CBK::MeshParam(myScene.getDevice())),myScene.getDevice());
	cObject->load("");
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->setMaterial("1 1 1 1 0 0 1 1 1 1 1 1 0 0 0 0 20");
	cObject->move(200.0f, 0.0f, 0.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	cObject->scale(10.0f, 10.0f, 10.0f);
	myScene.addObject("Sphere3", cObject);

	cObject = new CBK::Shape(new CBK::Shapes::Sphere(CBK::MeshParam(myScene.getDevice())),myScene.getDevice());
	cObject->load("");
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->setMaterial("0 1 0 1 0 0 1 1 1 1 1 1 0 0 0 0 20");
	cObject->move(100.0f, 0.0f, 100.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	cObject->scale(10.0f, 10.0f, 10.0f);
	myScene.addObject("Sphere4", cObject);

	cObject = new CBK::Shape(new CBK::Shapes::Sphere(CBK::MeshParam(myScene.getDevice())),myScene.getDevice());
	cObject->load("");
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->setMaterial("1 0 0 1 0 0 1 1 1 1 1 1 0 0 0 0 20");
	cObject->move(100.0f, 0.0f, 0.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	cObject->scale(10.0f, 10.0f, 10.0f);
	myScene.addObject("Sphere5", cObject);

	cObject = new CBK::Shape(new CBK::Shapes::Sphere(CBK::MeshParam(myScene.getDevice())),myScene.getDevice());
	cObject->load("");
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->setMaterial("1 1 0 1 0 0 1 1 1 1 1 1 0 0 0 0 20");
	cObject->move(0.0f, 0.0f, 100.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	cObject->scale(10.0f, 10.0f, 10.0f);
	myScene.addObject("Sphere6", cObject);

	cObject = new CBK::Shape(new CBK::Shapes::Sphere(CBK::MeshParam(myScene.getDevice())),myScene.getDevice());
	cObject->load("");
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->setMaterial("0 0 0 1 0 0 1 1 1 1 1 1 0 0 0 0 20");
	cObject->move(200.0f, 0.0f, 200.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	cObject->scale(10.0f, 10.0f, 10.0f);
	myScene.addObject("Sphere7", cObject);


	cObject = new CBK::Shape(new CBK::Shapes::Sphere(CBK::MeshParam(myScene.getDevice())),myScene.getDevice());
	cObject->load("");
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->setMaterial("0.5 1 1 1 0 0 1 1 1 1 1 1 0 0 0 0 20");
	cObject->move(100.0f, 0.0f, 200.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	cObject->scale(10.0f, 10.0f, 10.0f);
	myScene.addObject("Sphere8", cObject);

	cObject = new CBK::Shape(new CBK::Shapes::Sphere(CBK::MeshParam(myScene.getDevice())),myScene.getDevice());
	cObject->load("");
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->setMaterial("1 0.5 1 1 0 0 1 1 1 1 1 1 0 0 0 0 20");
	cObject->move(200.0f, 0.0f, 100.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	cObject->scale(10.0f, 10.0f, 10.0f);
	myScene.addObject("Sphere9", cObject);

	cObject = new CBK::Shape(new CBK::Shapes::Sphere(CBK::MeshParam(myScene.getDevice())),myScene.getDevice());
	cObject->load("");
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->setMaterial("1 0.5 0.5 1 0 0 1 1 1 1 1 1 0 0 0 0 20");
	cObject->move(0.0f, 0.0f, -200.0f);
	cObject->scale(10.0f, 10.0f, 10.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	myScene.addObject("Sphere10", cObject);

	cObject = new CBK::Shape(new CBK::Shapes::Sphere(CBK::MeshParam(myScene.getDevice())),myScene.getDevice());
	cObject->load("");
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->setMaterial("0.5 1 0.5 1 0 0 1 1 1 1 1 1 0 0 0 0 20");
	cObject->move(-200.0f, 0.0f, 0.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	cObject->scale(10.0f, 10.0f, 10.0f);
	myScene.addObject("Sphere11", cObject);

	cObject = new CBK::Shape(new CBK::Shapes::Sphere(CBK::MeshParam(myScene.getDevice())),myScene.getDevice());
	cObject->load("");
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->setMaterial("0.5 0.5 0.5 1 0 0 1 1 1 1 1 1 0 0 0 0 20");
	cObject->move(-100.0f, 0.0f, -100.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	cObject->scale(10.0f, 10.0f, 10.0f);
	myScene.addObject("Sphere12", cObject);

	cObject = new CBK::Shape(new CBK::Shapes::Sphere(CBK::MeshParam(myScene.getDevice())),myScene.getDevice());
	cObject->load("");
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->setMaterial("1 0.5 0.5 1 0 0 1 1 1 1 1 1 0 0 0 0 20");
	cObject->move(-100.0f, 0.0f, 0.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	cObject->scale(10.0f, 10.0f, 10.0f);
	myScene.addObject("Sphere13", cObject);

	cObject = new CBK::Shape(new CBK::Shapes::Sphere(CBK::MeshParam(myScene.getDevice())),myScene.getDevice());
	cObject->load("");
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->setMaterial("0 0 0.5 1 0 0 1 1 1 1 1 1 0 0 0 0 20");
	cObject->move(0.0f, 0.0f, -100.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	cObject->scale(10.0f, 10.0f, 10.0f);
	myScene.addObject("Sphere14", cObject);

	cObject = new CBK::Shape(new CBK::Shapes::Sphere(CBK::MeshParam(myScene.getDevice())),myScene.getDevice());
	cObject->load("");
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->setMaterial("1 1 0.5 1 0 0 1 1 1 1 1 1 0 0 0 0 20");
	cObject->move(-200.0f, 0.0f, -200.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	cObject->scale(10.0f, 10.0f, 10.0f);
	myScene.addObject("Sphere15", cObject);

	cObject = new CBK::Shape(new CBK::Shapes::Sphere(CBK::MeshParam(myScene.getDevice())),myScene.getDevice());
	cObject->load("");
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->setMaterial("1 0.5 1 1 0 0 1 1 1 1 1 1 0 0 0 0 20");
	cObject->move(-100.0f, 0.0f, -200.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	cObject->scale(10.0f, 10.0f, 10.0f);
	myScene.addObject("Sphere16", cObject);

/*
	cObject = new CBK::Shape(myScene.getDevice());
	cObject->setMeshLoader(myScene.getMeshFactory());
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->load("bigship1.x");
	cObject->setMaterial("0.5 1 1 1 0 0 1 1 1 1 1 1 0 0 0 0 20");
	cObject->move(-200.0f, 0.0f, -100.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	cObject->scale(5.0f, 5.0f, 5.0f);
	myScene.addObject("Sphere17", cObject);
*/
/*
	cObject = new CBK::Shape(new CBK::Shapes::objLoader("triCube2.obj", CBK::MeshParam(myScene.getDevice(), myScene.getMaterialFactory(), myScene.getTextureFactory())), myScene.getDevice());
	cObject->setMaterial("1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 20");
	cObject->setTexture("crate.jpg");
	cObject->setParent(myScene.getObject("CenterPivot"));
	cObject->move(0.0f, 0.0f, -2.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	myScene.addObject("objFile", cObject);

	cObject = new CBK::Shape(myScene.getDevice());
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->setMeshLoader(myScene.getMeshFactory());
	cObject->load("bigship1.x");
	cObject->scale(0.15f, 0.15f, 0.15f);
	cObject->setParent(myScene.getObject("CenterPivot"));
	cObject->move(0.0f, 0.0f, 2.0f);
	cObject->addLight(myScene.getLight("Sun"));
	cObject->addLight(myScene.getLight("Back"));
	cObject->addLight(myScene.getLight("Top"));
	myScene.addObject("BigShip", cObject);
*/
	myScene.sortObjects();

	cObject = myScene.addTerrian("coastMountain64.raw", "Main", 64, 64, 50, 1.0f);
	cObject->setMaterialLoader(myScene.getMaterialFactory());
	cObject->setTextureLoader(myScene.getTextureFactory());
	cObject->addLight(myScene.getLight("Sun"));
	cObject->setMaterial("1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 20");
	myScene.applyTerrain("Main");

	//
	// Position and aim the camera.
	//
	CBK::Camera* cCamera;

	cCamera = new CBK::Camera(CBK::Camera::AIRCRAFT, myScene.getDevice());
	cCamera->setPosition(0.0f, cCamera->getTerrainOffset(), 0.0f);
	cCamera->pitch(2.0f * 3.1415926535f / 4.0f);
	myScene.addCamera("Main", cCamera);
	myScene.applyCamera("Main");

	//
	// Set projection matrix.
	//

	myScene.getDevice()->SetRenderState(D3DRS_SPECULARENABLE, true);
	myScene.getDevice()->SetRenderState(D3DRS_NORMALIZENORMALS, true);

	return true;
}

void Cleanup()
{
//	delete TheTerrain;
}

bool Display(float timeDelta)
{
	CBK::Light::numLightChanges = 0;
	CBK::Texture::numTextureChanges = 0;
	CBK::Material::numMaterialChanges = 0;
	myScene.update(timeDelta).draw();

	return true;
}

//
// WndProc
//
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	if (myScene.getDevice() == 0) return DefWindowProc(hwnd, msg, wParam, lParam);

	switch( msg )
	{
	case WM_DESTROY:
		{
			::PostQuitMessage(0);
			break;
		}
	
	case WM_GETMINMAXINFO:
		{
			MINMAXINFO& minmax = *(reinterpret_cast<MINMAXINFO*>(lParam));
			minmax.ptMinTrackSize.x = 320;
			minmax.ptMinTrackSize.y = 240;
			return 0;
		}

	case WM_SIZING:
		{
			RECT& newSize = *(reinterpret_cast<RECT*>(lParam));

			switch (wParam)
			{
			case WMSZ_TOP:
			case WMSZ_BOTTOM:
				{
					LONG nWidth = LONG((320.0f/240.0f) * float(newSize.bottom - newSize.top));
					newSize.right = nWidth + newSize.left;
					break;
				}

			default:
				{
					LONG nHeight = LONG((240.0f/320.0f) * float(newSize.right - newSize.left));
					newSize.bottom = nHeight + newSize.top;
					break;
				}
			}

			return true;
		}

	case WM_LBUTTONDOWN:
		{
			RECT rc;
			GetClientRect(hwnd, &rc);
			const float mouseX = float(LOWORD(lParam)) / float(rc.right - rc.left);
			const float mouseY = float(HIWORD(lParam)) / float(rc.bottom - rc.top);
			
			myScene.mouseLClick(mouseX, mouseY, (wParam & MK_SHIFT) != 0, (wParam & MK_CONTROL) != 0, (wParam & MK_LBUTTON) != 0, (wParam & MK_RBUTTON) != 0, (wParam & MK_MBUTTON) != 0);
			return 0;
		}
	
	case WM_RBUTTONDOWN:
		{
			RECT rc;
			GetClientRect(hwnd, &rc);
			const float mouseX = float(LOWORD(lParam)) / float(rc.right - rc.left);
			const float mouseY = float(HIWORD(lParam)) / float(rc.bottom - rc.top);
			
			myScene.mouseRClick(mouseX, mouseY, (wParam & MK_SHIFT) != 0, (wParam & MK_CONTROL) != 0, (wParam & MK_LBUTTON) != 0, (wParam & MK_RBUTTON) != 0, (wParam & MK_MBUTTON) != 0);
			return 0;
		}
	
	case WM_MBUTTONDOWN:
		{
			RECT rc;
			GetClientRect(hwnd, &rc);
			const float mouseX = float(LOWORD(lParam)) / float(rc.right - rc.left);
			const float mouseY = float(HIWORD(lParam)) / float(rc.bottom - rc.top);

			myScene.mouseMClick(mouseX, mouseY, (wParam & MK_SHIFT) != 0, (wParam & MK_CONTROL) != 0, (wParam & MK_LBUTTON) != 0, (wParam & MK_RBUTTON) != 0, (wParam & MK_MBUTTON) != 0);
			return 0;
		}

	case WM_LBUTTONUP:
		{
			RECT rc;
			GetClientRect(hwnd, &rc);
			const float mouseX = float(LOWORD(lParam)) / float(rc.right - rc.left);
			const float mouseY = float(HIWORD(lParam)) / float(rc.bottom - rc.top);
			
			myScene.mouseLUp(mouseX, mouseY, (wParam & MK_SHIFT) != 0, (wParam & MK_CONTROL) != 0, (wParam & MK_LBUTTON) != 0, (wParam & MK_RBUTTON) != 0, (wParam & MK_MBUTTON) != 0);
			return 0;
		}
	
	case WM_RBUTTONUP:
		{
			RECT rc;
			GetClientRect(hwnd, &rc);
			const float mouseX = float(LOWORD(lParam)) / float(rc.right - rc.left);
			const float mouseY = float(HIWORD(lParam)) / float(rc.bottom - rc.top);
			
			myScene.mouseRUp(mouseX, mouseY, (wParam & MK_SHIFT) != 0, (wParam & MK_CONTROL) != 0, (wParam & MK_LBUTTON) != 0, (wParam & MK_RBUTTON) != 0, (wParam & MK_MBUTTON) != 0);
			return 0;
		}
	
	case WM_MBUTTONUP:
		{
			RECT rc;
			GetClientRect(hwnd, &rc);
			const float mouseX = float(LOWORD(lParam)) / float(rc.right - rc.left);
			const float mouseY = float(HIWORD(lParam)) / float(rc.bottom - rc.top);

			myScene.mouseMUp(mouseX, mouseY, (wParam & MK_SHIFT) != 0, (wParam & MK_CONTROL) != 0, (wParam & MK_LBUTTON) != 0, (wParam & MK_RBUTTON) != 0, (wParam & MK_MBUTTON) != 0);
			return 0;
		}

	case WM_MOUSEMOVE:
		{
			RECT rc;
			GetClientRect(hwnd, &rc);
			const float mouseX = float(LOWORD(lParam)) / float(rc.right - rc.left);
			const float mouseY = float(HIWORD(lParam)) / float(rc.bottom - rc.top);
			
			myScene.mouseMove(mouseX, mouseY, (wParam & MK_SHIFT) != 0, (wParam & MK_CONTROL) != 0, (wParam & MK_LBUTTON) != 0, (wParam & MK_RBUTTON) != 0, (wParam & MK_MBUTTON) != 0);
			return 0;
		}

	case 0x20A: //WM_MOUSEWHEEL
		{
			RECT rc;
			GetClientRect(hwnd, &rc);
			const float mouseX = float(LOWORD(lParam)) / float(rc.right - rc.left);
			const float mouseY = float(HIWORD(lParam)) / float(rc.bottom - rc.top);

			WORD tMouseDir = HIWORD(wParam);

			const float mouseDir = float(*reinterpret_cast<signed short*>(&tMouseDir)) / 120.0f;
			const WPARAM rWParam = LOWORD(wParam);
			
			myScene.mouseScroll(mouseDir, mouseX, mouseY, (rWParam & MK_SHIFT) != 0, (rWParam & MK_CONTROL) != 0, (rWParam & MK_LBUTTON) != 0, (rWParam & MK_RBUTTON) != 0, (rWParam & MK_MBUTTON) != 0);
			return 0;
		}

	case WM_KEYDOWN:
		{
			myScene.keyDown(long(wParam));
			switch (wParam)
			{
			case VK_ESCAPE:
				{
					::DestroyWindow(hwnd);
				}
				break;
			}
			return 0;
		}

	case WM_KEYUP:
		{
			myScene.keyUp(long(wParam));
			return 0;
		}
	}

	return ::DefWindowProc(hwnd, msg, wParam, lParam);
}

//
// WinMain
//
int WINAPI WinMain(HINSTANCE hinstance,
				   HINSTANCE prevInstance, 
				   PSTR cmdLine,
				   int showCmd)
{
	if(myScene.setup(hinstance).getDevice() == 0)
	{
		::MessageBox(0, "InitD3D() - FAILED", 0, 0);
		return 0;
	}
		
	if(!Setup())
	{
		::MessageBox(0, "Setup() - FAILED", 0, 0);
		return 0;
	}

	d3d::EnterMsgLoop( Display );

	Cleanup();

	myScene.getDevice()->Release();

	return 0;
}