📄 ch6p1_createdevice.cpp
字号:
/*
#############################################################################
Ch6p1_CreateDevice.cpp: a program that demonstrates how to create a device
using DirectX 8.0.
#############################################################################
*/
// include files ////////////////////////////////////////////////////////////
#include <windows.h> // needed for windows
#include <d3d8.h> // directx 8 header
// global variables /////////////////////////////////////////////////////////
const char * g_strAppName = "Ch6p1_CreateDevice";
LPDIRECT3D8 g_pD3D = NULL; // Used to create the D3DDevice
LPDIRECT3DDEVICE8 g_pd3dDevice = NULL; // Our rendering device
HWND g_hWnd = NULL; // our window handle
/****************************************************************************
PaintWindow: called by WindowProc when our window needs painting.
****************************************************************************/
void PaintWindow(HDC hdc)
{
// most directX games don't really use WM_PAINT.
// instead, they run their own animation loop, and flip (aka "present")
// their backbuffers several times per second.
// the following code clears the backbuffer black, then displays it.
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
// Present the backbuffer contents to the display
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
/****************************************************************************
InitDirect3D: initializes Direct3D 8 and creates a windowed device.
****************************************************************************/
void InitDirect3D(void)
{
// create a Direct3D device
g_pD3D = Direct3DCreate8( D3D_SDK_VERSION );
if(g_pD3D == NULL) {
throw("Direct3DCreate8 failed.");
}
// Get the current desktop display mode
D3DDISPLAYMODE d3ddm;
if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) {
throw("GetAdapterDisplayMode failed.");
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) ); // this will set all members to zero
// setting zero for width and height will tell windows to use window
// dimensions for backbuffer dimensions.
d3dpp.BackBufferWidth = 0;
d3dpp.BackBufferHeight = 0;
// request a back buffer format that matches the current desktop display
// format.
d3dpp.BackBufferFormat = d3ddm.Format;
// we want 1 back buffer
d3dpp.BackBufferCount = 1;
// no multisampling
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
// "discard" swap effect. This means that we should never care about
// the contents of the front buffer - we should always re-render the
// entire screen on the back buffer each frame. This is the most
// efficient method of presenting the back buffer.
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
// use our window as the device window
d3dpp.hDeviceWindow = g_hWnd;
// we want to do D3D in a window
d3dpp.Windowed = TRUE;
// we don't want Direct3D to manage depth buffers for us
// (that's because we don't use any right now)
d3dpp.EnableAutoDepthStencil = false;
d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
// no special flags
d3dpp.Flags = 0;
// default refresh rate
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
// default presentation interval (we must use this because we're in
// a window)
d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
// Create the Direct3D device.
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, g_hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice)))
{
throw("CreateDevice failed.");
}
}
/****************************************************************************
UnInitDirect3D: cleans up Direct3D by releasing all the interfaces we've
created.
****************************************************************************/
void UnInitDirect3D(void)
{
// first, release any devices we've created.
if(g_pd3dDevice != NULL) {
g_pd3dDevice->Release();
g_pd3dDevice = NULL; // just to be safe
}
// next, release the direct3d interface.
if(g_pD3D != NULL) {
g_pD3D->Release();
g_pD3D = NULL; // just to be safe
}
}
/****************************************************************************
WindowProc: Windows calls this function when we dispatch messages.
****************************************************************************/
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg) {
case WM_PAINT:
{
PAINTSTRUCT ps;
// get the DC we're supposed to use from Windows
BeginPaint(hwnd, &ps);
HDC hdc = ps.hdc;
// paint our window (function is defined above)
PaintWindow(hdc);
// tell Windows we're done painting.
EndPaint(hwnd, &ps);
}
// we processed the message, so return 0.
return(0);
case WM_DESTROY: // our window is being destroyed! quit!
UnInitDirect3D();
PostQuitMessage(0);
return(0);
}
// all the other messages, we don't care about, so we let DefWindowProc
// handle them.
return(DefWindowProc(hwnd, uMsg, wParam, lParam));
}
/****************************************************************************
InitWindow: creates a window class and a window.
****************************************************************************/
HWND InitWindow(HINSTANCE hinst, int nCmdShow)
{
HWND hwnd;
WNDCLASSEX wc;
// set up and register window class
memset(&wc, 0, sizeof(wc));
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc; // change this to NULL and crash!
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinst;
wc.hIcon = NULL;
wc.hIconSm = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "MyCoolWindow";
RegisterClassEx(&wc);
// create a window that's 640 pixels wide, 480 tall.
hwnd = CreateWindowEx(0, "MyCoolWindow", g_strAppName,
WS_OVERLAPPEDWINDOW,
10, 10, 640, 480, NULL, NULL, hinst, NULL);
if (!hwnd) {
::MessageBox(NULL, "CreateWindow failed!", g_strAppName, MB_ICONSTOP);
exit(-1);
}
ShowWindow(hwnd, nCmdShow);
return(hwnd);
}
/****************************************************************************
WinMain: program execution starts here.
****************************************************************************/
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// create a window
g_hWnd = InitWindow(hInstance, nCmdShow);
// this is a C++ try-catch block. It works very simply. Inside the try,
// there are throw() functions. These "throw" errors, which are caught
// by the "catch" statement at the end of the try block.
// (for more information, see the appendix.)
try {
InitDirect3D();
} catch(const char *errmsg) {
// if we threw any const char *'s, catch them here, display the error,
// then exit.
MessageBox(g_hWnd, errmsg, g_strAppName, 0);
exit(-1);
}
catch(...) {
// catch unhandled exceptions.
MessageBox(g_hWnd, "An unknown error occurred.", g_strAppName, 0);
exit(-1);
}
// note that we clean all this stuff up when our window is destroyed,
// aka when we get a WM_DESTROY message.
// message pump
while (1) {
MSG msg;
if (PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE))
{
int result = GetMessage(&msg, 0, 0, 0);
if (!result) return(msg.wParam);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// we'll never get here, but the compiler will complain if we don't
// have this line.
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -