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

📄 d3dapp.c

📁 国外游戏开发者杂志1997年第九期配套代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 *  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 + -