// EffectRender.cpp: implementation of the CEffectRender class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
//#include "AtumApplication.h"
#include "EffectRender.h"
#include <list>
#include <direct.h>

#include "MainFrm.h"
#include "MapEditor.h"
#include "MapEditorDoc.h"
#include "MapEditorView.h"
#include "AppEffectData.h"
#include <algorithm>

extern LPDIRECT3DDEVICE8	g_pD3dDev;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CEffectRender::CEffectRender()
{
	m_pVB1 = NULL;
	memset(m_pVB2,0x00,4*2);
	memset(m_pVB4,0x00,4*4);
	memset(m_pVB8,0x00,4*8);
	memset(m_pVB16,0x00,4*16);

	m_pTexEffectData = NULL;
	memset(m_pTexture, 0x00, TEX_EFFECT_NUM*4);
	memset(m_nTextureRenderCount, 0x00, TEX_EFFECT_NUM*4);
	memset(m_pObjEffectMesh, 0x00, OBJ_EFFECT_NUM*4);
//	memset(m_nObjRenderCount, 0x00, OBJ_EFFECT_NUM*4);
	m_fTextureCheckTime = 60;

	m_pEffectData = NULL;
	m_pObjectData = NULL;
	

	m_bZBufferTemp = FALSE;// by JHLEE
}

CEffectRender::~CEffectRender()
{
	int i = 0;
	SAFE_RELEASE(m_pVB1);
	for(i=0;i<2;i++)
		SAFE_RELEASE(m_pVB2[i]);
	for(i=0;i<4;i++)
		SAFE_RELEASE(m_pVB4[i]);
	for(i=0;i<8;i++)
		SAFE_RELEASE(m_pVB8[i]);
	for(i=0;i<16;i++)
		SAFE_RELEASE(m_pVB16[i]);

	SAFE_DELETE(m_pTexEffectData);
	SAFE_DELETE(m_pEffectData);
	SAFE_DELETE(m_pObjectData);
	for(i=0;i<TEX_EFFECT_NUM;i++)
		SAFE_RELEASE(m_pTexture[i]);
	for(i=0;i<OBJ_EFFECT_NUM;i++)
		SAFE_DELETE(m_pObjEffectMesh[i]);
}

int CEffectRender::GetEmptyObjectIndex()
{
	int index = 0;
	for(int i=0;i<OBJ_EFFECT_NUM;i++)
	{
		if(!m_pObjEffectMesh[i])
			return i;
	}
	return -1;

}

int CEffectRender::LoadObject(char* strName)
{
	CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
	CMapEditorView* pView = (CMapEditorView*)pFrame->GetActiveView();

	map<string,int>::iterator it = m_mapObjNameToIndex.find(strName);
	if(it == m_mapObjNameToIndex.end())
	{
		char strPath[MAX_PATH];
		CGameData* pMeshData = new CGameData();
//		pView->LoadPath( strPath, IDS_DIRECTORY_EFFECT, strName );
		wsprintf(strPath,".\\Res-Eff\\%s",strName);
		pMeshData->SetFile(strPath,FALSE, NULL, 0);
		int index = GetEmptyObjectIndex();
		m_pObjEffectMesh[index] = new CSkinnedMesh(FALSE);
		m_pObjEffectMesh[index]->InitDeviceObjects();
		m_pObjEffectMesh[index]->LoadMeshHierarchyFromMem( pMeshData );
		m_pObjEffectMesh[index]->m_nRenderCount = 2;
		m_mapObjNameToIndex[strName] = index;
		delete pMeshData;
		return index;
	}
	else
	{
		return it->second;
	}
}

int CEffectRender::GetEmptyTextureIndex()
{
	int index = 0;
	for(int i=0;i<TEX_EFFECT_NUM;i++)
	{
		if(!m_pTexture[i])
			return i;
	}
	return -1;
}

DataHeader* CEffectRender::FindEffectInfo(char* strName)
{
	CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
	CMapEditorView* pView = (CMapEditorView*)pFrame->GetActiveView();

	if(!m_pEffectData)
		return NULL;
	DataHeader * pDataHeader = m_pEffectData->GetStartPosition();
	while(pDataHeader)
	{
		// 8글자만 비교한다. 확장자는 제외시킨다.
		if(strncmp(strName, pDataHeader->m_FileName,8)==0)
		{
			return pDataHeader;
		}
		pDataHeader = m_pEffectData->GetNext();
	}
	return NULL;
}

DataHeader* CEffectRender::FindObjectInfo(char* strName)
{
	CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
	CMapEditorView* pView = (CMapEditorView*)pFrame->GetActiveView();

	if(!m_pObjectData)
		return NULL;
	DataHeader * pDataHeader = m_pObjectData->GetStartPosition();
	while(pDataHeader)
	{
		// 8글자만 비교한다. 확장자는 제외시킨다.
		if(strncmp(strName, pDataHeader->m_FileName,8)==0)
		{
			return pDataHeader;
		}
		pDataHeader = m_pObjectData->GetNext();
	}
	return NULL;
}

int CEffectRender::LoadTexture(char* strName)
{
	if(!m_pTexEffectData)
		return -1;
	map<string,int>::iterator it = m_mapTexNameToIndex.find(strName);
	if(it == m_mapTexNameToIndex.end())
	{
		DataHeader * pDataHeader = m_pTexEffectData->GetStartPosition();
		while(pDataHeader)
		{
			if(strncmp(strName, pDataHeader->m_FileName,8)==0)
			{
				int index = GetEmptyTextureIndex();
				if(index<0)
					return -1;
				// load texture from memory
				HRESULT hr=D3DXCreateTextureFromFileInMemory( g_pD3dDev, pDataHeader->m_pData,  pDataHeader->m_DataSize,  &m_pTexture[index]);
				if(hr!=D3D_OK)
				{
					m_pTexture[index] = NULL;
					return -1;
				}
				m_nTextureRenderCount[index] = 2;
				m_mapTexNameToIndex[strName] = index;
				return index;
			}
			pDataHeader = m_pTexEffectData->GetNext();
		}
	} 
	else
	{
		return it->second;
	}
	return -1;
}

void CEffectRender::Tick(float fElapsedTime)
{
	// texture delete : 60초에 한번씩
	m_fTextureCheckTime -= fElapsedTime;
	if(m_fTextureCheckTime>0.0f)
		return;
	m_fTextureCheckTime = 60.0f;
	int i = 0;
	for(i=0;i<TEX_EFFECT_NUM;i++)
	{
		if(m_nTextureRenderCount[i] == 0)
			continue;
//		m_nTextureRenderCount[i]--;		// By JHLee
		if(m_nTextureRenderCount[i]==2)// if(m_nTextureRenderCount[i] == 1)
		{
			map<string,int>::iterator it = m_mapTexNameToIndex.begin();
			while(it != m_mapTexNameToIndex.end())
			{
				if(it->second == i)
				{
					m_mapTexNameToIndex.erase(it);
					break;
				}
				it++;
			}
			m_nTextureRenderCount[i] = 0;
			SAFE_RELEASE(m_pTexture[i]);
		}
		else// if(m_nTextureRenderCount[i] >= 2)
		{
			m_nTextureRenderCount[i] = 2;
		}
	}
/*	for(i=0;i<OBJ_EFFECT_NUM;i++)
	{

		if(m_nObjRenderCount[i] == 0)
			continue;
		m_nObjRenderCount[i]--;		
		if(m_nObjRenderCount[i]==2)// if(m_nObjRenderCount[i] == 1)
		{
			map<string,int>::iterator it = m_mapObjNameToIndex.begin();
			while(it != m_mapObjNameToIndex.end())
			{
				if(it->second == i)
				{
					m_mapObjNameToIndex.erase(it);
					break;
				}
				it++;
			}
			m_pObjEffectMesh[i]->InvalidateDeviceObjects();
			m_pObjEffectMesh[i]->DeleteDeviceObjects();
			SAFE_DELETE(m_pObjEffectMesh[i]);
			m_nObjRenderCount[i] = 0;
		}
		else// if(m_nObjRenderCount[i] >= 2)
		{
			m_nObjRenderCount[i] = 2;
		}
	}
*/
	// By JHLee
	for(i=0;i<OBJ_EFFECT_NUM;i++)
	{
		if(m_pObjEffectMesh[i] && m_pObjEffectMesh[i]->m_nRenderCount)
		{
			if(m_pObjEffectMesh[i]->m_nRenderCount == 2)// if(m_nObjRenderCount[i] == 1)
			{
				map<string,int>::iterator it = m_mapObjNameToIndex.begin();
				while(it != m_mapObjNameToIndex.end())
				{
					if(it->second == i)
					{
						m_mapObjNameToIndex.erase(it);
						break;
					}
					it++;
				}
				m_pObjEffectMesh[i]->InvalidateDeviceObjects();
				m_pObjEffectMesh[i]->DeleteDeviceObjects();
				SAFE_DELETE(m_pObjEffectMesh[i]);
//				m_nObjRenderCount[i] = 0;
			}
			else// if(m_nObjRenderCount[i] >= 2)
			{
				m_pObjEffectMesh[i]->m_nRenderCount = 2;
			}
		}
	}
}
/*
void CEffectRender::RenderCloud()
{
	//////////////////////////////////////// Test /////////////////////////
	// Cloud
	CCharacterInfo* pChar;
	if(pView->m_pCloudInfo)
	{
		pChar = pView->m_pCloudInfo;
		if(pChar)
		{
			RenderCharacterInfo(pChar);
		}
	}

}
*/
void CEffectRender::Render()
{
	CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
	CMapEditorView* pView = (CMapEditorView*)pFrame->GetActiveView();

	m_bZBufferTemp = FALSE; // by JHLEE
	// effect gathering
	//object
	CCharacterInfo* pChar;
	int nIndex;
	D3DXVECTOR3 vLookat;
	D3DXVec3Normalize(&vLookat,&pView->m_pCamera->GetViewDir());
	vLookat = pView->m_pCamera->GetEyePt() + 32*40.0f*vLookat;
	int xi = (int)(vLookat.x/40.0f);
	int zi = (int)(vLookat.z/40.0f);
	for(int i=xi-32;i<xi+32;i++)
	{
		for(int j=zi-32;j<zi+32;j++)
		{
			if(i >= 0 && i < pView->m_pBackground->m_sXSize && j >= 0 && j < pView->m_pBackground->m_sYSize)
			{
				nIndex = i*1000 + j;
				map<INT, CAtumNode *>::iterator it = pView->m_pBackground->m_mapObjectData.find(nIndex);
				if(it != pView->m_pBackground->m_mapObjectData.end())
				{
					CObjectChild * pObject = (CObjectChild *)it->second->m_pChild;
					while(pObject)
					{
						pChar = pObject->m_pCharacterInfo;
						if(pChar)
							RenderCharacterInfo(pChar);
						pObject = (CObjectChild *)pObject->m_pNext;
					}
				}
			}
		}
	}
	if(pView->m_pEffectList)
	{
		CAppEffectData * pEffect = (CAppEffectData *)pView->m_pEffectList->m_pChild;
		while(pEffect)
		{
			pChar = pEffect->m_pCharacterInfo;
			if(pChar)
			{
				RenderCharacterInfo(pChar);
			}
			pEffect = (CAppEffectData*)pEffect->m_pNext;
		}
	}
}

void CEffectRender::RenderCharacterInfo(CCharacterInfo* pChar)
{
	vector<LONGLONG>::iterator itCurrent = pChar->m_vecCurrentBodyCondition.begin();
	while(itCurrent != pChar->m_vecCurrentBodyCondition.end())
	{
		map<LONGLONG,CBodyConditionInfo*>::iterator itBody = pChar->m_mapBodyCondition.find(*itCurrent);
		if(itBody != pChar->m_mapBodyCondition.end())
		{
			CBodyConditionInfo* pBody = itBody->second;
			vector<CEffectInfo*>::iterator itEffect = pBody->m_vecEffect.begin();
			while(itEffect != pBody->m_vecEffect.end())
			{
				// effect rendering
				CEffectInfo* pEffectInfo = (*itEffect);

				switch(pEffectInfo->m_nEffectType)
				{
				case EFFECT_TYPE_OBJECT:
					{
						if(pEffectInfo->m_pEffect)
						{
							CObjectAni* pEffect = (CObjectAni*)pEffectInfo->m_pEffect;
							if(pEffect->m_bZbufferEnable)
							{// Z buffer enable effect loading
								m_vecZEnableEffect.push_back((Effect*)pEffect);
							}
							else 
							{
								ObjectAniRender(pEffect);
							}
						}
					}
					break;
				case EFFECT_TYPE_SPRITE:
					{
						if(pEffectInfo->m_pEffect)
						{
							CSpriteAni* pEffect = (CSpriteAni*)pEffectInfo->m_pEffect;
							if(pEffect->m_bZbufferEnable)
							{// Z buffer enable effect loading
								m_vecZEnableEffect.push_back((Effect*)pEffect);
							}
							else 
							{
								SpriteAniRender(pEffect);
							}
						}
					}
					break;
				case EFFECT_TYPE_PARTICLE:
					{
						if(pEffectInfo->m_pEffect)
						{
							CParticleSystem* pEffect = (CParticleSystem*)pEffectInfo->m_pEffect;
							if(pEffect->m_bZbufferEnable)
							{// Z buffer enable effect loading
								m_vecZEnableEffect.insert(m_vecZEnableEffect.end(),
									pEffect->m_vecParticle.begin(), pEffect->m_vecParticle.end());
							}
							else 
							{
								ParticleSystemRender(pEffect);
							}
						}
					}
					break;
				}
				itEffect++;
			}//if(!Effect.end())
		}//if(!bodyCondition.end())
//		}//if(0)
		itCurrent++;
	}//end()

}

void CEffectRender::SpriteAniRender(CSpriteAni* pEffect)
{
	CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
	CMapEditorView* pView = (CMapEditorView*)pFrame->GetActiveView();

	DWORD dwSrc,dwDest,dwColorOp;
	g_pD3dDev->GetRenderState(D3DRS_SRCBLEND,&dwSrc);
	g_pD3dDev->GetRenderState(D3DRS_DESTBLEND,&dwDest);
	g_pD3dDev->GetTextureStageState(0,D3DTSS_COLOROP,&dwColorOp);

	g_pD3dDev->SetRenderState( D3DRS_LIGHTING, TRUE );
	g_pD3dDev->SetRenderState( D3DRS_ZENABLE, pEffect->m_bZbufferEnable);
	g_pD3dDev->SetRenderState( D3DRS_ALPHABLENDENABLE,  pEffect->m_bAlphaBlending );
	if(pEffect->m_bAlphaBlending)
	{
		g_pD3dDev->SetRenderState(D3DRS_SRCBLEND,pEffect->m_nSrcBlend);
		g_pD3dDev->SetRenderState(D3DRS_DESTBLEND,pEffect->m_nDestBlend);
	}
	g_pD3dDev->SetTextureStageState(0,D3DTSS_COLOROP,pEffect->m_nTextureRenderState);
//    g_pD3dDev->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR  );
//    g_pD3dDev->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR  );
	g_pD3dDev->SetVertexShader( D3DFVF_SPRITE_VERTEX );

	// set light
	D3DXVECTOR3 vAxis = pView->m_pCamera->GetViewDir();
	pView->m_light1.Direction  = vAxis;
 	g_pD3dDev->SetLight( 1, &pView->m_light1 );
	g_pD3dDev->LightEnable( 1, TRUE );

	D3DXMATRIX matScale;
//	D3DXVECTOR3 pos = pEffect->m_pParent->m_pParent->m_pParent->m_vPos + pEffect->m_pParent->m_vPos;
	D3DXVECTOR3 pos = pEffect->m_pParent->m_vPos;
	D3DXVec3TransformCoord( &pos, &pos, &pEffect->m_pParent->m_pParent->m_mMatrix);
	 
	D3DXMatrixScaling(&matScale, pEffect->m_fTextureSize,pEffect->m_fTextureSize,pEffect->m_fTextureSize);
	matScale *= pView->m_pCamera->GetBillboardMatrix();
	if((pEffect->m_pParent && pEffect->m_pParent->m_fBillboardRotateAngle > 0 )|| 
	   pEffect->m_fCurrentRotateAngle != 0)
	{
		D3DXMATRIX matRotate;
//		vAxis = pEffect->m_pParent->m_vPos - pView->m_pCamera->GetEyePt();
//		vAxis = pos - pView->m_pCamera->GetEyePt();
		D3DXMatrixRotationAxis( &matRotate, &vAxis, pEffect->m_fCurrentRotateAngle );
		matScale *= matRotate;
	}
	matScale._41 = pos.x;
	matScale._42 = pos.y;
	matScale._43 = pos.z;

	D3DMATERIAL8 mtrl;
	D3DUtil_InitMaterial(mtrl, pEffect->m_cColor.r, 
		pEffect->m_cColor.g, pEffect->m_cColor.b, pEffect->m_cColor.a);

	g_pD3dDev->SetTransform( D3DTS_WORLD, &matScale );
	if(pEffect->m_nTextureVertexBufferType == 0)
		g_pD3dDev->SetStreamSource( 0, m_pVB4[pEffect->m_nSpriteType], sizeof(SPRITE_VERTEX) );
	else if(pEffect->m_nTextureVertexBufferType == 1)
		g_pD3dDev->SetStreamSource( 0, m_pVB8[pEffect->m_nSpriteType], sizeof(SPRITE_VERTEX) );
	else if(pEffect->m_nTextureVertexBufferType == 2)
		g_pD3dDev->SetStreamSource( 0, m_pVB16[pEffect->m_nSpriteType], sizeof(SPRITE_VERTEX) );
	else if(pEffect->m_nTextureVertexBufferType == 3)
		g_pD3dDev->SetStreamSource( 0, m_pVB2[pEffect->m_nSpriteType], sizeof(SPRITE_VERTEX) );
	else if(pEffect->m_nTextureVertexBufferType == 4)
		g_pD3dDev->SetStreamSource( 0, m_pVB1, sizeof(SPRITE_VERTEX) );
	g_pD3dDev->SetMaterial( &mtrl );
	// set texture
	int index = LoadTexture(pEffect->m_strTextureFile);
	if(index>=0)
	{
		g_pD3dDev->SetTexture( 0, m_pTexture[index]);
		if(m_nTextureRenderCount[index] == 2)	// By JHLee
			m_nTextureRenderCount[index]++;
	}
	g_pD3dDev->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );

	if(strlen(pEffect->m_strLightMapFile)>0)
	{
		g_pD3dDev->SetRenderState( D3DRS_ALPHABLENDENABLE,pEffect->m_bLightMapAlphaBlending );
		g_pD3dDev->SetRenderState(D3DRS_SRCBLEND,pEffect->m_nLightMapSrcBlend);
		g_pD3dDev->SetRenderState(D3DRS_DESTBLEND,pEffect->m_nLightMapDestBlend);
		g_pD3dDev->SetTextureStageState(0,D3DTSS_COLOROP,pEffect->m_nLightMapRenderState);
//		Set texture
		index = LoadTexture(pEffect->m_strLightMapFile);
		if(index>=0)
		{
			g_pD3dDev->SetTexture( 0, m_pTexture[index]);
			if(m_nTextureRenderCount[index] == 2)	// By JHLee
				m_nTextureRenderCount[index]++;
		}
		g_pD3dDev->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
	}
	g_pD3dDev->SetRenderState(D3DRS_SRCBLEND,dwSrc);
	g_pD3dDev->SetRenderState(D3DRS_DESTBLEND,dwDest);
	g_pD3dDev->SetTextureStageState(0,D3DTSS_COLOROP,dwColorOp);

	g_pD3dDev->LightEnable( 1, FALSE );
}


void CEffectRender::ParticleSystemRender(CParticleSystem* pEffect)
{
	CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
	CMapEditorView* pView = (CMapEditorView*)pFrame->GetActiveView();

	//	g_pD3dDev->ApplyStateBlock( pEffect->m_dwStateBlock );
	switch(pEffect->m_nParticleType)
	{
	case PARTICLE_OBJECT_TYPE:
		{
			for(int i=0; i<pEffect->m_vecParticle.size(); i++)
			{
				ObjectParticleRender(((CParticle*)pEffect->m_vecParticle[i])->m_pObjectAni, (CParticle*)pEffect->m_vecParticle[i]);
			}
		}
		break;
	case PARTICLE_SPRITE_TYPE:
		{
	g_pD3dDev->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
	g_pD3dDev->SetVertexShader( D3DFVF_SPRITE_VERTEX );
//	g_pD3dDev->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
//	g_pD3dDev->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
	g_pD3dDev->SetRenderState( D3DRS_ZENABLE, pEffect->m_bZbufferEnable );
	g_pD3dDev->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	g_pD3dDev->SetRenderState( D3DRS_SRCBLEND, pEffect->m_dwSrcBlend );
	g_pD3dDev->SetRenderState( D3DRS_DESTBLEND, pEffect->m_dwDestBlend );
	g_pD3dDev->SetRenderState( D3DRS_LIGHTING, TRUE );
	g_pD3dDev->SetStreamSource( 0, m_pVB1, sizeof(SPRITE_VERTEX) );
	// set light
	D3DXVECTOR3 vAxis = pView->m_pCamera->GetViewDir();
	pView->m_light1.Direction  = vAxis;
 	g_pD3dDev->SetLight( 1, &pView->m_light1 );
	g_pD3dDev->LightEnable( 1, TRUE );
	int nOldTextureIndex = -1;
	for(int i=0; i<pEffect->m_vecParticle.size(); i++)
	{
		CParticle* p = (CParticle*)pEffect->m_vecParticle[i];
		nOldTextureIndex = ParticleRender(pEffect, p, vAxis, nOldTextureIndex);
/*		D3DXMATRIX matScale;
		D3DXVECTOR3 pos;
		D3DMATERIAL8 mtrl;
		D3DUtil_InitMaterial(mtrl, p->m_cColor.r, p->m_cColor.g,p->m_cColor.b, p->m_cColor.a);
		pos = p->m_vPos;//실제 좌표
		D3DXMatrixScaling(&matScale, p->m_fSize,p->m_fSize,p->m_fSize);
		matScale *= pView->m_pCamera->GetBillboardMatrix();
		if(pEffect->m_pParent && pEffect->m_pParent->m_fBillboardRotateAngle > 0)
		{
			D3DXMATRIX matRotate;
//			vAxis = pEffect->m_pParent->m_vPos - pView->m_pCamera->GetEyePt();
//			vAxis = p->m_vPos - pView->m_pCamera->GetEyePt();
			D3DXMatrixRotationAxis( &matRotate, &vAxis, p->m_fCurrentRotateAngle );
			matScale *= matRotate;
		}
		matScale._41 = pos.x;
		matScale._42 = pos.y;
		matScale._43 = pos.z;
//		matScale._41 += pEffect->m_pParent->m_vPos.x;
//		matScale._42 += pEffect->m_pParent->m_vPos.y;
//		matScale._43 += pEffect->m_pParent->m_vPos.z;

		g_pD3dDev->SetTransform( D3DTS_WORLD, &matScale );
		// set texture
		
		int index = 0;
		if(nOldTextureIndex == -1 || pEffect->m_nTextureNumber != 1)
		{
			index = LoadTexture(pEffect->m_strTextureName[p->m_nTextureType]);
			if(index>=0 && nOldTextureIndex != index)
			{
				g_pD3dDev->SetTexture( 0, m_pTexture[index]);
				if(m_nTextureRenderCount[index] == 2)	// By JHLee
					m_nTextureRenderCount[index]++;
				nOldTextureIndex = index;
			}
			else
			{
//				if(index<0)
//				DbgOut("Error in nOldTexture:%d,index:%d,TextureNumber:%d",nOldTextureIndex,index,pEffect->m_nTextureNumber);
			}
		}
		g_pD3dDev->SetMaterial( &mtrl );
		g_pD3dDev->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
*/	}
	g_pD3dDev->LightEnable( 1, FALSE );
		}
		break;
	}

}
int CEffectRender::ParticleRender(CParticleSystem* pParticleSystem, CParticle* p, D3DXVECTOR3 vAxis, int nOldTextureIndex)
{
	CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
	CMapEditorView* pView = (CMapEditorView*)pFrame->GetActiveView();
	D3DXMATRIX matScale;
	D3DXVECTOR3 pos;
	D3DMATERIAL8 mtrl;
	D3DUtil_InitMaterial(mtrl, p->m_cColor.r, p->m_cColor.g,p->m_cColor.b, p->m_cColor.a);
	pos = p->m_vPos;//실제 좌표
	D3DXMatrixScaling(&matScale, p->m_fSize,p->m_fSize,p->m_fSize);
	matScale *= pView->m_pCamera->GetBillboardMatrix();
	if(pParticleSystem->m_pParent && pParticleSystem->m_pParent->m_fBillboardRotateAngle > 0)
	{
		D3DXMATRIX matRotate;
		D3DXMatrixRotationAxis( &matRotate, &vAxis, p->m_fCurrentRotateAngle );
		matScale *= matRotate;
	}
	matScale._41 = pos.x;
	matScale._42 = pos.y;
	matScale._43 = pos.z;

	g_pD3dDev->SetTransform( D3DTS_WORLD, &matScale );
	// set texture
	
	int index = 0;
	if(nOldTextureIndex == -1 || pParticleSystem->m_nTextureNumber != 1)
	{
		index = LoadTexture(pParticleSystem->m_strTextureName[p->m_nTextureType]);
		if(index>=0 && nOldTextureIndex != index)
		{
			g_pD3dDev->SetTexture( 0, m_pTexture[index]);
			if(m_nTextureRenderCount[index] == 2)	// By JHLee
				m_nTextureRenderCount[index]++;
			nOldTextureIndex = index;
		}
	}
	g_pD3dDev->SetMaterial( &mtrl );
	g_pD3dDev->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
	return nOldTextureIndex;

}
void CEffectRender::ObjectAniRender(CObjectAni* pEffect)
{
	CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
	CMapEditorView* pView = (CMapEditorView*)pFrame->GetActiveView();

	DWORD dwSrc,dwDest,dwColorOp;
	g_pD3dDev->GetRenderState(D3DRS_SRCBLEND,&dwSrc);
	g_pD3dDev->GetRenderState(D3DRS_DESTBLEND,&dwDest);
	g_pD3dDev->GetTextureStageState(0,D3DTSS_COLOROP,&dwColorOp);

	g_pD3dDev->SetRenderState( D3DRS_LIGHTING, TRUE );

	g_pD3dDev->SetRenderState( D3DRS_ZENABLE, pEffect->m_bZbufferEnable);
	g_pD3dDev->SetRenderState( D3DRS_ALPHABLENDENABLE,  pEffect->m_bAlphaBlending );
	if(pEffect->m_bAlphaBlending)
	{
		g_pD3dDev->SetRenderState(D3DRS_SRCBLEND,pEffect->m_nSrcBlend);
		g_pD3dDev->SetRenderState(D3DRS_DESTBLEND,pEffect->m_nDestBlend);
	}
	g_pD3dDev->SetTextureStageState(0,D3DTSS_COLOROP,pEffect->m_nTextureRenderState);
//	g_pD3dDev->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR  );
//	g_pD3dDev->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR  );
	D3DXMATRIX matScale;
	D3DXVECTOR3 pos;
	if(pEffect->m_pParent)
	{
//		pos = pData->m_pParent->m_vPos;
		pos = pEffect->m_pParent->m_vPos;//상대 좌표
	}
	else 
	{
		pos = D3DXVECTOR3(0,0,0);
	}
	D3DXMatrixScaling(&matScale, pEffect->m_fScale,pEffect->m_fScale,pEffect->m_fScale);
	if(pEffect->m_pParent && pEffect->m_pParent->m_bUseBillboard)
	{
		matScale *= pView->m_pCamera->GetBillboardMatrix();
		D3DXMATRIX matRotate;
		D3DXVECTOR3 vAxis = pView->m_pCamera->GetViewDir();//pos - pView->m_pCamera->GetEyePt();
		D3DXMatrixRotationAxis( &matRotate, &vAxis, pEffect->m_pParent->m_fBillboardAngle );
		matScale *= matRotate;

		if(pEffect->m_pParent->m_fBillboardRotatePerSec>0)
		{
			D3DXMatrixRotationAxis( &matRotate, &vAxis, pEffect->m_fCurrentBillboardRotateAngle );
			matScale *= matRotate;
		} 
		if(pEffect->m_fCurrentRandomUpAngleX != 0)
		{
			D3DXMatrixRotationAxis( &matRotate, &vAxis, pEffect->m_fCurrentRandomUpAngleX );
			matScale *= matRotate;
		}

//		matScale._41 = pos.x;
//		matScale._42 = pos.y;
//		matScale._43 = pos.z;

		matScale._41 = pEffect->m_pParent->m_pParent->m_mMatrix._41;
		matScale._42 = pEffect->m_pParent->m_pParent->m_mMatrix._42;
		matScale._43 = pEffect->m_pParent->m_pParent->m_mMatrix._43;
		matScale._41 += pEffect->m_pParent->m_vPos.x;
		matScale._42 += pEffect->m_pParent->m_vPos.y;
		matScale._43 += pEffect->m_pParent->m_vPos.z;

		// set light
		pView->m_light1.Direction  = pView->m_pCamera->GetViewDir();
 		g_pD3dDev->SetLight( 1, &pView->m_light1 );
		g_pD3dDev->LightEnable( 1, TRUE );
	} else
	{
		D3DXMATRIX lookat;
		D3DXVECTOR3 up = pEffect->m_pParent->m_vUp;
		D3DXVECTOR3 target = pEffect->m_pParent->m_vTarget;
		if(pEffect->m_fCurrentRandomUpAngleX != 0 || pEffect->m_fCurrentRandomUpAngleZ != 0)
		{
			up = D3DXVECTOR3(0,1,0);
			target = pEffect->m_pParent->m_vPos;
			D3DXVECTOR3 vel = D3DXVECTOR3(0,0,1);
			D3DXMATRIX matRotateX, matRotateZ;
			D3DXVECTOR3 vAxis(1,0,0);// up vector 회전축(X축)
			D3DXMatrixRotationAxis( &matRotateX, &vAxis, pEffect->m_fCurrentRandomUpAngleX);
			D3DXVec3TransformCoord( &up, &up, &matRotateX );
			D3DXVec3TransformCoord( &vel, &vel, &matRotateX );
			vAxis = D3DXVECTOR3(0,0,1);// up vector 회전축(X축)
			D3DXMatrixRotationAxis( &matRotateZ, &vAxis, pEffect->m_fCurrentRandomUpAngleZ);
			D3DXVec3TransformCoord( &up, &up, &matRotateZ );
			D3DXVec3TransformCoord( &vel, &vel, &matRotateZ );
			target += vel;
		} 
		D3DXMatrixLookAtLH( &lookat, &pos, &target, &up);
		D3DXMatrixInverse( &lookat, NULL, &lookat );
		matScale = lookat * matScale;// * matScale;
//		D3DXMATRIX mat = pEffect->m_pParent->m_pParent->m_mMatrix;
//		mat._41 += pEffect->m_pParent->m_vPos.x;
//		mat._42 += pEffect->m_pParent->m_vPos.y;
//		mat._43 += pEffect->m_pParent->m_vPos.z;
//		matScale *= mat;
		D3DXMATRIX mat = pEffect->m_pParent->m_pParent->m_mMatrix;
		mat._41 = 0;
		mat._42 = 0;
		mat._43 = 0;
		matScale *= mat;
		matScale._41 += pEffect->m_pParent->m_pParent->m_mMatrix._41;
		matScale._42 += pEffect->m_pParent->m_pParent->m_mMatrix._42;
		matScale._43 += pEffect->m_pParent->m_pParent->m_mMatrix._43;

/*
		D3DXMATRIX mat = pEffect->m_pParent->m_pParent->m_mMatrix;
		mat._41 = 0;
		mat._42 = 0;
		mat._43 = 0;
		D3DXVECTOR3 vTemp;
		D3DXVec3TransformCoord( &vTemp, &pEffect->m_pParent->m_vPos, &mat );
		matScale._41 += vTemp.x;
		matScale._42 += vTemp.y;
		matScale._43 += vTemp.z;
*/		// set light
		pView->m_light1.Direction  = pView->m_pCamera->GetViewDir();
 		g_pD3dDev->SetLight( 1, &pView->m_light1 );
		g_pD3dDev->LightEnable( 1, TRUE );
	}

	int index = LoadObject(pEffect->m_strObjectFile);
	if(index<0)
		return;
	switch(pEffect->m_nObjectAniType)
	{
	case 0:// object animation
		{
			m_pObjEffectMesh[index]->Tick(pEffect->m_fCurrentObjectAniTime);
			m_pObjEffectMesh[index]->AnotherTexture(1);
		}
		break;
	case 1:// texture animation
		{
			m_pObjEffectMesh[index]->AnotherTexture(pEffect->m_nCurrentTextureType+1);
		}
		break;
	case 2:// object + texture animation
		{
			m_pObjEffectMesh[index]->Tick(pEffect->m_fCurrentObjectAniTime);
			m_pObjEffectMesh[index]->AnotherTexture(pEffect->m_nCurrentTextureType+1);
		}
		break;
	}

	D3DMATERIAL8 mtrl;
	D3DUtil_InitMaterial(mtrl, pEffect->m_cColor.r, 
		pEffect->m_cColor.g, pEffect->m_cColor.b, pEffect->m_cColor.a);
	BOOL bTemp = m_pObjEffectMesh[index]->m_bMaterial;
	m_pObjEffectMesh[index]->m_bMaterial = TRUE;
	m_pObjEffectMesh[index]->m_material = mtrl;
//	절대 좌표 세팅
	m_pObjEffectMesh[index]->SetWorldMatrix(matScale);//*pEffect->m_pParent->m_pParent->m_mMatrix);

	if(m_bZBufferTemp)
	{	// By JHLEE
		g_pD3dDev->SetRenderState( D3DRS_ZENABLE, TRUE);
	}
	
	// by dhkwon, 030917
	LPDIRECT3DTEXTURE8 pOrgTex = NULL;
	if(pEffect->m_strTextureFile[0])
	{
		int i = LoadTexture(pEffect->m_strTextureFile);
		if(m_nTextureRenderCount[i] == 2)
			m_nTextureRenderCount[i]++;
		pOrgTex = m_pObjEffectMesh[index]->SetTexture(m_pTexture[i], 0);
	}
	m_pObjEffectMesh[index]->Render();
	if(pEffect->m_strTextureFile[0])
	{
		m_pObjEffectMesh[index]->SetTexture(pOrgTex, 0);
	}
//	if(m_nObjRenderCount[index] < 3)
//		m_nObjRenderCount[index]++;
	if(m_pObjEffectMesh[index] && m_pObjEffectMesh[index]->m_nRenderCount == 2) // By JHLee
		m_pObjEffectMesh[index]->m_nRenderCount++;
	if(pEffect->m_bLightMapUse)
	{
		g_pD3dDev->SetRenderState( D3DRS_ALPHABLENDENABLE,  pEffect->m_bLightMapAlphaBlending );
		g_pD3dDev->SetRenderState(D3DRS_SRCBLEND,pEffect->m_nLightMapSrcBlend);
		g_pD3dDev->SetRenderState(D3DRS_DESTBLEND,pEffect->m_nLightMapDestBlend);
		g_pD3dDev->SetTextureStageState(0,D3DTSS_COLOROP,pEffect->m_nLightMapRenderState);
		// by dhkwon, 030917
//		LPDIRECT3DTEXTURE8 pOrgTex = NULL;
		if(pEffect->m_strTextureFile[0])
		{
			int i = LoadTexture(pEffect->m_strTextureFile);
			if(m_nTextureRenderCount[i] == 2)
				m_nTextureRenderCount[i]++;
			pOrgTex = m_pObjEffectMesh[index]->SetTexture(m_pTexture[i], 0);
		}
		m_pObjEffectMesh[index]->Render();
		if(pEffect->m_strTextureFile[0])
		{
			m_pObjEffectMesh[index]->SetTexture(pOrgTex, 0);
		}
	}

	m_pObjEffectMesh[index]->m_bMaterial = bTemp;
	g_pD3dDev->SetRenderState(D3DRS_SRCBLEND,dwSrc);
	g_pD3dDev->SetRenderState(D3DRS_DESTBLEND,dwDest);
	g_pD3dDev->SetTextureStageState(0,D3DTSS_COLOROP,dwColorOp);
	g_pD3dDev->LightEnable( 1, FALSE );

}

