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

📄 d3dmain.cpp

📁 国外游戏开发者杂志1997年第九期配套代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/**************************************************************************

Mixed Rendering

 **************************************************************************/
/***************************************************************
*
*       This program has been developed by Intel Corporation.  
*		You have Intel's permission to incorporate this code 
*       into your product, royalty free.  Intel has various 
*	    intellectual property rights which it may assert under
*       certain circumstances, such as if another manufacturer's
*       processor mis-identifies itself as being "GenuineIntel"
*		when the CPUID instruction is executed.
*
*       Intel specifically disclaims all warranties, express or
*       implied, and all liability, including consequential and
*		other indirect damages, for the use of this code, 
*		including liability for infringement of any proprietary
*		rights, and including the warranties of merchantability
*		and fitness for a particular purpose.  Intel does not 
*		assume any responsibility for any errors which may 
*		appear in this code nor any responsibility to update it.
*
*  * Other brands and names are the property of their respective
*    owners.
*
*  Copyright (c) 1995, Intel Corporation.  All rights reserved.
***************************************************************/

/*
 *  Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
 *
 *  File: d3dmain.cpp
 *
 *  Each of the Direct3D samples must be linked with this file.  It contains
 *  the code which allows them to run in the Windows environment.
 *
 *  A window is created using d3dmain.res which allows the user to select the
 *  Direct3D driver to use and change the render options.  The D3DApp
 *  collection of functions is used to initialize DirectDraw, Direct3D and
 *  keep surfaces and D3D devices available for rendering.
 *
 *  Frame rate and a screen mode information buffer is Blt'ed to the screen
 *  by functions in stats.cpp.
 *
 *  Each sample is executed through the functions: InitScene, InitView,
 *  RenderScene, ReleaseView, ReleaseScene and OverrideDefaults, as described
 *  in d3ddemo.h.  Samples can also read mouse and keyboard input via
 *  SetMouseCallback and SetKeyboardCallback.
 */ 

#include "d3dmain.h"
#include "main.h"
#include "ddutil.h"
#include "d3dappi.h"
/*
 * GLOBAL VARIABLES
 */
 
// These surfaces are used as the destination for the SW rendering
LPDIRECTDRAW					  lpDD_SW                 = NULL;
HANDLE SW_Win;


int compositeMethod  =  TEXTUREMAP_COMPOSITE ;

// Texture generated from the SW buffer after each frame 
    
    LPDIRECT3DTEXTURE           lpActiveTexture = NULL;
	LPDIRECTDRAWSURFACE     lpDDTextureSurfaceSPOT  = NULL;
    LPDIRECT3DTEXTURE           lpSPOTTexture = NULL;
    D3DTEXTUREHANDLE            SPOTTextureHandle;

	LPDIRECTDRAWSURFACE  lpDDActiveSurfaceSystem  = NULL;
	LPDIRECTDRAWSURFACE  lpDDDevelopSurfaceSystem = NULL;
	LPDIRECTDRAWSURFACE  lpDDTempSurfaceSystem    = NULL;
	LPDIRECTDRAWSURFACE  lpDDSurfaceSystem        = NULL;
    
	LPDIRECTDRAWSURFACE  lpDDZBufferSystem        = NULL;


HANDLE eventHandle;
HANDLE compositeHandle;
HANDLE th;
DWORD dwThreadId;
int countHW=0, countSW=0;



D3DAppInfo* d3dapp;	    /* Pointer to read only collection of DD and D3D
			       objects maintained by D3DApp */
d3dmainglobals myglobs;	    /* collection of global variables */

BOOL(*MouseHandler)(UINT, WPARAM, LPARAM);    /* sample's function which traps
						 mouse input */
BOOL(*KeyboardHandler)(UINT, WPARAM, LPARAM); /* sample's functions which traps
                                                 keyboard input */

/*
 *  INTERNAL FUNCTION PROTOTYPES
 */
static BOOL AppInit(HINSTANCE hInstance, LPSTR lpCmdLine);
static BOOL CreateD3DApp(LPSTR lpCmdLine);
static BOOL BeforeDeviceDestroyed(LPVOID lpContext);
static BOOL AfterDeviceCreated(int w, int h, LPDIRECT3DVIEWPORT* lpViewport,
			       LPVOID lpContext);
void CleanUpAndPostQuit(void);
static void InitGlobals(void);
static BOOL AppPause(BOOL f);
void ReportD3DAppError(void);
static BOOL RenderLoop(void);
static BOOL RestoreSurfaces();
long FAR PASCAL WindowProc(HWND hWnd, UINT message, WPARAM wParam,
			   LPARAM lParam );

/****************************************************************************/
/*                            WinMain                                       */
/****************************************************************************/
/*
 * Initializes the application then enters a message loop which calls sample's
 * RenderScene until a quit message is received.
 */
int PASCAL
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
	int nCmdShow)
{
    int failcount = 0; /* number of times RenderLoop has failed */
    MSG	msg;
    HACCEL hAccelApp;

    hPrevInstance;
    /*
     * Create the window and initialize all objects needed to begin rendering
     */
    if(!AppInit(hInstance, lpCmdLine))
    	return FALSE;
    hAccelApp = LoadAccelerators(hInstance, "AppAccel");    

    while (!myglobs.bQuit) {
	/* 
	 * Monitor the message queue until there are no pressing
	 * messages
	 */
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
            if (msg.message == WM_QUIT) {
		CleanUpAndPostQuit();
                break;
	    }
            if (!myglobs.hWndMain || !TranslateAccelerator(myglobs.hWndMain,
							   hAccelApp, &msg)) {
                TranslateMessage(&msg); 
                DispatchMessage(&msg);
            }
	/* 
	 * If the app is not minimized, not about to quit, not paused, either the
	 * active fullscreen app or in a window and D3D has been initialized,
	 * we can render
	 */
        } else if (d3dapp->bRenderingIsOK && !d3dapp->bMinimized 
		   && !d3dapp->bPaused && !myglobs.bQuit
		   && (d3dapp->bAppActive || !d3dapp->bFullscreen)) {
	    /*
	     * If were are not in single step mode or if we are and the
	     * bDrawAFrame flag is set, render one frame
	     */
            if (!(myglobs.bSingleStepMode && !myglobs.bDrawAFrame)) {
		/* 
		 * Attempt to render a frame, if it fails, take a note.  If
		 * rendering fails more than twice, abort execution.
		 */
		if (!RenderLoop()) {
		    ++failcount;
		    if (failcount == 3) {
			Msg("Rendering has failed too many times.  Aborting execution.\n");
			CleanUpAndPostQuit();
			break;
		    }
		}
	    }
	    /*
	     * Reset the bDrawAFrame flag if we are in single step mode
	     */
            if (myglobs.bSingleStepMode)
                myglobs.bDrawAFrame = FALSE;
        } else {
            WaitMessage();
	}
    }

    DestroyWindow(myglobs.hWndMain);
    return msg.wParam;
}

/**********************************************************************************/
/* This is a separate thread and continues in an infinite loop until process is ready
/* to exit (and will be killed by the main thread .
/* For each frame the following operations are executed :
   1. Clean the Develop and the Z-buffer (using DDraw Blt() )
   2. render the SW scene to the develop buffer
   3. synchornize with the HW thread :
      a:  SIGNAL that SW is ready
	  b:  WAIT   for Composite event  (The HW actually only switched the buffers now)
	  c:  RESET  Composite event 
*/
/**********************************************************************************/
void DrawFrameSW(void)
{
  HRESULT ddrval;
  BOOL bResult;
  DDBLTFX ddbltfx;
 
 while (TRUE){
	
	// Erase the system memory buffer
	memset(&ddbltfx, 0, sizeof(ddbltfx));
    ddbltfx.dwSize = sizeof(DDBLTFX);
    ddbltfx.dwFillColor = 0;
    if(compositeMethod  ==  TEXTUREMAP_COMPOSITE )
	   ddrval = lpDDDevelopSurfaceSystem->Blt( NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
    else	// compositeMethod  == BLT_COMPOSITE
	   ddrval = lpDDSurfaceSystem->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
       if (ddrval != DD_OK)
       Msg("Clearing the SW Develop buffer failed.\0", ddrval);
    // Erase the associated Z-buffer
	memset(&ddbltfx, 0, sizeof(ddbltfx));
    ddbltfx.dwSize = sizeof(DDBLTFX);
    ddbltfx.dwFillDepth = 0x7fff;
    ddrval = lpDDZBufferSystem->Blt(NULL, NULL, NULL, DDBLT_DEPTHFILL | DDBLT_WAIT, &ddbltfx);
     if (ddrval != DD_OK)
       Msg("Clearing the SW Zbuffer failed.\0", ddrval);
    
		// Start to render the SW scene
	countSW++;

	// render the SW scene
    if(compositeMethod  ==  TEXTUREMAP_COMPOSITE )
	  bResult = RenderSWScene(lpDDDevelopSurfaceSystem );  
    else	// compositeMethod  == BLT_COMPOSITE
	  bResult = RenderSWScene(lpDDSurfaceSystem);  
    if (bResult == FALSE)
	   Msg("Call to Software Render  Scene failed.\0", 0);
     // SIGNAL that SW is ready
	 SetEvent(eventHandle); 
     // Suspend SW thread - until SW output is consumed into composite 
	 // the 'consuming' is dependent of the Blit method .
	 WaitForSingleObject(compositeHandle,1000);
	 ResetEvent(compositeHandle);

 };  // loop indefinitely

}

/****************************************************************************/
/*             D3DApp Initialization and callback functions                 */
/****************************************************************************/
/*
 * AppInit
 * Creates the window and initializes all objects necessary to begin rendering
 */
static BOOL
AppInit(HINSTANCE hInstance, LPSTR lpCmdLine)
{
    WNDCLASS wc;
    HMENU hmenu;
    int i;

    /*
     * Initialize the global variables
     */
    InitGlobals();
    myglobs.hInstApp = hInstance;
    myglobs.lpCmdLine = lpCmdLine;

    /*
     * Enumerate the DD drivers
     */
    if (!D3DAppEnumerateDDDevices(&myglobs.NumDDDrivers, &myglobs.DDDriver[0])) {
	ReportD3DAppError();
	return FALSE;
    }
    /*
     * Choose the last device enumerated which will probably be secondary 3d hardware.
     */
    myglobs.CurrDDDriver = myglobs.NumDDDrivers - 1;

    /*
     * Register the window class
     */
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon( hInstance, "AppIcon");
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wc.lpszMenuName = "AppMenu";
    wc.lpszClassName = "Example";
    if (!RegisterClass(&wc))
        return FALSE;
    /*
     * Create a window with some default settings that may change
     */
    myglobs.hWndMain = CreateWindowEx(
         WS_EX_APPWINDOW,
	 "Example",
	 "D3D Example",
	 WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
	 WS_THICKFRAME | WS_MINIMIZEBOX,
         CW_USEDEFAULT, CW_USEDEFAULT,
	 START_WIN_SIZE, START_WIN_SIZE,
         NULL,				    /* parent window */
	 NULL,				    /* menu handle */
	 hInstance,			    /* program handle */
	 NULL);				    /* create parms */	
    if (!myglobs.hWndMain){
    	Msg("CreateWindowEx failed");
    	return FALSE;
    }
    /*
     * Display the window
     */
    ShowWindow(myglobs.hWndMain, SW_SHOWNORMAL);
    UpdateWindow(myglobs.hWndMain);

#if 0
	// DEBUG - helps with fullscreen exclusive debugs!
	ShowWindow(myglobs.hWndMain, SW_HIDE);
#endif


#if 1   // I don't want users to be able to change drivers
    /*
     * Add the list of DD drivers D3DApp found to the file menu
     */
    for (i = 0; i < myglobs.NumDDDrivers; i++) {
        InsertMenu(hmenu,  6 + i, MF_BYPOSITION | MF_STRING,
		   MENU_FIRST_DDDRIVER + i, myglobs.DDDriver[i].Name);
    }
#endif
    /* 
     * Have the example initialize it components which remain constant
     * throughout execution
     */
    if (!InitScene())
        return FALSE;



    /*
     * Call D3DApp to initialize all DD and D3D objects necessary to render.
     * D3DApp will call the device creation callback which will initialize the
     * viewport and the sample's execute buffers.
     */
    if (!CreateD3DApp(lpCmdLine))
	return FALSE;

#if 0
	// DEBUG - helps with fullscreen exclusive debugs!
	ShowWindow(myglobs.hWndMain, SW_HIDE);
#endif

	// Initialize theSW stuff NOW
	{
    HRESULT ddrval;
	DDSURFACEDESC ddsd;
    char *error_str;

	ddrval = DirectDrawCreate(NULL, &lpDD_SW, NULL);
    if (ddrval != DD_OK)
    {
      error_str = D3DAppErrorToString(ddrval);
      Msg(error_str, ddrval);
      return(FALSE);
    }
   	// Set the cooperation level to normal for HEL
	// (second window is not necessary and part of the development legacy)
	
	ddrval = lpDD_SW->SetCooperativeLevel(NULL, DDSCL_NORMAL);
	if (ddrval != DD_OK)
	{
	  error_str = D3DAppErrorToString(ddrval);
      Msg(error_str, ddrval);
	  return(FALSE);
	}

#define sizeX	256
#define sizeY	256
	memset(&ddsd, 0, sizeof(DDSURFACEDESC));
    ddsd.dwSize  = sizeof(DDSURFACEDESC);
    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH ;
	ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY; 
    ddsd.dwWidth  = sizeX;
	ddsd.dwHeight = sizeY;
	 //active and develop buffers for the texture map composite method
	ddrval = lpDD_SW->CreateSurface(&ddsd,  &lpDDActiveSurfaceSystem, NULL);
    ddrval = lpDD_SW->CreateSurface(&ddsd,  &lpDDDevelopSurfaceSystem, NULL);
	// single system buf for blt coposite method
	ddrval = lpDD_SW->CreateSurface(&ddsd,  &lpDDSurfaceSystem, NULL);
    if (ddrval != DD_OK)
	{
        error_str = D3DAppErrorToString(ddrval);
        Msg(error_str, ddrval);
	  if (ddrval == DDERR_OUTOFMEMORY || ddrval == DDERR_OUTOFVIDEOMEMORY)
	  {
        Msg("Not enough memory to create the system surface (SW).\0", ddrval);
		return(FALSE);
      }
	  else
	  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -