如何以与显示器不同的分辨率渲染全屏框架? [英] How do I render a fullscreen frame with a different resolution than my display?

查看:110
本文介绍了如何以与显示器不同的分辨率渲染全屏框架?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am in the process of teaching myself DirectX development while going through all the tutorials on http://directxtutorial.com/. I have run into a problem that I believe is related to me having multiple monitors.

我的显示器为1920 x1080.当我的代码在其当前状态下运行时,我的主监视器变为黑色,光标位于中间.当我将代码顶部的SCREEN定义设置为1920 x 1080时,我的程序可以正常运行,并显示带有海军背景的sprite.当我离开屏幕时,将其定义为1440 x 900,并禁用第二台监视器,我的程序运行正常.这就是让我相信我的第二台显示器整理东西时会出现问题的原因.

My display is 1920 x 1080. When my code runs in its current state my primary monitor becomes black with the cursor in the middle. When I set my SCREEN defines at the top of my code to 1920 x 1080 my program runs fine and displays my sprite with the navy background. When I leave the SCREEN defines as 1440 x 900 and disable my second monitor my program runs fine. This is what leads me to believe there is some issue with my second monitor hosing up things.

任何帮助将不胜感激!

下面是我当前的代码:

    // 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;
    }

这是我在输出"窗口中的调试信息.

Here is my debug information from my Output window.

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.

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

This is where it triggers the breakpoint. When I click continue, the rest of the below is displayed.

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. 确定哪个监视器是主监视器,默认情况下,DirectX将输出到主监视器.

  1. Identify which monitor is primary monitor, by default, DirectX will output to the primary monitor.

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

Make sure the resolution you set is available for the monitor you are rendering to. if you use an unsupported resolution, DirectX will failed when creating device.

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

, use the following code if you don't want to hard-code the screen resolution.

    // 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,则可能会有所不同.启用调试模式后,您将在输出窗口中获得很多有用的信息,这些信息将帮助您解决大多数问题.

这篇关于如何以与显示器不同的分辨率渲染全屏框架?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