📄 shaderapidx8.cpp
字号:
void CShaderAPIDX8::GetBackBufferDimensions( int& width, int& height ) const
{
width = m_nWindowWidth; //m_PresentParameters.BackBufferWidth;
height = m_nWindowHeight; //m_PresentParameters.BackBufferHeight;
}
//-----------------------------------------------------------------------------
// Changes the window size
//-----------------------------------------------------------------------------
bool CShaderAPIDX8::ResizeWindow( const MaterialVideoMode_t &mode, int flags, int nSampleCount )
{
// We don't need to do crap if the window was set up to set up
// to be resizing...
if (flags & MATERIAL_VIDEO_MODE_RESIZING)
return false;
// not fully implemented yet...
Assert(0);
// Release all objects in video memory
ShaderUtil()->ReleaseShaderObjects();
// Reset the device
SetPresentParameters( mode, flags, nSampleCount );
RECORD_COMMAND( DX8_RESET, 1 );
RECORD_STRUCT( &m_PresentParameters, sizeof(m_PresentParameters) );
HRESULT hr = m_pD3DDevice->Reset( &m_PresentParameters );
if (FAILED(hr))
return false;
GetDisplayMode( m_Mode );
// Initialize the app's device-dependent objects
ShaderUtil()->RestoreShaderObjects();
return true;
}
//-----------------------------------------------------------------------------
// Methods for interprocess communication to release resources
//-----------------------------------------------------------------------------
#define MATERIAL_SYSTEM_WINDOW_ID 0xFEEDDEAD
#define RELEASE_MESSAGE 0x5E740DE0
#define REACQUIRE_MESSAGE 0x5E740DE1
static BOOL CALLBACK EnumChildWindowsProc( HWND hWnd, LPARAM lParam )
{
int windowId = GetWindowLong( hWnd, GWL_USERDATA );
if (windowId == MATERIAL_SYSTEM_WINDOW_ID)
{
COPYDATASTRUCT copyData;
copyData.dwData = lParam;
copyData.cbData = 0;
copyData.lpData = 0;
SendMessage(hWnd, WM_COPYDATA, 0, (LPARAM)©Data);
}
return TRUE;
}
static BOOL CALLBACK EnumWindowsProc( HWND hWnd, LPARAM lParam )
{
EnumChildWindows( hWnd, EnumChildWindowsProc, lParam );
return TRUE;
}
static void SendIPCMessage( bool release )
{
// Gotta send this to all windows, since we don't know which ones
// are material system apps...
DWORD msg = release ? RELEASE_MESSAGE : REACQUIRE_MESSAGE;
EnumWindows( EnumWindowsProc, msg );
}
//-----------------------------------------------------------------------------
// Adds a hook to let us know when other instances are setting the mode
//-----------------------------------------------------------------------------
#ifdef STRICT
#define WINDOW_PROC WNDPROC
#else
#define WINDOW_PROC FARPROC
#endif
HWND g_HWndCookie;
static LRESULT CALLBACK ShaderDX8WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
// FIXME: Should these IPC messages tell when an app has focus or not?
// If so, we'd want to totally disable the shader api layer when an app
// doesn't have focus.
// Look for the special IPC message that tells us we're trying to set
// the mode....
switch(msg)
{
case WM_COPYDATA:
{
COPYDATASTRUCT* pData = (COPYDATASTRUCT*)lParam;
// that number is our magic cookie number
if (pData->dwData == RELEASE_MESSAGE)
{
g_ShaderAPIDX8.OtherAppInitializing(true);
}
else if (pData->dwData == REACQUIRE_MESSAGE)
{
g_ShaderAPIDX8.OtherAppInitializing(false);
}
}
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
static HWND GetTopmostParentWindow( HWND hWnd )
{
// Find the parent window...
HWND hParent = GetParent(hWnd);
while (hParent)
{
hWnd = hParent;
hParent = GetParent(hWnd);
}
return hWnd;
}
static void InstallWindowHook( HWND hWnd )
{
HWND hParent = GetTopmostParentWindow(hWnd);
// Attach a child window to the parent; we're gonna store special info there
// We can't use the USERDATA, cause other apps may want to use this.
HINSTANCE hInst = (HINSTANCE)GetWindowLong( hParent, GWL_HINSTANCE );
WNDCLASS wc;
memset( &wc, 0, sizeof( wc ) );
wc.style = CS_NOCLOSE | CS_PARENTDC;
wc.lpfnWndProc = ShaderDX8WndProc;
wc.hInstance = hInst;
wc.lpszClassName = "shaderdx8";
RegisterClass( &wc );
// Create the window
g_HWndCookie = CreateWindow( "shaderdx8", "shaderdx8", WS_CHILD,
0, 0, 0, 0, hParent, NULL, hInst, NULL );
// Marks it as a material system window
SetWindowLong( g_HWndCookie, GWL_USERDATA, MATERIAL_SYSTEM_WINDOW_ID );
}
static void RemoveWindowHook( HWND hWnd )
{
if (g_HWndCookie)
{
DestroyWindow( g_HWndCookie );
g_HWndCookie = 0;
}
}
//-----------------------------------------------------------------------------
// Can we download textures?
//-----------------------------------------------------------------------------
bool CShaderAPIDX8::CanDownloadTextures() const
{
if( IsDeactivated() )
return false;
return (m_pD3DDevice != NULL);
}
//-----------------------------------------------------------------------------
// Are we using graphics?
//-----------------------------------------------------------------------------
bool CShaderAPIDX8::IsUsingGraphics() const
{
return (m_pD3DDevice != NULL);
}
//-----------------------------------------------------------------------------
// Grab/release the render targets
//-----------------------------------------------------------------------------
void CShaderAPIDX8::AcquireRenderTargets()
{
if (!m_pBackBufferSurface)
{
m_pD3DDevice->GetRenderTarget( 0, &m_pBackBufferSurface );
Assert( m_pBackBufferSurface );
}
if (!m_pZBufferSurface)
{
m_pD3DDevice->GetDepthStencilSurface( &m_pZBufferSurface );
Assert( m_pZBufferSurface );
}
}
void CShaderAPIDX8::ReleaseRenderTargets()
{
if (m_pBackBufferSurface)
{
m_pBackBufferSurface->Release();
m_pBackBufferSurface = NULL;
}
if (m_pZBufferSurface)
{
m_pZBufferSurface->Release();
m_pZBufferSurface = NULL;
}
}
void CShaderAPIDX8::AllocFrameSyncObjects( void )
{
if( m_DeviceSupportsCreateQuery == 0 )
{
m_pFrameSyncQueryObject = NULL;
return;
}
// FIXME FIXME FIXME!!!!! Need to record this.
HRESULT hr = D3DDevice()->CreateQuery( D3DQUERYTYPE_EVENT, &m_pFrameSyncQueryObject );
if( hr == D3DERR_NOTAVAILABLE )
{
Warning( "D3DQUERYTYPE_EVENT not available on this driver\n" );
Assert( m_pFrameSyncQueryObject == NULL );
}
else
{
Assert( hr == D3D_OK );
Assert( m_pFrameSyncQueryObject );
m_pFrameSyncQueryObject->Issue( D3DISSUE_END );
}
}
void CShaderAPIDX8::FreeFrameSyncObjects( void )
{
// FIXME FIXME FIXME!!!!! Need to record this.
if( !m_pFrameSyncQueryObject )
{
return;
}
m_pFrameSyncQueryObject->Release();
m_pFrameSyncQueryObject = NULL;
}
//-----------------------------------------------------------------------------
// Initialize, shutdown the Device....
//-----------------------------------------------------------------------------
bool CShaderAPIDX8::InitDevice( void* hwnd, const MaterialVideoMode_t &mode, int flags, int nSampleCount )
{
bool restoreNeeded = false;
if (m_pD3DDevice)
{
ReleaseResources();
restoreNeeded = true;
}
FreeFrameSyncObjects();
ShutdownDevice();
// windowed
if (!CreateD3DDevice( (HWND)hwnd, mode, flags, nSampleCount ))
return false;
AcquireRenderTargets();
// Hook up our own windows proc to get at messages to tell us when
// other instances of the material system are trying to set the mode
InstallWindowHook( (HWND)hwnd );
m_Caps.m_TextureMemorySize = ComputeTextureMemorySize( m_DeviceGUID, m_DeviceType );
CreateMatrixStacks();
// Hide the cursor
RECORD_COMMAND( DX8_SHOW_CURSOR, 1 );
RECORD_INT( false );
m_pD3DDevice->ShowCursor( false );
// Initialize the shader manager
ShaderManager()->Init( ( flags & MATERIAL_VIDEO_MODE_PRELOAD_SHADERS ) != 0 );
// Initialize the shader shadow
ShaderShadow()->Init();
// Initialize the mesh manager
MeshMgr()->Init();
// Initialize the transition table.
m_TransitionTable.Init( GetDXSupportLevel() >= 90 );
// Initialize the render state
InitRenderState( );
// Create the ambient texture
CreateAmbientCubeTexture();
// Clear the z and color buffers
ClearBuffers( true, true, -1, -1 );
if (restoreNeeded)
ReacquireResources();
AllocFrameSyncObjects();
#if 0
// create a surface to copy the backbuffer into.
D3DSURFACE_DESC backbufferDesc;
m_pBackBufferSurface->GetDesc( &backbufferDesc );
HRESULT hr = m_pD3DDevice->CreateTexture( backbufferDesc.Width, backbufferDesc.Height,
1, 0, backbufferDesc.Format, D3DPOOL_DEFAULT, &m_pFBTexture );
Assert( !FAILED( hr ) );
#endif
RECORD_COMMAND( DX8_BEGIN_SCENE, 0 );
m_pD3DDevice->BeginScene();
return true;
}
void CShaderAPIDX8::ShutdownDevice( )
{
if (m_pD3DDevice)
{
// Deallocate all textures
DeleteAllTextures();
// Release render targets
ReleaseRenderTargets();
// Free objects that are used for frame syncing.
FreeFrameSyncObjects();
for (int i = 0; i < NUM_MATRIX_MODES; ++i)
{
if (m_pMatrixStack[i])
{
int ref = m_pMatrixStack[i]->Release();
Assert( ref == 0 );
}
}
// Shutdown the transition table.
m_TransitionTable.Shutdown();
MeshMgr()->Shutdown();
ShaderManager()->Shutdown();
ReleaseAllVertexDecl( );
RECORD_COMMAND( DX8_DESTROY_DEVICE, 0 );
m_pD3DDevice->Release();
#ifdef STUBD3D
delete ( CStubD3DDevice * )m_pD3DDevice;
#endif
m_pD3DDevice = 0;
RemoveWindowHook( m_HWnd );
m_HWnd = 0;
}
}
//-----------------------------------------------------------------------------
// Sets the mode...
//-----------------------------------------------------------------------------
bool CShaderAPIDX8::SetMode( void* hwnd, const MaterialVideoMode_t &mode, int flags, int nSampleCount )
{
Assert( m_pD3D );
// If we can't render windowed, we'll automatically switch to fullscreen...
if (!CanRenderWindowed())
{
flags &= ~(MATERIAL_VIDEO_MODE_WINDOWED | MATERIAL_VIDEO_MODE_RESIZING);
}
if (!ValidateMode( hwnd, mode, flags ))
return false;
bool ok;
if (!DoesModeRequireDeviceChange(hwnd, mode, flags))
{
ok = ResizeWindow( mode, flags, nSampleCount );
}
else
{
ok = InitDevice( hwnd, mode, flags, nSampleCount );
}
if (!ok)
return false;
if (flags & MATERIAL_VIDEO_MODE_WINDOWED)
{
// FIXME: Resize the window...?
if ((mode.m_Width != 0) && (mode.m_Height != 0))
{
/*
SetWindowPos( m_HWnd, HW
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -