1822 lines
46 KiB
C++
1822 lines
46 KiB
C++
#include "StdAfx.h"
|
||
#include "EtDevice.h"
|
||
#include <direct.h>
|
||
#include "EtStateManager.h"
|
||
#include "EtSystemFont.h"
|
||
#include "EternityEngine/EternityEngine.h"
|
||
#include "EtTexture.h"
|
||
//#include "..\\..\\..\\Client\\DragonNest\\LogWnd.h"
|
||
|
||
//#define USE_PERF_TEST
|
||
|
||
#ifdef _DEBUG
|
||
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
|
||
#endif
|
||
|
||
CEtDevice g_EtDevice;
|
||
DWORD g_dwTextureColorKey = 0;
|
||
|
||
CEtDevice::CEtDevice()
|
||
{
|
||
m_pD3D = NULL;
|
||
m_pDD = NULL;
|
||
m_pDevice = NULL;
|
||
|
||
m_pBackBufferSurface = NULL;
|
||
m_pDepthStencilSurface = NULL;
|
||
m_pFont = NULL;
|
||
|
||
m_pCurSetRenderTarget = NULL;
|
||
m_pCurSetDepthStencil = NULL;
|
||
|
||
m_bShaderDebug = false;
|
||
m_SupportedAntiAliasType = MULTISAMPLE_NONE;
|
||
|
||
m_pOutOfMemoryCallBack = &FnDeviceOutOfMemory();
|
||
|
||
m_vecVertexDecl.reserve( 256 );
|
||
|
||
#ifdef PRE_MOD_MEMORY_CHECK
|
||
m_dwLocalVideoMemory = 0;
|
||
#else
|
||
m_bUseDDrawMemCheck = true;
|
||
#endif
|
||
m_dwTotalAvailTextureMemory = 0;
|
||
|
||
m_pPrePresentCallback = NULL;
|
||
|
||
m_nCurrentPolyCount = 0;
|
||
m_nPolyCountPerFrame = 0;
|
||
m_bCallOutOfMemory = false;
|
||
#ifdef PRE_FIX_CLIENT_MEMOPTIMIZE
|
||
m_pFlushWaitDeleteCallback = NULL;
|
||
#endif
|
||
m_hWnd = 0;
|
||
m_pSystemFont = NULL;
|
||
memset( &m_Param, 0, sizeof( D3DPRESENT_PARAMETERS ) );
|
||
}
|
||
|
||
CEtDevice::~CEtDevice()
|
||
{
|
||
Clear();
|
||
}
|
||
|
||
void CEtDevice::Clear()
|
||
{
|
||
ClearEffectMacro();
|
||
|
||
for( std::vector< VertexDecl >::iterator it = m_vecVertexDecl.begin(); it != m_vecVertexDecl.end(); ++it ) {
|
||
SAFE_RELEASE( it->pDecl );
|
||
}
|
||
m_vecVertexDecl.clear();
|
||
|
||
SAFE_RELEASE( m_pFont );
|
||
SAFE_RELEASE( m_pBackBufferSurface );
|
||
SAFE_RELEASE( m_pDepthStencilSurface );
|
||
|
||
SAFE_RELEASE( m_pDevice );
|
||
SAFE_RELEASE( m_pD3D );
|
||
SAFE_RELEASE( m_pDD );
|
||
|
||
m_vecApplyQualityPath.clear();
|
||
}
|
||
|
||
void CEtDevice::CreateDDraw()
|
||
{
|
||
ScopeLock<CSyncLock> Lock(m_DeviceLostLock);
|
||
SAFE_RELEASE( m_pDD );
|
||
DirectDrawCreateEx( NULL, ( VOID** )&m_pDD, IID_IDirectDraw7, NULL );
|
||
ADD_D3D_RES( m_pDD );
|
||
}
|
||
|
||
void CEtDevice::EnumDisplayMode()
|
||
{
|
||
int i, nCount;
|
||
D3DDISPLAYMODE DisplayMode;
|
||
m_vecDisplayMode.clear();
|
||
|
||
nCount = m_pD3D->GetAdapterModeCount( 0, D3DFMT_X8R8G8B8 );
|
||
for( i = 0; i < nCount; i++ )
|
||
{
|
||
m_pD3D->EnumAdapterModes( 0, D3DFMT_X8R8G8B8, i, &DisplayMode );
|
||
if( ( DisplayMode.Height / ( float )DisplayMode.Width ) > 0.5f ) // 16 : 9 <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ػ<D8BB> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
{
|
||
m_vecDisplayMode.push_back( DisplayMode );
|
||
}
|
||
}
|
||
}
|
||
|
||
void CEtDevice::FindSuitableDisplayMode( int &nWidth, int &nHeight )
|
||
{
|
||
int i;
|
||
std::vector< int > vecSuitableDisplayMode;
|
||
bool bWide = false;;
|
||
|
||
if( nHeight / ( float )nWidth < 0.7f )
|
||
{
|
||
bWide = true;
|
||
}
|
||
|
||
for( i = 0; i < ( int )m_vecDisplayMode.size(); i++ )
|
||
{
|
||
if( bWide )
|
||
{
|
||
if( m_vecDisplayMode[ i ].Height / ( float )m_vecDisplayMode[ i ].Width < 0.7f )
|
||
{
|
||
vecSuitableDisplayMode.push_back( i );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if( m_vecDisplayMode[ i ].Height / ( float )m_vecDisplayMode[ i ].Width > 0.7f )
|
||
{
|
||
vecSuitableDisplayMode.push_back( i );
|
||
}
|
||
}
|
||
}
|
||
if( vecSuitableDisplayMode.empty() )
|
||
{
|
||
for( i = 0; i < ( int )m_vecDisplayMode.size(); i++ )
|
||
{
|
||
vecSuitableDisplayMode.push_back( i );
|
||
}
|
||
}
|
||
|
||
for( i = ( int )vecSuitableDisplayMode.size() - 1; i >= 0; i-- )
|
||
{
|
||
if( ( m_vecDisplayMode[ vecSuitableDisplayMode[ i ] ].Width == nWidth ) && ( m_vecDisplayMode[ vecSuitableDisplayMode[ i ] ].Height == nHeight ) )
|
||
{
|
||
return;
|
||
}
|
||
}
|
||
|
||
int nNearIndex, nMinValue;
|
||
nMinValue = INT_MAX;
|
||
nNearIndex = -1;
|
||
for( i = ( int )vecSuitableDisplayMode.size() - 1; i >= 0; i-- )
|
||
{
|
||
if( m_vecDisplayMode[ vecSuitableDisplayMode[ i ] ].Width == nWidth )
|
||
{
|
||
if( abs( ( int )( m_vecDisplayMode[ vecSuitableDisplayMode[ i ] ].Height - nHeight ) ) < nMinValue )
|
||
{
|
||
nNearIndex = i;
|
||
nMinValue = abs( ( int )( m_vecDisplayMode[ vecSuitableDisplayMode[ i ] ].Height - nHeight ) );
|
||
}
|
||
}
|
||
}
|
||
if( nNearIndex == -1 )
|
||
{
|
||
for( i = ( int )vecSuitableDisplayMode.size() - 1; i >= 0; i-- )
|
||
{
|
||
if( m_vecDisplayMode[ vecSuitableDisplayMode[ i ] ].Height == nHeight )
|
||
{
|
||
if( abs( ( int )( m_vecDisplayMode[ vecSuitableDisplayMode[ i ] ].Width - nWidth ) ) < nMinValue )
|
||
{
|
||
nNearIndex = i;
|
||
nMinValue = abs( ( int )( m_vecDisplayMode[ vecSuitableDisplayMode[ i ] ].Width - nWidth ) );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if( nNearIndex == -1 )
|
||
{
|
||
nWidth = MIN_RES_WIDTH;
|
||
for( i = 0; i < ( int )vecSuitableDisplayMode.size(); i++ )
|
||
{
|
||
if( ( int )( m_vecDisplayMode[ vecSuitableDisplayMode[ i ] ].Width * m_vecDisplayMode[ vecSuitableDisplayMode[ i ] ].Height ) >= nWidth * nHeight )
|
||
{
|
||
nNearIndex = i;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if( nNearIndex == -1 )
|
||
{
|
||
nNearIndex = ( int )vecSuitableDisplayMode.size() - 1;
|
||
}
|
||
|
||
if( nNearIndex == -1 ) {
|
||
nWidth = MIN_RES_WIDTH;
|
||
nHeight = MIN_RES_HEIGHT;
|
||
}
|
||
else {
|
||
nWidth = m_vecDisplayMode[ vecSuitableDisplayMode [ nNearIndex ] ].Width;
|
||
nHeight = m_vecDisplayMode[ vecSuitableDisplayMode[ nNearIndex ] ].Height;
|
||
}
|
||
}
|
||
|
||
int CEtDevice::FindSuitableRefreshRate( int nWidth, int nHeight )
|
||
{
|
||
int nResultRefreshRate = 0;
|
||
const int nTargetRefreshRate = 60;
|
||
for( int i = 0; i < ( int )m_vecDisplayMode.size(); i++ )
|
||
{
|
||
if( m_vecDisplayMode[i].Width == nWidth && m_vecDisplayMode[i].Height == nHeight ) {
|
||
if( abs((int)m_vecDisplayMode[i].RefreshRate - nTargetRefreshRate) < abs(nResultRefreshRate - nTargetRefreshRate) ) {
|
||
nResultRefreshRate = m_vecDisplayMode[i].RefreshRate;
|
||
}
|
||
}
|
||
}
|
||
return nResultRefreshRate;
|
||
}
|
||
|
||
int CEtDevice::Initialize( HWND hWnd, int nWidth, int nHeight, bool bWindow, bool bEnableMultiThread, bool bVSync, bool bEnableShaderDebug )
|
||
{
|
||
LabelRetry:
|
||
m_hWnd = hWnd;
|
||
m_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
|
||
m_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &m_Caps);
|
||
ADD_D3D_RES( m_pD3D );
|
||
|
||
EnumDisplayMode();
|
||
if( bWindow == false )
|
||
{
|
||
FindSuitableDisplayMode( nWidth, nHeight );
|
||
}
|
||
|
||
m_AdapterFormat = D3DFMT_X8R8G8B8;
|
||
memset( &m_Param, 0, sizeof( D3DPRESENT_PARAMETERS ) );
|
||
m_Param.BackBufferWidth = nWidth;
|
||
m_Param.BackBufferHeight = nHeight;
|
||
m_Param.BackBufferFormat = m_AdapterFormat;
|
||
m_Param.BackBufferCount = 1;
|
||
m_Param.EnableAutoDepthStencil = true;
|
||
m_Param.AutoDepthStencilFormat = D3DFMT_D24S8;
|
||
m_Param.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||
m_Param.Windowed = bWindow;
|
||
if( bWindow )
|
||
{
|
||
m_Param.FullScreen_RefreshRateInHz = 0;
|
||
}
|
||
else
|
||
{
|
||
m_Param.FullScreen_RefreshRateInHz = FindSuitableRefreshRate( nWidth, nHeight);
|
||
}
|
||
SetVSync( bVSync );
|
||
m_Param.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
|
||
|
||
DWORD dwFlags;
|
||
|
||
m_DevType = D3DDEVTYPE_HAL;
|
||
dwFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
|
||
if( (m_Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 || m_Caps.VertexShaderVersion < D3DVS_VERSION(1,1) )
|
||
{
|
||
dwFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
|
||
}
|
||
if( bEnableMultiThread )
|
||
{
|
||
dwFlags |= D3DCREATE_MULTITHREADED;
|
||
}
|
||
if( bEnableShaderDebug )
|
||
{
|
||
m_bShaderDebug = true;
|
||
m_DevType = D3DDEVTYPE_REF;
|
||
dwFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
|
||
}
|
||
|
||
bool bProfileMode = false;
|
||
#ifndef _FINAL_BUILD
|
||
char* lpCommandLine = ::GetCommandLine();
|
||
if(strstr(lpCommandLine, "/perf"))
|
||
{
|
||
bProfileMode = true;
|
||
}
|
||
#endif
|
||
#ifdef USE_PERF_TEST
|
||
bProfileMode = true;
|
||
#endif
|
||
|
||
if( bProfileMode )
|
||
{
|
||
m_nAdapter = D3DADAPTER_DEFAULT;
|
||
m_DevType = D3DDEVTYPE_HAL;
|
||
// Look for 'NVIDIA PerfHUD' adapter
|
||
// If it is present, override default settings
|
||
for (UINT Adapter=0;Adapter<m_pD3D->GetAdapterCount();Adapter++)
|
||
{
|
||
D3DADAPTER_IDENTIFIER9 Identifier;
|
||
HRESULT Res;
|
||
Res = m_pD3D->GetAdapterIdentifier(Adapter,0,&Identifier);
|
||
if (strstr(Identifier.Description,"PerfHUD") != 0)
|
||
{
|
||
m_nAdapter = Adapter;
|
||
m_DevType = D3DDEVTYPE_REF;
|
||
break;
|
||
}
|
||
}
|
||
if( FAILED( m_pD3D->CreateDevice( m_nAdapter, m_DevType, hWnd, dwFlags, &m_Param, &m_pDevice ) ) )
|
||
{
|
||
ASSERT( 0 && "CreateDevice() Failed!!" );
|
||
return ETERR_CREATEDEVICEFAIL;
|
||
}
|
||
ADD_D3D_RES( m_pDevice );
|
||
}
|
||
else
|
||
{
|
||
m_nAdapter = D3DADAPTER_DEFAULT;
|
||
HRESULT hr;
|
||
if( FAILED( hr = m_pD3D->CreateDevice( m_nAdapter, m_DevType, hWnd, dwFlags, &m_Param, &m_pDevice ) ) )
|
||
{
|
||
static int nRetryStep = 5; // <20><><EFBFBD><EFBFBD><EFBFBD>̽<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>н<EFBFBD> <20>ټ<EFBFBD><D9BC><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>õ<EFBFBD><C3B5>Ѵ<EFBFBD>...
|
||
if( nRetryStep-- > 0 ) {
|
||
SAFE_RELEASE( m_pD3D );
|
||
Sleep( 100 );
|
||
goto LabelRetry;
|
||
}
|
||
//if( hr == D3DERR_DEVICELOST ) {
|
||
ASSERT( 0 && "CreateDevice() Failed!!" );
|
||
return ETERR_CREATEDEVICEFAIL;
|
||
//}
|
||
}
|
||
ADD_D3D_RES( m_pDevice );
|
||
}
|
||
|
||
m_pDevice->GetDeviceCaps( &m_Caps );
|
||
|
||
m_pDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &m_pBackBufferSurface );
|
||
m_pDevice->GetDepthStencilSurface( &m_pDepthStencilSurface );
|
||
|
||
GetEtStateManager()->Initialize( this );
|
||
|
||
ADD_D3D_RES( m_pBackBufferSurface );
|
||
ADD_D3D_RES( m_pDepthStencilSurface );
|
||
|
||
EtMultiSampleType SampleTypes[] = { MULTISAMPLE_8_SAMPLES, MULTISAMPLE_4_SAMPLES, MULTISAMPLE_2_SAMPLES};
|
||
for ( int i = 0; i < _countof(SampleTypes); i++) {
|
||
HRESULT resultFullScreen = m_pD3D->CheckDeviceMultiSampleType( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, FALSE, (D3DMULTISAMPLE_TYPE)SampleTypes[i], NULL);
|
||
HRESULT resultWindowed = m_pD3D->CheckDeviceMultiSampleType( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, (D3DMULTISAMPLE_TYPE)SampleTypes[i], NULL);
|
||
HRESULT resultDepthFullScreen = m_pD3D->CheckDeviceMultiSampleType( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_D24S8, FALSE, (D3DMULTISAMPLE_TYPE)SampleTypes[i], NULL);
|
||
HRESULT resultDepthWindowed = m_pD3D->CheckDeviceMultiSampleType( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, (D3DMULTISAMPLE_TYPE)SampleTypes[i], NULL);
|
||
if( resultFullScreen == D3D_OK && resultWindowed == D3D_OK &&
|
||
resultDepthFullScreen == D3D_OK && resultDepthWindowed == D3D_OK ) {
|
||
m_SupportedAntiAliasType = SampleTypes[i];
|
||
break;
|
||
}
|
||
}
|
||
|
||
SetClipCursor( !m_Param.Windowed );
|
||
|
||
CreateDDraw();
|
||
GetEtStateManager()->Reset();
|
||
SetDefaultState();
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ʷ<EFBFBD> <20>ѹ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
|
||
ClearBuffer( 0x00000000 );
|
||
ShowFrame();
|
||
|
||
#ifdef PRE_MOD_MEMORY_CHECK
|
||
CheckTotalLocalVideoMemory();
|
||
#else
|
||
m_dwTotalAvailTextureMemory = m_pDevice->GetAvailableTextureMem( );
|
||
#endif
|
||
|
||
return ET_OK;
|
||
}
|
||
|
||
void CEtDevice::SetVSync( bool bVSync )
|
||
{
|
||
m_Param.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||
if( bVSync && m_Caps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE )
|
||
{
|
||
m_Param.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
|
||
}
|
||
}
|
||
|
||
bool CEtDevice::IsOnlyLowShaderAvailable( void )
|
||
{
|
||
if( NULL == m_pD3D )
|
||
return false;
|
||
|
||
// <20><><EFBFBD><EFBFBD> G31/G33 ī<>尰<EFBFBD><E5B0B0> <20><><EFBFBD><EFBFBD> <20>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE>
|
||
// GMA X3000 <20>̻<EFBFBD><CCBB><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>.
|
||
bool bIsOnlyLowShaderAvailable = false;
|
||
|
||
D3DCAPS9 Caps; // Device CAPs structure
|
||
D3DADAPTER_IDENTIFIER9 AdapterID; // Used to store device info
|
||
|
||
// Retrieve device capabilities
|
||
if( m_pD3D->GetDeviceCaps( 0, D3DDEVTYPE_HAL, &Caps ) != D3D_OK )
|
||
{
|
||
return true; // caps <20><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..
|
||
}
|
||
|
||
// Check vendor and device ID and enable software vertex
|
||
// processing for Intel(R) Graphics...
|
||
// Gather the primary adapter's information...
|
||
if( m_pD3D->GetAdapterIdentifier(0,0,&AdapterID ) != D3D_OK )
|
||
{
|
||
return true; // <20>ƴ<EFBFBD><C6B4><EFBFBD> <20>ĺ<EFBFBD><C4BA>ڵ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..
|
||
}
|
||
|
||
// 915, 945, G31/G33, Q35 <20>̳<EFBFBD><CCB3><EFBFBD><EFBFBD><EFBFBD> <20>Ͽ<EFBFBD><CFBF><EFBFBD> <20><><EFBFBD><EFBFBD>¥<EFBFBD><C2A5> <20><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>̴<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
// Intel Architecture
|
||
if( AdapterID.VendorId == 0x8086 )
|
||
{
|
||
if( //( AdapterID.DeviceId == 0x2A02 ) || // GM965 Device 0
|
||
//( AdapterID.DeviceId == 0x2A03 ) || // GM965 Device 1
|
||
//( AdapterID.DeviceId == 0x29A2 ) || // G965 Device 0
|
||
//( AdapterID.DeviceId == 0x29A3 ) || // G965 Device 1
|
||
( AdapterID.DeviceId == 0x27A2 ) || // 945GM Device 0
|
||
( AdapterID.DeviceId == 0x27A6 ) || // 945GM Device 1
|
||
( AdapterID.DeviceId == 0x2772 ) || // 945G Device 0
|
||
( AdapterID.DeviceId == 0x2776 ) || // 945G Device 1
|
||
( AdapterID.DeviceId == 0x2592 ) || // 915GM Device 0
|
||
( AdapterID.DeviceId == 0x2792 ) || // 915GM Device 1
|
||
( AdapterID.DeviceId == 0x2582 ) || // 915G Device 0
|
||
( AdapterID.DeviceId == 0x2782 ) || // 915G Device 1
|
||
( AdapterID.DeviceId == 0x2972 ) || // 946GZ Device 0
|
||
( AdapterID.DeviceId == 0x2973 ) || // 946GZ Device 1
|
||
//( AdapterID.DeviceId == 0x2992 ) || // Q965/Q963 Device 0
|
||
//( AdapterID.DeviceId == 0x2993 ) || // Q965/Q963 Device 1
|
||
( AdapterID.DeviceId == 0x29b2 ) || // Q35 Device 0
|
||
( AdapterID.DeviceId == 0x29b3 ) || // Q35 Device 1
|
||
( AdapterID.DeviceId == 0x29c2 ) || // G33/G31 Device 0
|
||
( AdapterID.DeviceId == 0x29c3 ) || // G33/G31 Device 1
|
||
( AdapterID.DeviceId == 0x29d2 ) || // Q33 Device 0
|
||
( AdapterID.DeviceId == 0x29d3 ) // Q33 Device 1
|
||
)
|
||
{
|
||
bIsOnlyLowShaderAvailable = true;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// #42934 <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>迭<EFBFBD><E8BFAD> <20>ƴѰ<C6B4><D1B0><EFBFBD> <20>ȼ<EFBFBD> <20><><EFBFBD>̴<EFBFBD><CCB4><EFBFBD> StaticFlowControlDepth <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD>쿡
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD> <20><><EFBFBD>̴<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
if( 0 == Caps.PS20Caps.StaticFlowControlDepth )
|
||
bIsOnlyLowShaderAvailable = true;
|
||
}
|
||
|
||
return bIsOnlyLowShaderAvailable;
|
||
}
|
||
|
||
void CEtDevice::Reinitialize( int nWidth, int nHeight )
|
||
{
|
||
if( m_pDevice )
|
||
{
|
||
SAFE_RELEASE( m_pBackBufferSurface );
|
||
SAFE_RELEASE( m_pDepthStencilSurface );
|
||
m_Param.BackBufferWidth = nWidth;
|
||
m_Param.BackBufferHeight = nHeight;
|
||
if( m_Param.Windowed ) {
|
||
m_Param.FullScreen_RefreshRateInHz = 0;
|
||
}
|
||
else {
|
||
m_Param.FullScreen_RefreshRateInHz = FindSuitableRefreshRate( nWidth, nHeight);
|
||
}
|
||
HRESULT hr = m_pDevice->Reset( &m_Param );
|
||
if( FAILED(hr) ) {
|
||
MessageBox( 0 ,"Device cannot be reset.", "DragonNest", MB_OK);
|
||
PostQuitMessage( 0 );
|
||
}
|
||
m_pDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &m_pBackBufferSurface );
|
||
m_pDevice->GetDepthStencilSurface( &m_pDepthStencilSurface );
|
||
ADD_D3D_RES( m_pBackBufferSurface );
|
||
ADD_D3D_RES( m_pDepthStencilSurface );
|
||
GetEtStateManager()->Reset();
|
||
SetDefaultState();
|
||
}
|
||
CreateDDraw();
|
||
|
||
SetClipCursor( !m_Param.Windowed );
|
||
}
|
||
|
||
void CEtDevice::SetDefaultState()
|
||
{
|
||
GetEtStateManager()->SetDefaultState();
|
||
|
||
m_pCurSetRenderTarget = m_pBackBufferSurface;
|
||
m_pCurSetDepthStencil = m_pDepthStencilSurface;
|
||
}
|
||
|
||
void CEtDevice::ClearBuffer( D3DCOLOR COLOR, float fZ, DWORD dwStencil, bool bClearColor, bool bClearZ, bool bClearStencil )
|
||
{
|
||
DWORD dwFlags = 0;
|
||
if( bClearColor )
|
||
{
|
||
dwFlags |= D3DCLEAR_TARGET;
|
||
}
|
||
if( IsEnableZTest() )
|
||
{
|
||
if( bClearZ )
|
||
{
|
||
dwFlags |= D3DCLEAR_ZBUFFER;
|
||
}
|
||
if( bClearStencil )
|
||
{
|
||
dwFlags |= D3DCLEAR_STENCIL;
|
||
}
|
||
}
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->Clear( 0, NULL, dwFlags, COLOR, fZ, dwStencil );
|
||
}
|
||
|
||
EtDeviceCheck CEtDevice::DeviceValidCheck()
|
||
{
|
||
HRESULT hr;
|
||
|
||
//if( m_Param.Windowed )
|
||
{
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
hr = m_pDevice->TestCooperativeLevel();
|
||
if( FAILED( hr ) )
|
||
{
|
||
if( hr == D3DERR_DEVICENOTRESET )
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>̽<EFBFBD><CCBD><EFBFBD> <20>ҽ<EFBFBD><D2BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѱ<EFBFBD><D1B0><EFBFBD>.
|
||
return DC_CAN_RESET;
|
||
}
|
||
else if ( hr == D3DERR_DEVICELOST )
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>̽<EFBFBD><CCBD><EFBFBD> <20>ҽ<EFBFBD><D2BD>߰<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ұ<EFBFBD><D2B0><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
return DC_CANNOT_RESET;
|
||
}
|
||
else
|
||
{
|
||
// <20><EFBFBD><D7BF><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ұ<EFBFBD><D2B0><EFBFBD><EFBFBD>̴<EFBFBD>.
|
||
return DC_CANNOT_RESET;
|
||
}
|
||
}
|
||
}
|
||
|
||
return DC_OK;
|
||
}
|
||
|
||
void CEtDevice::SetRenderTarget( EtSurface *pSurface )
|
||
{
|
||
if( pSurface == m_pCurSetRenderTarget ) {
|
||
return;
|
||
}
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->SetRenderTarget( 0 , pSurface ); // MRT <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
m_pCurSetRenderTarget = pSurface;
|
||
}
|
||
|
||
void CEtDevice::SetDepthStencilSurface( EtSurface *pSurface )
|
||
{
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->SetDepthStencilSurface( pSurface );
|
||
m_pCurSetDepthStencil = pSurface;
|
||
}
|
||
|
||
void CEtDevice::DumpBackBuffer( LPDIRECT3DSURFACE9 pSurface, LPDIRECT3DSURFACE9 pSourceSurface )
|
||
{
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->StretchRect( (pSourceSurface == NULL) ? m_pBackBufferSurface : pSourceSurface ,
|
||
NULL, pSurface, NULL, D3DTEXF_POINT );
|
||
}
|
||
|
||
void CEtDevice::SaveBackbuffer( const char *pFileName, D3DXIMAGE_FILEFORMAT Format )
|
||
{
|
||
D3DXSaveSurfaceToFile( pFileName, Format, m_pBackBufferSurface, NULL, NULL );
|
||
}
|
||
|
||
void CEtDevice::SaveBackbuffer( WCHAR *pFileName, D3DXIMAGE_FILEFORMAT Format )
|
||
{
|
||
D3DXSaveSurfaceToFileW( pFileName, Format, m_pBackBufferSurface, NULL, NULL );
|
||
}
|
||
|
||
int CEtDevice::FindVertexDeclaration( D3DVERTEXELEMENT9* pVertexElements )
|
||
{
|
||
int i, j, nElementCount, nSrcCount;
|
||
D3DVERTEXELEMENT9 *Decl;
|
||
|
||
nSrcCount = 0;
|
||
while( 1 )
|
||
{
|
||
if( pVertexElements[ nSrcCount ].Stream == 0xff )
|
||
{
|
||
break;
|
||
}
|
||
nSrcCount++;
|
||
}
|
||
|
||
nElementCount = 32;
|
||
for( i = 0; i < ( int )m_vecVertexDecl.size(); i++ )
|
||
{
|
||
Decl = m_vecVertexDecl[ i ].Elem;
|
||
nElementCount = m_vecVertexDecl[ i ].nElemCount;
|
||
|
||
if( nSrcCount != nElementCount - 1 )
|
||
{
|
||
continue;
|
||
}
|
||
for( j = 0; j < nSrcCount; j++)
|
||
{
|
||
if( ( Decl[ j ].Method != pVertexElements[ j ].Method ) ||
|
||
( Decl[ j ].Offset != pVertexElements[ j ].Offset ) ||
|
||
( Decl[ j ].Stream != pVertexElements[ j ].Stream ) ||
|
||
( Decl[ j ].Type != pVertexElements[ j ].Type ) ||
|
||
( Decl[ j ].UsageIndex != pVertexElements[ j ].UsageIndex ) )
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
if( j >= nSrcCount )
|
||
{
|
||
return i;
|
||
}
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
int CEtDevice::CreateVertexDeclaration( D3DVERTEXELEMENT9* pVertexElements )
|
||
{
|
||
int nFindIndex;
|
||
|
||
nFindIndex = FindVertexDeclaration( pVertexElements );
|
||
if( nFindIndex != -1 )
|
||
{
|
||
return nFindIndex;
|
||
}
|
||
|
||
EtVertexDecl *pDecl = NULL;
|
||
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->CreateVertexDeclaration( pVertexElements, &pDecl );
|
||
ADD_D3D_RES( pDecl );
|
||
|
||
|
||
VertexDecl Decl;
|
||
Decl.pDecl = pDecl;
|
||
pDecl->GetDeclaration( Decl.Elem, ( UINT * )&Decl.nElemCount );
|
||
|
||
m_vecVertexDecl.push_back( Decl );
|
||
|
||
|
||
return ( int )( m_vecVertexDecl.size() - 1 );
|
||
}
|
||
|
||
EtVertexDecl *CEtDevice::GetVertexDeclaration( int nIndex )
|
||
{
|
||
if( ( nIndex < 0 ) || ( nIndex >= ( int )m_vecVertexDecl.size() ) )
|
||
{
|
||
ASSERT( 0 && "Invalid Vertex Declaration Index" );
|
||
return NULL;
|
||
}
|
||
|
||
return m_vecVertexDecl[ nIndex ].pDecl;
|
||
}
|
||
|
||
// Device <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>Լ<EFBFBD><D4BC><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ƿ<F0B8A3B9>,
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ°<CFB4><C2B0><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>ִ<EFBFBD>.
|
||
void CEtDevice::GetVertexElement( int nIndex, D3DVERTEXELEMENT9* pElement, UINT* pNumElements )
|
||
{
|
||
if( ( nIndex < 0 ) || ( nIndex >= ( int )m_vecVertexDecl.size() ) )
|
||
{
|
||
ASSERT( 0 && "Invalid Vertex Declaration Index" );
|
||
return ;
|
||
}
|
||
|
||
VertexDecl &decl = m_vecVertexDecl[ nIndex ];
|
||
|
||
for( UINT i = 0; i < decl.nElemCount; i++ ) {
|
||
pElement[ i ] = decl.Elem[ i ];
|
||
}
|
||
if( pNumElements ) {
|
||
*pNumElements = decl.nElemCount;
|
||
}
|
||
}
|
||
|
||
void CEtDevice::SetVertexDeclaration( int nIndex )
|
||
{
|
||
if( ( nIndex < 0 ) || ( nIndex >= ( int )m_vecVertexDecl.size() ) )
|
||
{
|
||
ASSERT( 0 && "Invalid Vertex Declaration Index" );
|
||
return;
|
||
}
|
||
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->SetVertexDeclaration( m_vecVertexDecl[ nIndex ].pDecl );
|
||
}
|
||
|
||
#ifdef PRE_FIX_CLIENT_MEMOPTIMIZE
|
||
bool CEtDevice::CheckFlushWaitDelete()
|
||
{
|
||
bool bResult[2] = { true, true };
|
||
|
||
if( m_pFlushWaitDeleteCallback ) {
|
||
bResult[1] = m_pFlushWaitDeleteCallback();
|
||
}
|
||
else bResult[1] = false;
|
||
|
||
if( CEtResource::IsEmptyWaitDelete() ) bResult[0] = false;
|
||
else CEtResource::FlushWaitDelete();
|
||
|
||
if( bResult[0] == true || bResult[1] == true ) return true;
|
||
|
||
return false;
|
||
}
|
||
#endif
|
||
|
||
EtVertexBuffer *CEtDevice::CreateVertexBuffer( int nLength, DWORD dwFVF, EtUsage Usage, EtPool Pool )
|
||
{
|
||
EtVertexBuffer *pBuffer = NULL;
|
||
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
HRESULT hr = m_pDevice->CreateVertexBuffer( nLength, Usage, dwFVF, ( D3DPOOL )Pool, &pBuffer, NULL );
|
||
if( hr == E_OUTOFMEMORY ) {
|
||
#ifdef PRE_FIX_CLIENT_MEMOPTIMIZE
|
||
if( CheckFlushWaitDelete() ) {
|
||
return CreateVertexBuffer( nLength, dwFVF, Usage, Pool );
|
||
}
|
||
else {
|
||
m_szLastErrorMsg = "CreateVertexBuffer";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
#else
|
||
if( CEtResource::IsEmptyWaitDelete() ) {
|
||
m_szLastErrorMsg = "CreateVertexBuffer";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
else {
|
||
CEtResource::FlushWaitDelete();
|
||
return CreateVertexBuffer( nLength, dwFVF, Usage, Pool );
|
||
}
|
||
#endif
|
||
}
|
||
ADD_D3D_RES( pBuffer );
|
||
|
||
return pBuffer;
|
||
}
|
||
EtIndexBuffer *CEtDevice::CreateIndexBuffer( int nLength, EtUsage Usage, EtPool Pool )
|
||
{
|
||
EtIndexBuffer *pBuffer = NULL;
|
||
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
HRESULT hr = m_pDevice->CreateIndexBuffer( nLength, Usage, D3DFMT_INDEX16, ( D3DPOOL )Pool, &pBuffer, NULL );
|
||
if( hr == E_OUTOFMEMORY ) {
|
||
#ifdef PRE_FIX_CLIENT_MEMOPTIMIZE
|
||
if( CheckFlushWaitDelete() ) {
|
||
return CreateIndexBuffer( nLength, Usage, Pool );
|
||
}
|
||
else {
|
||
m_szLastErrorMsg = "CreateIndexBuffer";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
#else
|
||
if( CEtResource::IsEmptyWaitDelete() ) {
|
||
m_szLastErrorMsg = "CreateIndexBuffer";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
else {
|
||
CEtResource::FlushWaitDelete();
|
||
return CreateIndexBuffer( nLength, Usage, Pool );
|
||
}
|
||
#endif
|
||
}
|
||
|
||
ADD_D3D_RES( pBuffer );
|
||
|
||
return pBuffer;
|
||
}
|
||
|
||
void CEtDevice::SetStreamSource( int nStreamNum, EtVertexBuffer *pBuffer, int nStride, int nStartIndex )
|
||
{
|
||
if( pBuffer == NULL )
|
||
{
|
||
ASSERT( 0 && "Invalid VertexBuffer" );
|
||
}
|
||
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->SetStreamSource( nStreamNum, pBuffer, nStartIndex, nStride );
|
||
}
|
||
|
||
void CEtDevice::SetIndexBuffer( EtIndexBuffer *pBuffer )
|
||
{
|
||
if( pBuffer == NULL )
|
||
{
|
||
ASSERT( 0 && "Invalid IndexBuffer" );
|
||
}
|
||
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->SetIndices( pBuffer );
|
||
}
|
||
|
||
EtBaseTexture *CEtDevice::CreateTexture( int nWidth, int nHeight, EtFormat Format, EtUsage Usage, EtPool Pool, int nLevel )
|
||
{
|
||
LPDIRECT3DTEXTURE9 pTexture = NULL;
|
||
|
||
if( nWidth < 0 )
|
||
{
|
||
nWidth = Width() / abs( nWidth );
|
||
}
|
||
if( nHeight < 0 )
|
||
{
|
||
nHeight = Height() / abs( nHeight );
|
||
}
|
||
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
HRESULT hr = D3DXCreateTexture( m_pDevice, nWidth, nHeight, nLevel, Usage, ( D3DFORMAT )Format, ( D3DPOOL )Pool, &pTexture );
|
||
if( hr == E_OUTOFMEMORY ) {
|
||
#ifdef PRE_FIX_CLIENT_MEMOPTIMIZE
|
||
if( CheckFlushWaitDelete() ) {
|
||
return CreateTexture( nWidth, nHeight, Format, Usage, Pool, nLevel );
|
||
}
|
||
else {
|
||
m_szLastErrorMsg = "CreateTexture";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
#else
|
||
if( CEtResource::IsEmptyWaitDelete() ) {
|
||
m_szLastErrorMsg = "CreateTexture";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
else {
|
||
CEtResource::FlushWaitDelete();
|
||
return CreateTexture( nWidth, nHeight, Format, Usage, Pool, nLevel );
|
||
}
|
||
#endif
|
||
}
|
||
|
||
ADD_D3D_RES( pTexture );
|
||
return pTexture;
|
||
}
|
||
|
||
EtBaseTexture *CEtDevice::CreateRenderTargetTexture( int nWidth, int nHeight, EtFormat Format, EtUsage Usage, EtPool Pool )
|
||
{
|
||
LPDIRECT3DTEXTURE9 pTexture = NULL;
|
||
|
||
if( nWidth < 0 )
|
||
{
|
||
nWidth = Width() / abs( nWidth );
|
||
}
|
||
if( nHeight < 0 )
|
||
{
|
||
nHeight = Height() / abs( nHeight );
|
||
}
|
||
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
HRESULT hr = D3DXCreateTexture( m_pDevice, nWidth, nHeight, 1, D3DUSAGE_RENDERTARGET | Usage, ( D3DFORMAT )Format, ( D3DPOOL )Pool, &pTexture );
|
||
|
||
if( hr == E_OUTOFMEMORY ) {
|
||
#ifdef PRE_FIX_CLIENT_MEMOPTIMIZE
|
||
if( CheckFlushWaitDelete() ) {
|
||
return CreateRenderTargetTexture( nWidth, nHeight, Format, Usage, Pool );
|
||
}
|
||
else {
|
||
m_szLastErrorMsg = "CreateRenderTargetTexture";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
#else
|
||
if( CEtResource::IsEmptyWaitDelete() ) {
|
||
m_szLastErrorMsg = "CreateRenderTargetTexture";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
else {
|
||
CEtResource::FlushWaitDelete();
|
||
return CreateRenderTargetTexture( nWidth, nHeight, Format, Usage, Pool );
|
||
}
|
||
#endif
|
||
}
|
||
|
||
ADD_D3D_RES( pTexture );
|
||
return pTexture;
|
||
}
|
||
|
||
EtSurface *CEtDevice::CreateRenderTarget( int nWidth, int nHeight, EtFormat Format, EtPool Pool, EtMultiSampleType MultiSampleType )
|
||
{
|
||
if( nWidth < 0 )
|
||
{
|
||
nWidth = Width() / abs( nWidth );
|
||
}
|
||
if( nHeight < 0 )
|
||
{
|
||
nHeight = Height() / abs( nHeight );
|
||
}
|
||
|
||
EtSurface *pSurface = NULL;
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
HRESULT hr = m_pDevice->CreateRenderTarget( nWidth, nHeight, (D3DFORMAT)Format, (D3DMULTISAMPLE_TYPE)MultiSampleType, 0, FALSE, &pSurface, NULL);
|
||
|
||
if( hr == E_OUTOFMEMORY ) {
|
||
#ifdef PRE_FIX_CLIENT_MEMOPTIMIZE
|
||
if( CheckFlushWaitDelete() ) {
|
||
return CreateRenderTarget( nWidth, nHeight, Format, Pool, MultiSampleType );
|
||
}
|
||
else {
|
||
m_szLastErrorMsg = "CreateRenderTarget";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
#else
|
||
if( CEtResource::IsEmptyWaitDelete() ) {
|
||
m_szLastErrorMsg = "CreateRenderTarget";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
else {
|
||
CEtResource::FlushWaitDelete();
|
||
return CreateRenderTarget( nWidth, nHeight, Format, Pool, MultiSampleType );
|
||
}
|
||
#endif
|
||
}
|
||
|
||
if( !pSurface && MultiSampleType != MULTISAMPLE_NONE ) { // <20><>Ƽ<EFBFBD>˸<EFBFBD><CBB8>ƽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD>...
|
||
OutputDebug(" Fail Create MultiSample RenderTarget\n");
|
||
m_pDevice->CreateRenderTarget( nWidth, nHeight, (D3DFORMAT)Format, D3DMULTISAMPLE_NONE, 0, FALSE, &pSurface, NULL);
|
||
}
|
||
|
||
ADD_D3D_RES( pSurface );
|
||
|
||
return pSurface;
|
||
}
|
||
|
||
EtSurface *CEtDevice::CreateDepthStencil( int nWidth, int nHeight, EtFormat Format, EtMultiSampleType MultiSampleType )
|
||
{
|
||
EtSurface *pSurface = NULL;
|
||
|
||
if( nWidth < 0 )
|
||
{
|
||
nWidth = Width() / abs( nWidth );
|
||
}
|
||
if( nHeight < 0 )
|
||
{
|
||
nHeight = Height() / abs( nHeight );
|
||
}
|
||
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
HRESULT hr = m_pDevice->CreateDepthStencilSurface( nWidth, nHeight, ( D3DFORMAT )Format, (D3DMULTISAMPLE_TYPE) MultiSampleType, 0,
|
||
TRUE, &pSurface, NULL );
|
||
if( hr == E_OUTOFMEMORY ) {
|
||
#ifdef PRE_FIX_CLIENT_MEMOPTIMIZE
|
||
if( CheckFlushWaitDelete() ) {
|
||
return CreateDepthStencil( nWidth, nHeight, Format, MultiSampleType );
|
||
}
|
||
else {
|
||
m_szLastErrorMsg = "CreateDepthStencil";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
#else
|
||
if( CEtResource::IsEmptyWaitDelete() ) {
|
||
m_szLastErrorMsg = "CreateDepthStencil";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
else {
|
||
CEtResource::FlushWaitDelete();
|
||
return CreateDepthStencil( nWidth, nHeight, Format, MultiSampleType );
|
||
}
|
||
#endif
|
||
}
|
||
|
||
ADD_D3D_RES( pSurface );
|
||
return pSurface;
|
||
}
|
||
|
||
EtBaseTexture *CEtDevice::LoadTextureFromMemory( char *pSource, int nSrcSize, bool bPow2, UINT nWidth, UINT nHeight, int nMipLevel )
|
||
{
|
||
LPDIRECT3DTEXTURE9 pTexture = NULL;
|
||
|
||
if( nWidth == 0 && nHeight == 0 )
|
||
{
|
||
if( bPow2 )
|
||
{
|
||
nWidth = D3DX_DEFAULT;
|
||
nHeight = D3DX_DEFAULT;
|
||
}
|
||
else
|
||
{
|
||
nWidth = D3DX_DEFAULT_NONPOW2;
|
||
nHeight = D3DX_DEFAULT_NONPOW2;
|
||
}
|
||
}
|
||
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
HRESULT hr = D3DXCreateTextureFromFileInMemoryEx( m_pDevice, pSource, nSrcSize, nWidth, nHeight, nMipLevel, 0,
|
||
D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, g_dwTextureColorKey, NULL, NULL, &pTexture );
|
||
if( hr == E_OUTOFMEMORY ) {
|
||
#ifdef PRE_FIX_CLIENT_MEMOPTIMIZE
|
||
if( CheckFlushWaitDelete() ) {
|
||
return LoadTextureFromMemory( pSource, nSrcSize, bPow2 );
|
||
}
|
||
else {
|
||
m_szLastErrorMsg = "LoadTextureFromMemory";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
#else
|
||
if( CEtResource::IsEmptyWaitDelete() ) {
|
||
m_szLastErrorMsg = "LoadTextureFromMemory";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
else {
|
||
CEtResource::FlushWaitDelete();
|
||
return LoadTextureFromMemory( pSource, nSrcSize, bPow2 );
|
||
}
|
||
#endif
|
||
}
|
||
|
||
|
||
ADD_D3D_RES( pTexture );
|
||
return pTexture;
|
||
}
|
||
|
||
EtBaseTexture *CEtDevice::LoadVolumeTextureFromMemory( char *pSource, int nSrcSize, bool bPow2, UINT nWidth, UINT nHeight )
|
||
{
|
||
LPDIRECT3DVOLUMETEXTURE9 pTexture = NULL;
|
||
|
||
if( nWidth == 0 && nHeight == 0 )
|
||
{
|
||
if( bPow2 )
|
||
{
|
||
nWidth = D3DX_DEFAULT;
|
||
nHeight = D3DX_DEFAULT;
|
||
}
|
||
else
|
||
{
|
||
nWidth = D3DX_DEFAULT_NONPOW2;
|
||
nHeight = D3DX_DEFAULT_NONPOW2;
|
||
}
|
||
}
|
||
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
HRESULT hr = D3DXCreateVolumeTextureFromFileInMemoryEx( m_pDevice, pSource, nSrcSize, nWidth, nHeight, D3DX_DEFAULT,
|
||
1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, g_dwTextureColorKey, NULL, NULL, &pTexture );
|
||
if( hr == E_OUTOFMEMORY ) {
|
||
#ifdef PRE_FIX_CLIENT_MEMOPTIMIZE
|
||
if( CheckFlushWaitDelete() ) {
|
||
return LoadVolumeTextureFromMemory( pSource, nSrcSize, bPow2 );
|
||
}
|
||
else {
|
||
m_szLastErrorMsg = "LoadVolumeTextureFromMemory";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
#else
|
||
if( CEtResource::IsEmptyWaitDelete() ) {
|
||
m_szLastErrorMsg = "LoadVolumeTextureFromMemory";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
else {
|
||
CEtResource::FlushWaitDelete();
|
||
return LoadVolumeTextureFromMemory( pSource, nSrcSize, bPow2 );
|
||
}
|
||
#endif
|
||
}
|
||
|
||
ADD_D3D_RES( pTexture );
|
||
return pTexture;
|
||
}
|
||
|
||
EtBaseTexture *CEtDevice::LoadCubeTextureFromMemory( char *pSource, int nSrcSize, bool bPow2, UINT nWidth, UINT nHeight )
|
||
{
|
||
LPDIRECT3DCUBETEXTURE9 pTexture = NULL;
|
||
|
||
if( nWidth == 0 && nHeight == 0 )
|
||
{
|
||
if( bPow2 )
|
||
{
|
||
nWidth = D3DX_DEFAULT;
|
||
nHeight = D3DX_DEFAULT;
|
||
}
|
||
else
|
||
{
|
||
nWidth = D3DX_DEFAULT_NONPOW2;
|
||
nHeight = D3DX_DEFAULT_NONPOW2;
|
||
}
|
||
}
|
||
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
HRESULT hr = D3DXCreateCubeTextureFromFileInMemoryEx( m_pDevice, pSource, nSrcSize, nWidth, nHeight, 0, D3DFMT_UNKNOWN,
|
||
D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, g_dwTextureColorKey, NULL, NULL, &pTexture );
|
||
if( hr == E_OUTOFMEMORY ) {
|
||
#ifdef PRE_FIX_CLIENT_MEMOPTIMIZE
|
||
if( CheckFlushWaitDelete() ) {
|
||
return LoadCubeTextureFromMemory( pSource, nSrcSize, bPow2 );
|
||
}
|
||
else {
|
||
m_szLastErrorMsg = "LoadCubeTextureFromMemory";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
#else
|
||
if( CEtResource::IsEmptyWaitDelete() ) {
|
||
m_szLastErrorMsg = "LoadCubeTextureFromMemory";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
else {
|
||
CEtResource::FlushWaitDelete();
|
||
return LoadCubeTextureFromMemory( pSource, nSrcSize, bPow2 );
|
||
}
|
||
#endif
|
||
}
|
||
|
||
ADD_D3D_RES( pTexture );
|
||
return pTexture;
|
||
}
|
||
|
||
EtBaseTexture *CEtDevice::LoadTextureFromFile( const char *pFileName, bool bPow2 )
|
||
{
|
||
LPDIRECT3DTEXTURE9 pTexture = NULL;
|
||
|
||
UINT nSize;
|
||
if( bPow2 )
|
||
{
|
||
nSize = D3DX_DEFAULT;
|
||
}
|
||
else
|
||
{
|
||
nSize = D3DX_DEFAULT_NONPOW2;
|
||
}
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
HRESULT hr = D3DXCreateTextureFromFileEx( m_pDevice, pFileName, nSize, nSize, nSize, 0, D3DFMT_UNKNOWN,
|
||
D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, g_dwTextureColorKey, NULL, NULL, &pTexture );
|
||
if( hr == E_OUTOFMEMORY ) {
|
||
#ifdef PRE_FIX_CLIENT_MEMOPTIMIZE
|
||
if( CheckFlushWaitDelete() ) {
|
||
return LoadTextureFromFile( pFileName, bPow2 );
|
||
}
|
||
else {
|
||
m_szLastErrorMsg = "LoadTextureFromFile";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
#else
|
||
if( CEtResource::IsEmptyWaitDelete() ) {
|
||
m_szLastErrorMsg = "LoadTextureFromFile";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
else {
|
||
CEtResource::FlushWaitDelete();
|
||
return LoadTextureFromFile( pFileName, bPow2 );
|
||
}
|
||
#endif
|
||
}
|
||
|
||
ADD_D3D_RES( pTexture );
|
||
return pTexture;
|
||
}
|
||
|
||
EtBaseTexture *CEtDevice::LoadVolumeTextureFromFile( const char *pFileName, bool bPow2 )
|
||
{
|
||
LPDIRECT3DVOLUMETEXTURE9 pTexture = NULL;
|
||
|
||
UINT nSize;
|
||
if( bPow2 )
|
||
{
|
||
nSize = D3DX_DEFAULT;
|
||
}
|
||
else
|
||
{
|
||
nSize = D3DX_DEFAULT_NONPOW2;
|
||
}
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
HRESULT hr = D3DXCreateVolumeTextureFromFileEx( m_pDevice, pFileName, nSize, nSize, D3DX_DEFAULT, 1, 0,
|
||
D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, g_dwTextureColorKey, NULL, NULL, &pTexture );
|
||
if( hr == E_OUTOFMEMORY ) {
|
||
#ifdef PRE_FIX_CLIENT_MEMOPTIMIZE
|
||
if( CheckFlushWaitDelete() ) {
|
||
return LoadVolumeTextureFromFile( pFileName, bPow2 );
|
||
}
|
||
else {
|
||
m_szLastErrorMsg = "LoadVolumeTextureFromFile";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
#else
|
||
if( CEtResource::IsEmptyWaitDelete() ) {
|
||
m_szLastErrorMsg = "LoadVolumeTextureFromFile";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
else {
|
||
CEtResource::FlushWaitDelete();
|
||
return LoadVolumeTextureFromFile( pFileName, bPow2 );
|
||
}
|
||
#endif
|
||
}
|
||
|
||
ADD_D3D_RES( pTexture );
|
||
return pTexture;
|
||
}
|
||
|
||
EtBaseTexture *CEtDevice::LoadCubeTextureFromFile( const char *pFileName, bool bPow2 )
|
||
{
|
||
LPDIRECT3DCUBETEXTURE9 pTexture = NULL;
|
||
|
||
UINT nSize;
|
||
if( bPow2 )
|
||
{
|
||
nSize = D3DX_DEFAULT;
|
||
}
|
||
else
|
||
{
|
||
nSize = D3DX_DEFAULT_NONPOW2;
|
||
}
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
HRESULT hr = D3DXCreateCubeTextureFromFileEx( m_pDevice, pFileName, nSize, nSize, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
|
||
D3DX_DEFAULT, D3DX_DEFAULT, g_dwTextureColorKey, NULL, NULL, &pTexture );
|
||
if( hr == E_OUTOFMEMORY ) {
|
||
#ifdef PRE_FIX_CLIENT_MEMOPTIMIZE
|
||
if( CheckFlushWaitDelete() ) {
|
||
return LoadCubeTextureFromFile( pFileName, bPow2 );
|
||
}
|
||
else {
|
||
m_szLastErrorMsg = "LoadCubeTextureFromFile";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
#else
|
||
if( CEtResource::IsEmptyWaitDelete() ) {
|
||
m_szLastErrorMsg = "LoadCubeTextureFromFile";
|
||
OnOutOfMemory();
|
||
return NULL;
|
||
}
|
||
else {
|
||
CEtResource::FlushWaitDelete();
|
||
return LoadCubeTextureFromFile( pFileName, bPow2 );
|
||
}
|
||
#endif
|
||
}
|
||
|
||
ADD_D3D_RES( pTexture );
|
||
return pTexture;
|
||
}
|
||
|
||
void CEtDevice::SetTexture( int nSampler, EtBaseTexture *pTexture )
|
||
{
|
||
if( GetEtStateManager()->IsEnable() ) {
|
||
GetEtStateManager()->SetTexture( nSampler, pTexture );
|
||
}
|
||
else {
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->SetTexture( nSampler, pTexture );
|
||
}
|
||
}
|
||
|
||
void CEtDevice::ClearEffectMacro()
|
||
{
|
||
D3DXMACRO Macro;
|
||
int i;
|
||
|
||
for( i = 0; i < ( int )m_EffectMacroString.size(); i++ )
|
||
{
|
||
if( m_EffectMacroString[ i ] )
|
||
{
|
||
delete [] m_EffectMacroString[ i ];
|
||
}
|
||
}
|
||
m_EffectMacroString.clear();
|
||
m_EffectMacro.clear();
|
||
memset( &Macro, 0, sizeof( D3DXMACRO ) );
|
||
m_EffectMacro.push_back( Macro );
|
||
}
|
||
|
||
void CEtDevice::AddEffectMacro( char *szName, char *szDefinition )
|
||
{
|
||
D3DXMACRO Macro;
|
||
char *pString;
|
||
|
||
pString = new char[ strlen( szName ) + 1 ];
|
||
strcpy( pString, szName );
|
||
m_EffectMacroString.push_back( pString );
|
||
Macro.Name = pString;
|
||
pString = new char[ strlen( szDefinition ) + 1 ];
|
||
strcpy( pString, szDefinition );
|
||
m_EffectMacroString.push_back( pString );
|
||
Macro.Definition = pString;
|
||
m_EffectMacro[ m_EffectMacro.size() - 1 ] = Macro;
|
||
memset( &Macro, 0, sizeof( D3DXMACRO ) );
|
||
m_EffectMacro.push_back( Macro );
|
||
}
|
||
|
||
#ifdef PRE_CRASH_CHECK_BACKUP
|
||
float g_fMemoryPercent;
|
||
#endif
|
||
EtEffect *CEtDevice::LoadEffectFromMemory( char *pSource, int nSrcSize, void *pSharedEffectPool, ID3DXInclude *pInclude )
|
||
{
|
||
EtEffect *pEffect = NULL;
|
||
DWORD dwFlags = 0;//D3DXFX_LARGEADDRESSAWARE;
|
||
|
||
LPD3DXBUFFER pCompileError = NULL;
|
||
|
||
#ifdef PRE_CRASH_CHECK_BACKUP
|
||
g_fMemoryPercent = GetMemoryUsePercent();
|
||
#endif
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
D3DXCreateEffect( m_pDevice, pSource, nSrcSize, &m_EffectMacro[ 0 ], pInclude, dwFlags, ( LPD3DXEFFECTPOOL )pSharedEffectPool, &pEffect, &pCompileError );
|
||
|
||
if( pCompileError ) {
|
||
OutputDebug("%s\n", pCompileError->GetBufferPointer());
|
||
}
|
||
|
||
ADD_D3D_RES( pEffect );
|
||
return pEffect;
|
||
}
|
||
|
||
EtEffect *CEtDevice::LoadEffectFromFile( const char *pFileName, void *pSharedEffectPool )
|
||
{
|
||
EtEffect *pEffect = NULL;
|
||
DWORD dwFlags;
|
||
|
||
dwFlags = 0;
|
||
if( m_bShaderDebug )
|
||
{
|
||
dwFlags |= D3DXSHADER_DEBUG;
|
||
dwFlags |= D3DXSHADER_SKIPOPTIMIZATION;
|
||
dwFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
|
||
}
|
||
|
||
char szPath[ _MAX_PATH ], szCurDir[ _MAX_PATH ];
|
||
GetCurrentDirectory( _MAX_PATH, szCurDir );
|
||
_GetPath( szPath, _countof(szPath), pFileName );
|
||
_chdir( szPath );
|
||
|
||
LPD3DXBUFFER pCompileError = NULL;
|
||
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
D3DXCreateEffectFromFile( m_pDevice, pFileName, &m_EffectMacro[ 0 ], NULL, dwFlags, ( LPD3DXEFFECTPOOL )pSharedEffectPool, &pEffect, &pCompileError );
|
||
|
||
if( pCompileError ) {
|
||
OutputDebug("%s\n", pCompileError->GetBufferPointer());
|
||
}
|
||
|
||
SetCurrentDirectory( szCurDir );
|
||
|
||
ADD_D3D_RES( pEffect );
|
||
return pEffect;
|
||
}
|
||
|
||
void* CEtDevice::CreateFont( const char *pFontName )
|
||
{
|
||
ID3DXFont *pFont = NULL;
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
D3DXCreateFont( m_pDevice, 12, 0, 0, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
|
||
DEFAULT_PITCH | FF_DONTCARE, pFontName, &pFont ) ;
|
||
ADD_D3D_RES( pFont );
|
||
return pFont;
|
||
}
|
||
|
||
void* CEtDevice::CreateSystemFont( const char *pFontName )
|
||
{
|
||
CEtSystemFont *pFont = CEtSystemFont::Create( 12 , pFontName );
|
||
return pFont;
|
||
}
|
||
|
||
void *CEtDevice::CreateSprite()
|
||
{
|
||
ID3DXSprite *pSprite = NULL;
|
||
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
D3DXCreateSprite( m_pDevice, &pSprite );
|
||
|
||
ADD_D3D_RES( pSprite );
|
||
return pSprite;
|
||
}
|
||
|
||
void CEtDevice::SetCullMode( CullMode Mode )
|
||
{
|
||
SetRenderState( D3DRS_CULLMODE, Mode );
|
||
}
|
||
|
||
void CEtDevice::SetWireframe( bool bEnable )
|
||
{
|
||
SetRenderState( D3DRS_FILLMODE, bEnable ? D3DFILL_WIREFRAME : D3DFILL_SOLID );
|
||
}
|
||
|
||
bool CEtDevice::EnableAlphaBlend( bool bEnable )
|
||
{
|
||
DWORD dwValue;
|
||
bool bRet = false;
|
||
GetRenderState( D3DRS_ALPHABLENDENABLE, &dwValue );
|
||
if( dwValue )
|
||
{
|
||
bRet = true;
|
||
}
|
||
|
||
SetRenderState( D3DRS_ALPHABLENDENABLE, bEnable );
|
||
if( bEnable )
|
||
{
|
||
SetRenderState( D3DRS_ALPHAREF, 0x0 );
|
||
SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
|
||
SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
|
||
SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
|
||
}
|
||
else
|
||
{
|
||
SetRenderState( D3DRS_ALPHAREF, ALPHA_TEST_VALUE );
|
||
}
|
||
|
||
return bRet;
|
||
}
|
||
|
||
bool CEtDevice::EnableAlphaTest( bool bEnable )
|
||
{
|
||
DWORD dwValue;
|
||
bool bRet = false;
|
||
GetRenderState( D3DRS_ALPHATESTENABLE, &dwValue );
|
||
if( dwValue )
|
||
{
|
||
bRet = true;
|
||
}
|
||
|
||
SetRenderState( D3DRS_ALPHATESTENABLE, bEnable );
|
||
|
||
return bRet;
|
||
}
|
||
|
||
bool CEtDevice::IsEnableAlphaTest()
|
||
{
|
||
DWORD dwValue;
|
||
GetRenderState( D3DRS_ALPHATESTENABLE, &dwValue );
|
||
return dwValue != FALSE;
|
||
}
|
||
|
||
DWORD CEtDevice::SetAlphaRef( DWORD dwAlphaRef )
|
||
{
|
||
DWORD dwRet = GetAlphaRef();
|
||
SetRenderState( D3DRS_ALPHAREF, dwAlphaRef );
|
||
return dwRet;
|
||
}
|
||
|
||
DWORD CEtDevice::GetAlphaRef()
|
||
{
|
||
DWORD dwAlphaRef;
|
||
GetRenderState( D3DRS_ALPHAREF, &dwAlphaRef );
|
||
return dwAlphaRef;
|
||
}
|
||
|
||
bool CEtDevice::IsEnableAlphaBlend()
|
||
{
|
||
DWORD dwValue;
|
||
GetRenderState( D3DRS_ALPHABLENDENABLE, &dwValue );
|
||
return dwValue != FALSE;
|
||
}
|
||
|
||
bool CEtDevice::EnableZ( bool bEnable )
|
||
{
|
||
DWORD bRet = TRUE;
|
||
GetRenderState( D3DRS_ZENABLE, &bRet );
|
||
SetRenderState( D3DRS_ZWRITEENABLE, bEnable );
|
||
SetRenderState( D3DRS_ZENABLE, bEnable ? D3DZB_TRUE : D3DZB_FALSE );
|
||
return (bRet != FALSE);
|
||
}
|
||
|
||
bool CEtDevice::EnableZTest( bool bZTest )
|
||
{
|
||
bool bRet = IsEnableZTest();
|
||
SetRenderState( D3DRS_ZENABLE, bZTest ? D3DZB_TRUE : D3DZB_FALSE );
|
||
return bRet;
|
||
}
|
||
|
||
bool CEtDevice::IsEnableZTest()
|
||
{
|
||
DWORD dwValue;
|
||
GetRenderState( D3DRS_ZENABLE, &dwValue );
|
||
if( dwValue )
|
||
{
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
float CEtDevice::SetDepthBias( float fBias )
|
||
{
|
||
float fRet;
|
||
|
||
GetRenderState( D3DRS_DEPTHBIAS, (DWORD*)&fRet );
|
||
SetRenderState( D3DRS_DEPTHBIAS, *(DWORD*)&fBias );
|
||
|
||
return fRet;
|
||
}
|
||
|
||
bool CEtDevice::EnableZWrite( bool bEnable )
|
||
{
|
||
bool bRet = IsEnableZWrite();
|
||
SetRenderState( D3DRS_ZWRITEENABLE, bEnable );
|
||
return bRet;
|
||
}
|
||
|
||
EtCmpFunc CEtDevice::SetZFunc( EtCmpFunc ZFunc )
|
||
{
|
||
DWORD dwRet;
|
||
GetRenderState( D3DRS_ZFUNC, &dwRet );
|
||
SetRenderState( D3DRS_ZFUNC, ZFunc );
|
||
return ( EtCmpFunc )dwRet;
|
||
}
|
||
|
||
bool CEtDevice::IsEnableZWrite()
|
||
{
|
||
DWORD dwValue;
|
||
GetRenderState( D3DRS_ZWRITEENABLE, &dwValue );
|
||
if( dwValue )
|
||
{
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
EtBlendOP CEtDevice::SetBlendOP( EtBlendOP BlendOP )
|
||
{
|
||
DWORD dwOldBlendOP;
|
||
GetRenderState( D3DRS_BLENDOP, &dwOldBlendOP );
|
||
SetRenderState( D3DRS_BLENDOP, BlendOP );
|
||
return ( EtBlendOP )dwOldBlendOP;
|
||
}
|
||
|
||
EtBlendMode CEtDevice::SetSrcBlend( EtBlendMode BlendMode )
|
||
{
|
||
DWORD dwOldBlend;
|
||
GetRenderState( D3DRS_SRCBLEND, &dwOldBlend );
|
||
SetRenderState( D3DRS_SRCBLEND, BlendMode );
|
||
return ( EtBlendMode )dwOldBlend;
|
||
}
|
||
|
||
EtBlendMode CEtDevice::SetDestBlend( EtBlendMode BlendMode )
|
||
{
|
||
DWORD dwOldBlend;
|
||
GetRenderState( D3DRS_DESTBLEND, &dwOldBlend );
|
||
SetRenderState( D3DRS_DESTBLEND, BlendMode );
|
||
return ( EtBlendMode )dwOldBlend;
|
||
}
|
||
|
||
void CEtDevice::SetWorldTransform( EtMatrix *pWorldMat )
|
||
{
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->SetTransform( D3DTS_WORLD, pWorldMat );
|
||
}
|
||
|
||
void CEtDevice::SetViewTransform( EtMatrix *pViewMat )
|
||
{
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->SetTransform( D3DTS_VIEW, pViewMat );
|
||
}
|
||
|
||
void CEtDevice::SetProjTransform( EtMatrix *pProjMat )
|
||
{
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->SetTransform( D3DTS_PROJECTION, pProjMat );
|
||
}
|
||
|
||
void CEtDevice::GetFVF( DWORD *dwFVF )
|
||
{
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->GetFVF( dwFVF );
|
||
}
|
||
|
||
void CEtDevice::SetFVF( DWORD dwFVF )
|
||
{
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->SetFVF( dwFVF );
|
||
}
|
||
|
||
void CEtDevice::SetVertexShader( LPDIRECT3DVERTEXSHADER9 pShader )
|
||
{
|
||
if( GetEtStateManager()->IsEnable() ) {
|
||
GetEtStateManager()->SetVertexShader( (LPDIRECT3DVERTEXSHADER9)pShader );
|
||
}
|
||
else {
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->SetVertexShader( pShader );
|
||
}
|
||
}
|
||
|
||
void CEtDevice::SetPixelShader( LPDIRECT3DPIXELSHADER9 pShader )
|
||
{
|
||
if( GetEtStateManager()->IsEnable() ) {
|
||
GetEtStateManager()->SetPixelShader( (LPDIRECT3DPIXELSHADER9)pShader );
|
||
}
|
||
else {
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->SetPixelShader( pShader );
|
||
}
|
||
}
|
||
|
||
//void CEtDevice::EnableLight( bool bEnable )
|
||
//{
|
||
// SetRenderState( D3DRS_LIGHTING, bEnable );
|
||
//}
|
||
|
||
void CEtDevice::SetCursorProperties( EtSurface *pSurface, UINT nXHotSpot, UINT nYHotSpot )
|
||
{
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->SetCursorProperties( nXHotSpot, nYHotSpot, pSurface );
|
||
}
|
||
|
||
void CEtDevice::ShowCursor( bool bShow )
|
||
{
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->ShowCursor( bShow );
|
||
}
|
||
|
||
void CEtDevice::SetCursorPos( int nX, int nY )
|
||
{
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->SetCursorPosition( nX, nY, D3DCURSOR_IMMEDIATE_UPDATE );
|
||
}
|
||
|
||
void CEtDevice::SetGammaRamp( float fGamma, int nBright )
|
||
{
|
||
if( !m_pDevice ) return;
|
||
int i;
|
||
D3DGAMMARAMP GammaRamp;
|
||
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->GetGammaRamp( 0, &GammaRamp );
|
||
for ( i = 0; i < 256; i++ )
|
||
{
|
||
float fValue = ( float )( 255 * pow( ( float ) i / 256, 1 / fGamma ) ) + nBright;
|
||
if( fValue < 0 )
|
||
{
|
||
fValue = 0;
|
||
}
|
||
if( fValue > 255 )
|
||
{
|
||
fValue = 255;
|
||
}
|
||
GammaRamp.red[ i ] = ( ( WORD )fValue ) << 8;
|
||
GammaRamp.green[ i ] = GammaRamp.red[ i ];
|
||
GammaRamp.blue[ i ] = GammaRamp.red[ i ];
|
||
}
|
||
m_pDevice->SetGammaRamp( 0, D3DSGR_CALIBRATE, &GammaRamp );
|
||
}
|
||
|
||
#ifdef PRE_MOD_MEMORY_CHECK
|
||
void CEtDevice::CheckTotalLocalVideoMemory()
|
||
{
|
||
ScopeLock<CSyncLock> Lock(m_DeviceLostLock);
|
||
|
||
// DDraw GetAvailableVidMem <20>Լ<EFBFBD><D4BC><EFBFBD> <20>Ẹ<EFBFBD><E1BAB8>,
|
||
// D3D GetAvailableTextureMem <20>Լ<EFBFBD><D4BC><EFBFBD> <20>Ẹ<EFBFBD><E1BAB8>,
|
||
// Windows WMI<4D><49><EFBFBD><EFBFBD> <20><><EFBFBD>ϴ<EFBFBD> <20>͵<EFBFBD> <20>غôµ<C3B4>,
|
||
// <20><><EFBFBD><EFBFBD> <20><>Ȯ<EFBFBD>Ѱ<EFBFBD>, <20><>Ż<EFBFBD><C5BB> DDraw<61><77> <20><><EFBFBD>ϰ<EFBFBD>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD>뷮<EFBFBD><EBB7AE> D3D<33><44> üũ<C3BC>ϴ°Ŵ<C2B0>.
|
||
// WMI<4D><49> AvailMemory<72><79> <20>ƴ϶<C6B4>, <20><>¥ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ī<EFBFBD><C4AB> <20><DEB8> <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD>, <20>Դٰ<D4B4> <20>Ϻ<EFBFBD> <20>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD> <20>ȸԾ <20>Ⱦ<EFBFBD><C8BE><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||
if( m_pDD != NULL )
|
||
{
|
||
DDSCAPS2 ddsCaps2;
|
||
DWORD dwTotal, dwFree;
|
||
memset( &ddsCaps2, 0, sizeof( DDSCAPS2 ) );
|
||
ddsCaps2.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
|
||
if( m_pDD->GetAvailableVidMem( &ddsCaps2, &dwTotal, &dwFree ) == DD_OK )
|
||
m_dwLocalVideoMemory = dwTotal;
|
||
}
|
||
if( m_pDevice )
|
||
{
|
||
m_dwTotalAvailTextureMemory = m_pDevice->GetAvailableTextureMem();
|
||
}
|
||
m_dwMaxLocalVideoMemory = m_dwLocalVideoMemory / 1024 / 1024;
|
||
}
|
||
#endif
|
||
|
||
float CEtDevice::GetMemoryUsePercent()
|
||
{
|
||
ScopeLock<CSyncLock> Lock(m_DeviceLostLock);
|
||
#ifdef PRE_MOD_MEMORY_CHECK
|
||
m_dwUsingLocalVideoMemory = (m_dwTotalAvailTextureMemory - m_pDevice->GetAvailableTextureMem()) / 1024 / 1024;
|
||
return (m_dwTotalAvailTextureMemory - m_pDevice->GetAvailableTextureMem() ) / ( float )m_dwLocalVideoMemory;
|
||
#else
|
||
if( m_bUseDDrawMemCheck ) {
|
||
if( m_pDD == NULL ) {
|
||
return 0.0f;
|
||
}
|
||
DDSCAPS2 ddsCaps2;
|
||
DWORD dwTotal, dwFree;
|
||
memset( &ddsCaps2, 0, sizeof( DDSCAPS2 ) );
|
||
ddsCaps2.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
|
||
m_pDD->GetAvailableVidMem( &ddsCaps2, &dwTotal, &dwFree );
|
||
if( dwTotal == 0 ) {
|
||
return 0.0f;
|
||
}
|
||
return ( dwTotal - dwFree ) / ( float )dwTotal;
|
||
}
|
||
else {
|
||
if( m_pDevice == NULL ) {
|
||
return 0.0f;
|
||
}
|
||
return (m_dwTotalAvailTextureMemory - m_pDevice->GetAvailableTextureMem() ) / ( float )m_dwTotalAvailTextureMemory ;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
bool CEtDevice::CheckDeviceFormat( EtFormat CheckFormat, EtUsage Usage )
|
||
{
|
||
if( FAILED( m_pD3D->CheckDeviceFormat( m_nAdapter, m_DevType, m_AdapterFormat, Usage, D3DRTYPE_SURFACE, ( D3DFORMAT )CheckFormat ) ) )
|
||
{
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
void CEtDevice::SetClipCursor( bool bClip )
|
||
{
|
||
#if !defined(_DEBUG) && !defined(_RDEBUG) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD> <20>ʿ<EFBFBD><CABF><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> Ŭ<><C5AC> <20><><EFBFBD><EFBFBD>
|
||
if( bClip ) {
|
||
RECT rcWindow;
|
||
::GetWindowRect( m_hWnd, &rcWindow );
|
||
::ClipCursor( &rcWindow );
|
||
}
|
||
else {
|
||
::ClipCursor( NULL );
|
||
}
|
||
#endif
|
||
}
|
||
|
||
void CEtDevice::OnOutOfMemory()
|
||
{
|
||
if( m_pOutOfMemoryCallBack ) {
|
||
m_bCallOutOfMemory = true;
|
||
m_pOutOfMemoryCallBack->Run();
|
||
}
|
||
}
|
||
|
||
void CEtDevice::ShowFrame( RECT *pTargetRect )
|
||
{
|
||
if( m_pPrePresentCallback ) m_pPrePresentCallback();
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->Present( NULL, pTargetRect, NULL, NULL );
|
||
m_nPolyCountPerFrame = m_nCurrentPolyCount;
|
||
m_nCurrentPolyCount = 0;
|
||
}
|
||
|
||
void CEtDevice::GetRenderState( D3DRENDERSTATETYPE State, DWORD *pdwValue )
|
||
{
|
||
GetEtStateManager()->GetRenderStateDefered( State, pdwValue);
|
||
}
|
||
|
||
void CEtDevice::SetRenderState( D3DRENDERSTATETYPE State, DWORD dwValue )
|
||
{
|
||
GetEtStateManager()->SetRenderStateDefered( State, dwValue);
|
||
}
|
||
|
||
void CEtDevice::GetSamplerState( DWORD Sampler, D3DSAMPLERSTATETYPE State, DWORD *pdwValue )
|
||
{
|
||
GetEtStateManager()->GetSamplerStateDefered( Sampler, State, pdwValue);
|
||
}
|
||
|
||
void CEtDevice::SetSamplerState( DWORD Sampler, D3DSAMPLERSTATETYPE State, DWORD Value )
|
||
{
|
||
GetEtStateManager()->SetSamplerStateDefered( Sampler, State, Value);
|
||
}
|
||
|
||
void CEtDevice::GetTextureStageState( DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pValue)
|
||
{
|
||
GetEtStateManager()->GetTextureStageStateDefered( Stage, Type, pValue);
|
||
}
|
||
|
||
void CEtDevice::SetTextureStageState( DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value)
|
||
{
|
||
GetEtStateManager()->SetTextureStageStateDefered( Stage, Type, Value);
|
||
}
|
||
|
||
DWORD CEtDevice::SetColorWriteEnable( DWORD dwEnable )
|
||
{
|
||
DWORD dwCur;
|
||
GetRenderState( D3DRS_COLORWRITEENABLE, &dwCur );
|
||
SetRenderState( D3DRS_COLORWRITEENABLE, dwEnable );
|
||
return dwCur;
|
||
}
|
||
|
||
void CEtDevice::DrawPrimitive( PrimitiveType nPrimitiveType, int nStartVertex, int nPrimitiveCount )
|
||
{
|
||
GetEtStateManager()->FlushDeferedStates();
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->DrawPrimitive( ( D3DPRIMITIVETYPE )nPrimitiveType, nStartVertex, nPrimitiveCount );
|
||
m_nCurrentPolyCount += nPrimitiveCount;
|
||
}
|
||
|
||
void CEtDevice::DrawIndexedPrimitive( PrimitiveType nPrimitiveType, int nStartVertex, int nVertexCount, int nStartIndex, int nPrimitiveCount )
|
||
{
|
||
GetEtStateManager()->FlushDeferedStates();
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->DrawIndexedPrimitive( ( D3DPRIMITIVETYPE )nPrimitiveType, nStartVertex, 0, nVertexCount, nStartIndex, nPrimitiveCount );
|
||
m_nCurrentPolyCount += nPrimitiveCount;
|
||
}
|
||
|
||
void CEtDevice::DrawPrimitiveUP( PrimitiveType nPrimitiveType, int nPrimitiveCount, void *pVertexData, int nStride )
|
||
{
|
||
GetEtStateManager()->FlushDeferedStates();
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->DrawPrimitiveUP( ( D3DPRIMITIVETYPE )nPrimitiveType, nPrimitiveCount, pVertexData, nStride );
|
||
m_nCurrentPolyCount += nPrimitiveCount;
|
||
}
|
||
|
||
void CEtDevice::DrawIndexedPrimitiveUP( PrimitiveType nPrimitiveType, int nMinVertexIndex, int nNumVertices, int nPrimitiveCount, void *pIndexData, EtFormat IndexDataFormat, void *pVertexData, int nStride )
|
||
{
|
||
GetEtStateManager()->FlushDeferedStates();
|
||
ScopeLock< CSyncLock > Lock( m_DeviceLock );
|
||
m_pDevice->DrawIndexedPrimitiveUP( ( D3DPRIMITIVETYPE )nPrimitiveType, nMinVertexIndex, nNumVertices, nPrimitiveCount, pIndexData, (D3DFORMAT)IndexDataFormat, pVertexData, nStride);
|
||
m_nCurrentPolyCount += nPrimitiveCount;
|
||
}
|