代码改变世界

Programming 2D Games 读书笔记(第三章)

2013-09-21 12:31  Clingingboy  阅读(358)  评论(0编辑  收藏  举报

 

示例一:DirectX Window

Graphics类用于初始化Direct 3D

image

主流程:

仅需要粗体部分

    try{
        // Create Graphics object
        graphics = new Graphics;
        // Initialize Graphics, throws GameError
        graphics->initialize(hwnd, GAME_WIDTH, GAME_HEIGHT, FULLSCREEN);

        // main message loop
        int done = 0;
        while (!done)
        {
            // PeekMessage,non-blocking method for checking for Windows messages.
            if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
            {
                // look for quit message
                if (msg.message == WM_QUIT)
                    done = 1;

                // decode and pass messages on to WinProc
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            } else
                graphics->showBackbuffer();
        }
        SAFE_DELETE(graphics);  // free memory before exit
        return msg.wParam;
    }
    catch(const GameError &err)
    {
        MessageBox(NULL, err.getMessage(), "Error", MB_OK);
    }
  1. Direct3DCreate9创建IDirect3D9
  2. GetDeviceCaps测试是否支持硬件顶点支持
  3. initD3Dpp初始化D3DPRESENT_PARAMETERS参数
    //=============================================================================
    // Initialize D3D presentation parameters
    //=============================================================================
    void Graphics::initD3Dpp()
    {
        try{
            ZeroMemory(&d3dpp, sizeof(d3dpp));              // fill the structure with 0
            // fill in the parameters we need
            d3dpp.BackBufferWidth   = width;
            d3dpp.BackBufferHeight  = height;
            if(fullscreen)                                  // if fullscreen
                d3dpp.BackBufferFormat  = D3DFMT_X8R8G8B8;  // 24 bit color
            else
                d3dpp.BackBufferFormat  = D3DFMT_UNKNOWN;   // use desktop setting
            d3dpp.BackBufferCount   = 1;
            d3dpp.SwapEffect        = D3DSWAPEFFECT_DISCARD;
            d3dpp.hDeviceWindow     = hwnd;
            d3dpp.Windowed          = (!fullscreen);
            d3dpp.PresentationInterval   = D3DPRESENT_INTERVAL_IMMEDIATE;
        } catch(...)
        {
            throw(GameError(gameErrorNS::FATAL_ERROR, 
                    "Error initializing D3D presentation parameters"));
    
        }
    }
  4. CreateDevice
  5. showBackbuffer
    //=============================================================================
    // Display the backbuffer
    //=============================================================================
    HRESULT Graphics::showBackbuffer()
    {
        result = E_FAIL;    // default to fail, replace on success
        // (this function will be moved in later versions)
        // Clear the backbuffer to lime green 
        device3d->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,255,0), 0.0f, 0);
    
        // Display backbuffer to screen
        result = device3d->Present(NULL, NULL, NULL, NULL);
    
        return result;
    }
    

 

//=============================================================================
// Initialize DirectX graphics
// throws GameError on error
//=============================================================================
void Graphics::initialize(HWND hw, int w, int h, bool full)
{
    hwnd = hw;
    width = w;
    height = h;
    fullscreen = full;

    //initialize Direct3D
    direct3d = Direct3DCreate9(D3D_SDK_VERSION);
    if (direct3d == NULL)
        throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing Direct3D"));

    initD3Dpp();        // init D3D presentation parameters

    // determine if graphics card supports harware texturing and lighting and vertex shaders
    D3DCAPS9 caps;
    DWORD behavior;
    result = direct3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
    // If device doesn't support HW T&L or doesn't support 1.1 vertex 
    // shaders in hardware, then switch to software vertex processing.
    if( (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
            caps.VertexShaderVersion < D3DVS_VERSION(1,1) )
        behavior = D3DCREATE_SOFTWARE_VERTEXPROCESSING;  // use software only processing
    else
        behavior = D3DCREATE_HARDWARE_VERTEXPROCESSING;  // use hardware only processing

    //create Direct3D device
    result = direct3d->CreateDevice(
        D3DADAPTER_DEFAULT,
        D3DDEVTYPE_HAL,
        hwnd,
        behavior,
        &d3dpp, 
        &device3d);

    if (FAILED(result))
        throw(GameError(gameErrorNS::FATAL_ERROR, "Error creating Direct3D device"));
 
}

示例二:DirectX Full Screen

见initD3Dpp方法的Windowed属性

参考:http://www.cnblogs.com/Clingingboy/archive/2012/07/27/2611651.html

示例三:DirectX Device Capabilities

获取指定显卡支持的显示模式
全屏时检测

  1. GetAdapterModeCount:Returns the number of display modes available on this adapter.
  2. EnumAdapterModes:
  3. Queries the device to determine whether the specified adapter supports the requested format and display mode. This method could be used in a loop to enumerate all the available adapter modes.

bool Graphics::isAdapterCompatible()
{
    UINT modes = direct3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, 
                                            d3dpp.BackBufferFormat);
    for(UINT i=0; i<modes; i++)
    {
        result = direct3d->EnumAdapterModes( D3DADAPTER_DEFAULT, 
                                        d3dpp.BackBufferFormat,
                                        i, &pMode);
        if( pMode.Height == d3dpp.BackBufferHeight &&
            pMode.Width  == d3dpp.BackBufferWidth &&
            pMode.RefreshRate >= d3dpp.FullScreen_RefreshRateInHz)
            return true;
    }
    return false;
}