/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////*****************************************************************************************************////////////////
///////////////** 																									**///////////////
//////////////**								~ Zoo Engine (Moteur 3D pour SCOL) ~								 **//////////////
/////////////**											  ~ version 1.0 ~											  **/////////////
/////////////**																										  **/////////////
//////////////**										par Pacôme DANHIEZ		  									 **//////////////
///////////////** 																									**///////////////
////////////////*****************************************************************************************************////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///																																  ///
///		FICHIER :	ZooScene.cpp																								  ///
///																																  ///
///		NATURE	:	Définition de la classe de visualisation de la scene - Méthodes principales (IDLE, DISPLAY, etc) -			  ///
///																																  ///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////




#include	"..\Basic\ZooScene.h"
#include "../scol/objstr.h"
#include "../scol/colors.h"


#ifdef _BENCH_SOFT_
	ZProfile	*profile;
#endif





///////////////////////////////////////////////////////////
///			TREE CONTROL FOR THE SCENE GRAPH			///
///////////////////////////////////////////////////////////
#ifdef	_INFO_SCREEN_

HTREEITEM	selectedITEM = NULL;

HWND		TreeGraph = NULL;
HWND		TreeDatas = NULL;
WNDPROC		TreeProc = NULL;

int			InfoScreenHH = 600;
int			InfoStaticHH = 100;
int			InfoTreeHH	 = 200;
int			InfoMouseHH	 = InfoScreenHH-InfoStaticHH-InfoTreeHH;

bool		focusTreeGraph	= true;
bool		blockRendering	= false;
bool		refreshInfos	= true;

int			focusInfo    = -10;
int			scrollInfoH1 = 0;
int			scrollInfoW1 = 0;
int			scrollInfoH2 = 0;
int			scrollInfoW2 = 0;



struct ItemAndInfo
{
	HTREEITEM	item;
	ZData		*node;
};

vector<ItemAndInfo>		ItemListGraph;
vector<ItemAndInfo>		ItemListDatas;

#define		TREE_INSERT_FIRST	1
#define		TREE_INSERT_SORT	2
#define		TREE_INSERT_LAST	4


LRESULT CALLBACK TreeProcBis(HWND hwnd, unsigned msg, UINT wParam, LONG lParam)
{
    switch (msg)
    {
		case WM_COMMAND :
			break;
		case WM_LBUTTONUP :        
			break;
		case WM_LBUTTONDBLCLK : 
			break;
		case WM_RBUTTONDOWN :  
			break;
		case WM_MOUSEMOVE :
			break;
    }
	return CallWindowProc(TreeProc, hwnd, msg, wParam, lParam);
}

void CreateTree(int w, int h, int x, int y, int flag) 
{
	INITCOMMONCONTROLSEX init;

	init.dwSize = sizeof(INITCOMMONCONTROLSEX);
	init.dwICC  = ICC_TREEVIEW_CLASSES;
 
    InitCommonControlsEx(&init);

	int winFlagEx	= WS_EX_CLIENTEDGE;
	int winFlag		= WS_VISIBLE | WS_CHILD | TVS_HASLINES | WS_BORDER | WS_HSCROLL | WS_VSCROLL | TVS_LINESATROOT | TVS_HASBUTTONS;

	if(flag==0)		TreeGraph =  CreateWindowEx(winFlagEx, WC_TREEVIEW, "", winFlag, x, y, w, h, mainInfoWND, (HMENU)0, hInstINFO, NULL);
	else			TreeDatas =  CreateWindowEx(winFlagEx, WC_TREEVIEW, "", winFlag, x, y, w, h, mainInfoWND, (HMENU)0, hInstINFO, NULL);

	if(TreeProc==NULL)  TreeProc = (WNDPROC) GetWindowLong(TreeGraph, GWL_WNDPROC);
    SetWindowLong(TreeGraph, GWL_WNDPROC, (long) TreeProcBis);

    ShowWindow(TreeGraph, SW_SHOW);
    UpdateWindow(TreeGraph);
}

HTREEITEM AddTreeChild(HTREEITEM parent, char* label, ZData	*node, int flag, int nbTree)
{
	if(TreeGraph==NULL)  return NULL;
 
	TV_INSERTSTRUCT  tvi;
 
	tvi.item.mask  = TVIF_TEXT;
	tvi.item.pszText = label;

    if(label==NULL)		tvi.item.cchTextMax = 0;
	else				tvi.item.cchTextMax = strlen(label);

    if(parent==NULL)	tvi.hParent = TVI_ROOT;
    else				tvi.hParent = parent;

    if(flag & TREE_INSERT_FIRST)		tvi.hInsertAfter = TVI_FIRST;
    else if(flag & TREE_INSERT_SORT)	tvi.hInsertAfter = TVI_SORT;
    else								tvi.hInsertAfter = TVI_LAST;
 
	HTREEITEM item;

    if(nbTree==0)
	{
		item = TreeView_InsertItem(TreeGraph, &tvi);

		ItemListGraph.resize(ItemListGraph.size()+1);
		ItemListGraph[ItemListGraph.size()-1].item = item;
		ItemListGraph[ItemListGraph.size()-1].node = node;

		UpdateWindow(TreeGraph);
	}
	else
	{
		item = TreeView_InsertItem(TreeDatas, &tvi);

		ItemListDatas.resize(ItemListDatas.size()+1);
		ItemListDatas[ItemListDatas.size()-1].item = item;
		ItemListDatas[ItemListDatas.size()-1].node = node;

		UpdateWindow(TreeDatas);
	}

    return item;
}

string apendice[] = {	string("--OBJ"), string("--CAM"), string("--LGH"), string("--SHL"), 
						string("--COL"), string("--SPR"), string("--ANI"), string("--PCL"), 
						string("--SND")														};

string texApendice("--TEX");
string matApendice("--MAT");
string pclApendice("--PART");
string effApendice("--EFF");

void ZScene::BuildTreeGraph(ZNode* node, HTREEITEM parent)
{
	if(TreeGraph==NULL)		CreateTree(mainInfoWW/2, mainInfoWH-InfoScreenHH, 0, 0, 0);
	if(parent==NULL)
	{
		ItemListGraph.resize(0);
		TreeView_DeleteAllItems(TreeGraph);
	}
 
	ZNode*		curNode = node->son;
	string		name;
	HTREEITEM	curItem;
 
	while(curNode!=NULL)
	{
		name = curNode->name + apendice[curNode->type];
		curItem = AddTreeChild(parent, (char*)name.c_str(), curNode, TREE_INSERT_FIRST, 0);
 		if(curNode->son!=NULL)  BuildTreeGraph(curNode, curItem);
		curNode = curNode->next;
	}
}

void ZScene::BuildTreeDatas()
{
	if(TreeDatas==NULL)		CreateTree(mainInfoWW/2+1, mainInfoWH-InfoScreenHH, mainInfoWW/2, 0, 1);

	ItemListDatas.resize(0);
	TreeView_DeleteAllItems(TreeDatas);

	string		name;

	for(int i=0; i<MatList.Size(); i++)
	{
		name = MatList[i]->name + matApendice;
		AddTreeChild(NULL, (char*)name.c_str(), MatList[i], TREE_INSERT_LAST, 1);
	}

	for(i=0; i<TexList.Size(); i++)
	{
		name = TexList[i]->name + texApendice;
		AddTreeChild(NULL, (char*)name.c_str(), TexList[i], TREE_INSERT_LAST, 1);
	}
	
	for(i=0; i<PclDef.Size(); i++)
	{
		name = PclDef[i]->name + pclApendice;
		AddTreeChild(NULL, (char*)name.c_str(), PclDef[i], TREE_INSERT_LAST, 1);
	}

	for(i=0; i<PclEff.Size(); i++)
	{
		name = PclEff[i]->name + effApendice;
		AddTreeChild(NULL, (char*)name.c_str(), PclEff[i], TREE_INSERT_LAST, 1);
	}
}


#endif
 
///////////////////////////////////////////////////////////
///			END OF TREE CONTROL FOR THE GRAPH			///
///////////////////////////////////////////////////////////

 

 





///////////////////////////////////////////////////////////////////////////
///		CONSTRUCTOR														///
///////////////////////////////////////////////////////////////////////////
ZScene::ZScene(bool accel)
{
	WW = HH = 0;

	generalTextureFilter = TF_LINEAR;

	updateGraphList  = true;
	lastBaseNodeList = NULL;

	textureModified		= true;
	materialModified	= true;
	meshModified		= true;

	depthEvent			= false;

	activeCam		= NULL;
	activeListener	= NULL;

	accelerated = accel;

	generalRealLighting	= false;

	// Test d'une fonction pour remplacer la fonction rand() par genrand()
	// qui devrait être 4 fois plus rapide.
}



///////////////////////////////////////////////////////////////////////////
///		DESTRUCTOR														///
///////////////////////////////////////////////////////////////////////////
ZScene::~ZScene()
{
	Reset();

	delete World;
}



///////////////////////////////////////////////////////////////////////////
///		Reset															///
///////////////////////////////////////////////////////////////////////////
void ZScene::Reset()
{
	World->FreeWorld();

	// Ordre à ne pas modifier
	for(int i=0;i<PclDef.Size();i++)		delete PclDef[i];
	PclDef.Empty();

	for(i=0;i<MshList.Size();i++)			delete MshList[i];
	MshList.Empty();

	for(i=0;i<MatList.Size();i++)			delete MatList[i];
	MatList.Empty();
	
	for(i=0;i<FntList.Size();i++)			delete FntList[i];
	FntList.Empty();

	for(i=0;i<TexList.Size();i++)			delete TexList[i];
	TexList.Empty();

	for(i=0;i<PclEff.Size();i++)			delete PclEff[i];
	PclEff.Empty();

	cbObj.Empty();

	activeCam		= NULL;
	activeListener	= NULL;

	updateGraphList = true;
	lastBaseNodeList = NULL;

	textureModified		= true;
	materialModified	= true;
	meshModified		= true;
}



///////////////////////////////////////////////////////////////////////////
///		InitWorld														///
///////////////////////////////////////////////////////////////////////////
void ZScene::InitWorld()
{

#ifdef _BENCH_SOFT_
	profile = new ZProfile(50);
#endif


	///////////////////////////
	// Init the CONTAINERS
	World = new ZWorld(this);

	if(accelerated)
	{
		////////////////////////////
		// Ambient Light settings
		glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
		//glPolygonMode(GL_FRONT,GL_FILL);
		glCullFace(GL_BACK);
		glEnable(GL_CULL_FACE);

		
		///////////////////////////
		// Normals settings			
		glDisable(GL_AUTO_NORMAL);
		glEnable(GL_NORMALIZE);



#ifdef _INFO_SCREEN_
		///////////////////////////////////////////////////
		///	Classical settings for the scene			///
		///////////////////////////////////////////////////
		lastTime	= 0;
		frameCount	= 0;
		GetTimePassed(&lastTime);
		for(int i=0; i<256; i++)		totalTime[i]	= 0.0f;


		///////////////////////////
		/// Define font
		ZTexture	*tex_FONT;
		tex_FONT = new ZTexture(true);
		TexList.Add(tex_FONT);

		tex_FONT->SetTextureFilter(TF_BILINEAR);
		tex_FONT->LoadTexture("font.jpg");
		tex_FONT->SetParams(false, false, false, false, false, false, 0, 255, 0, 77);
		tex_FONT->CreateModifiedImg();
		tex_FONT->SetupTexture();
		tex_FONT->SetName("font.jpg");

		ZFont	*font;
		font = new ZFont();
		FntList.Add(font);

		font->SetName("ClassicFont");
		font->SetTexture(tex_FONT);
		font->BuildFontLists(16, 16);
#endif
	}
}



///////////////////////////////////////////////////////////////////////////
///		SetActiveCam													///
///////////////////////////////////////////////////////////////////////////
void ZScene::SetActiveCam(ZCamera* curCam)
{
	activeCam = curCam;

	if( (WW != curCam->width) || (HH != curCam->height) )
	{
		WW = curCam->width;
		HH = curCam->height;
	   
		if(accelerated)	glViewport(0, 0, WW, HH);
	}
}



///////////////////////////////////////////////////////////////////////////
///		SetActiveListener												///
///////////////////////////////////////////////////////////////////////////
void ZScene::SetActiveListener(ZSound* listener)
{
	activeListener = listener;
}







///////////////////////////////////////////////////////////////////////////
///		UpdateMaterials													///
///////////////////////////////////////////////////////////////////////////
void ZScene::UpdateMaterialByTextures()
{
	ZMaterial*	curMat;
	ZTexture*	tex;

	for(int j=0; j < MatList.Size(); j++)
	{
		curMat = MatList[j];

		if(tex=curMat->GetTexture1())		 curMat->modified |= tex->modified;
		if(tex=curMat->GetTexture2())		 curMat->modified |= tex->modified;

		materialModified |= curMat->modified;
	}
}





///////////////////////////////////////////////////////////////////////////
///		UpdateMeshByMaterials											///
///////////////////////////////////////////////////////////////////////////
void ZScene::UpdateMeshByMaterials()
{
	ZMesh	*curMesh;

	bool				matModif;
	int					i, j;
	ListFaceByMat		*list;

	for(j=0; j < MshList.Size(); j++)
	{
		curMesh = MshList[j];

		// test de modification d'un matériau (au moins) contenu dans la liste
		matModif = false;

		list = &(curMesh->FacesMatGour);
		for(i=0; (i<list->size())&&(!matModif); i++)		matModif |= (*list)[i].mat->modified;

		list = &(curMesh->FacesMatFlat);
		for(i=0; (i<list->size())&&(!matModif); i++)		matModif |= (*list)[i].mat->modified;
		
		list = &(curMesh->FacesMatNo);
		for(i=0; (i<list->size())&&(!matModif); i++)		matModif |= (*list)[i].mat->modified;

		curMesh->hasViewChanged |= matModif;

		meshModified |= curMesh->hasViewChanged;
	}
}



///////////////////////////////////////////////////////////////////////////
///		UpdateMeshes													///
///////////////////////////////////////////////////////////////////////////
void ZScene::UpdateMeshes()
{
	ZMesh	*curMesh;

	for(int j=0; j < MshList.Size(); j++)
	{
		curMesh = MshList[j];

		// création des Faces-Lists si besoin est..
		if(accelerated && curMesh->hasViewChanged)				curMesh->MakeFacesList();

		// Calcul des normales si besoin est..
		if(curMesh->hasTopoChanged)
		{
			curMesh->ComputeOBB();

			if(curMesh->dependency==false)
			{
				curMesh->CreateFacesNormals();
				curMesh->CreateVertsNormals();
			}
		}

		// APRES tout ça : création des display lists si besoin est..
		if( accelerated && (curMesh->displayListCreate==true) && (curMesh->dependency==false) && (curMesh->hasTopoChanged || curMesh->hasViewChanged) )			curMesh->CreateDisplayList();
	}
}



///////////////////////////////////////////////////////////////////////////
///		SetMaterialMeshForNext											///
///////////////////////////////////////////////////////////////////////////
void ZScene::SetMaterialMeshForNext()
{
	int		i;

	for(i=0; i < MshList.Size(); i++)
	{
		MshList[i]->hasViewChanged = false;
		MshList[i]->hasTopoChanged = false;
	}

	for(i=0; i < MatList.Size(); i++)		MatList[i]->modified = false;
	for(i=0; i < TexList.Size();  i++)		TexList[i]->modified = false;

	textureModified		= false;
	materialModified	= false;
	meshModified		= false;
}






///////////////////////////////////////////////////////////////////////////
///		DATAS COMPUTING													///
///////////////////////////////////////////////////////////////////////////
int NBObjects, NBpolygons, NBCameras, NBLights, NBShell, NBCollision, NBAnims, NBvisibleObjects, NBvisiblePolygons;


void CalculateNbObjects(ZNode *node)
{
	ZNode* curNode = node->son;
	ZObject	*obj;

	while(curNode)
	{
		if (curNode->type == OBJ_TYPE_ID)
		{
			NBObjects++;
			obj = (ZObject*) curNode;

			if(obj->GetMesh())			NBpolygons += obj->GetMesh()->NbFaces;

			if( (obj->visible) && (obj->GetMesh()) )
			{
				NBvisibleObjects++;
				NBvisiblePolygons += obj->GetMesh()->NbFaces;
			}
		}
		else if (curNode->type == CAM_TYPE_ID)		NBCameras++;
		else if (curNode->type == LGH_TYPE_ID)		NBLights++;
		else if (curNode->type == SHL_TYPE_ID)		NBShell++;
		else if (curNode->type == COL_TYPE_ID)		NBCollision++;
		else if (curNode->type == ANI_TYPE_ID)		NBAnims++;

		CalculateNbObjects(curNode);

		curNode = curNode->next;
	}
}














///////////////////////////////////////////////////////////////////////////
///		Display															///
///////////////////////////////////////////////////////////////////////////

void ZScene::Display(float r, float g, float b, ZNode *baseNode, bool wired, bool ortho, bool clear)
{
	///////////////////////////////////////////////////
	///	Classical settings for OpenGL rendering		///
	///////////////////////////////////////////////////


	///////////////////////////
	// Ambient Lgh setting
	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);

	glCullFace(GL_BACK);
	glEnable(GL_CULL_FACE);


	///////////////////////////
	/// Normals settings
	glEnable(GL_NORMALIZE);


	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);




	///////////////////////////////////////////////////////////	
	///////////////////////////////////////////////////////////	
	///////////////////////////////////////////////////////////	
	
	
	int		i=0;
	float	time;
	
	time = timeGetTime();



	///////////////////////////////////////////////
	/// Initialize the screen buffer			///
	///////////////////////////////////////////////

	glDrawBuffer(GL_BACK);


	depthEvent = !depthEvent;
	depthEvent = true;
	if(depthEvent)	    glDepthRange( 0.0, 0.5 );
	else			    glDepthRange( 1.0, 0.5 );

	if(clear)
	{
		glClearColor(r, g, b, 1.0f);

		if(depthEvent)
		{
			glClearDepth( 0.5 );
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		}
		else
			glClear(GL_COLOR_BUFFER_BIT);
	}



	///////////////////////////////////////////////
	/// Transformation of camera & FOG ppties	///
	///////////////////////////////////////////////


	// The camera's world matrix has been computed *before* the call of this function
	glMatrixMode(GL_PROJECTION);

	if(!ortho)		activeCam->ComputeMatrix();
	else			activeCam->ComputeMatrixOrtho();
	orthoGraphic = ortho;


	glLoadMatrixf(activeCam->visionMatx.matxArray);


	// Put the fog if necessary
	if(activeCam->Zfog <= (activeCam->Zfar-0.1f))
	{
		glEnable(GL_FOG);

		glFogi(GL_FOG_MODE,		GL_LINEAR);
		glFogf(GL_FOG_START,	activeCam->Zfog);
		glFogf(GL_FOG_END,		activeCam->Zfar);
		glHint(GL_FOG_HINT,		GL_FASTEST);

		if(generalRealLighting==false)
		{
			float	fog_color[4] = { r/2.0f, g/2.0f, b/2.0f, 1.0f };
			glFogfv(GL_FOG_COLOR, fog_color);
		}
		else
		{
			float	fog_color[4] = { r, g, b, 1.0f };
			glFogfv(GL_FOG_COLOR, fog_color);
		}

		fog_ENABLED = true;
	}
	else
	{
		glDisable(GL_FOG);
		fog_ENABLED = false;
	}




	///////////////////////////////////////////////
	/// Computing								///
	///////////////////////////////////////////////

	// ----> Create the lists <---- //

#ifdef	_INFO_SCREEN_

	if(refreshInfos)
	{
		BuildTreeGraph(World, NULL);
		BuildTreeDatas();
		refreshInfos = false;
	}

#endif


	if( updateGraphList || (lastBaseNodeList!=baseNode) )
	{
		World->createNodeLists(baseNode);								// Create the linear lists of OBJECT & LIGHT & CAMS
		updateGraphList  = false;
		lastBaseNodeList = baseNode;
	}




	if( textureModified )
	{
		UpdateMaterialByTextures();
		textureModified = false;
	}


	if( materialModified )
	{
		UpdateMeshByMaterials();
		materialModified = false;
	}


	// ----> Compute the matrices <----

	World->ComputeMatrices(activeCam, (ZNodeGraph*)baseNode, activeCam->cameraMatx, 1.0f, true);

	if( meshModified )
	{
		UpdateMeshes();
		meshModified = false;
	}




	// ----> Transform the vertices <----
	World->TransformVertices();
	World->ComputeNormals(true);

	World->ViewFrustrumCull(activeCam, (float)WW, (float)HH, ortho);	// after, becoz of the shared vertices...


	World->UpdateSounds(activeListener);



	///////////////////////////////////////////////
	/// Transformation of objects & lights		///
	///////////////////////////////////////////////

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	World->PutLightSettings(activeCam->cameraMatx);					// put the light settings (opengGL settings)
	SetMaterialMeshForNext();										// re-set the flags for the next computing (flags of modification)


	///////////////////////////
	/// Drawing				///
	///////////////////////////

	// ----- SOLID RENDERING -----
	if(!wired)
	{
		glEnable(GL_DEPTH_TEST);

		// -------> PASS 1 rendering <------- //
		glEnable(GL_TEXTURE_2D);

		glDisable(GL_BLEND);
		glDisable(GL_LIGHTING);
		glDisable(GL_DITHER);

		glAlphaFunc(GL_GREATER, CONST_ALPHA_TEST);


		if(depthEvent)			glDepthFunc(GL_LEQUAL);
		else					glDepthFunc(GL_GEQUAL);
		glDepthMask(GL_TRUE);


		// Object rendering
		World->RenderObjectPass1();										// Pass 1 : render the first textures & the colors of the objects

		// Sprite rendering
		World->RenderSpritesPASS1(activeCam->RealWorldAngles.z);

		// Particles rendering
		World->RenderParticles(activeCam->RealWorldAngles, activeCam->RealWorldMat, activeCam->cameraMatx);

		// -----------------------------------//




		// -------> PASS 2 rendering <------- //
		glEnable(GL_TEXTURE_2D);
		glEnable(GL_BLEND);

		glDisable(GL_LIGHTING);

		glDepthFunc(GL_EQUAL);
		glDepthMask(GL_FALSE);

		glAlphaFunc(GL_NOTEQUAL, 0);

		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

		// Object rendering
		World->RenderObjectPass2();										// Pass 2 : render the second textures & the colors of the objects

		// Sprite rendering
		World->RenderSpritesPASS2(activeCam->RealWorldAngles.z);
		// -----------------------------------//




		// -------> PASS 3 rendering <------- //

		if(fog_ENABLED)
		{
//			glFogf(GL_FOG_START, activeCam->Zfog + (activeCam->Zfar-activeCam->Zfog)*0.9f);
//			glFogi(GL_FOG_MODE,		GL_EXP);

			float	fog_WHITE[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
			glFogfv(GL_FOG_COLOR, fog_WHITE);
		}


		glEnable(GL_LIGHTING);
 		glEnable(GL_BLEND);

		glDisable(GL_TEXTURE_2D);

		glDepthFunc(GL_EQUAL);
		glDepthMask(GL_FALSE);

		glShadeModel(GL_SMOOTH);


#ifndef		_BLENDING_CONTROL_

		if(generalRealLighting==false)		glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
		else								glBlendFunc(GL_DST_COLOR, GL_ZERO);

#else
		if(valSRC==0)
		{
			if(valDST==0)			glBlendFunc(GL_ZERO, GL_ZERO);
			else if(valDST==1)		glBlendFunc(GL_ZERO, GL_ONE);
			else					glBlendFunc(GL_ZERO, 0x0300+valDST-2);
		}
		else
		if(valSRC==1)
		{
			if(valDST==0)			glBlendFunc(GL_ONE, GL_ZERO);
			else if(valDST==1)		glBlendFunc(GL_ONE, GL_ONE);
			else					glBlendFunc(GL_ONE, 0x0300+valDST-2);
		}
		else
		{
			if(valDST==0)			glBlendFunc(0x0300+valSRC-2, GL_ZERO);
			else if(valDST==1)		glBlendFunc(0x0300+valSRC-2, GL_ONE);
			else					glBlendFunc(0x0300+valSRC-2, 0x0300+valDST-2);
		}
#endif



		// Lighted faces rendering
		World->RenderObjectPass3();										// Pass 3 : render the lighting of the objects

		World->RenderSpritesPASS3(activeCam->RealWorldAngles.z);


		// NoLight faces rendering
		if(fog_ENABLED && generalRealLighting==false)
		{
			glDisable(GL_LIGHTING);
			World->RenderObjectPass4();									// Pass 4 : render the NO-lighting objects
		}

		// -----------------------------------//




		// -----> PASS TRANSP rendering <---- //
		if(fog_ENABLED)
		{
			float	fog_color[4] = { r, g, b, 1.0f };
			glFogfv(GL_FOG_COLOR, fog_color);
		}


		glEnable(GL_TEXTURE_2D);
		glEnable(GL_BLEND);

		glDisable(GL_LIGHTING);

		if(depthEvent)			glDepthFunc(GL_LEQUAL);
		else					glDepthFunc(GL_GEQUAL);
		glDepthMask(GL_FALSE);

		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

		glEnable(GL_ALPHA_TEST);
		glAlphaFunc(GL_NOTEQUAL, 0);

		World->RenderObjectPassTransp(activeCam);							// Pass 2 : render the second textures & the colors of the objects
		// -----------------------------------//



/*
		// -----> PASS Additive rendering <---- //
		glShadeModel(GL_FLAT);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE);
		World->RenderAdditiveParticles(activeCam->RealWorldAngles, activeCam->cameraMatx);
		// ------------------------------------ //
*/

 		glEnable(GL_TEXTURE_2D);
		glDisable(GL_BLEND);

		glDisable(GL_LIGHTING);

		if(depthEvent)			glDepthFunc(GL_LEQUAL);
		else					glDepthFunc(GL_GEQUAL);
		glDepthMask(GL_TRUE);
	}
	else
	// ----- WIRED RENDERING -----
	{
		glDisable(GL_DEPTH_TEST);
		glDisable(GL_TEXTURE_2D);
		glDisable(GL_BLEND);
		glDisable(GL_LIGHTING);
		glDisable(GL_DITHER);
		glDisable(GL_ALPHA_TEST);

		World->RenderObjectWired(1.0f);
	}


/*
	if(monClavier[VK_UP]==true)	
	{
		_asm{int 3};
		// Prépare l'écran d'info
		glViewport(0, 0, WW, HH);

		glDisable(GL_CULL_FACE);
		glDisable(GL_TEXTURE_2D);
		glLoadIdentity();
		glTranslated(mainInfoWW-20,10,0);

		glColor3f(1.0f, 1.0f, 1.0f);
		glBegin(GL_QUADS);
			glVertex2i(-20, 0);
			glVertex2i(-20, 10);
			glVertex2i(-10, 10);
			glVertex2i(-10, 0);
		glEnd();

		
		if(!blockRendering)		glColor3f(0.3f, 1.0f, 0.3f);
		else					glColor3f(1.0f, 0.3f, 0.3f);

		glBegin(GL_QUADS);
			glVertex2i(0, 0);
			glVertex2i(0, 10);
			glVertex2i(10, 10);
			glVertex2i(10, 0);
		glEnd();
		glEnable(GL_TEXTURE_2D);
	}
*/

	// Time computing
#ifdef	_INFO_SCREEN_

	totalTime[frameCount] = GetTimePassed(&lastTime);

	FPS = 0.0f;
	for(i=0; i<256; i++)		FPS	+= totalTime[i];
	FPS = 256.0f / FPS;


	DisplayInfos(r, g, b, baseNode, wired, ortho, clear);

	frameCount++;
	frameCount &= 255;

#endif
}






#ifdef	_INFO_SCREEN_


void ZScene::DisplayInfos(float r, float g, float b, ZNode *baseNode, bool wired, bool ortho, bool clear)
{
	const char* TXTblend[] = {"GL_ZERO", "GL_ONE", "GL_SRC_COLOR", "GL_ONE_MINUS_SRC_COLOR", "GL_SRC_ALPHA", 
							  "GL_ONE_MINUS_SRC_ALPHA", "GL_DST_ALPHA", "GL_ONE_MINUS_DST_ALPHA", "GL_DST_COLOR",
							  "GL_ONE_MINUS_DST_COLOR", "GL_SRC_ALPHA_SATURATE"};

	ZFont *font;


	///////////////////////////////////////////////////////
	///			Infos sur la fenêtre de tree			///
	///////////////////////////////////////////////////////

	if(mainInfoDC)
	{
		// Conserve les anciens params au chaud
		HGLRC	currentRC = wglGetCurrentContext();
		HDC		currentDC = wglGetCurrentDC();
		wglMakeCurrent(mainInfoDC, mainInfoRC);

		// Prépare l'écran d'info
		glViewport(0, 0, mainInfoWW, InfoScreenHH);
		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		glClearDepth( 1.0 );
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		glDisable(GL_CULL_FACE);
		glDrawBuffer(GL_BACK);


		// Ecrit les données intéressantes
		font = FntList[0];
		font->InitFontPrint(mainInfoWW, InfoScreenHH, false);


		glDisable(GL_TEXTURE_2D);
		glLoadIdentity();
		glTranslated(mainInfoWW-20,10,0);

		glColor3f(1.0f, 1.0f, 1.0f);
		glBegin(GL_QUADS);
			glVertex2i(-20, 0);
			glVertex2i(-20, 10);
			glVertex2i(-10, 10);
			glVertex2i(-10, 0);
		glEnd();

		
		if(!blockRendering)		glColor3f(0.3f, 1.0f, 0.3f);
		else					glColor3f(1.0f, 0.3f, 0.3f);

		glBegin(GL_QUADS);
			glVertex2i(0, 0);
			glVertex2i(0, 10);
			glVertex2i(10, 10);
			glVertex2i(10, 0);
		glEnd();
		glEnable(GL_TEXTURE_2D);


		///////////////////////////////
		///		Données GENERALES	///
		///////////////////////////////

		glColor3f(0.5f,0.5f,1.0f);
		font->Print(5, 5,  0, "FPS  :%d", (int)(FPS));

		NBObjects = NBpolygons = NBCameras = NBLights = NBShell = NBCollision = NBAnims = NBvisibleObjects = NBvisiblePolygons = 0;
		CalculateNbObjects(World);

		glColor3f(1.0f,1.0f,1.0f);
		font->Print(5, 20, 0, "Poly :%d", NBpolygons);
		font->Print(5, 35, 0, "Vpoly:%d", NBvisiblePolygons);

		glColor3f(1.0f,0.3f,1.0f);
		font->Print(5, 50, 0, "Obj  :%d", NBObjects);
		font->Print(5, 65, 0, "Vobj :%d", NBvisibleObjects);

		font->Print(175,  5, 0, "Cam:%d", NBCameras);
		font->Print(175, 20, 0, "Lgh:%d", NBLights);
		font->Print(175, 35, 0, "Shl:%d", NBShell);
		font->Print(175, 50, 0, "Col:%d", NBCollision);
		font->Print(175, 65, 0, "Ani:%d", NBAnims);

		font->Print(345,  5, 0, "Mat:%d", MatList.Size());
		font->Print(345, 20, 0, "Tex:%d", TexList.Size());
		font->Print(345, 35, 0, "Msh:%d", MshList.Size());

		glColor3f(1.0f,1.0f,1.0f);
		if(fog_ENABLED)		font->Print(345, 65, 0, "FOG enabled");
		else				font->Print(345, 65, 0, "FOG disabled");


		///////////////////////////////
		///		Données du TREE		///
		///////////////////////////////

		glColor3f(0.5f,1.0f,0.5f);
		font->Print(5, InfoStaticHH, 0, "InfoTree");

		glDisable(GL_TEXTURE_2D);
		glLoadIdentity();
		glTranslated(3,InfoStaticHH-5,0);
		glColor3f(0.6f, 0.6f, 0.6f);
		glBegin(GL_QUADS);
			glVertex2i(0, 0);
			glVertex2i(0, 2);
			glVertex2i(mainInfoWW-5, 2);
			glVertex2i(mainInfoWW-5, 0);
		glEnd();
		glEnable(GL_TEXTURE_2D);

		glScissor(0, InfoMouseHH+10, mainInfoWW, InfoTreeHH-30);	// lower-left corner TO uper-right corner
		glEnable(GL_SCISSOR_TEST);

		if(focusInfo==1 && keysPressed[VK_UP]	&& scrollInfoH1<0)				scrollInfoH1 += 5;
		if(focusInfo==1 && keysPressed[VK_DOWN] && scrollInfoH1>-500)			scrollInfoH1 -= 5;
		if(focusInfo==1 && keysPressed[VK_LEFT]  && scrollInfoW1<0)				scrollInfoW1 += 5;
		if(focusInfo==1 && keysPressed[VK_RIGHT] && scrollInfoW1>-500)			scrollInfoW1 -= 5;

		int		decalH = InfoStaticHH - 20 + scrollInfoH1;
		int		decalW = scrollInfoW1;

		if(selectedITEM)
		{
			for(int kk=0; kk<ItemListGraph.size() && ItemListGraph[kk].item!=selectedITEM; kk++);

			if(kk<ItemListGraph.size())
			{
				ZData	*selectNode = ItemListGraph[kk].node;

				ZVector3	posi = ((ZNodeGraph*)selectNode)->GetPRS()->GetPos();
				font->Print(135+decalW, 10+decalH, 0, "[%d,%d,%d]", AROUNDINT(posi.x*100.0f), AROUNDINT(posi.y*100.0f), AROUNDINT(posi.z*100.0f));
				ZVector3	rota = ((ZNodeGraph*)selectNode)->GetPRS()->GetAng();
				font->Print(135+decalW, 10+decalH, 0, "[%d,%d,%d]", AROUNDINT(rota.x*100.0f), AROUNDINT(rota.y*100.0f), AROUNDINT(rota.z*100.0f));

				if(selectNode->type==OBJ_TYPE_ID)
				{
					ZObject	*obj = (ZObject*) selectNode;
					glColor3f(1.0f,1.0f,1.0f);
					font->Print(5+decalW, 40+decalH, 0, "OBJECT    : %s", obj->name.c_str());
					glColor3f(0.7f,0.8f,0.9f);
					if(obj->GetMesh()->dependency==true || obj->GetMesh()->displayListCreate==false)
						font->Print(5+decalW, 55+decalH, 0, "TOPO      : %s - dynamic", obj->GetMesh()->name.c_str());
					else
						font->Print(5+decalW, 55+decalH, 0, "TOPO      : %s - static", obj->GetMesh()->name.c_str());
					if(obj->IsMultiMeshes())		font->Print(5+decalW, 70+decalH, 0, "MultiTOPO : yes");
					else							font->Print(5+decalW, 70+decalH, 0, "MultiTOPO : no");
					if(obj->visible)				font->Print(5+decalW, 85+decalH, 0, "Visible   : yes");
					else							font->Print(5+decalW, 85+decalH, 0, "Visible   : no");
					if(obj->normalsTransformed)		font->Print(5+decalW, 100+decalH, 0, "Normals Transformed : yes");
					else							font->Print(5+decalW, 100+decalH, 0, "Normals Transformed : no");
				}
				else if(selectNode->type==CAM_TYPE_ID)
				{
					ZCamera	*cam = (ZCamera*) selectNode;
					glColor3f(1.0f,1.0f,1.0f);
					font->Print(5, 40+decalH, 0,  "CAMERA   : %s", cam->name.c_str());
					glColor3f(0.7f,0.8f,0.9f);
					font->Print(5+decalW, 55+decalH, 0,  "dist XY  : [%d,%d]", cam->dx, cam->dy);
					font->Print(5+decalW, 70+decalH, 0,  "Size WH  : [%d,%d]", cam->width, cam->height);
					font->Print(5+decalW, 85+decalH, 0,  "Z near   : %d", (int)(cam->Znear*100.0f));
					font->Print(5+decalW, 100+decalH, 0, "Z fog    : %d", (int)(cam->Zfog*100.0f));
					font->Print(5+decalW, 115+decalH, 0, "Z far    : %d", (int)(cam->Zfar*100.0f));
				}
				else if(selectNode->type==LGH_TYPE_ID)
				{
					ZLight	*lgh = (ZLight*) selectNode;
					glColor3f(1.0f,1.0f,1.0f);
					font->Print(5+decalW, 40+decalH, 0, "LIGHT  : %s", lgh->name.c_str());
					if(lgh->oldStyle)
					{
						glColor3f(0.7f,0.8f,0.9f);
						font->Print(5, 55+decalH, 0, "Style  : old");
							 if(lgh->LightType==LIGHT_AMBIENT)		font->Print(5+decalW, 70+decalH, 0, "Type   : AMBIENT  %d", lgh->alpha);
						else if(lgh->LightType==LIGHT_PARA)			font->Print(5+decalW, 70+decalH, 0, "Type   : PARA  %d  %d", lgh->alpha, lgh->beta);
						else if(lgh->LightType==LIGHT_OMNI)			font->Print(5+decalW, 70+decalH, 0, "Type   : OMNI  %d  %d  %d", lgh->alpha, lgh->beta, lgh->dist);
						else if(lgh->LightType==LIGHT_SPOT)			font->Print(5+decalW, 70+decalH, 0, "Type   : SPOT  %d  %d  %d", lgh->alpha, lgh->beta, lgh->dist);
					}
					else
					{
						glColor3f(0.7f,0.8f,0.9f);
						font->Print(5+decalW, 55+decalH, 0, "Style  : new");
						if(lgh->LightType==LIGHT_AMBIENT)
						{
							int coul;
							font->Print(5+decalW, 70+decalH, 0, "Type   : AMBIENT");
							font->Print(5+decalW, 85+decalH, 0, "Components");
							coul = AROUNDINT(lgh->ambient[2]*CONST_COLOR) + (AROUNDINT(lgh->ambient[1]*CONST_COLOR)<<8) + (AROUNDINT(lgh->ambient[0]*CONST_COLOR)<<16);
							glColor3f(1.0f,0.5f,0.5f);
							font->Print(5+decalW, 100+decalH, 0, "  Ambient  : %d", coul);
						}
						else if(lgh->LightType==LIGHT_PARA)
						{
							int coul;
							font->Print(5+decalW, 70+decalH, 0, "Type   : PARA");
							glColor3f(1.0f,0.5f,0.5f);
							font->Print(5+decalW, 85+decalH, 0, "  Components");
							coul = AROUNDINT(lgh->ambient[2]*CONST_COLOR) + (AROUNDINT(lgh->ambient[1]*CONST_COLOR)<<8) + (AROUNDINT(lgh->ambient[0]*CONST_COLOR)<<16);
							font->Print(5+decalW, 100+decalH, 0, "  Ambient  : %d", coul);
							coul = AROUNDINT(lgh->diffuse[2]*CONST_COLOR) + (AROUNDINT(lgh->diffuse[1]*CONST_COLOR)<<8) + (AROUNDINT(lgh->diffuse[0]*CONST_COLOR)<<16);
							font->Print(5+decalW, 115+decalH, 0, "  Diffuse  : %d", coul);
							coul = AROUNDINT(lgh->specular[2]*CONST_COLOR) + (AROUNDINT(lgh->specular[1]*CONST_COLOR)<<8) + (AROUNDINT(lgh->specular[0]*CONST_COLOR)<<16);
							font->Print(5+decalW, 130+decalH, 0, "  Specular : %d", coul);
						}
						else if(lgh->LightType==LIGHT_OMNI)
						{
							int coul;
							font->Print(5+decalW, 70+decalH, 0, "Type   : OMNI");
							glColor3f(1.0f,0.5f,0.5f);
							font->Print(5+decalW, 85+decalH, 0, " Components");
							coul = AROUNDINT(lgh->ambient[2]*CONST_COLOR) + (AROUNDINT(lgh->ambient[1]*CONST_COLOR)<<8) + (AROUNDINT(lgh->ambient[0]*CONST_COLOR)<<16);
							font->Print(5+decalW, 100+decalH, 0, " Ambient  : %d", coul);
							coul = AROUNDINT(lgh->diffuse[2]*CONST_COLOR) + (AROUNDINT(lgh->diffuse[1]*CONST_COLOR)<<8) + (AROUNDINT(lgh->diffuse[0]*CONST_COLOR)<<16);
							font->Print(5+decalW, 115+decalH, 0, " Diffuse  : %d", coul);
							coul = AROUNDINT(lgh->specular[2]*CONST_COLOR) + (AROUNDINT(lgh->specular[1]*CONST_COLOR)<<8) + (AROUNDINT(lgh->specular[0]*CONST_COLOR)<<16);
							font->Print(5+decalW, 130+decalH, 0, " Specular : %d", coul);
							glColor3f(0.5f,0.5f,1.0f);
							font->Print(5+decalW, 145+decalH, 0, "  Attenuate CONST : %d", AROUNDINT(lgh->attenuate_const*100.0f));
							font->Print(5+decalW, 160+decalH, 0, "  Attenuate QUADR : %d", AROUNDINT(lgh->attenuate_quadr*100.0f));
						}
						else if(lgh->LightType==LIGHT_SPOT)
						{
							int coul;
							font->Print(5+decalW, 70+decalH, 0, "Type   : OMNI");
							glColor3f(1.0f,0.5f,0.5f);
							font->Print(5+decalW, 85+decalH, 0, " Components");
							coul = AROUNDINT(lgh->ambient[2]*CONST_COLOR) + (AROUNDINT(lgh->ambient[1]*CONST_COLOR)<<8) + (AROUNDINT(lgh->ambient[0]*CONST_COLOR)<<16);
							font->Print(5+decalW, 100+decalH, 0, " Ambient  : %d", coul);
							coul = AROUNDINT(lgh->diffuse[2]*CONST_COLOR) + (AROUNDINT(lgh->diffuse[1]*CONST_COLOR)<<8) + (AROUNDINT(lgh->diffuse[0]*CONST_COLOR)<<16);
							font->Print(5+decalW, 115+decalH, 0, " Diffuse  : %d", coul);
							coul = AROUNDINT(lgh->specular[2]*CONST_COLOR) + (AROUNDINT(lgh->specular[1]*CONST_COLOR)<<8) + (AROUNDINT(lgh->specular[0]*CONST_COLOR)<<16);
							font->Print(5+decalW, 130+decalH, 0, " Specular : %d", coul);
							glColor3f(0.5f,0.5f,1.0f);
							font->Print(5+decalW, 145+decalH, 0, "  Attenuate CONST : %d", AROUNDINT(lgh->attenuate_const*100.0f));
							font->Print(5+decalW, 160+decalH, 0, "  Attenuate QUADR : %d", AROUNDINT(lgh->attenuate_quadr*100.0f));
							font->Print(5+decalW, 175+decalH, 0, "  Cut-off angle   : %d", AROUNDINT(lgh->spot_cut_off));
						}
					}
				}
				else if(selectNode->type==SHL_TYPE_ID)
				{
					ZShell	*shl = (ZShell*) selectNode;
					glColor3f(1.0f,1.0f,1.0f);
					font->Print(5+decalW, 40+decalH, 0, "SHELL  : %s", shl->name.c_str());
				}
				else if(selectNode->type==COL_TYPE_ID)
				{
					glColor3f(1.0f,1.0f,1.0f);
					font->Print(5+decalW, 40+decalH, 0, "COLLISION  : %s", selectNode->name.c_str());
				}
				else if(selectNode->type==SPR_TYPE_ID)
				{
					ZSprite		*spr = (ZSprite*) selectNode;
					glColor3f(1.0f,1.0f,1.0f);
					font->Print(5+decalW, 40+decalH, 0, "SPRITE    : %s", spr->name.c_str());
					glColor3f(0.7f,0.8f,0.9f);
					font->Print(5+decalW, 70+decalH, 0, "Size WH   : [%d,%d]", AROUNDINT(spr->halfW*2.0f), AROUNDINT(spr->halfH*2.0f));
					font->Print(5+decalW, 85+decalH, 0, "Rotation  : %d", AROUNDINT(spr->rotationZ));
					ZMaterial	*mater = spr->GetMaterial();
					font->Print(5+decalW, 100+decalH, 0,"Material  : %s", mater->name.c_str());
					glColor3f(1.0f,0.5f,0.5f);
					if(mater->GetTexture1())	font->Print(5+decalW, 115+decalH, 0," Texture1   : %s", mater->GetTexture1()->name.c_str());
					else						font->Print(5+decalW, 115+decalH, 0," Texture1   : NO TEXTURE");
					if(mater->GetTexture2())	font->Print(5+decalW, 130+decalH, 0," Texture2   : %s", mater->GetTexture2()->name.c_str());
					else						font->Print(5+decalW, 130+decalH, 0," Texture2   : NO TEXTURE");
					font->Print(5+decalW, 145+decalH, 0," Color FLAT : [%d,%d,%d]", AROUNDINT(mater->color.x*CONST_COLOR), AROUNDINT(mater->color.y*CONST_COLOR), AROUNDINT(mater->color.z*CONST_COLOR));
					glColor3f(0.5f,0.5f,1.0f);
					font->Print(5+decalW, 160+decalH, 0,"  Flags");
					if(mater->IsOnMode(RENDER_TEXTURED))		font->Print(5+decalW, 175+decalH, 0,"  RENDER_TEXTURED       TRUE");
					else										font->Print(5+decalW, 175+decalH, 0,"  RENDER_TEXTURED       FALSE");
					if(mater->IsOnMode(RENDER_TEXTURED_BIS))	font->Print(5+decalW, 190+decalH, 0,"  RENDER_TEXTURED_BIS   TRUE  [%d]", AROUNDINT(mater->alpha*255.0f));
					else										font->Print(5+decalW, 190+decalH, 0,"  RENDER_TEXTURED_BIS   FALSE");
					if(mater->IsOnMode(RENDER_LIGHTED))			font->Print(5+decalW, 205+decalH, 0,"  RENDER_LIGHTED        TRUE");
					else										font->Print(5+decalW, 205+decalH, 0,"  RENDER_LIGHTED        FALSE");
					if(mater->IsOnMode(RENDER_GOURAUD_LIGHT))	font->Print(5+decalW, 220+decalH, 0,"  RENDER_GOURAUD_LIGHT  TRUE");
					else										font->Print(5+decalW, 220+decalH, 0,"  RENDER_GOURAUD_LIGHT  FALSE");
					if(mater->IsOnMode(RENDER_COLOR1))			font->Print(5+decalW, 235+decalH, 0,"  RENDER_COLOR1         TRUE  [%d,%d,%d]", AROUNDINT(mater->color1.x*CONST_COLOR), AROUNDINT(mater->color1.y*CONST_COLOR), AROUNDINT(mater->color1.z*CONST_COLOR));
					else										font->Print(5+decalW, 235+decalH, 0,"  RENDER_COLOR1         FALSE");
					if(mater->IsOnMode(RENDER_COLOR2))			font->Print(5+decalW, 250+decalH, 0,"  RENDER_COLOR2         TRUE  [%d,%d,%d]", AROUNDINT(mater->color2.x*CONST_COLOR), AROUNDINT(mater->color2.y*CONST_COLOR), AROUNDINT(mater->color2.z*CONST_COLOR));
					else										font->Print(5+decalW, 250+decalH, 0,"  RENDER_COLOR2         FALSE");
					if(mater->IsOnMode(RENDER_COLOR_VERTEX))	font->Print(5+decalW, 265+decalH, 0,"  RENDER_COLOR_VERTEX   TRUE");
					else										font->Print(5+decalW, 265+decalH, 0,"  RENDER_COLOR_VERTEX   FALSE");
					if(mater->IsOnMode(RENDER_TRANSP))			font->Print(5+decalW, 280+decalH, 0,"  RENDER_TRANSP         TRUE  [%d]", mater->GetCoeffTransp());
					else										font->Print(5+decalW, 280+decalH, 0,"  RENDER_TRANSP         FALSE");
					if(mater->IsOnMode(RENDER_ENVMAP))			font->Print(5+decalW, 295+decalH, 0,"  RENDER_ENVMAP         TRUE");
					else										font->Print(5+decalW, 295+decalH, 0,"  RENDER_ENVMAP         FALSE");
					if(mater->GetTexture1())					font->Print(5+decalW, 310+decalH, 0,"  Transparency Color    [%d,%d,%d] [%d]", mater->GetTexture1()->GetTranspR(), mater->GetTexture1()->GetTranspG(), mater->GetTexture1()->GetTranspB(), mater->GetTexture1()->GetRate());
				}
				else if(selectNode->type==ANI_TYPE_ID)
				{
					ZAnim	*anim = (ZAnim*) selectNode;
					glColor3f(1.0f,1.0f,1.0f);
					font->Print(5+decalW, 40+decalH, 0, "ANIMATION : %s", anim->name.c_str());
					glColor3f(0.7f,0.8f,0.9f);
					font->Print(5+decalW, 55+decalH, 0, "Length    : %d", anim->getLength());
					font->Print(5+decalW, 70+decalH, 0, "Nb Position Keys -> %d", anim->listPos.size());
					font->Print(5+decalW, 85+decalH, 0, "Nb Rotation Keys -> %d", anim->listRot.size());
				}
				else if(selectNode->type==PCL_TYPE_ID)
				{
					ZEmitter	*part = (ZEmitter*) selectNode;
					glColor3f(1.0f,1.0f,1.0f);
					font->Print(5+decalW, 40+decalH, 0, "PARTICLE : %s", part->name.c_str());
					glColor3f(0.7f,0.8f,0.9f);
					if(part->visible)		font->Print(5+decalW, 40+decalH, 0, "Visible  : yes");
					else					font->Print(5+decalW, 40+decalH, 0, "Visible  : no");

					glColor3f(1.0f,0.0f,0.0f);
					font->Print(5+decalW, 70+decalH, 0, "LIFE		: %f", part->life);
					font->Print(5+decalW, 85+decalH, 0, "AGE		: %f", part->age);
					font->Print(5+decalW,100+decalH, 0, "TIMESTEP	: %f", part->dt);

					int v = part->volume.type;
					if(v==VOLUME_SPHERE)
						font->Print(5+decalW, 115+decalH, 0, "VOLUME : %s", "sphere");
					if(v==VOLUME_CONE)
						font->Print(5+decalW, 115+decalH, 0, "VOLUME : %s", "cone");
					if(v==VOLUME_PLAN)
						font->Print(5+decalW, 115+decalH, 0, "VOLUME : %s", "plan");
					if(v==VOLUME_LINE)
						font->Print(5+decalW, 115+decalH, 0, "VOLUME : %s", "ligne");

					font->Print(5+decalW, 130+decalH, 0, "VOLUMEA	: %f %f %f", part->volume.vectorA.x, part->volume.vectorA.y, part->volume.vectorA.z);
					font->Print(5+decalW, 145+decalH, 0, "VOLUMEB	: %f %f %f", part->volume.vectorB.x, part->volume.vectorB.y, part->volume.vectorB.z);

					if(part->pFather==NULL)
						font->Print(5+decalW, 160+decalH, 0, "LINKED : %s", "no");
					else
						font->Print(5+decalW, 160+decalH, 0, "FATHER : %s", part->pFather->name);


					int n=0;

					if(part->particlelist.size()==0)
						font->Print(5+decalW, 190+decalH, 0, "PARTICLE : %s", "none");
					else for(int i=0;i<part->particlelist.size();i++)
					{
						font->Print(5+decalW, 190+i*15+decalH, 0, "PARTICLE : %s", part->particlelist[i].parttype->name.c_str());
						n+=part->particlelist[i].list.size();
					}
					font->Print(5+decalW, 175+decalH, 0, "NUMBER	: %d", n);

					int h = 205 + 15*part->particlelist.size();
					ZMatrix mat = part->worldMat;
										
					font->Print(5+decalW, h+decalH, 0, "%f %f %f %f", mat._11, mat._12, mat._13, mat._14);
					font->Print(5+decalW, h+decalH+15, 0, "%f %f %f %f", mat._21, mat._22, mat._23, mat._24);
					font->Print(5+decalW, h+decalH+30, 0, "%f %f %f %f", mat._31, mat._32, mat._33, mat._34);
					font->Print(5+decalW, h+decalH+45, 0, "%f %f %f %f", mat._41, mat._42, mat._43, mat._44);

					ZVector3 rot = mat.GetAnglesYXZ();
					font->Print(5+decalW, h+decalH+60, 0, "Angles  : %f %f %f", rot.x, rot.y, rot.z);
					font->Print(5+decalW, h+decalH+75, 0, "Position :%f %f %f", part->RealPos.x, part->RealPos.y, part->RealPos.z);

					if(part->state&PCL_ENABLE)			font->Print(5+decalW, h+decalH+90, 0, "ENABLE");
					else								font->Print(5+decalW, h+decalH+90, 0, "DISABLE");

					if(part->state&PCL_ACTIVE)			font->Print(5+decalW, h+decalH+105, 0, "ACTIVE");
					else								font->Print(5+decalW, h+decalH+105, 0, "INACTIVE");

					if(part->effectlist.size()==0)
						font->Print(5+decalW, 190+decalH, 0, "EFFECT : none");
					else for(int i=0;i<part->effectlist.size();i++)
						font->Print(5+decalW, h+120+i*15+decalH, 0, "EFFECT : %s", part->effectlist[i]->name.c_str());

						
				}
				else if(selectNode->type==SND_TYPE_ID)		font->Print(5+decalW, 40+decalH, 0, "SOUND");
			}
			// Recherche sur le TreeDatas
			else
			{
				for(kk=0; kk<ItemListDatas.size() && ItemListDatas[kk].item!=selectedITEM; kk++);

				if(kk<ItemListDatas.size())
				{
					ZData	*selectNode = ItemListDatas[kk].node;

					if(selectNode->type==MAT_TYPE_ID)
					{
						ZMaterial	*mater = (ZMaterial*) selectNode;
						glColor3f(1.0f,1.0f,1.0f);
						font->Print(5+decalW, 40+decalH, 0, "MATERIAL   : %s", mater->name.c_str());

						glColor3f(1.0f,0.5f,0.5f);
						if(mater->GetTexture1())	
						{
							font->Print(5+decalW, 60+decalH, 0,"Texture1   : %s", mater->GetTexture1()->name.c_str());
							font->Print(38+decalW, 290+decalH, 1,"Tex 1");
						}
						else						font->Print(5+decalW, 60+decalH, 0,"Texture1   : NO TEXTURE");
						if(mater->GetTexture2())
						{
							font->Print(5+decalW, 75+decalH, 0,"Texture2   : %s", mater->GetTexture2()->name.c_str());
							font->Print(238+decalW, 290+decalH, 1,"Tex 2");
						}
						else						font->Print(5+decalW, 75+decalH, 0,"Texture2   : NO TEXTURE");
						font->Print(5+decalW, 90+decalH, 0,"Color FLAT : [%d,%d,%d]", AROUNDINT(mater->color.x*CONST_COLOR), AROUNDINT(mater->color.y*CONST_COLOR), AROUNDINT(mater->color.z*CONST_COLOR));
						glColor3f(0.5f,0.5f,1.0f);
						font->Print(5+decalW, 105+decalH, 0," Flags");
						if(mater->IsOnMode(RENDER_TEXTURED))		font->Print(5+decalW, 120+decalH, 0," RENDER_TEXTURED       TRUE");
						else										font->Print(5+decalW, 120+decalH, 0," RENDER_TEXTURED       FALSE");
						if(mater->IsOnMode(RENDER_TEXTURED_BIS))	font->Print(5+decalW, 135+decalH, 0," RENDER_TEXTURED_BIS   TRUE  [%d]", AROUNDINT(mater->alpha*255.0f));
						else										font->Print(5+decalW, 135+decalH, 0," RENDER_TEXTURED_BIS   FALSE");
						if(mater->IsOnMode(RENDER_LIGHTED))			font->Print(5+decalW, 150+decalH, 0," RENDER_LIGHTED        TRUE");
						else										font->Print(5+decalW, 150+decalH, 0," RENDER_LIGHTED        FALSE");
						if(mater->IsOnMode(RENDER_GOURAUD_LIGHT))	font->Print(5+decalW, 165+decalH, 0," RENDER_GOURAUD_LIGHT  TRUE");
						else										font->Print(5+decalW, 165+decalH, 0," RENDER_GOURAUD_LIGHT  FALSE");
						if(mater->IsOnMode(RENDER_COLOR1))			font->Print(5+decalW, 180+decalH, 0," RENDER_COLOR1         TRUE  [%d,%d,%d]", AROUNDINT(mater->color1.x*CONST_COLOR), AROUNDINT(mater->color1.y*CONST_COLOR), AROUNDINT(mater->color1.z*CONST_COLOR));
						else										font->Print(5+decalW, 180+decalH, 0," RENDER_COLOR1         FALSE");
						if(mater->IsOnMode(RENDER_COLOR2))			font->Print(5+decalW, 195+decalH, 0," RENDER_COLOR2         TRUE  [%d,%d,%d]", AROUNDINT(mater->color2.x*CONST_COLOR), AROUNDINT(mater->color2.y*CONST_COLOR), AROUNDINT(mater->color2.z*CONST_COLOR));
						else										font->Print(5+decalW, 195+decalH, 0," RENDER_COLOR2         FALSE");
						if(mater->IsOnMode(RENDER_COLOR_VERTEX))	font->Print(5+decalW, 210+decalH, 0," RENDER_COLOR_VERTEX   TRUE");
						else										font->Print(5+decalW, 210+decalH, 0," RENDER_COLOR_VERTEX   FALSE");
						if(mater->IsOnMode(RENDER_TRANSP))			font->Print(5+decalW, 225+decalH, 0," RENDER_TRANSP         TRUE  [%d]", mater->GetCoeffTransp());
						else										font->Print(5+decalW, 225+decalH, 0," RENDER_TRANSP         FALSE");
						if(mater->IsOnMode(RENDER_ENVMAP))			font->Print(5+decalW, 240+decalH, 0," RENDER_ENVMAP         TRUE");
						else										font->Print(5+decalW, 240+decalH, 0," RENDER_ENVMAP         FALSE");
						if(mater->GetTexture1())					font->Print(5+decalW, 255+decalH, 0," Transparency Color    [%d,%d,%d] [%d]", mater->GetTexture1()->GetTranspR(), mater->GetTexture1()->GetTranspG(), mater->GetTexture1()->GetTranspB(), mater->GetTexture1()->GetRate());

						if(mater->GetTexture1())
						{
							glColor3f(1.0f, 1.0f, 1.0f);
							mater->GetTexture1()->PutGLparams();
							int sizeT = 130;

							glLoadIdentity();
							glTranslated(10+decalW,310+decalH,0);

							glBegin(GL_QUADS);
								glTexCoord2f(0.0f, 1.0f);			glVertex2i(0, 0);
								glTexCoord2f(0.0f, 0.0f);			glVertex2d(0, sizeT);
								glTexCoord2f(1.0f, 0.0f);			glVertex2i(sizeT, sizeT);
								glTexCoord2f(1.0f, 1.0f);			glVertex2i(sizeT, 0);
							glEnd();
						}

						if(mater->GetTexture2())
						{
							glColor3f(1.0f, 1.0f, 1.0f);
							mater->GetTexture2()->PutGLparams();
							int sizeT = 130;

							glLoadIdentity();
							glTranslated(210+decalW,310+decalH,0);

							glBegin(GL_QUADS);
								glTexCoord2f(0.0f, 1.0f);			glVertex2i(0, 0);
								glTexCoord2f(0.0f, 0.0f);			glVertex2d(0, sizeT);
								glTexCoord2f(1.0f, 0.0f);			glVertex2i(sizeT, sizeT);
								glTexCoord2f(1.0f, 1.0f);			glVertex2i(sizeT, 0);
							glEnd();
						}
					}
					else if(selectNode->type==TEX_TYPE_ID)
					{
						ZTexture	*tex = (ZTexture*) selectNode;
						glColor3f(1.0f,1.0f,1.0f);
						font->Print(5+decalW, 40+decalH, 0, "TEXTURE   : %s", tex->name.c_str());
						
						if(tex->A)		font->Print(5+decalW, 60+decalH, 0,"  Transparency Color    [%d,%d,%d] [%d]", tex->GetTranspR(), tex->GetTranspG(), tex->GetTranspB(), tex->GetRate());
						else			font->Print(5+decalW, 60+decalH, 0,"  No transparency");

						glColor3f(1.0f, 1.0f, 1.0f);
						tex->PutGLparams();
						int sizeT = 130;

						glLoadIdentity();
						glTranslated(38+decalW,80+decalH,0);

						glBegin(GL_QUADS);
							glTexCoord2f(0.0f, 1.0f);			glVertex2i(0, 0);
							glTexCoord2f(0.0f, 0.0f);			glVertex2d(0, sizeT);
							glTexCoord2f(1.0f, 0.0f);			glVertex2i(sizeT, sizeT);
							glTexCoord2f(1.0f, 1.0f);			glVertex2i(sizeT, 0);
						glEnd();
					}
					else if(selectNode->type==PCLDEF_TYPE_ID)
					{
						ZParticle	*part = (ZParticle*) selectNode;
						glColor3f(1.0f,0.0f,0.0f);
						font->Print(5+decalW, 40+decalH, 0, "PARTICLE   : %s", part->name.c_str());
						font->Print(5+decalW, 55+decalH, 0, "LIFE		: %f", part->life);
						font->Print(5+decalW, 70+decalH, 0, "rate		: %f", part->rate);
						font->Print(5+decalW, 85+decalH, 0, "size		: %f", part->size[0]);
						font->Print(5+decalW,100+decalH, 0, "spin		: %f", part->spin[0]);

						int n = part->color.size();
						int h = 20;
						int w = 200/n;

						for(int i=0;i<n;i++)
							font->Print(5+decalW,115+15*i+decalH, 0, "color		: %f %f %f %f", part->color[i].value.x, part->color[i].value.y, part->color[i].value.z, part->color[i].value.w);

						glDisable(GL_TEXTURE_2D);
						glLoadIdentity();
						glTranslated(38+decalW,140+n*15+decalH,0);

						glPolygonMode(GL_FRONT, GL_LINE);
						glColor3f(1.0f, 1.0f, 1.0f);
						glBegin(GL_QUADS);
							glVertex2i(-1, -1);
							glVertex2d(-1, h+1);
							glVertex2i(201, h+1);
							glVertex2i(201, 0);
						glEnd();

						glPolygonMode(GL_FRONT, GL_FILL);
						for(i=0;i<n;i++)
						{
							glTranslated(w*i,0,0);
							glBegin(GL_QUADS);
								glColor3f(part->color[i].value.x, part->color[i].value.y, part->color[i].value.z);
								glVertex2i(0, 0);
								glVertex2d(0, h);
								glVertex2i(w, h);
								glVertex2i(w, 0);
							glEnd();
						}
						glEnable(GL_TEXTURE_2D);
					}
					else if(selectNode->type==PCLEFF_TYPE_ID)
					{
						ZEffect	*eff = (ZEffect*) selectNode;
						glColor3f(1.0f,0.0f,0.0f);
						font->Print(5+decalW, 40+decalH, 0, "EFFECT   : %s", eff->name.c_str());
						if(eff->etype==EFFECT_MAGNETIC)
							font->Print(5+decalW, 55+decalH, 0, "TYPE	: %s", "magnetic");
						if(eff->etype==EFFECT_ELECTRIC)
							font->Print(5+decalW, 55+decalH, 0, "TYPE	: %s", "electric");
						if(eff->etype==EFFECT_CONSTANT)
							font->Print(5+decalW, 55+decalH, 0, "TYPE	: %s", "constant");
						if(eff->etype==EFFECT_HELICOID)
							font->Print(5+decalW, 55+decalH, 0, "TYPE	: %s", "helicoid");
						if(eff->etype==EFFECT_PLANCOLL)
							font->Print(5+decalW, 55+decalH, 0, "TYPE	: %s", "plancoll");
						if(eff->etype==EFFECT_CHAOTIC0)
							font->Print(5+decalW, 55+decalH, 0, "TYPE	: %s", "chaotic0");
						if(eff->etype==EFFECT_CHAOTIC1)
							font->Print(5+decalW, 55+decalH, 0, "TYPE	: %s", "chaotic1");

						font->Print(5+decalW, 70+decalH, 0, "VOLUMEA	: %f %f %f", eff->vectorA.x, eff->vectorA.y, eff->vectorA.z);
						font->Print(5+decalW, 85+decalH, 0, "VOLUMEB	: %f %f %f", eff->vectorB.x, eff->vectorB.y, eff->vectorB.z);
						font->Print(5+decalW,100+decalH, 0, "VOLUMEC	: %f %f %f", eff->vectorC.x, eff->vectorC.y, eff->vectorC.z);
					}
				}
			}
		}


		///////////////////////////////////////////////
		///		Affichage des données de souris		///
		///////////////////////////////////////////////

		glDisable(GL_SCISSOR_TEST);

		glColor3f(0.3f,1.0f,0.3f);
		font->texture->PutGLparams();
		font->Print(5, InfoStaticHH+InfoTreeHH+2, 0, "InfoScreen");

		glDisable(GL_TEXTURE_2D);
		glLoadIdentity();
		glTranslated(3,InfoStaticHH+InfoTreeHH-3,0);
		glColor3f(0.6f, 0.6f, 0.6f);
		glBegin(GL_QUADS);
			glVertex2i(0, 0);
			glVertex2i(0, 2);
			glVertex2i(mainInfoWW-5, 2);
			glVertex2i(mainInfoWW-5, 0);
		glEnd();
		glEnable(GL_TEXTURE_2D);

		glScissor(0, 0, mainInfoWW, InfoMouseHH-20);
		glEnable(GL_SCISSOR_TEST);

		int		faceNb;
		float	dist;

		if(focusInfo==2 && keysPressed[VK_UP]	&& scrollInfoH2<0)			scrollInfoH2 += 5;
		if(focusInfo==2 && keysPressed[VK_DOWN] && scrollInfoH2>-500)		scrollInfoH2 -= 5;
		if(focusInfo==2 && keysPressed[VK_LEFT]  && scrollInfoW2<0)			scrollInfoW2 += 5;
		if(focusInfo==2 && keysPressed[VK_RIGHT] && scrollInfoW2>-500)		scrollInfoW2 -= 5;

		decalH = InfoStaticHH+InfoTreeHH+scrollInfoH2;
		decalW = scrollInfoW2;

		ZObject*	resultat = Getinfo(mainMouseX, mainMouseY, NULL, NULL, NULL, NULL, &faceNb, &dist);

		// Ecrit les données intéressantes

		if(resultat)
		{
			glColor3f(1.0f,1.0f,1.0f);
			font->Print(5+decalW, 30+decalH, 0, "OBJECT     : %s", resultat->name.c_str());
			font->Print(200+decalW, 30+decalH, 0, "Dist : %d", (int)(dist*100.0f));

			glColor3f(0.7f,0.8f,0.9f);
			if(resultat->GetMesh()->dependency==true || resultat->GetMesh()->displayListCreate==false)
				font->Print(5+decalW, 50+decalH, 0, "TOPO       : %s - dynamic", resultat->GetMesh()->name.c_str());
			else
				font->Print(5+decalW, 50+decalH, 0, "TOPO       : %s - static", resultat->GetMesh()->name.c_str());
			if(resultat->IsMultiMeshes())		font->Print(5+decalW, 65+decalH, 0, "MultiTOPO  : yes");
			else								font->Print(5+decalW, 65+decalH, 0, "MultiTOPO  : no");
			if(resultat->visible)				font->Print(5+decalW, 80+decalH, 0, "Visible    : yes");
			else								font->Print(5+decalW, 80+decalH, 0, "Visible    : no");
			if(resultat->normalsTransformed)	font->Print(5+decalW, 95+decalH, 0, "NormTransf : yes");
			else								font->Print(5+decalW, 95+decalH, 0, "NormTransf : no");

			glColor3f(0.0f,1.0f,1.0f);
			
			ZFace	*curFace = &(resultat->GetMesh()->Faces[faceNb]);
			font->Print(5+decalW, 115+decalH, 0,"Face       : %d [%d,%d] [%d,%d] [%d,%d]", faceNb, 
						AROUNDINT(curFace->UV1[0].u*CONST_TEX_COORD), AROUNDINT(curFace->UV1[0].v*CONST_TEX_COORD),
						AROUNDINT(curFace->UV1[1].u*CONST_TEX_COORD), AROUNDINT(curFace->UV1[1].v*CONST_TEX_COORD),
						AROUNDINT(curFace->UV1[2].u*CONST_TEX_COORD), AROUNDINT(curFace->UV1[2].v*CONST_TEX_COORD)	);
			ZMaterial	*mater = curFace->GetMaterial();
			font->Print(5+decalW, 130+decalH, 0,"Material   : %s", mater->name.c_str());

			glColor3f(1.0f,0.5f,0.5f);
			if(mater->GetTexture1())
			{
				font->Print(5+decalW, 150+decalH, 0," Texture1   : %s", mater->GetTexture1()->name.c_str());
				font->Print(38+decalW, 380+decalH, 1,"Tex 1");
			}
			else						font->Print(5+decalW, 150+decalH, 0," Texture1   : NO TEXTURE");
			if(mater->GetTexture2())	
			{
				font->Print(5+decalW, 165+decalH, 0," Texture2   : %s", mater->GetTexture2()->name.c_str());
				font->Print(238+decalW, 380+decalH, 1,"Tex 2");
			}
			else						font->Print(5+decalW, 165+decalH, 0," Texture2   : NO TEXTURE");
			font->Print(5+decalW, 180+decalH, 0," Color FLAT : [%d,%d,%d]", AROUNDINT(mater->color.x*CONST_COLOR), AROUNDINT(mater->color.y*CONST_COLOR), AROUNDINT(mater->color.z*CONST_COLOR));

			glColor3f(0.5f,0.5f,1.0f);
			font->Print(5+decalW, 200+decalH, 0,"  Flags");
			if(mater->IsOnMode(RENDER_TEXTURED))		font->Print(5+decalW, 215+decalH, 0,"  RENDER_TEXTURED       TRUE");
			else										font->Print(5+decalW, 215+decalH, 0,"  RENDER_TEXTURED       FALSE");
			if(mater->IsOnMode(RENDER_TEXTURED_BIS))	font->Print(5+decalW, 230+decalH, 0,"  RENDER_TEXTURED_BIS   TRUE  [%d]", AROUNDINT(mater->alpha*255.0f));
			else										font->Print(5+decalW, 230+decalH, 0,"  RENDER_TEXTURED_BIS   FALSE");
			if(mater->IsOnMode(RENDER_LIGHTED))			font->Print(5+decalW, 245+decalH, 0,"  RENDER_LIGHTED        TRUE");
			else										font->Print(5+decalW, 245+decalH, 0,"  RENDER_LIGHTED        FALSE");
			if(mater->IsOnMode(RENDER_GOURAUD_LIGHT))	font->Print(5+decalW, 260+decalH, 0,"  RENDER_GOURAUD_LIGHT  TRUE");
			else										font->Print(5+decalW, 260+decalH, 0,"  RENDER_GOURAUD_LIGHT  FALSE");
			if(mater->IsOnMode(RENDER_COLOR1))			font->Print(5+decalW, 275+decalH, 0,"  RENDER_COLOR1         TRUE  [%d,%d,%d]", AROUNDINT(mater->color1.x*CONST_COLOR), AROUNDINT(mater->color1.y*CONST_COLOR), AROUNDINT(mater->color1.z*CONST_COLOR));
			else										font->Print(5+decalW, 275+decalH, 0,"  RENDER_COLOR1         FALSE");
			if(mater->IsOnMode(RENDER_COLOR2))			font->Print(5+decalW, 290+decalH, 0,"  RENDER_COLOR2         TRUE  [%d,%d,%d]", AROUNDINT(mater->color2.x*CONST_COLOR), AROUNDINT(mater->color2.y*CONST_COLOR), AROUNDINT(mater->color2.z*CONST_COLOR));
			else										font->Print(5+decalW, 290+decalH, 0,"  RENDER_COLOR2         FALSE");
			if(mater->IsOnMode(RENDER_COLOR_VERTEX))	font->Print(5+decalW, 305+decalH, 0,"  RENDER_COLOR_VERTEX   TRUE");
			else										font->Print(5+decalW, 305+decalH, 0,"  RENDER_COLOR_VERTEX   FALSE");
			if(mater->IsOnMode(RENDER_TRANSP))			font->Print(5+decalW, 320+decalH, 0,"  RENDER_TRANSP         TRUE  [%d]", mater->GetCoeffTransp());
			else										font->Print(5+decalW, 320+decalH, 0,"  RENDER_TRANSP         FALSE");
			if(mater->IsOnMode(RENDER_ENVMAP))			font->Print(5+decalW, 335+decalH, 0,"  RENDER_ENVMAP         TRUE");
			else										font->Print(5+decalW, 335+decalH, 0,"  RENDER_ENVMAP         FALSE");
			if(mater->GetTexture1())					font->Print(5+decalW, 350+decalH, 0,"  Transparency Color    [%d,%d,%d] [%d]", mater->GetTexture1()->GetTranspR(), mater->GetTexture1()->GetTranspG(), mater->GetTexture1()->GetTranspB(), mater->GetTexture1()->GetRate());

			if(mater->GetTexture1())
			{
				glColor3f(1.0f, 1.0f, 1.0f);
				mater->GetTexture1()->PutGLparams();
				int sizeT = 130;

				glLoadIdentity();
				glTranslated(10+decalW,400+decalH,0);

				glBegin(GL_QUADS);
					glTexCoord2f(0.0f, 1.0f);			glVertex2i(0, 0);
					glTexCoord2f(0.0f, 0.0f);			glVertex2i(0, sizeT);
					glTexCoord2f(1.0f, 0.0f);			glVertex2i(sizeT, sizeT);
					glTexCoord2f(1.0f, 1.0f);			glVertex2i(sizeT, 0);
				glEnd();
			}

			if(mater->GetTexture2())
			{
				glColor3f(1.0f, 1.0f, 1.0f);
				mater->GetTexture2()->PutGLparams();
				int sizeT = 130;

				glLoadIdentity();
				glTranslated(210+decalW,400+decalH,0);

				glBegin(GL_QUADS);
					glTexCoord2f(0.0f, 1.0f);			glVertex2i(0, 0);
					glTexCoord2f(0.0f, 0.0f);			glVertex2i(0, sizeT);
					glTexCoord2f(1.0f, 0.0f);			glVertex2i(sizeT, sizeT);
					glTexCoord2f(1.0f, 1.0f);			glVertex2i(sizeT, 0);
				glEnd();
			}
		}

		font->StopFontPrint();

		glDisable(GL_SCISSOR_TEST);

		// Blit et repasse sur la fenêtre courrante
		SwapBuffers(mainInfoDC);
		wglMakeCurrent(currentDC, currentRC);
	}

	
	if(blockRendering)
	{
		MSG		msg;
		if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
		{
			if(msg.message==WM_QUIT)
			{
				blockRendering = false;
			}
			else
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
		if(blockRendering)	Display(r, g, b, baseNode, wired, ortho, clear);
	}


}



#endif











///////////////////////////////////////////////////////////////////////////
///		DisplaySOFT														///
///////////////////////////////////////////////////////////////////////////

void ZScene::DisplaySOFT(RenderBuffer *buffer, float r, float g, float b, ZNode *baseNode, bool wired, bool ortho, bool clear)
{



#ifdef _BENCH_SOFT_
	profile->BeginProfile(0);
	profile->BeginProfile(6);
	profile->BeginProfileCYCLE(0);
	profile->BeginProfileCYCLE(6);
#endif


	if(!ortho)		activeCam->ComputeMatrix();
	else			activeCam->ComputeMatrixOrtho();
	orthoGraphic = ortho;



	///////////////////////////////////////////////
	/// Computing								///
	///////////////////////////////////////////////

	// ----> Create the lists <---- //
	if( updateGraphList || (lastBaseNodeList!=baseNode) )
	{
		World->createNodeLists(baseNode);					// Create the linear lists of OBJECT & LIGHT & CAMS
		updateGraphList  = false;
		lastBaseNodeList = baseNode;
	}

	if( textureModified )
	{
		UpdateMaterialByTextures();
		textureModified = false;
	}

	if( materialModified )
	{
		UpdateMeshByMaterials();
		materialModified = false;
	}


	// ----> Compute the matrices <----

	World->ComputeMatrices(activeCam, (ZNodeGraph*)baseNode, activeCam->cameraMatx, 1.0f, true);

	if( meshModified )
	{
		UpdateMeshes();
		meshModified = false;
	}


#ifdef _BENCH_SOFT_
	profile->EndProfile(0);
	profile->EndProfileCYCLE(0);
	profile->BeginProfile(1);
	profile->BeginProfileCYCLE(1);
#endif

	// ----> Transform the vertices <----
	World->TransformVertices();

	World->ComputeNormals(false);

	World->UpdateSounds(activeListener);


	///////////////////////////////////////////////
	/// Transformation of objects & lights		///
	///////////////////////////////////////////////

	SetMaterialMeshForNext();										// re-set the flags for the next computing (flags of modification)

	World->ViewFrustrumCull(activeCam, (float)WW, (float)HH, ortho);

	World->ComputeLightTarget(activeCam->cameraMatx);

#ifdef _BENCH_SOFT_
	profile->EndProfile(1);
	profile->EndProfileCYCLE(1);
	profile->BeginProfile(2);
	profile->BeginProfileCYCLE(2);
#endif

	// Spécifique au mode SOFTWARE
	World->SelectFaces(activeCam, wired, ortho);

#ifdef _BENCH_SOFT_
	profile->EndProfile(2);
	profile->EndProfileCYCLE(2);
	profile->BeginProfile(3);
	profile->BeginProfileCYCLE(3);
#endif

	// Calcul de la couleur de fond
	unsigned char int_r, int_g, int_b;
	int	color;
	if(clear)
	{
		int_r =  AROUNDINT(r*CONST_COLOR);
		int_g = AROUNDINT(g*CONST_COLOR);
		int_b = AROUNDINT(b*CONST_COLOR);

		color = _COLOR_BGR_TO_I (int_b, int_g, int_r);
		InitFogPalette(color); 
	}

#ifdef _BENCH_SOFT_
	profile->EndProfile(3);
	profile->EndProfileCYCLE(3);
	profile->BeginProfile(4);
	profile->BeginProfileCYCLE(4);
#endif


	// Effaçage du buffer écran
	if(clear)
	{
#ifndef _SOFT_ASM_



		///////////////////////////////////////////////////
		//
		// $LB : CLEAR function, C version 
		//
		///////////////////////////////////////////////////





		////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		//
		// $LB : byte per byte clear algo, we should be able to do better

		/*
		int		iii, bufSize;
		OBJBITMAP_BUFFER	buff_remp = (OBJBITMAP_BUFFER) buffer->Image;
		bufSize = buffer->width * buffer->height;

		for(iii=0; iii<bufSize; iii++)		{*(buff_remp++) = int_b; *(buff_remp++) = int_g; *(buff_remp++) = int_r;}
		*/

		//
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		

		//////////////////////////////////////////////////////////////////////////
		//
		// $LB : 32bits per 32bits clear algo
		//
		//////////////////////////////////////////////////////////////////////////
		
		int iii,bufSizeb, bufSizew;
		unsigned long int pkt1, pkt2, pkt3;
		unsigned char* ptr;
		unsigned long int* buff_remp = (unsigned long int*) buffer->Image;


		bufSizeb = buffer->width * buffer->height;
		bufSizew = bufSizeb>>2; //<=> /12
		bufSizeb *= 3;

		ptr = (unsigned char*) &pkt1;
		*(ptr++) = int_b;
		*(ptr++) = int_g;
		*(ptr++) = int_r;
		*(ptr)   = int_b;
		pkt2 = (pkt1>>8) | (int_g<<24);
	    pkt3 = (pkt2>>8) | (int_r<<24);


		for (iii=0; iii<bufSizew; iii++)

		{ *(buff_remp++) = pkt1; *(buff_remp++) = pkt2; *(buff_remp++) = pkt3;	}


		ptr = (unsigned char*) buff_remp;
		for (iii=0; iii < (bufSizeb - ((bufSizew*3)<<2)); iii++)

		{ *(ptr++) = int_b; *(ptr++) = int_g; *(ptr++) = int_r;	}
		

		///////////////////////////////////////////////////////////////////////////////





		
#else

		///////////////////////////////////////////////////
		//
		// $LB : CLEAR function, MASM assembler version 
		//
		///////////////////////////////////////////////////





		//////////////////////////////////////////////////
		//
		// $LB : old 16 bits algo
		//
		//////////////////////////////////////////////////

		/*
		int		bufSize = buffer->width * buffer->height;
		short	*buff_remp = (short*) buffer->Image;
		_asm{															
			pushad													
				xor		eax, eax
				xor		edi, edi
				mov		ax,	 fond16									
				mov		edi, buff_remp
				mov		ecx, bufSize
				rep		stosw											
				popad													
		}															
		*/

		///////////////////////////////////////////////////



		////////////////////////////////////////////////////////////////////////////
		//
		// $LB : new 24 bits algo, copy byte per byte, it works but it's not good,
		//       because i'm not a MASM guy :) TO DO : optimise and define the "_SOFT_ASM_"
		//       flag in the project settings, in order to compile.
		//
		////////////////////////////////////////////////////////////////////////////
		int		bufSize = buffer->width * buffer->height;
		unsigned char* buff_remp = (unsigned char*) buffer->Image;
		_asm{															
			pushad													
				xor		eax, eax
				xor		edi, edi
				mov		edi, buff_remp
				mov		ecx, bufSize
				xor     ebx, ebx
				mywhile:
			    inc    ebx 
				mov     al,int_b
				stosb
				mov     al,int_g
				stosb
				mov     al,int_r
				stosb
				cmp     ebx, ecx
				jbe     mywhile
				popad													
		}					

#endif
	}



#ifdef _BENCH_SOFT_
	profile->EndProfile(4);
	profile->EndProfileCYCLE(4);
	profile->BeginProfile(5);
	profile->BeginProfileCYCLE(5);
#endif


//	_asm{int 3};

	// Rendu SOFT de la scene
	if(!wired)		World->RenderSOFT(activeCam, buffer, color, clear);
	else			World->RenderSOFT_Wired(activeCam, buffer, color, clear);
	

#ifdef _BENCH_SOFT_
	profile->EndProfile(5);
	profile->EndProfileCYCLE(5);
	profile->EndProfile(6);
	profile->EndProfileCYCLE(6);



		MMechostr(0, "Graph & Matrix  : %f\t%d\n", profile->GetAverageTime(0), profile->GetAverageCYCLE(0));
	MMechostr(0, "VFC & Transform : %f\t%d\n", profile->GetAverageTime(1), profile->GetAverageCYCLE(1));
	MMechostr(0, "SelectFaces     : %f\t%d\n", profile->GetAverageTime(2), profile->GetAverageCYCLE(2));
	MMechostr(0, "InitFogPalette  : %f\t%d\n", profile->GetAverageTime(3), profile->GetAverageCYCLE(3));
	MMechostr(0, "Clear ecran     : %f\t%d\n", profile->GetAverageTime(4), profile->GetAverageCYCLE(4));
	MMechostr(0, "Rendu           : %f\t%d\n", profile->GetAverageTime(5), profile->GetAverageCYCLE(5));
	
	MMechostr(0, "Total           : %f\t%d\n", profile->GetAverageTime(6), profile->GetAverageCYCLE(6));

	MMechostr(0, "SelectFaces (*) : %f\t%d\n\n", profile->GetAverageTime(7), profile->GetAverageCYCLE(7));

	MMechostr(0, "UpdateFace      : %f\t%d\n", profile->GetAverageTime(8), profile->GetAverageCYCLE(8));
	MMechostr(0, "RenderLineSoft  : %f\t%d\n\n", profile->GetAverageTime(9), profile->GetAverageCYCLE(9));

#endif

}











///////////////////////////////////////////////////////////////////////////////////////////////
/// Getinfo																					///
///																							///
///		This function give the object pointed by (xplot, yplot)	and texture infos			///
///																							///
///////////////////////////////////////////////////////////////////////////////////////////////

ZObject*	ZScene::Getinfo(int xplot, int yplot, float * u, float * v, float * z, int *handmat, int *faceNb, float *distance)
{
	if(orthoGraphic==false)
	{
		ZPRS*		curPRS;

		curPRS  = activeCam->GetPRS();

		ZVector4	visee;
		ZVector3	origine, rayon;

		// ----- Position de la camera -----
		origine.SetCoord(activeCam->worldPos.x, activeCam->worldPos.y, activeCam->worldPos.z);


		// ----- Position de la target (sur le plan Znear) -----
		// Recuperation de la matrice de rotation de la camera
		ZMatrix		mat;
		mat = activeCam->worldMat * (1.0f/activeCam->worldScale);
		mat._14 = mat._24 = mat._34 = 0.0f;
		mat._44 = 1.0f;

		// Calcul de la position réelle en 3D à partir de la position écran
		float	top		= activeCam->Znear * ((double)(activeCam->height/2)) / ((double)activeCam->dy);
		float	right	= top * ((float)WW/(float)HH);

		visee.SetCoord( 2.0f * right * (float) ( (float)xplot-(float)WW/2.0f ) / (float)WW, 
						2.0f * top   * (float) ( (float)HH/2.0f-(float)yplot ) / (float)HH, 
						-activeCam->Znear,
						0.0f);
		visee *= mat;
		rayon.SetCoord(visee.x, visee.y, visee.z);
		rayon.Normalize();


	 	// ----- Init des vars de résultat -----
		ZObject*	resultat;
		resultat = NULL;

		ZMatrix		camMatInv = activeCam->worldMat;
		camMatInv.Inverse();

		// ----- Test sur l'ensemble des objets 3D -----
		if(distance)
		{
			*distance = 100000000.0f;
			World->SelectionTest(camMatInv, origine, rayon, distance, activeCam->Znear, u, v, z, &resultat, faceNb);
		}
		else
		{
			float	distanceTmp = 100000000.0f;
			World->SelectionTest(camMatInv, origine, rayon, &distanceTmp, activeCam->Znear, u, v, z, &resultat, faceNb);
		}

		return	resultat;
	}
	else
	{
		ZVector3	origine, rayon;
		rayon.SetCoord(0.0f, 0.0f, -1.0f);

		// Calcul de la position réelle en 3D à partir de la position écran
		float	top		= /*activeCam->Znear */ ((double)(activeCam->height/2)) / ((double)activeCam->dy);
		float	right	= top * ((float)WW/(float)HH);

		origine.SetCoord( ((float) ( (float)xplot-(float)WW/2.0f ) / (float)WW)   *   (2.0f * 5.0f * (float)WW / ((float)activeCam->dx)),
					      ((float) ( (float)HH/2.0f-(float)yplot ) / (float)HH)   *   (2.0f * 5.0f * (float)HH / ((float)activeCam->dy)),
						  /*-activeCam->Znear*/1000000.0f);


		// ----- Init des vars de résultat -----
		ZObject*	resultat;
		resultat = NULL;

		ZMatrix		camMatInv = activeCam->worldMat;
		camMatInv.Inverse();

		// ----- Test sur l'ensemble des objets 3D -----
		float	distanceTmp = 100000000.0f;
		World->SelectionTest(camMatInv, origine, rayon, &distanceTmp, activeCam->Znear, u, v, z, &resultat, faceNb);

		return	resultat;
	}
}









