📄 display.cpp
字号:
#include "HEADERS.H"
#include "DISPLAY.H"
USING NAMESPACE CGE::DISPLAY;
BOOL Behavior::BehaviorCreate(VOID * hWnd,LONG w,LONG h,BOOL bWindowed)
{
DIRECTX = Direct3DCreate8(D3D_SDK_VERSION);
if(DIRECTX == NULL)
{
return FALSE;
}
D3DADAPTER_IDENTIFIER8 Identifier;
ZeroMemory(&Identifier,sizeof(D3DADAPTER_IDENTIFIER8));
if ( FAILED(DIRECTX->GetAdapterIdentifier(0,0,&Identifier)))
{
SAFE_RELEASE(DIRECTX);
return FALSE;
}
_tcscat(m_strAdapterInfo,TEXT("AdapterInfo:"));
_tcscat(m_strAdapterInfo,Identifier.Description);
_tcscat(m_strAdapterInfo,TEXT("\n"));
ZeroMemory(&D3DPARAMETER,sizeof(D3DPRESENT_PARAMETERS));
D3DPARAMETER.Windowed = bWindowed;
D3DPARAMETER.BackBufferCount = 1;
D3DPARAMETER.BackBufferWidth = w;
D3DPARAMETER.BackBufferHeight = h;
D3DPARAMETER.hDeviceWindow = (HWND)hWnd;
D3DPARAMETER.SwapEffect = bWindowed ? D3DSWAPEFFECT_DISCARD:D3DSWAPEFFECT_COPY_VSYNC;
D3DPARAMETER.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
D3DPARAMETER.FullScreen_PresentationInterval = bWindowed ? 0:D3DPRESENT_INTERVAL_ONE;
D3DDISPLAYMODE d3ddm;
if ( bWindowed )
{
DIRECTX->GetAdapterDisplayMode(0,&d3ddm);
D3DPARAMETER.BackBufferFormat = d3ddm.Format;
}
else
{
d3ddm.Format = CheckDisplayMode(w , h, 32);
if(d3ddm.Format != D3DFMT_UNKNOWN)
{
D3DPARAMETER.BackBufferFormat = d3ddm.Format;
}
else
{
d3ddm.Format = CheckDisplayMode(w, h, 16);
if( d3ddm.Format != D3DFMT_UNKNOWN)
{
D3DPARAMETER.BackBufferFormat = d3ddm.Format;
}
else
{
SAFE_RELEASE(DIRECTX);
return FALSE;
}
}
}
if(DIRECTX->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D32) == D3D_OK)
{
D3DPARAMETER.AutoDepthStencilFormat = D3DFMT_D32;
D3DPARAMETER.EnableAutoDepthStencil = TRUE;
_tcscat(m_strAdapterInfo,TEXT("DepthStencil:D3DFMT_D32\n"));
}
else if(DIRECTX->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8) == D3D_OK)
{
D3DPARAMETER.AutoDepthStencilFormat = D3DFMT_D24X8;
D3DPARAMETER.EnableAutoDepthStencil = TRUE;
_tcscat(m_strAdapterInfo,TEXT("DepthStencil:D3DFMT_D24X8\n"));
}
else if(DIRECTX->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16) == D3D_OK)
{
D3DPARAMETER.AutoDepthStencilFormat = D3DFMT_D16;
D3DPARAMETER.EnableAutoDepthStencil = TRUE;
_tcscat(m_strAdapterInfo,TEXT("DepthStencil:D3DFMT_D16\n"));
}
else
{
D3DPARAMETER.EnableAutoDepthStencil = FALSE;
}
if(FAILED(DIRECTX->GetDeviceCaps(0,D3DDEVTYPE_HAL,&CAPS)))
{
SAFE_RELEASE(DIRECTX);
return FALSE;
}
if(FAILED(ConfirmDevice(&CAPS)))
{
SAFE_RELEASE(DIRECTX);
return FALSE;
}
if(FAILED(DIRECTX->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DPARAMETER.hDeviceWindow,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &D3DPARAMETER, &DEVICE)))
{
SAFE_RELEASE(DIRECTX);
_tcscat(m_strAdapterInfo,TEXT(":create failed.\n"));
MessageBox(NULL,m_strAdapterInfo,"Error",MB_OK);
return FALSE;
}
if(FAILED(DEVICE->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&BACK_SURFACE)))
{
SAFE_RELEASE(DIRECTX);
SAFE_RELEASE(DEVICE);
return FALSE;
}
if ( InitializeOnFirstTime() == FALSE )
{
SAFE_RELEASE(DIRECTX);
SAFE_RELEASE(DEVICE);
SAFE_RELEASE(BACK_SURFACE);
return FALSE;
}
if ( InitializeEntironment() == FALSE )
{
SAFE_RELEASE(DIRECTX);
SAFE_RELEASE(DEVICE);
SAFE_RELEASE(BACK_SURFACE);
return FALSE;
}
if ( AfreshEntironment() == FALSE )
{
SAFE_RELEASE(DIRECTX);
SAFE_RELEASE(DEVICE);
SAFE_RELEASE(BACK_SURFACE);
return FALSE;
}
m_bReady = TRUE;
return TRUE;
}
D3DFORMAT Behavior::CheckDisplayMode(LONG nWidth, LONG nHeight, INT nDepth)
{
register UINT x;
D3DDISPLAYMODE d3ddm;
for(x = 0; x < DIRECTX->GetAdapterModeCount(0); x++)
{
DIRECTX->EnumAdapterModes(0, x, &d3ddm);
if(d3ddm.Width == nWidth)
{
if(d3ddm.Height == nHeight)
{
if((d3ddm.Format == D3DFMT_R5G6B5) || (d3ddm.Format == D3DFMT_X1R5G5B5) || (d3ddm.Format == D3DFMT_X4R4G4B4))
{
if(nDepth == 16)
{
return d3ddm.Format;
}
}
else if((d3ddm.Format == D3DFMT_R8G8B8) || (d3ddm.Format == D3DFMT_X8R8G8B8))
{
if(nDepth == 32)
{
return d3ddm.Format;
}
}
}
}
}
return D3DFMT_UNKNOWN;
}
BOOL Behavior::CheckCooperativeLevel()
{
HRESULT hr;
if( FAILED( hr = DEVICE->TestCooperativeLevel() ) )
{
// 当设备丢失时,要等到设备有效后方可继续
if( D3DERR_DEVICELOST==hr )
return FALSE;
// 重置设备
if( D3DERR_DEVICENOTRESET==hr )
{
// 在重置前必须要释放资源
if ( TRUE == SetfreeEntironment() )
{
SAFE_RELEASE(BACK_SURFACE);
if( FAILED( hr = DEVICE->Reset(&D3DPARAMETER) ) )
return FALSE;
if(FAILED(DEVICE->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&BACK_SURFACE)))
{
SAFE_RELEASE(DIRECTX);
SAFE_RELEASE(DEVICE);
return FALSE;
}
// 在重置后必须要重新载入资源
return AfreshEntironment();
}
}
return FALSE;
}
return TRUE;
}
BOOL Behavior::SetBehavior(LONG Width, LONG Height, BOOL bWindowed)
{
if( !Width || !Height )
return FALSE;
D3DPARAMETER.BackBufferWidth = Width;
D3DPARAMETER.BackBufferHeight = Height;
D3DDISPLAYMODE d3ddm;
if ( bWindowed )
{
DIRECTX->GetAdapterDisplayMode(0,&d3ddm);
D3DPARAMETER.BackBufferFormat = d3ddm.Format;
}
else
{
d3ddm.Format = CheckDisplayMode(Width , Height, 32);
if(d3ddm.Format != D3DFMT_UNKNOWN)
{
D3DPARAMETER.BackBufferFormat = d3ddm.Format;
}
else
{
d3ddm.Format = CheckDisplayMode(Width, Height, 16);
if( d3ddm.Format != D3DFMT_UNKNOWN)
{
D3DPARAMETER.BackBufferFormat = d3ddm.Format;
}
else
{
return FALSE;
}
}
}
if ( SUCCEEDED(DEVICE->Reset(&D3DPARAMETER)))
{
return TRUE;
}
return CheckCooperativeLevel();
}
LONG Behavior::BackBufferWidth()
{
D3DSURFACE_DESC desc;
if ( BACK_SURFACE )
{
BACK_SURFACE->GetDesc(&desc);
return desc.Width;
}
return -1;
}
LONG Behavior::BackBufferHeight()
{
D3DSURFACE_DESC desc;
if ( BACK_SURFACE )
{
BACK_SURFACE->GetDesc(&desc);
return desc.Height;
}
return -1;
}
VOID Behavior::CheckRunTime()
{
MSG msg;
BOOL fMessage;
PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
while(msg.message != WM_QUIT)
{
if ( m_bActive == TRUE )
{
fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);
}
else
{
fMessage = GetMessage(&msg, NULL, 0U, 0U);
}
if(fMessage)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
if( m_bActive && m_bReady)
{
if (CheckCooperativeLevel() == TRUE)
{
DrawEntironment();
}
}
if ( FALSE == CheckFrameInMove())
{
continue;
}
}
}
}
LRESULT Behavior::DefineUserMsgProc(HWND hWnd, UINT msg, WPARAM wParam,LPARAM lParam)
{
static RECT m_rcWindowBounds = {0,0,0,0};
static RECT m_rcWindowClient = {0,0,0,0};
switch( msg )
{
case WM_PAINT:
if( DEVICE && !m_bReady )
{
if( D3DPARAMETER.Windowed )
{
DrawEntironment();
}
}
break;
case WM_KEYUP:
switch (wParam)
{
case VK_ESCAPE:
SendMessage(hWnd,WM_CLOSE,0,0);
return 0;break;
} break;
case WM_GETMINMAXINFO:
((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
break;
case WM_ENTERSIZEMOVE:
m_bReady = FALSE;
break;
case WM_SIZE:
if( SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam )
{
m_bActive = FALSE;
}
else
{
m_bActive = TRUE;
}
break;
case WM_EXITSIZEMOVE:
m_bReady = TRUE;
if( m_bActive && D3DPARAMETER.Windowed )
{
RECT rcClientOld;
rcClientOld = m_rcWindowClient;
GetWindowRect( hWnd, &m_rcWindowBounds );
GetClientRect( hWnd, &m_rcWindowClient );
if( rcClientOld.right - rcClientOld.left !=
m_rcWindowClient.right - m_rcWindowClient.left ||
rcClientOld.bottom - rcClientOld.top !=
m_rcWindowClient.bottom - m_rcWindowClient.top)
{
m_bReady = FALSE;
LONG NewWidth = m_rcWindowClient.right - m_rcWindowClient.left;
LONG NewHeight = m_rcWindowClient.bottom - m_rcWindowClient.top;
if( SetBehavior(NewWidth,NewHeight) == FALSE )
{
return FALSE;
}
m_bReady = TRUE;
}
}
break;
case WM_MOUSEMOVE:
if( m_bActive && m_bReady && DEVICE != NULL )
{
POINT ptCursor;
GetCursorPos( &ptCursor );
if( !D3DPARAMETER.Windowed )
ScreenToClient( hWnd, &ptCursor );
DEVICE->SetCursorPosition( ptCursor.x, ptCursor.y, 0L );
}
break;
case WM_POWERBROADCAST:
switch( wParam )
{
#ifndef PBT_APMQUERYSUSPEND
#define PBT_APMQUERYSUSPEND 0x0000
#endif
case PBT_APMQUERYSUSPEND:
return TRUE;
#ifndef PBT_APMRESUMESUSPEND
#define PBT_APMRESUMESUSPEND 0x0007
#endif
case PBT_APMRESUMESUSPEND:
return TRUE;
}
break;
case WM_SYSCOMMAND:
switch( wParam )
{
case SC_MOVE:
case SC_SIZE:
case SC_MAXIMIZE:
case SC_MONITORPOWER:
if( FALSE == D3DPARAMETER.Windowed )
return TRUE;
break;
}
break;
case WM_CLOSE:
CleanupOnLastTime();
DestroyWindow( hWnd );
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -