⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 directx8visualsystem.cpp

📁 game code对于游戏地图的编辑代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// QGEngine
#include "DirectX8VisualSystem.h"
#include "../../Main/QLogManager.h"
#include "../../Main/QResourceManager.h"
#include "../../Main/QString.h"
#include "../../Main/Exception.h"
#include "../../XMLParse/XMLDocument.h"
#include "../../Main/QMath.h"

#include "D3DSettings.h"
#include "Win32Window.h"
#include "Dx8Enumeration.h"
#include "../../Main/QLight.h"
#include "../../Main/QViewPort.h"
#include "../../Main/QTextureManager.h"
#include "../../Main/QMaterialManager.h"
#include "../../Main/QHardwareBufferManager.h"
#include "D3D8BufferFactory.h"
#include "D3D8TextureFactory.h"
#include "D3D8Texture.h"
#include "D3D8VertexBuffer.h"
#include "D3D8IndexBuffer.h"

#include "D3DMapping.h"
#include "DxUtil.h"


D3DXCOLOR ColorToD3DXCOLOR(const Color& color)
{
//	return D3DXCOLOR((Real32)color.red/255,(Real32)color.green/255,(Real32)color.blue/255,(Real32)color.alpha/255);
	return D3DXCOLOR( Int32(color) );
}

D3DRECT RectToD3DRECT(const Rect& rect)
{
	D3DRECT r;
	r.x1 = rect.x;
	r.y1 = rect.y;
	r.x2 = rect.x+rect.width;
	r.y2 = rect.y+rect.height;
	return r;
}

void Matrix4ToD3DXMATRIX(const Matrix4& mat,D3DXMATRIX& dmat)
{
	for(Int32 i=0;i<4;++i)
		for( Int32 j=0;j<4;++j )
			dmat.m[i][j] = mat.m[i][j];
}

DirectX8VisualSystem::DirectX8VisualSystem(HINSTANCE hInst):
			m_pd3d(NULL),m_pd3dDevice(NULL),m_HInst(hInst)
{
}
DirectX8VisualSystem::~DirectX8VisualSystem()
{
	Destroy();
}

Bool DirectX8VisualSystem::Initialize()
{
	if( m_HInst == 0 )
	{
		LOGLOW("DirectX8VisualSystem::Initialize : HINSTANCE Required");
		return false;
	}
	
	m_pd3d = Direct3DCreate8(D3D_SDK_VERSION);
	if( m_pd3d == NULL )
	{
		LOGLOW("DirectX8VisualSystem::Initialize : Fail to Create Direct3D");
		return false;
	}
	// 创建窗口
	Win32Window* pWin = (Win32Window*)m_WindowDevice;
	if( !pWin )	
	{
		//在此之前没有创建窗口,则根据Settings创建窗口
		pWin = new Win32Window;
		pWin->Create("QGEnginWindow", true ,640,480,0,0,m_HInst);
		AddWindowDevice(pWin);
	}
	HWND hWnd = pWin->getWindowHandle();
	if( hWnd == 0 ) 
	{
		LOGLOW("DirectX8VisualSystem::Initialize : HWND Required");
		return false;
	}

	DX8Enumeration d3dEnum(m_pd3d);
	d3dEnum.BuildDeviceList();
	
	LoadSettings(&d3dEnum);

	D3DAdapterInfo adapter = d3dEnum.GetCurrentAdapter();
	D3DDeviceInfo  device  = adapter.devices[adapter.dwCurrentDevice];
	D3DModeInfo    mode    = device.modes[device.dwCurrentMode];
	if( !device.bWindowed )
	{
		if( !pWin->TurnToFullScreen() )  // force to windowed mode
		{
			if( device.bCanDoWindowed )
				device.bWindowed =true;
			else
			{
				LOGBOREME("Fail to Toggle to Fullscreen Mode");
				return false;
			}
		}
	}
	else
	{
		Int32 w,h,l,t;		
		m_WindowDevice->getMetrics(w,h,l,t);
		if(  mode.Width!= w ||  mode.Height!= h )
			m_WindowDevice->Resize(mode.Width,mode.Height);
	}


//创建D3D设备
	D3DPRESENT_PARAMETERS d3dpp; 
	ZeroMemory( &d3dpp, sizeof(d3dpp) );
	d3dpp.Windowed = !pWin->isFullScreen();
	d3dpp.BackBufferCount = 1;
	d3dpp.MultiSampleType = d3dpp.Windowed ? device.MultiSampleTypeWindowed : device.MultiSampleTypeFullscreen;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.EnableAutoDepthStencil = d3dEnum.IsUseDepthStencilBuffer();
	d3dpp.AutoDepthStencilFormat = mode.DepthStencilFormat;
	d3dpp.hDeviceWindow = hWnd;
	if( d3dpp.Windowed )
	{
		Int32 width,height,left,top;
		pWin->getMetrics(width,height,left,top);
		d3dpp.BackBufferWidth = width;
		d3dpp.BackBufferHeight= height;
		d3dpp.BackBufferFormat= adapter.d3ddmDesktop.Format;
	}
	else
	{
		d3dpp.BackBufferWidth = mode.Width;
		d3dpp.BackBufferHeight= mode.Height;
		d3dpp.BackBufferFormat= mode.Format;
	}

	if( device.d3dCaps.PrimitiveMiscCaps & D3DPMISCCAPS_NULLREFERENCE )
	{
		LOGBOREME("DirectX8VisualSystem::Initialize : Null ref device that can't render anything");
	}

	if( FAILED( m_pd3d->CreateDevice( d3dEnum.GetCurrentAdapterIdx(), device.DeviceType, hWnd,
				mode.dwBehavior,&d3dpp, &m_pd3dDevice ) ) )
	{
		LOGBOREME("DirectX8VisualSystem::Initialize : Fail to Create Direct3DDevice");
		return false;
	}
	m_pd3dDevice->GetDeviceCaps(&m_Caps);

	//注册BufferFactory
	HardwareBufferManager::Instance().SetBufferFactory(new D3D8BufferFactory(m_pd3dDevice));
	//注册TextureFactory
	TextureManager::Instance().SetTextureFactory(new D3D8TextureFactory(m_pd3dDevice));
	MaterialManager::Instance();

	//也许 我们还需要对鼠标进行剪切
	//...
	return true;
}

void DirectX8VisualSystem::Destroy()
{
	IVisualSys::Destroy();
	HardwareBufferManager::Destroy();
	TextureManager::Destroy();
	MaterialManager::Destroy();
	SAFE_RELEASE(m_pd3dDevice);
	SAFE_RELEASE(m_pd3d);
}

void DirectX8VisualSystem::LoadSettings(DX8Enumeration* d3dEnum)
{
	XML::XMLDocument* configFile = (XML::XMLDocument*) ResourceManager::Instance().GetResource("QConfig.xml");
	XML::XMLTag &settingTag = configFile->getXMLRootNode().getChild("Settings").getTag();
	XML::XMLAttribute* tmp;
	tmp = settingTag.getAttribute("showConfigDlg");
	if( tmp && tmp->Value().toBool() )
	{
		//在对话框中配置
		CD3DSettingsDialog* dlg = new CD3DSettingsDialog(d3dEnum);
		dlg->ShowDialog( m_HInst,((Win32Window*)m_WindowDevice)->getWindowHandle() );
		settingTag.setAttribute("adapterIndex",
			String::IntToString(d3dEnum->GetCurrentAdapterIdx()));
		settingTag.setAttribute("deviceIndex",
			String::IntToString(d3dEnum->GetCurrentAdapter().dwCurrentDevice));
		settingTag.setAttribute("modeIndex",
			String::IntToString(d3dEnum->GetCurrentAdapter().devices[d3dEnum->GetCurrentAdapter().dwCurrentDevice].dwCurrentMode));
 		settingTag.setAttribute("windowed",
			String::BoolToString(d3dEnum->GetCurrentAdapter().devices[d3dEnum->GetCurrentAdapter().dwCurrentDevice].bWindowed));
		settingTag.setAttribute("enableBuffer",
			String::BoolToString(d3dEnum->IsUseDepthStencilBuffer()));
		settingTag.setAttribute("useMixedVertexProcessing",
			String::BoolToString(d3dEnum->IsMixedVertexProcessing()));
		delete dlg;
	}
	else
	{
		tmp = settingTag.getAttribute(String("useDefault"));
		if( !tmp || !tmp->Value().toBool() )
		{
			try
			{
				d3dEnum->SetCurrentAdapterIdx(settingTag.getAttribute("adapterIndex")->Value().toInt());
				d3dEnum->GetCurrentAdapter().dwCurrentDevice = settingTag.getAttribute("deviceIndex")->Value().toInt();
				d3dEnum->GetCurrentAdapter().devices[d3dEnum->GetCurrentAdapter().dwCurrentDevice].dwCurrentMode = 
					settingTag.getAttribute("modeIndex")->Value().toInt();
				d3dEnum->GetCurrentAdapter().devices[d3dEnum->GetCurrentAdapter().dwCurrentDevice].bWindowed = 
					settingTag.getAttribute("windowed")->Value().toBool();
				d3dEnum->UseDepthStencilBuffer( settingTag.getAttribute("enableBuffer")->Value().toBool() );
				d3dEnum->UseMixedVertexProcessing(settingTag.getAttribute("useMixedVertexProcessing")->Value().toBool());
			}
			catch (...) 
			{
				LOGLOW("FAIL to Load VisualSystem Settings");
			}
		}
	}

}
/************************************************************************/
/* 灯光																	*/
/************************************************************************/
void DirectX8VisualSystem::EnableLighting(Bool able)
{
	if( FAILED(m_pd3dDevice->SetRenderState(D3DRS_LIGHTING,able) ))
	{
		LOGLOW("DirectX8VisualSystem::EnableLighting : Cannot enable/disable the lighting");
	}
}
void DirectX8VisualSystem::SetAmbientLight(Color color)
{
	HRESULT hr = m_pd3dDevice->SetRenderState(D3DRS_AMBIENT,color);
	if( FAILED(hr))
		LOGLOW("DirectX8VisualSystem::SetAmbientLight : Cannot set the AmbientLight");
}
void DirectX8VisualSystem::_addLight(Light* light)
{
	for( Int32 i=0;i<MAX_LIGHTS;++i)
	{
		if( m_Lights[i]==NULL )
		{
			m_Lights[i] = light;
			++m_LightsNum;
			_setD3D8Light(i,light);
			break;
		}
	}
	if( i==MAX_LIGHTS )
		LOGLOW("DirectX8VisualSystem::_addLight : Too Many Lights");
}
void DirectX8VisualSystem::RemoveLight(String& name,Light** pLightOut)
{
	for( Int32 i=0;i<MAX_LIGHTS;++i)
	{
		if( m_Lights[i] && m_Lights[i]->getName()==name )
		{
			m_pd3dDevice->LightEnable(i,FALSE);
			*pLightOut = m_Lights[i];
			m_Lights[i] = NULL;
			--m_LightsNum;
			break;
		}
	}
	if( i==MAX_LIGHTS)
		LOGLOW("DirectX8VisualSystem::_removeLight : Cannot locate the light to remove"); 
}
void DirectX8VisualSystem::RemoveAllLights()
{
	for( Int32 i=0;i<MAX_LIGHTS;++i )
	{
		if( m_Lights[i] )
		{
			m_pd3dDevice->LightEnable(i,FALSE);
			--m_LightsNum;
		}
	}
}
void DirectX8VisualSystem::_modifyLight(Light* lt)
{
	for( Int32 i=0;i<MAX_LIGHTS;++i)
	{
		if( m_Lights[i] == lt )
		{
			_setD3D8Light(i,lt);
			break;
		}
	}
	if( i == MAX_LIGHTS )
		LOGLOW("DirectX8VisualSystem::_modifyLight : Cannot locate the light to modify");
}
void DirectX8VisualSystem::_setD3D8Light(Int32 index,Light* lt)
{
	if( lt->isStateON() )
	{
		//创建D3D8灯光
		D3DLIGHT8 d3dLight;
		ZeroMemory(&d3dLight,sizeof(d3dLight));
		d3dLight.Type = D3DMapping::Get(lt->getLightType());
		if( d3dLight.Type == D3DLIGHT_SPOT )
		{
			d3dLight.Falloff = lt->getSpotlightFalloff();
			d3dLight.Theta = Math::AngleUnitsToRadians( lt->getSpotlightInnerAngle() );
			d3dLight.Phi = Math::AngleUnitsToRadians( lt->getSpotlightOuterAngle() );
		}
		Color color = lt->getDiffuseColor();
		d3dLight.Diffuse = ColorToD3DXCOLOR(color);
		color = lt->getSpecularColor();
		d3dLight.Specular= ColorToD3DXCOLOR(color);
		Vector3 vec;
		if( lt->getLightType() != LT_DIRECTIONAL )
		{
			vec = lt->getPosition();
			d3dLight.Position = D3DXVECTOR3(vec.x,vec.y,vec.z);
		}
		if( lt->getLightType() != LT_POINT )
		{
			vec = lt->getDirection();
			d3dLight.Direction = D3DXVECTOR3(vec.x,vec.y,vec.z);
		}
		d3dLight.Range = lt->getAttenuationRange();
		d3dLight.Attenuation0 = lt->getAttenuationConstant();
		d3dLight.Attenuation1 = lt->getAttenuationLinear();
		d3dLight.Attenuation2 = lt->getAttenuationQuadric();
		if( FAILED( m_pd3dDevice->SetLight(index,&d3dLight) ))
		{
			LOGLOW("DirectX8VisualSystem::_setD3D8Light : Cannot Set the Light");
			return;
		}
	}
	if( FAILED( m_pd3dDevice->LightEnable(index,lt->isStateON() ) ) )
	{
		LOGLOW("DirectX8VisualSystem::_setD3D8Light : Cannot Enable the Light");
		return;
	}
	lt->clearModifiedFlag();
}

/************************************************************************/
/* 贴图设置                                                    */
/************************************************************************/
void DirectX8VisualSystem::_setTexture(Int32 stage,const String& texName,Bool enable )
{
	D3D8Texture* dt = (D3D8Texture*)TextureManager::Instance().GetTexture(texName);
	if( dt && enable )
	{
		LPDIRECT3DTEXTURE8 ptex = dt->GetTexture();
		if( m_TexStageDesc[stage].pTex!=dt )
		{
			if( FAILED(m_pd3dDevice->SetTexture(stage,ptex)) )
			{
				LOGLOW( String("DirectX8VisualSystem::_setTexture : Cannot SetTexture :"+texName));
				return;
			}
			m_TexStageDesc[stage].pTex = dt;
		}
	}
	else
	{
		//如果原本在state层使用了texture,则禁用它
		if( m_TexStageDesc[stage].pTex != 0 )
		{
			if( FAILED(m_pd3dDevice->SetTexture(stage,0)) )
			{
				LOGLOW( String("DirectX8VisualSystem::_setTexture : Cannot Disable the Texture : "+texName) );
				return;
			}
			m_TexStageDesc[stage].pTex = 0;
		}
		if( FAILED( m_pd3dDevice->SetTextureStageState(stage,D3DTSS_COLOROP,D3DTOP_DISABLE )) )
		{
			LOGLOW("DirectX8VisualSystem::_setTexture : Cannot set ColorOperation disabled");
			return;
		}
	}
}
void DirectX8VisualSystem::_setTextureBlendMode(Int32 stage,LayerBlendModeEx mode)
{
	D3DTEXTURESTAGESTATETYPE tss;
	if( mode.blendType = LBT_COLOUR )
		tss = D3DTSS_COLOROP;
	else
		tss = D3DTSS_ALPHAOP;

	//要求使用 手动因子 (manual factor)
	if( mode.operation == LBX_BLEND_MANUAL )
	{
		if( FAILED(m_pd3dDevice->SetRenderState(D3DRS_TEXTUREFACTOR,D3DXCOLOR(0.0, 0.0, 0.0, mode.factor))) )
		{
			LOGLOW("DirectX8VisualSystem::_setTextureBlendMode : Cannot set Texture manual factor");
			return;
		}
	}
	if( FAILED( m_pd3dDevice->SetTextureStageState(stage,tss,D3DMapping::Get(mode.operation,&m_Caps) ) ) )
	{
		LOGLOW("DirectX8VisualSystem::_setTextureBlendMode : Cannot set Texture Render Operation");
	}

	//设置Arg1
	D3DXCOLOR color;
	if(mode.blendType == LBT_COLOUR )
	{
		tss = D3DTSS_COLORARG1;
		color = D3DXCOLOR(mode.colourArg1);
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -