📄 d3dapp.c
字号:
/*
* Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
*
* File: d3dapp.c
*
* Top level D3DApp functions and internal global variables. See
* d3dapp.h for more information.
*
* D3DApp is a collection of helper functions for Direct3D applications.
* D3DApp consists of the following files:
* d3dapp.h Main D3DApp header to be included by application
* d3dappi.h Internal header
* d3dapp.c D3DApp functions seen by application.
* ddcalls.c All calls to DirectDraw objects except textures
* d3dcalls.c All calls to Direct3D objects except textures
* texture.c Texture loading and managing texture list
* misc.c Miscellaneous calls
*/
#include "d3dappi.h"
#include <d3drm.h> /* For D3DRM error codes only */
#define INITGUID
/***************************************************************************/
/* GLOBAL VARIABLES */
/***************************************************************************/
/*
* All DD and D3D objects which are also available to the application
* See d3dapp.h for typedef
*/
D3DAppInfo d3dappi;
/*
* Internal record of the render state. See d3dapp.h for typedef
*/
D3DAppRenderState d3dapprs;
/*
* Callback functions for D3D device creation and destruction
*/
BOOL(*D3DDeviceDestroyCallback)(LPVOID);
LPVOID D3DDeviceDestroyCallbackContext;
BOOL(*D3DDeviceCreateCallback)(int, int, LPDIRECT3DVIEWPORT*, LPVOID);
LPVOID D3DDeviceCreateCallbackContext;
/*
* The last error code and string
*/
HRESULT LastError;
char LastErrorString[256];
/*
* List of dirty rectangles on back buffer and client area
*/
int NumDirtyClientRects, NumDirtyBackRects, NumDirtyZRects;
D3DRECT DirtyClient[D3DAPP_MAXCLEARRECTS];
D3DRECT DirtyBack[D3DAPP_MAXCLEARRECTS];
D3DRECT DirtyZ[D3DAPP_MAXCLEARRECTS];
/*
* List of texture handles which is copied to D3DAppInfo structure when
* necessary
*/
D3DTEXTUREHANDLE MasterTextureHandle[D3DAPP_MAXTEXTURES];
LPDIRECTDRAWCLIPPER lpClipper; /* Clipper in windowed case */
LPDIRECTDRAWPALETTE lpPalette; /* Front buffer's palette */
PALETTEENTRY ppe[256]; /* Current palette entries */
PALETTEENTRY Originalppe[256]; /* Windows palette entries at startup */
BOOL bD3DAppInitialized; /* Is D3DApp initialized? */
BOOL bPrimaryPalettized; /* Is the front buffer palettized? */
BOOL bPaletteActivate; /* Is the front buffer's palette valid? */
BOOL bIgnoreWM_SIZE; /* Ignore this WM_SIZE messages */
SIZE szLastClient; /* Dimensions of the last window */
SIZE szBuffers; /* Current buffer dimensions, not necessarily
the same as the client window */
int CallbackRefCount; /* How many times DeviceCreateCallback has
been called in a row */
/***************************************************************************/
/* FUNCTIONS */
/***************************************************************************/
/*
* D3DAppEnumerateDDDevices
*/
BOOL D3DAppEnumerateDDDevices(int* NumDevices, D3DAppDDDriver* lpDriver)
{
if (!NumDevices || !lpDriver) {
D3DAppISetErrorString("Invalid parameters passe to D3DAppEnumerateDDDevices.\n");
return FALSE;
}
return D3DAppIEnumDDDevices(NumDevices, lpDriver);
}
/*
* D3DAppCreateFromHWND
*/
BOOL D3DAppCreateFromHWND(DWORD flags, HWND hwnd, LPGUID lpDDGuid,
BOOL(*DeviceCreateCallback)(int, int,
LPDIRECT3DVIEWPORT*,
LPVOID),
LPVOID lpCreateContext,
BOOL(*DeviceDestroyCallback)(LPVOID),
LPVOID lpDestroyContext,
D3DAppInfo** D3DApp)
{
int driver, mode, w, h;
/*
* Clean the global varaibles and check the flags
*/
D3DAppISetDefaults();
if (flags & D3DAPP_ONLYSYSTEMMEMORY) {
d3dappi.bOnlySystemMemory = TRUE;
d3dappi.bOnlyEmulation = TRUE;
}
if (flags & D3DAPP_ONLYD3DEMULATION)
d3dappi.bOnlyEmulation = TRUE;
/*
* Create DirectDraw, remember the Windows display mode and enumerate the
* display modes
*/
ATTEMPT(D3DAppICreateDD(d3dappi.bOnlyEmulation ?
D3DAPP_ONLYDDEMULATION : 0L, lpDDGuid));
ATTEMPT(D3DAppIRememberWindowsMode());
ATTEMPT(D3DAppIEnumDisplayModes());
/*
* Create Direct3D and enumerate the D3D drivers
*/
ATTEMPT(D3DAppICreateD3D());
ATTEMPT(D3DAppIEnumDevices());
/*
* Set the device creation and destroy callback functions
*/
D3DDeviceDestroyCallback = DeviceDestroyCallback;
D3DDeviceDestroyCallbackContext = lpDestroyContext;
D3DDeviceCreateCallback = DeviceCreateCallback;
D3DDeviceCreateCallbackContext = lpCreateContext;
*D3DApp = &d3dappi;
d3dappi.hwnd = hwnd;
/*
* Choose a driver and display mode. Using the current window is
* prefered, but a fullscreen mode may be selected. Set the cooperative
* level and create the front and back buffers for this mode.
*/
driver = D3DAPP_YOUDECIDE;
mode = D3DAPP_YOUDECIDE;
ATTEMPT(D3DAppIVerifyDriverAndMode(&driver, &mode));
D3DAppIGetClientWin(hwnd);
if (mode == D3DAPP_USEWINDOW) {
w = d3dappi.szClient.cx;
h = d3dappi.szClient.cy;
ATTEMPT(D3DAppISetCoopLevel(hwnd, FALSE));
ATTEMPT(D3DAppICreateBuffers(hwnd, w, h, D3DAPP_BOGUS, FALSE,
d3dappi.Driver[driver].bIsHardware));
/*
* Change the currently selected mode if it's not compatible with
* this driver. Just to make sure that CurrMode is always a mode the
* current driver can do.
*/
if (!(d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth &
D3DAppIBPPToDDBD(d3dappi.Mode[d3dappi.CurrMode].bpp))){
ATTEMPT(D3DAppIPickDisplayMode(&d3dappi.CurrMode,
d3dappi.Driver[driver].Desc.dwDeviceRenderBitDepth));
}
} else {
szLastClient = d3dappi.szClient;
w = d3dappi.Mode[mode].w;
h = d3dappi.Mode[mode].h;
d3dappi.szClient.cx = w; d3dappi.szClient.cy = h;
ATTEMPT(D3DAppISetCoopLevel(hwnd, TRUE));
ATTEMPT(D3DAppISetDisplayMode(w, h, d3dappi.Mode[mode].bpp));
d3dappi.CurrMode = mode;
ATTEMPT(D3DAppICreateBuffers(hwnd, w, h, d3dappi.Mode[mode].bpp, TRUE,
d3dappi.Driver[driver].bIsHardware));
}
/*
* If the front buffer is palettized, initialize its palette
*/
ATTEMPT(D3DAppICheckForPalettized());
/*
* Create the Z-buffer
*/
ATTEMPT(D3DAppICreateZBuffer(w, h, driver));
/*
* Create the D3D device, load the textures, call the device create
* callback and set a default render state
*/
ATTEMPT(D3DAppICreateDevice(driver));
ATTEMPT(D3DAppILoadAllTextures());
ATTEMPT(D3DAppIFilterDisplayModes(driver)); /* bThisDriverCanDo flags */
ATTEMPT(D3DAppICallDeviceCreateCallback(w, h));
ATTEMPT(D3DAppISetRenderState());
/*
* Initialize dirty rectangle information
*/
D3DAppIValidateDirtyRects();
/*
* Ready to render
*/
bD3DAppInitialized = TRUE;
d3dappi.bRenderingIsOK = TRUE;
return TRUE;
exit_with_error:
D3DAppICallDeviceDestroyCallback();
RELEASE(d3dappi.lpD3DDevice);
RELEASE(d3dappi.lpZBuffer);
RELEASE(lpPalette);
RELEASE(lpClipper);
RELEASE(d3dappi.lpBackBuffer);
RELEASE(d3dappi.lpFrontBuffer);
if (d3dappi.bFullscreen) {
D3DAppIRestoreDispMode();
D3DAppISetCoopLevel(hwnd, FALSE);
}
RELEASE(d3dappi.lpD3D);
RELEASE(d3dappi.lpDD);
return FALSE;
}
/*
* D3DAppFullscreen
*/
BOOL D3DAppFullscreen(int mode)
{
int w, h, bpp;
BOOL b; /* was already in a fullscreen mode? */
d3dappi.bRenderingIsOK = FALSE;
/*
* Make sure this is a valid request, otherwise doctor mode so it will
* work with this driver.
*/
ATTEMPT(D3DAppIVerifyDriverAndMode(&d3dappi.CurrDriver, &mode));
/*
* Release everything
*/
ATTEMPT(D3DAppICallDeviceDestroyCallback());
if (d3dappi.bFullscreen) {
ATTEMPT(D3DAppIClearBuffers());
}
D3DAppIReleaseAllTextures();
RELEASE(d3dappi.lpD3DDevice);
RELEASE(d3dappi.lpZBuffer);
RELEASE(lpPalette);
RELEASE(lpClipper);
RELEASE(d3dappi.lpBackBuffer);
RELEASE(d3dappi.lpFrontBuffer);
/*
* Record information about the current status
*/
b = d3dappi.bFullscreen;
w = d3dappi.Mode[mode].w;
h = d3dappi.Mode[mode].h;
bpp = d3dappi.Mode[mode].bpp;
if (!b) {
/*
* If this is not a fullscreen mode, we'll need to record the window
* size for when we return to it.
*/
szLastClient = d3dappi.szClient;
}
/*
* Set the cooperative level and create front and back buffers
*/
d3dappi.szClient.cx = w; d3dappi.szClient.cy = h;
ATTEMPT(D3DAppISetCoopLevel(d3dappi.hwnd, TRUE));
ATTEMPT(D3DAppISetDisplayMode(w, h, bpp));
d3dappi.CurrMode = mode;
ATTEMPT(D3DAppICreateBuffers(d3dappi.hwnd, w, h, bpp, TRUE,
d3dappi.Driver[d3dappi.CurrDriver].bIsHardware));
/*
* If the front buffer is palettized, initialize its palette
*/
ATTEMPT(D3DAppICheckForPalettized());
/*
* Create the Z-buffer
*/
ATTEMPT(D3DAppICreateZBuffer(w, h, d3dappi.CurrDriver));
/*
* Create the D3D device, load the textures, call the device create
* callback and set a default render state
*/
ATTEMPT(D3DAppICreateDevice(d3dappi.CurrDriver));
ATTEMPT(D3DAppILoadAllTextures());
ATTEMPT(D3DAppICallDeviceCreateCallback(w, h));
ATTEMPT(D3DAppISetRenderState());
/*
* Set current mode and clear dirty rectangle information
*/
d3dappi.CurrMode = mode;
D3DAppIValidateDirtyRects();
d3dappi.bRenderingIsOK = TRUE;
return TRUE;
exit_with_error:
D3DAppICallDeviceDestroyCallback();
RELEASE(d3dappi.lpD3DDevice);
RELEASE(d3dappi.lpZBuffer);
RELEASE(lpPalette);
RELEASE(lpClipper);
RELEASE(d3dappi.lpBackBuffer);
RELEASE(d3dappi.lpFrontBuffer);
if (!b) {
D3DAppIRestoreDispMode();
D3DAppISetCoopLevel(d3dappi.hwnd, FALSE);
}
return FALSE;
}
/*
* D3DAppWindow
*/
BOOL
D3DAppWindow(int w, int h)
{
BOOL b; /* changing from a fullscreen mode? */
if (!d3dappi.bIsPrimary) {
D3DAppISetErrorString("It is not possible to create a D3D window with a hardware DirectDraw device. Check the bIsPrimary flag before calling D3DAppWindow.");
return FALSE;
}
b = d3dappi.bFullscreen;
/*
* If asked to set the window size, return it to the last value or use
* a default value.
*/
if (w == D3DAPP_YOUDECIDE) {
w = b ? szLastClient.cx : D3DAPP_DEFAULTWINDOWDIM;
}
if (h == D3DAPP_YOUDECIDE) {
h = b ? szLastClient.cy : D3DAPP_DEFAULTWINDOWDIM;
}
/*
* Release everything
*/
d3dappi.bRenderingIsOK = FALSE;
ATTEMPT(D3DAppICallDeviceDestroyCallback());
if (b) {
ATTEMPT(D3DAppIClearBuffers());
}
D3DAppIReleaseAllTextures();
RELEASE(d3dappi.lpD3DDevice);
RELEASE(d3dappi.lpZBuffer);
RELEASE(lpPalette);
RELEASE(lpClipper);
RELEASE(d3dappi.lpBackBuffer);
RELEASE(d3dappi.lpFrontBuffer);
/*
* Restore the display mode if we were in a fullscreen mode
*/
if (b) {
D3DAppIRestoreDispMode();
}
/*
* Set the cooperative level and create front and back buffers
*/
D3DAppISetCoopLevel(d3dappi.hwnd, FALSE);
D3DAppISetClientSize(d3dappi.hwnd, w, h, b);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -