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

📄 shaderapidx8.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 5 页
字号:

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)&copyData);
	}
	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 + -