📄 d3d_app.cpp
字号:
//-----------------------------------------------------------------------------
// File: D3DApp.cpp
//
// Desc: Application class for the Direct3D samples framework library.
//
// Copyright (c) 1998-1999 Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include <windows.h>
#include <mmsystem.h>
#include <stdio.h>
#include <tchar.h>
#include "d3d_app.h"
#include "graph.h"
#include "resource.h"
enum APPMSGTYPE { MSG_NONE, MSGERR_APPMUSTEXIT, MSGWARN_SWITCHEDTOSOFTWARE };
static LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
static D3D_APP *g_pD3DApp;
D3DEnum_DeviceInfo* g_pDeviceInfo = NULL;
LPDIRECTDRAW7 g_pDD = NULL;
LPDIRECT3D7 g_pD3D = NULL;
LPDIRECT3DDEVICE7 g_pd3dDevice = NULL;
LPDIRECTDRAWSURFACE7 g_pddsRenderTarget = NULL;
LPDIRECTDRAWSURFACE7 g_pddsZBuffer = NULL;
int g_iMouseX;
int g_iMouseY;
//窗口状态下Client区域的大小 , 全屏状态下屏幕的大小
int g_iViewWidth = 800;
int g_iViewHeight = 600;
D3D_APP::D3D_APP()
{
m_pFramework = NULL;
m_hWnd = NULL;
m_pDD = NULL;
m_pD3D = NULL;
m_pd3dDevice = NULL;
m_pddsRenderTarget = NULL;
m_pddsRenderTargetLeft = NULL;
m_bActive = FALSE;
m_bReady = FALSE;
m_bFrameMoving = TRUE;
m_bSingleStep = FALSE;
m_strWindowTitle = _T("Runner Test App");
m_bAppUseZBuffer = FALSE;
m_bAppUseStereo = FALSE;
m_bShowStats = FALSE;
m_fnConfirmDevice = NULL;
g_pD3DApp = this;
}
//-----------------------------------------------------------------------------
// Name: Create()
// Desc:
//-----------------------------------------------------------------------------
HRESULT D3D_APP::Create( HINSTANCE hInst, TCHAR* strCmdLine )
{
HRESULT hr;
// Enumerate available D3D devices. The callback is used so the app can
// confirm/reject each enumerated device depending on its capabilities.
if( FAILED( hr = D3DEnum_EnumerateDevices( m_fnConfirmDevice ) ) )
{
DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT );
return hr;
}
// Select a device. Ask for a hardware device that renders in a window.
if( FAILED( hr = D3DEnum_SelectDefaultDevice( &m_pDeviceInfo ) ) )
{
DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT );
return hr;
}
// Initialize the app's custom scene stuff
if( FAILED( hr = OneTimeSceneInit() ) )
{
DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT );
return hr;
}
if( NULL == ( m_pFramework = new CD3DFramework7() ) )
{
DisplayFrameworkError( E_OUTOFMEMORY, MSGERR_APPMUSTEXIT );
return E_OUTOFMEMORY;
}
// Register the window class
WNDCLASS wndClass = { 0, WndProc, 0, 0, hInst,
LoadIcon( hInst, MAKEINTRESOURCE(IDI_MAIN_ICON) ),
LoadCursor( NULL, IDC_ARROW ),
(HBRUSH)GetStockObject(WHITE_BRUSH),
NULL, _T("D3D Window") };
RegisterClass( &wndClass );
DWORD WndStyle = WS_VISIBLE|WS_CAPTION|WS_POPUPWINDOW;
//得到窗口应有尺寸
RECT rc;
rc.left = 0;
rc.right = g_iViewWidth;
rc.top = 0 ;
rc.bottom = g_iViewHeight;
AdjustWindowRect(&rc , WndStyle , FALSE);
// Create the render window
m_hWnd = CreateWindow( _T("D3D Window"), m_strWindowTitle,
WndStyle ,
100 , 100 , rc.right - rc.left , rc.bottom - rc.top , 0L,
NULL,
hInst, 0L );
UpdateWindow( m_hWnd );
// Initialize the 3D environment for the app
if( FAILED( hr = Initialize3DEnvironment() ) )
{
//DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT );
Cleanup3DEnvironment();
return E_FAIL;
}
// Setup the app so it can support single-stepping
m_dwBaseTime = timeGetTime();
// The app is ready to go
m_bReady = TRUE;
return S_OK;
}
//VOID D3D_APP::CheckKeyState() { }
//-----------------------------------------------------------------------------
// Name: Run()
// Desc: Message-processing loop. Idle time is used to render the scene.
//-----------------------------------------------------------------------------
#include "runner.h"
INT D3D_APP::Run()
{
// Now we're ready to recieve and process Windows messages.
BOOL bGotMsg;
MSG msg;
PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );
while( WM_QUIT != msg.message )
{
// Use PeekMessage() if the app is active, so we can use idle time to
// render the scene. Else, use GetMessage() to avoid eating CPU time.
if( m_bActive )
bGotMsg = PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE );
else
bGotMsg = GetMessage( &msg, NULL, 0U, 0U );
if( bGotMsg )
{
// Translate and dispatch the message
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
// Render a frame during idle time (no messages are waiting)
if( m_bActive && m_bReady )
{
GetRKeyState();
if( FAILED( Render3DEnvironment() ) )
DestroyWindow( m_hWnd );
}
}
}
return msg.wParam;
}
//-----------------------------------------------------------------------------
// Name: WndProc()
// Desc: Static msg handler which passes messages to the application class.
//-----------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
if( g_pD3DApp )
return g_pD3DApp->MsgProc( hWnd, uMsg, wParam, lParam );
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: Message handling function.
//-----------------------------------------------------------------------------
LRESULT D3D_APP::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam , LPARAM lParam )
{
HRESULT hr;
switch( uMsg )
{
case WM_PAINT:
// Handle paint messages when the app is not ready
if( m_pFramework && !m_bReady )
{
if( m_pDeviceInfo->bWindowed )
m_pFramework->ShowFrame();
else
m_pFramework->FlipToGDISurface( TRUE );
}
break;
case WM_MOVE:
// If in windowed mode, move the Framework's window
if( m_pFramework && m_bActive && m_bReady && m_pDeviceInfo->bWindowed )
m_pFramework->Move( (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam) );
break;
case WM_SIZE:
// Check to see if we are losing our window...
if( SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam )
m_bActive = FALSE;
else
m_bActive = TRUE;
// A new window size will require a new backbuffer
// size, so the 3D structures must be changed accordingly.
if( m_bActive && m_bReady && m_pDeviceInfo->bWindowed )
{
m_bReady = FALSE;
if( FAILED( hr = Change3DEnvironment() ) )
return 0;
m_bReady = TRUE;
}
break;
case WM_SETCURSOR:
// Prevent a cursor in fullscreen mode
if( m_bActive && m_bReady && !m_pDeviceInfo->bWindowed )
{
SetCursor(NULL);
return 1;
}
break;
case WM_SYSCOMMAND:
// Prevent moving/sizing and power loss in fullscreen mode
switch( wParam )
{
case SC_MOVE:
case SC_SIZE:
case SC_MAXIMIZE:
case SC_MONITORPOWER:
if( FALSE == m_pDeviceInfo->bWindowed )
return 1;
break;
}
break;
case WM_GETMINMAXINFO:
((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
break;
case WM_CLOSE:
DestroyWindow( hWnd );
return 0;
case WM_DESTROY:
Cleanup3DEnvironment();
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
//-----------------------------------------------------------------------------
// Name: Initialize3DEnvironment()
// Desc: Initializes the sample framework, then calls the app-specific function
// to initialize device specific objects. This code is structured to
// handled any errors that may occur duing initialization
//-----------------------------------------------------------------------------
HRESULT D3D_APP::Initialize3DEnvironment()
{
HRESULT hr;
DWORD dwFrameworkFlags = 0L;
dwFrameworkFlags |= ( !m_pDeviceInfo->bWindowed ? D3DFW_FULLSCREEN : 0L );
dwFrameworkFlags |= ( m_pDeviceInfo->bStereo ? D3DFW_STEREO : 0L );
dwFrameworkFlags |= ( m_bAppUseZBuffer ? D3DFW_ZBUFFER : 0L );
// Initialize the D3D framework
if( SUCCEEDED( hr = m_pFramework->Initialize( m_hWnd,
m_pDeviceInfo->pDriverGUID, m_pDeviceInfo->pDeviceGUID,
&m_pDeviceInfo->ddsdFullscreenMode, dwFrameworkFlags ) ) )
{
m_pDD = m_pFramework->GetDirectDraw();
m_pD3D = m_pFramework->GetDirect3D();
m_pd3dDevice = m_pFramework->GetD3DDevice();
m_pddsRenderTarget = m_pFramework->GetRenderSurface();
m_pddsRenderTargetLeft = m_pFramework->GetRenderSurfaceLeft();
m_ddsdRenderTarget.dwSize = sizeof(m_ddsdRenderTarget);
m_pddsRenderTarget->GetSurfaceDesc( &m_ddsdRenderTarget );
g_pDD = m_pDD;
g_pD3D = m_pD3D;
g_pd3dDevice = m_pd3dDevice;
g_pddsRenderTarget = m_pddsRenderTarget;
g_pDeviceInfo = m_pDeviceInfo;
g_pddsZBuffer =m_pFramework->GetZBufferSurface();
// Let the app run its startup code which creates the 3d scene.
if( SUCCEEDED( hr = InitDeviceObjects() ) )
return S_OK;
else
{
DeleteDeviceObjects();
m_pFramework->DestroyObjects();
}
}
// If we get here, the first initialization passed failed. If that was with a
// hardware device, try again using a software rasterizer instead.
if( m_pDeviceInfo->bHardware )
{
// Try again with a software rasterizer
DisplayFrameworkError( hr, MSGWARN_SWITCHEDTOSOFTWARE );
D3DEnum_SelectDefaultDevice( &m_pDeviceInfo, D3DENUM_SOFTWAREONLY );
return Initialize3DEnvironment();
}
return hr;
}
//-----------------------------------------------------------------------------
// Name: Change3DEnvironment()
// Desc: Handles driver, device, and/or mode changes for the app.
//-----------------------------------------------------------------------------
HRESULT D3D_APP::Change3DEnvironment()
{
HRESULT hr;
static BOOL bOldWindowedState = TRUE;
static DWORD dwSavedStyle;
static RECT rcSaved;
// Release all scene objects that will be re-created for the new device
DeleteDeviceObjects();
// Release framework objects, so a new device can be created
if( FAILED( hr = m_pFramework->DestroyObjects() ) )
{
DisplayFrameworkError( hr, MSGERR_APPMUSTEXIT );
SendMessage( m_hWnd, WM_CLOSE, 0, 0 );
return hr;
}
// Check if going from fullscreen to windowed mode, or vice versa.
if( bOldWindowedState != m_pDeviceInfo->bWindowed )
{
if( m_pDeviceInfo->bWindowed )
{
// Coming from fullscreen mode, so restore window properties
SetWindowLong( m_hWnd, GWL_STYLE, dwSavedStyle );
SetWindowPos( m_hWnd, HWND_NOTOPMOST, rcSaved.left, rcSaved.top,
( rcSaved.right - rcSaved.left ),
( rcSaved.bottom - rcSaved.top ), SWP_SHOWWINDOW );
}
else
{
// Going to fullscreen mode, save/set window properties as needed
dwSavedStyle = GetWindowLong( m_hWnd, GWL_STYLE );
GetWindowRect( m_hWnd, &rcSaved );
SetWindowLong( m_hWnd, GWL_STYLE, WS_POPUP|WS_SYSMENU|WS_VISIBLE );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -