如何使用与显示器不同的分辨率渲染全屏帧?

时间:2013-09-19 21:34:46

标签: c++ directx direct3d directx-9 direct3d9

我正在浏览http://directxtutorial.com/上的所有教程时自学DirectX开发。我遇到了一个问题,我认为这与我有多台显示器有关。

我的显示器是1920 x 1080.当我的代码以当前状态运行时,我的主显示器变为黑色,光标位于中间。当我将我的代码顶部的SCREEN定义设置为1920 x 1080时,我的程序运行正常并显示我的精灵与海军背景。当我离开SCREEN定义为1440 x 900并禁用我的第二台显示器时,我的程序运行正常。这就是让我相信我的第二台显示器出现问题的原因。

任何帮助将不胜感激!

以下是我目前的代码:

    // include the basic windows header files and the Direct3D header file
    #include <windows.h>
    #include <windowsx.h>
    #include <d3d9.h>
    #include <d3dx9.h>

    // define the screen resolution and keyboard macros
    #define SCREEN_WIDTH  1440
    #define SCREEN_HEIGHT 900
    #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
    #define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

    // include the Direct3D Library file
    #pragma comment (lib, "d3d9.lib")
    #pragma comment (lib, "d3dx9.lib")

    // global declarations
    LPDIRECT3D9 d3d;    // the pointer to our Direct3D interface
    LPDIRECT3DDEVICE9 d3ddev;    // the pointer to the device class
    LPD3DXSPRITE d3dspt;    // the pointer to our Direct3D Sprite interface
    BOOL stimToggle = TRUE;

    // sprite declarations
    LPDIRECT3DTEXTURE9 sprite;    // the pointer to the sprite

    // function prototypes
    void initD3D(HWND hWnd); // sets up and initializes Direct3D
    void render_frame(void); // renders a single frame
    void cleanD3D(void); // closes Direct3D and releases memory
    void init_input(HWND hWnd);

    // the WindowProc function prototype
    LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);


    // the entry point for any Windows program
    int WINAPI WinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPSTR lpCmdLine,
                       int nCmdShow)
    {
        HWND hWnd;
        WNDCLASSEX wc;

        ZeroMemory(&wc, sizeof(WNDCLASSEX));

        wc.cbSize = sizeof(WNDCLASSEX);
        wc.style = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc = (WNDPROC)WindowProc;
        wc.hInstance = hInstance;
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
        wc.lpszClassName = L"WindowClass1";

        RegisterClassEx(&wc);

        hWnd = CreateWindowEx(NULL,
                              L"WindowClass1",
                              L"Our Direct3D Program",
                              WS_EX_TOPMOST | WS_POPUP,
                              0, 0,
                              SCREEN_WIDTH, SCREEN_HEIGHT,
                              NULL,
                              NULL,
                              hInstance,
                              NULL);

        ShowWindow(hWnd, nCmdShow);

        // set up and initialize Direct3D
        initD3D(hWnd);
        init_input(hWnd);

        // enter the main loop:

        MSG msg;

        while(TRUE)
        {
            //DWORD starting_point = GetTickCount();

            if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
                if (msg.message == WM_QUIT)
                    break;

                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }

            render_frame();

            // check the 'escape' key
            if(KEY_DOWN(VK_ESCAPE))
                PostMessage(hWnd, WM_DESTROY, 0, 0);

            //while ((GetTickCount() - starting_point) < 25);
        }

        // clean up DirectX and COM
        cleanD3D();

        return msg.wParam;
    }


    // this is the main message handler for the program
    LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch(message)
        {
            case WM_DESTROY:
                {
                    PostQuitMessage(0);
                    return 0;
                } break;
            case WM_INPUT:
                {
                    RAWINPUT InputData;

                    UINT DataSize = sizeof(RAWINPUT);
                    GetRawInputData((HRAWINPUT)lParam,
                                    RID_INPUT,
                                    &InputData,
                                    &DataSize,
                                    sizeof(RAWINPUTHEADER));

                    // set the mouse button status
                    if(InputData.data.mouse.usButtonFlags == RI_MOUSE_LEFT_BUTTON_DOWN)
                        stimToggle = FALSE;
                    if(InputData.data.mouse.usButtonFlags == RI_MOUSE_LEFT_BUTTON_UP)
                        stimToggle = TRUE;

                    return 0;
                } break;
        }

        return DefWindowProc (hWnd, message, wParam, lParam);
    }


    // this function initializes and prepares Direct3D for use
    void initD3D(HWND hWnd)
    {
        d3d = Direct3DCreate9(D3D_SDK_VERSION);

        D3DPRESENT_PARAMETERS d3dpp;

        ZeroMemory(&d3dpp, sizeof(d3dpp));
        d3dpp.Windowed = FALSE;
        d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
        d3dpp.hDeviceWindow = hWnd;
        d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
        d3dpp.BackBufferWidth = SCREEN_WIDTH;
        d3dpp.BackBufferHeight = SCREEN_HEIGHT;
        d3dpp.BackBufferCount = 1;
        d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
        d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
        d3dpp.EnableAutoDepthStencil = FALSE;

        // create a device class using this information and the info from the d3dpp stuct
        d3d->CreateDevice(D3DADAPTER_DEFAULT,
                          D3DDEVTYPE_HAL,
                          hWnd,
                          D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                          &d3dpp,
                          &d3ddev);


        D3DXCreateSprite(d3ddev, &d3dspt);    // create the Direct3D Sprite object

        D3DXCreateTextureFromFileEx(d3ddev,    // the device pointer
                                    L"ast_sprite.png",    // the new file name
                                    D3DX_DEFAULT,    // default width
                                    D3DX_DEFAULT,    // default height
                                    D3DX_DEFAULT,    // no mip mapping
                                    NULL,    // regular usage
                                    D3DFMT_A8R8G8B8,    // 32-bit pixels with alpha
                                    D3DPOOL_MANAGED,    // typical memory handling
                                    D3DX_DEFAULT,    // no filtering
                                    D3DX_DEFAULT,    // no mip filtering
                                    D3DCOLOR_XRGB(0, 0, 128),    // the hot-pink color key
                                    NULL,    // no image info struct
                                    NULL,    // not using 256 colors
                                    &sprite);    // load to sprite

        return;
    }


    // this is the function used to render a single frame
    void render_frame(void)
    {
        // clear the window to a deep blue
        d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 128), 1.0f, 0);

        if(stimToggle)
        {
            d3ddev->BeginScene();    // begins the 3D scene
            d3dspt->Begin(D3DXSPRITE_ALPHABLEND);    // begin sprite drawing

            D3DSURFACE_DESC surfaceDesc;
            sprite->GetLevelDesc(NULL, &surfaceDesc); 

            // draw the sprite
            D3DXVECTOR3 center(surfaceDesc.Width / 2.0f, surfaceDesc.Height / 2.0f, 0.0f);    // center at the upper-left corner
            D3DXVECTOR3 position(SCREEN_WIDTH / 2.0f, SCREEN_HEIGHT / 2.0f, 0.0f);    // position at 50, 50 with no depth
            d3dspt->Draw(sprite, NULL, &center, &position, D3DCOLOR_XRGB(255, 255, 255));

            d3dspt->End();    // end sprite drawing
            d3ddev->EndScene();    // ends the 3D scene
        }

        d3ddev->Present(NULL, NULL, NULL, NULL);

        return;
    }

    // this is the function that initializes the Raw Input API
    void init_input(HWND hWnd)
    {
        RAWINPUTDEVICE Mouse;
        Mouse.usUsage = 0x02;    // register mouse
        Mouse.usUsagePage = 0x01;    // top-level mouse
        Mouse.dwFlags = NULL;    // flags
        Mouse.hwndTarget = hWnd;    // handle to a window

        RegisterRawInputDevices(&Mouse, 1, sizeof(RAWINPUTDEVICE));    // register the device
    }

    // this is the function that cleans up Direct3D and COM
    void cleanD3D(void)
    {
        sprite->Release();
        d3ddev->Release();
        d3d->Release();

        return;
    }

编辑: 这是我的输出窗口中的调试信息。

Direct3D9: (INFO) :======================= Hal SWVP device selected

Direct3D9: (INFO) :HalDevice Driver Style b

Direct3D9: :Subclassing window 00680b0a
Direct3D9: :StartExclusiveMode
Direct3D9: :WM_DISPLAYCHANGE: 1440x900x32
Direct3D9: (ERROR) :Lost due to display uniqueness change
Prototype.exe has triggered a breakpoint.

这是触发断点的地方。单击“继续”时,将显示以下其余部分。

Direct3D9: (INFO) :Using FF to PS converter

Direct3D9: (INFO) :Enabling multi-processor optimizations
Direct3D9: (INFO) :DDI threading started

Direct3D9: (INFO) :Using FF to VS converter in software vertex processing

Direct3D9: (ERROR) :************************************************************
Direct3D9: (ERROR) :ASSERTION FAILED! File s:\gfx_aug09\windows\directx\dxg\inactive\d3d9\d3d\fw\lhbatchfilter.cpp Line 3466: pArgs->Flags.Discard
Direct3D9: (ERROR) :************************************************************
Direct3D9: (ERROR) :************************************************************
Direct3D9: (ERROR) :ASSERTION FAILED! File s:\gfx_aug09\windows\directx\dxg\inactive\d3d9\d3d\fw\lhbatchfilter.cpp Line 3466: pArgs->Flags.Discard
Direct3D9: (ERROR) :************************************************************
Direct3D9: (ERROR) :************************************************************
Direct3D9: (ERROR) :ASSERTION FAILED! File s:\gfx_aug09\windows\directx\dxg\inactive\d3d9\d3d\fw\lhbatchfilter.cpp Line 3466: pArgs->Flags.Discard
Direct3D9: (ERROR) :************************************************************
D3D9 Helper: Warning: Default value for D3DRS_POINTSIZE_MAX is 2.19902e+012f, not 4.16345e-316f.  This is ok.
Direct3D9: :WM_ACTIVATEAPP: BEGIN Activating app pid=00003c58, tid=00005888
Direct3D9: :*** Active state changing
Direct3D9: :WM_ACTIVATEAPP: DONE Activating app pid=00003c58, tid=00005888
Direct3D9: :WM_ACTIVATEAPP: BEGIN Activating app pid=00003c58, tid=00005888
Direct3D9: :*** Already activated
Direct3D9: :WM_ACTIVATEAPP: DONE Activating app pid=00003c58, tid=00005888
Direct3D9: :WM_ACTIVATEAPP: BEGIN Activating app pid=00003c58, tid=00005888
Direct3D9: :*** Already activated
Direct3D9: :WM_ACTIVATEAPP: DONE Activating app pid=00003c58, tid=00005888

1 个答案:

答案 0 :(得分:1)

  1. 确定哪个监视器是主监视器,默认情况下,DirectX将输出到主监视器。

  2. 确保您设置的分辨率可用于要渲染的显示器。如果使用不支持的分辨率,则在创建设备时DirectX将失败。

  3. [编辑],如果您不想对屏幕分辨率进行硬编码,请使用以下代码。

        // Get max display resolution and set it as back buffer size
    
        D3DDISPLAYMODE displayMode ;
        d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode) ;
    
        int width = displayMode.Width;
        int height = displayMode.Height;
    
        d3dpp.BackBufferWidth = width;
        d3dpp.BackBufferHeight = height;
    
    1. 启用调试模式,因为您使用的是DirectX 9.0,这可以通过使用DirectX控制面板完成,它是C:\ Program Files \ Microsoft DirectX SDK(2010年6月)\ Utilities \ bin \ x86 \ dxcpl。 exe,如果您在另一个位置安装DirectX SDK,这可能会有所不同。启用调试模式后,您将在输出窗口中获得大量有用的信息,这将有助于您解决大多数问题。
    2. enter image description here