void CEffectRender::ObjectParticleRender(CObjectAni* pEffect, CParticle* pParticle)
{
	CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
	CMapEditorView* pView = (CMapEditorView*)pFrame->GetActiveView();

	DWORD dwSrc,dwDest,dwColorOp;
	g_pD3dDev->GetRenderState(D3DRS_SRCBLEND,&dwSrc);
	g_pD3dDev->GetRenderState(D3DRS_DESTBLEND,&dwDest);
	g_pD3dDev->GetTextureStageState(0,D3DTSS_COLOROP,&dwColorOp);

	g_pD3dDev->SetRenderState( D3DRS_LIGHTING, TRUE );

	g_pD3dDev->SetRenderState( D3DRS_ZENABLE, pEffect->m_bZbufferEnable);
	g_pD3dDev->SetRenderState( D3DRS_ALPHABLENDENABLE,  pEffect->m_bAlphaBlending );
	if(pEffect->m_bAlphaBlending)
	{
		g_pD3dDev->SetRenderState(D3DRS_SRCBLEND,pEffect->m_nSrcBlend);
		g_pD3dDev->SetRenderState(D3DRS_DESTBLEND,pEffect->m_nDestBlend);
	}
	g_pD3dDev->SetTextureStageState(0,D3DTSS_COLOROP,pEffect->m_nTextureRenderState);
//	g_pD3dDev->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR  );
//	g_pD3dDev->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR  );
	D3DXMATRIX matScale;
	D3DXVECTOR3 pos;
	if(pParticle)
	{
//		pos = pData->m_pParent->m_vPos;
		pos = pParticle->m_vPos;//상대 좌표
	}
	else 
	{
		pos = D3DXVECTOR3(0,0,0);
	}
	D3DXMatrixScaling(&matScale, pEffect->m_fScale,pEffect->m_fScale,pEffect->m_fScale);
	if(pEffect->m_pParent && pEffect->m_pParent->m_bUseBillboard)
	{
		matScale *= pView->m_pCamera->GetBillboardMatrix();
		D3DXMATRIX matRotate;
		D3DXVECTOR3 vAxis = pView->m_pCamera->GetViewDir();//pos - g_pD3dApp->m_pCamera->GetEyePt();
		D3DXMatrixRotationAxis( &matRotate, &vAxis, pEffect->m_pParent->m_fBillboardAngle );
		matScale *= matRotate;

		if(pEffect->m_pParent->m_fBillboardRotatePerSec>0)
		{
			D3DXMatrixRotationAxis( &matRotate, &vAxis, pEffect->m_fCurrentBillboardRotateAngle );
			matScale *= matRotate;
		} 
		if(pEffect->m_fCurrentRandomUpAngleX != 0)
		{
			D3DXMatrixRotationAxis( &matRotate, &vAxis, pEffect->m_fCurrentRandomUpAngleX );
			matScale *= matRotate;
		}

//		matScale._41 = pos.x;
//		matScale._42 = pos.y;
//		matScale._43 = pos.z;

		matScale._41 = pEffect->m_pParent->m_pParent->m_mMatrix._41;
		matScale._42 = pEffect->m_pParent->m_pParent->m_mMatrix._42;
		matScale._43 = pEffect->m_pParent->m_pParent->m_mMatrix._43;
		matScale._41 += pEffect->m_pParent->m_vPos.x;
		matScale._42 += pEffect->m_pParent->m_vPos.y;
		matScale._43 += pEffect->m_pParent->m_vPos.z;

 		// set light
		pView->m_light1.Direction  = pView->m_pCamera->GetViewDir();
 		g_pD3dDev->SetLight( 1, &pView->m_light1 );
		g_pD3dDev->LightEnable( 1, TRUE );
	} else
	{
		D3DXMATRIX lookat;
		D3DXVECTOR3 up = pEffect->m_pParent->m_vUp;
		D3DXVECTOR3 target = pEffect->m_pParent->m_vTarget;
		if(pEffect->m_fCurrentRandomUpAngleX != 0 || pEffect->m_fCurrentRandomUpAngleZ != 0)
		{
			up = D3DXVECTOR3(0,1,0);
			target = pParticle->m_vPos;
			D3DXVECTOR3 vel = D3DXVECTOR3(0,0,1);
			D3DXMATRIX matRotateX, matRotateZ;
			D3DXVECTOR3 vAxis(1,0,0);// up vector 회전축(X축)
			D3DXMatrixRotationAxis( &matRotateX, &vAxis, pEffect->m_fCurrentRandomUpAngleX);
			D3DXVec3TransformCoord( &up, &up, &matRotateX );
			D3DXVec3TransformCoord( &vel, &vel, &matRotateX );
			vAxis = D3DXVECTOR3(0,0,1);// up vector 회전축(X축)
			D3DXMatrixRotationAxis( &matRotateZ, &vAxis, pEffect->m_fCurrentRandomUpAngleZ);
			D3DXVec3TransformCoord( &up, &up, &matRotateZ );
			D3DXVec3TransformCoord( &vel, &vel, &matRotateZ );
			target += vel;
		} 
		D3DXMatrixLookAtLH( &lookat, &pos, &target, &up);
		D3DXMatrixInverse( &lookat, NULL, &lookat );
		matScale = lookat * matScale;// * matScale;
//		D3DXMATRIX mat = pEffect->m_pParent->m_pParent->m_mMatrix;
//		mat._41 += pEffect->m_pParent->m_vPos.x;
//		mat._42 += pEffect->m_pParent->m_vPos.y;
//		mat._43 += pEffect->m_pParent->m_vPos.z;
//		matScale *= mat;
		D3DXMATRIX mat = pEffect->m_pParent->m_pParent->m_mMatrix;
		matScale._11 = mat._11;
		matScale._12 = mat._12;
		matScale._13 = mat._13;
		matScale._21 = mat._21;
		matScale._22 = mat._22;
		matScale._23 = mat._23;
		matScale._31 = mat._31;
		matScale._32 = mat._32;
		matScale._33 = mat._33;
/*		mat._41 = 0;
		mat._42 = 0;
		mat._43 = 0;
//		matScale *= mat;

		D3DXMATRIX mat = pEffect->m_pParent->m_pParent->m_mMatrix;
		mat._41 = 0;
		mat._42 = 0;
		mat._43 = 0;
		D3DXVECTOR3 vTemp;
		D3DXVec3TransformCoord( &vTemp, &pEffect->m_pParent->m_vPos, &mat );
		matScale._41 += vTemp.x;
		matScale._42 += vTemp.y;
		matScale._43 += vTemp.z;
 */		// set light
		pView->m_light1.Direction  = pView->m_pCamera->GetViewDir();
 		g_pD3dDev->SetLight( 1, &pView->m_light1 );
		g_pD3dDev->LightEnable( 1, TRUE );
	}

	int index = LoadObject(pEffect->m_strObjectFile);
	if(index<0)
		return;
	switch(pEffect->m_nObjectAniType)
	{
	case 0:// object animation
		{
			m_pObjEffectMesh[index]->Tick(pEffect->m_fCurrentObjectAniTime);
			m_pObjEffectMesh[index]->AnotherTexture(1);
		}
		break;
	case 1:// texture animation
		{
			m_pObjEffectMesh[index]->AnotherTexture(pEffect->m_nCurrentTextureType+1);
		}
		break;
	case 2:// object + texture animation
		{
			m_pObjEffectMesh[index]->Tick(pEffect->m_fCurrentObjectAniTime);
			m_pObjEffectMesh[index]->AnotherTexture(pEffect->m_nCurrentTextureType+1);
		}
		break;
	}

	D3DMATERIAL8 mtrl;
	D3DUtil_InitMaterial(mtrl, pEffect->m_cColor.r, 
		pEffect->m_cColor.g, pEffect->m_cColor.b, pEffect->m_cColor.a);
	BOOL bTemp = m_pObjEffectMesh[index]->m_bMaterial;
	m_pObjEffectMesh[index]->m_bMaterial = TRUE;
	m_pObjEffectMesh[index]->m_material = mtrl;
//	절대 좌표 세팅
	m_pObjEffectMesh[index]->SetWorldMatrix(matScale);//*pEffect->m_pParent->m_pParent->m_mMatrix);

	if(m_bZBufferTemp)
	{	// By JHLEE
		g_pD3dDev->SetRenderState( D3DRS_ZENABLE, TRUE);
	}
	
	// by dhkwon, 030917
	LPDIRECT3DTEXTURE8 pOrgTex = NULL;
	if(pEffect->m_strTextureFile[0])
	{
		int i = LoadTexture(pEffect->m_strTextureFile);
		if(m_nTextureRenderCount[i] == 2)
			m_nTextureRenderCount[i]++;
		pOrgTex = m_pObjEffectMesh[index]->SetTexture(m_pTexture[i], 0);
	}
	m_pObjEffectMesh[index]->Render();
	if(pEffect->m_strTextureFile[0])
	{
		m_pObjEffectMesh[index]->SetTexture(pOrgTex, 0);
	}
//	if(m_nObjRenderCount[index] < 3)
//		m_nObjRenderCount[index]++;
	if(m_pObjEffectMesh[index] && m_pObjEffectMesh[index]->m_nRenderCount == 2) // By JHLee
		m_pObjEffectMesh[index]->m_nRenderCount++;
	if(pEffect->m_bLightMapUse)
	{
		g_pD3dDev->SetRenderState( D3DRS_ALPHABLENDENABLE,  pEffect->m_bLightMapAlphaBlending );
		g_pD3dDev->SetRenderState(D3DRS_SRCBLEND,pEffect->m_nLightMapSrcBlend);
		g_pD3dDev->SetRenderState(D3DRS_DESTBLEND,pEffect->m_nLightMapDestBlend);
		g_pD3dDev->SetTextureStageState(0,D3DTSS_COLOROP,pEffect->m_nLightMapRenderState);
		// by dhkwon, 030917
//		LPDIRECT3DTEXTURE8 pOrgTex = NULL;
		if(pEffect->m_strTextureFile[0])
		{
			int i = LoadTexture(pEffect->m_strTextureFile);
			if(m_nTextureRenderCount[i] == 2)
				m_nTextureRenderCount[i]++;
			pOrgTex = m_pObjEffectMesh[index]->SetTexture(m_pTexture[i], 0);
		}
		m_pObjEffectMesh[index]->Render();
		if(pEffect->m_strTextureFile[0])
		{
			m_pObjEffectMesh[index]->SetTexture(pOrgTex, 0);
		}
	}

	m_pObjEffectMesh[index]->m_bMaterial = bTemp;
	g_pD3dDev->SetRenderState(D3DRS_SRCBLEND,dwSrc);
	g_pD3dDev->SetRenderState(D3DRS_DESTBLEND,dwDest);
	g_pD3dDev->SetTextureStageState(0,D3DTSS_COLOROP,dwColorOp);
	g_pD3dDev->LightEnable( 1, FALSE );

}

void CEffectRender::RenderZEnable()
{
	CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
	CMapEditorView* pView = (CMapEditorView*)pFrame->GetActiveView();
	// effect sorting
	sort(m_vecZEnableEffect.begin(), m_vecZEnableEffect.end(), CompareEffect());
	// effect rendering
	vector<Effect*>::iterator itEffect = m_vecZEnableEffect.begin();
	while(itEffect != m_vecZEnableEffect.end())
	{
		// effect rendering
		Effect* pEffect = (*itEffect);

		switch(pEffect->dwType)
		{
		case EFFECT_TYPE_OBJECT:
			{
				ObjectAniRender((CObjectAni*)pEffect);
			}
			break;
		case EFFECT_TYPE_SPRITE:
			{
				SpriteAniRender((CSpriteAni*)pEffect);
			}
			break;
		case EFFECT_TYPE_PARTICLE:
			{
//				ParticleSystemRender((CParticleSystem*)pEffect);
				g_pD3dDev->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
				g_pD3dDev->SetVertexShader( D3DFVF_SPRITE_VERTEX );
				g_pD3dDev->SetRenderState( D3DRS_ZENABLE, ((CParticle*)pEffect)->m_pParent->m_bZbufferEnable );
				g_pD3dDev->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
				g_pD3dDev->SetRenderState( D3DRS_SRCBLEND, ((CParticle*)pEffect)->m_pParent->m_dwSrcBlend );
				g_pD3dDev->SetRenderState( D3DRS_DESTBLEND, ((CParticle*)pEffect)->m_pParent->m_dwDestBlend );
				g_pD3dDev->SetRenderState( D3DRS_LIGHTING, TRUE );
				g_pD3dDev->SetStreamSource( 0, m_pVB1, sizeof(SPRITE_VERTEX) );
				// set light
				D3DXVECTOR3 vAxis = pView->m_pCamera->GetViewDir();
				pView->m_light1.Direction  = vAxis;
 				g_pD3dDev->SetLight( 1, &pView->m_light1 );
				g_pD3dDev->LightEnable( 1, TRUE );
				ParticleRender(((CParticle*)pEffect)->m_pParent, (CParticle*)pEffect, vAxis, -1);
				g_pD3dDev->LightEnable( 1, FALSE );
			}
			break;
		}
		itEffect++;
	}//if(itEffect != m_vecZEnableEffect.end())

	m_vecZEnableEffect.clear();

}

HRESULT CEffectRender::InitDeviceObjects()// load game data file(texture)
{
	CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
	CMapEditorView* pView = (CMapEditorView*)pFrame->GetActiveView();
	_chdir(pView->m_strCurrentDir);
	m_pTexEffectData = new CGameData;
	char strPath[MAX_PATH];
	strcpy(strPath,".\\Res-Tex\\spreff.tex");
	m_pTexEffectData->SetFile(strPath, FALSE,NULL, 0);
	m_pEffectData = new CGameData;
	strcpy(strPath,".\\Res-Eff\\effectInfo.inf");
	m_pEffectData->SetFile(strPath, FALSE,NULL, 0);
	m_pObjectData = new CGameData;
	strcpy(strPath,".\\Res-Eff\\objectInfo.inf");
	m_pObjectData->SetFile(strPath, FALSE,NULL, 0);

	return S_OK;
}

HRESULT CEffectRender::RestoreDeviceObjects()// create vertex buffer
{
	float hsx,hsy;
	int i,j;
	hsx = 0.5f;
	hsy = 0.5f;
	SPRITE_VERTEX* v;
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			if( FAILED( g_pD3dDev->CreateVertexBuffer( 4*sizeof( SPRITE_VERTEX ),
				D3DUSAGE_WRITEONLY, D3DFVF_SPRITE_VERTEX, D3DPOOL_MANAGED, &m_pVB16[4*i+j] ) ) )
				return E_FAIL;
			m_pVB16[4*i+j]->Lock( 0, 0, (BYTE**)&v, 0 );
			v[0].p = D3DXVECTOR3(-hsx,-hsy,0);	v[0].tu=0.25f*j;		v[0].tv=0.25f*(i+1);	v[0].c = 0xffffffff;
			v[1].p = D3DXVECTOR3(-hsx,hsy,0);	v[1].tu=0.25f*j;		v[1].tv=0.25f*i;		v[1].c = 0xffffffff;
			v[2].p = D3DXVECTOR3(hsx,-hsy,0);	v[2].tu=0.25f*(j+1);	v[2].tv=0.25f*(i+1);	v[2].c = 0xffffffff;
			v[3].p = D3DXVECTOR3(hsx,hsy,0);	v[3].tu=0.25f*(j+1);	v[3].tv=0.25f*i;		v[3].c = 0xffffffff;
			m_pVB16[4*i+j]->Unlock();
		}
	}
	for(i=0;i<2;i++)
	{
		for(j=0;j<4;j++)
		{
			if( FAILED( g_pD3dDev->CreateVertexBuffer( 4*sizeof( SPRITE_VERTEX ),
				D3DUSAGE_WRITEONLY, D3DFVF_SPRITE_VERTEX, D3DPOOL_MANAGED, &m_pVB8[4*i+j] ) ) )
				return E_FAIL;
			m_pVB8[2*i+j]->Lock( 0, 0, (BYTE**)&v, 0 );
			v[0].p = D3DXVECTOR3(-hsx,-hsy,0);	v[0].tu=0.25f*j;		v[0].tv=0.5f*(i+1);		v[0].c = 0xffffffff;
			v[1].p = D3DXVECTOR3(-hsx,hsy,0);	v[1].tu=0.25f*j;		v[1].tv=0.5f*i;			v[1].c = 0xffffffff;
			v[2].p = D3DXVECTOR3(hsx,-hsy,0);	v[2].tu=0.25f*(j+1);	v[2].tv=0.5f*(i+1);		v[2].c = 0xffffffff;
			v[3].p = D3DXVECTOR3(hsx,hsy,0);	v[3].tu=0.25f*(j+1);	v[3].tv=0.5f*i;			v[3].c = 0xffffffff;
			m_pVB8[2*i+j]->Unlock();
		}
	}
	for(i=0;i<2;i++)
	{
		for(j=0;j<2;j++)
		{
			if( FAILED( g_pD3dDev->CreateVertexBuffer( 4*sizeof( SPRITE_VERTEX ),
				D3DUSAGE_WRITEONLY, D3DFVF_SPRITE_VERTEX, D3DPOOL_MANAGED, &m_pVB4[2*i+j] ) ) )
				return E_FAIL;
			m_pVB4[2*i+j]->Lock( 0, 0, (BYTE**)&v, 0 );
			v[0].p = D3DXVECTOR3(-hsx,-hsy,0);	v[0].tu=0.5f*j;			v[0].tv=0.5f*(i+1);		v[0].c = 0xffffffff;
			v[1].p = D3DXVECTOR3(-hsx,hsy,0);	v[1].tu=0.5f*j;			v[1].tv=0.5f*i;			v[1].c = 0xffffffff;
			v[2].p = D3DXVECTOR3(hsx,-hsy,0);	v[2].tu=0.5f*(j+1);		v[2].tv=0.5f*(i+1);		v[2].c = 0xffffffff;
			v[3].p = D3DXVECTOR3(hsx,hsy,0);	v[3].tu=0.5f*(j+1);		v[3].tv=0.5f*i;			v[3].c = 0xffffffff;
			m_pVB4[2*i+j]->Unlock();
		}
	}
	for(i=0;i<2;i++)
	{
		if( FAILED( g_pD3dDev->CreateVertexBuffer( 4*sizeof( SPRITE_VERTEX ),
			D3DUSAGE_WRITEONLY, D3DFVF_SPRITE_VERTEX, D3DPOOL_MANAGED, &m_pVB2[i] ) ) )
			return E_FAIL;
		m_pVB2[i]->Lock( 0, 0, (BYTE**)&v, 0 );
		v[0].p = D3DXVECTOR3(-hsx,-hsy,0);	v[0].tu=0.5f*i;		v[0].tv=1.0f;		v[0].c = 0xffffffff;
		v[1].p = D3DXVECTOR3(-hsx,hsy,0);	v[1].tu=0.5f*i;		v[1].tv=0.0f;		v[1].c = 0xffffffff;
		v[2].p = D3DXVECTOR3(hsx,-hsy,0);	v[2].tu=0.5f*(i+1);	v[2].tv=1.0f;		v[2].c = 0xffffffff;
		v[3].p = D3DXVECTOR3(hsx,hsy,0);	v[3].tu=0.5f*(i+1);	v[3].tv=0.0f;		v[3].c = 0xffffffff;
		m_pVB2[i]->Unlock();
	}
	if( FAILED( g_pD3dDev->CreateVertexBuffer( 4*sizeof( SPRITE_VERTEX ),
		D3DUSAGE_WRITEONLY, D3DFVF_SPRITE_VERTEX, D3DPOOL_MANAGED, &m_pVB1 ) ) )
		return E_FAIL;
	m_pVB1->Lock( 0, 0, (BYTE**)&v, 0 );
	v[0].p = D3DXVECTOR3(-hsx,-hsy,0);	v[0].tu=0.0f;	v[0].tv=1.0f;		v[0].c = 0xffffffff;
	v[1].p = D3DXVECTOR3(-hsx,hsy,0);	v[1].tu=0.0f;	v[1].tv=0.0f;		v[1].c = 0xffffffff;
	v[2].p = D3DXVECTOR3(hsx,-hsy,0);	v[2].tu=1.0f;	v[2].tv=1.0f;		v[2].c = 0xffffffff;
	v[3].p = D3DXVECTOR3(hsx,hsy,0);	v[3].tu=1.0f;	v[3].tv=0.0f;		v[3].c = 0xffffffff;
	m_pVB1->Unlock();
	return S_OK;
}

HRESULT CEffectRender::InvalidateDeviceObjects()
{
	int i = 0;
	SAFE_RELEASE(m_pVB1);
	for(i=0;i<2;i++)
		SAFE_RELEASE(m_pVB2[i]);
	for(i=0;i<4;i++)
		SAFE_RELEASE(m_pVB4[i]);
	for(i=0;i<8;i++)
		SAFE_RELEASE(m_pVB8[i]);
	for(i=0;i<16;i++)
		SAFE_RELEASE(m_pVB16[i]);
	return S_OK;
}

HRESULT CEffectRender::DeleteDeviceObjects()
{
	SAFE_DELETE(m_pTexEffectData);
	SAFE_DELETE(m_pEffectData);
	int i = 0;
	for(i=0;i<TEX_EFFECT_NUM;i++)
	{
		SAFE_RELEASE(m_pTexture[i]);
	}
	m_mapTexNameToIndex.clear();
	m_mapObjNameToIndex.clear();
	for(i=0;i<OBJ_EFFECT_NUM;i++)
	{
		if(m_pObjEffectMesh[i])
		{
			m_pObjEffectMesh[i]->InvalidateDeviceObjects();
			m_pObjEffectMesh[i]->DeleteDeviceObjects();
			SAFE_DELETE(m_pObjEffectMesh[i]);
		}
	}
	map<string,LPDIRECT3DTEXTURE8>::iterator it = m_mapTextToTexture.begin();
	while(it != m_mapTextToTexture.end())
	{
		LPDIRECT3DTEXTURE8 pTexture = it->second;
		SAFE_RELEASE(pTexture);
		it++;
	}
	m_mapTextToTexture.clear();
	m_mapTextRenderCount.clear();
	
	return S_OK;
}


// pEffect는 최대사이즈로 버퍼를 잡고 이 함수에 들어간다.
// 함수가 끝난 후에 내용을 사이즈만큼 복사하고, 버퍼는 삭제한다.
DWORD CEffectRender::LoadEffect(char* strName, DWORD dwEffectType, char* pEffect)
{
//	char strPath[MAX_PATH];
//	FILE * readFile;
	EffectFileHeader header;
	switch(dwEffectType)
	{
	case EFFECT_TYPE_OBJECT:
		{
			DataHeader* pDataHeader = FindEffectInfo(strName);
			if(pDataHeader)
			{
				memcpy( (void*)&header, pDataHeader->m_pData, sizeof(EffectFileHeader));
				memcpy( pEffect, pDataHeader->m_pData+sizeof(EffectFileHeader), sizeof(ObjectAniData)-sizeof(Effect));
			}
			
		}
		break;
	case EFFECT_TYPE_SPRITE:
		{
			DataHeader* pDataHeader = FindEffectInfo(strName);
			if(pDataHeader)
			{
				memcpy( (void*)&header, pDataHeader->m_pData, sizeof(EffectFileHeader));
				memcpy( pEffect, pDataHeader->m_pData+sizeof(EffectFileHeader), sizeof(SpriteAniData)-sizeof(Effect));
			}
		}
		break;
	case EFFECT_TYPE_PARTICLE:
		{
			DataHeader* pDataHeader = FindEffectInfo(strName);
			if(pDataHeader)
			{
				memcpy( (void*)&header, pDataHeader->m_pData, sizeof(EffectFileHeader));
				memcpy( pEffect, pDataHeader->m_pData+sizeof(EffectFileHeader), sizeof(ParticleData));
			}
		}
		break;
	}
	return header.dwEffectType;
}

// by dhkwon, 030923
BOOL CEffectRender::AddFontTexture(char* strText, LPDIRECT3DTEXTURE8 pTexture )
{
	map<string,LPDIRECT3DTEXTURE8>::iterator it = m_mapTextToTexture.find(strText);
	if(it == m_mapTextToTexture.end())
	{
		m_mapTextToTexture[strText] = pTexture;
		m_mapTextRenderCount[strText] = 2;
		return TRUE;
	}
	else
	{
		map<string,int>::iterator it = m_mapTextRenderCount.find(strText);
		if(it != m_mapTextRenderCount.end())
		{
			(it->second) ++;
		}
		return FALSE;
	}
	return FALSE;
}

// by dhkwon, 030923 
// 폰트에서 Texture를 지우지 않고, 이 함수를 통해 Texture가 지워진다.
// 곧, 폰트에서 Effect Render로 들어갈 Texture를 빼면 그 폰트의 Texture=NULL로 세팅한다.
BOOL CEffectRender::DeleteFontTexture(char* strText)
{
	map<string,LPDIRECT3DTEXTURE8>::iterator it = m_mapTextToTexture.find(strText);
	if(it != m_mapTextToTexture.end())
	{
		map<string,int>::iterator it2 = m_mapTextRenderCount.find(strText);
		if(it2 != m_mapTextRenderCount.end())
		{
			if((it2->second)>2)
			{
				it2->second --;
			}
			else
			{
		LPDIRECT3DTEXTURE8 pTexture = it->second;
		SAFE_RELEASE(pTexture);
		m_mapTextToTexture.erase(strText);
		m_mapTextRenderCount.erase(strText);
			}
		return TRUE;
		}
#ifdef _DEBUG
		else
		{
//			DBGOUT("EffectRender::DeleteFontTexture(char* strText) Text Count not exist : [%s]\n", strText);
			return FALSE;
		}
#endif
	}
#ifdef _DEBUG
	else
	{
//		DBGOUT("EffectRender::DeleteFontTexture(char* strText) Text not exist : [%s]\n", strText);
		return FALSE;
	}
#endif
	return FALSE;

}
