4

私はすでにhttps://gamedev.stackexchange.com/questions/50374/how-can-i-render-multiple-windows-with-directx-9-in-cでこの質問をしましたが、まだ受け取っていません答え。

DirectX 9 とスワップ チェーンを使用して複数のウィンドウをレンダリングしようとしていますが、2 つのウィンドウを作成しても、作成した最初のウィンドウしか表示されません。私の RendererDX9 ヘッダーは次のとおりです。

#include <d3d9.h>
#include <Windows.h>
#include <vector>

#include "RAT_Renderer.h"

namespace RAT_ENGINE
{
    class RAT_RendererDX9 : public RAT_Renderer
    {
    public:
        RAT_RendererDX9();
        ~RAT_RendererDX9();

        void Init(RAT_WindowManager* argWMan);
        void CleanUp();

        void ShowWin();


    private:
        LPDIRECT3D9           renderInterface; // Used to create the D3DDevice
        LPDIRECT3DDEVICE9     renderDevice;    // Our rendering device
        LPDIRECT3DSWAPCHAIN9* swapChain;       // Swapchain to make multi-window rendering possible
        WNDCLASSEX wc;

        std::vector<HWND> hwindows;

        void Render(int argI);
    };
}

そして、私の .cpp ファイルは次のとおりです。

#include "RAT_RendererDX9.h"


static LRESULT CALLBACK MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );


namespace RAT_ENGINE
{
    RAT_RendererDX9::RAT_RendererDX9() : renderInterface(NULL), renderDevice(NULL)
    {
    }

    RAT_RendererDX9::~RAT_RendererDX9()
    {
    }

    void RAT_RendererDX9::Init(RAT_WindowManager* argWMan)
    {   
        wMan = argWMan;
        // Register the window class
        WNDCLASSEX windowClass =
        {
            sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0, 0,
            GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
            "foo", NULL
        };

        wc = windowClass;

        RegisterClassEx( &wc );

        for (int i = 0; i< wMan->getWindows().size(); ++i)
        {
            HWND hWnd = CreateWindow( "foo", argWMan->getWindow(i)->getName().c_str(),
                                    WS_OVERLAPPEDWINDOW, argWMan->getWindow(i)->getX(), argWMan->getWindow(i)->getY(), 
                                    argWMan->getWindow(i)->getWidth(), argWMan->getWindow(i)->getHeight(),
                                    NULL, NULL, wc.hInstance, NULL );
            hwindows.push_back(hWnd);
        }

        // Create the D3D object, which is needed to create the D3DDevice.
        renderInterface = (LPDIRECT3D9)Direct3DCreate9( D3D_SDK_VERSION );

        // Set up the structure used to create the D3DDevice. Most parameters are
        // zeroed out. We set Windowed to TRUE, since we want to do D3D in a
        // window, and then set the SwapEffect to "discard", which is the most
        // efficient method of presenting the back buffer to the display.  And 
        // we request a back buffer format that matches the current desktop display 
        // format.
        D3DPRESENT_PARAMETERS deviceConfig;
        ZeroMemory( &deviceConfig, sizeof( deviceConfig ) );
        deviceConfig.Windowed = TRUE;
        deviceConfig.SwapEffect = D3DSWAPEFFECT_DISCARD;
        deviceConfig.BackBufferFormat = D3DFMT_UNKNOWN;
        deviceConfig.BackBufferHeight = 1024;
        deviceConfig.BackBufferWidth = 768;
        deviceConfig.EnableAutoDepthStencil = TRUE;
        deviceConfig.AutoDepthStencilFormat = D3DFMT_D16;

        // Create the Direct3D device. Here we are using the default adapter (most
        // systems only have one, unless they have multiple graphics hardware cards
        // installed) and requesting the HAL (which is saying we want the hardware
        // device rather than a software one). Software vertex processing is 
        // specified since we know it will work on all cards. On cards that support 
        // hardware vertex processing, though, we would see a big performance gain 
        // by specifying hardware vertex processing.
        renderInterface->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwindows[0],
                              D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                              &deviceConfig, &renderDevice );

        this->swapChain = new LPDIRECT3DSWAPCHAIN9[wMan->getWindows().size()];
        this->renderDevice->GetSwapChain(0, &swapChain[0]);

        for (int i = 0; i < wMan->getWindows().size(); ++i)
        {
            renderDevice->CreateAdditionalSwapChain(&deviceConfig, &swapChain[i]);  
        }

        renderDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); // Set cullmode to counterclockwise culling to save resources
        renderDevice->SetRenderState(D3DRS_AMBIENT, 0xffffffff);   // Turn on ambient lighting
        renderDevice->SetRenderState(D3DRS_ZENABLE, TRUE);         // Turn on the zbuffer
    }

    void RAT_RendererDX9::CleanUp()
    {
        renderDevice->Release();
        renderInterface->Release();
    }

    void RAT_RendererDX9::Render(int argI)
    {
        // Clear the backbuffer to a blue color
        renderDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );
        LPDIRECT3DSURFACE9 backBuffer = NULL;

        // Set draw target
        this->swapChain[argI]->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
        this->renderDevice->SetRenderTarget(0, backBuffer);

        // Begin the scene
        renderDevice->BeginScene();

        // End the scene
        renderDevice->EndScene();
        swapChain[argI]->Present(NULL, NULL, hwindows[argI], NULL, 0);
    }   

    void RAT_RendererDX9::ShowWin()
    {
        for (int i = 0; i < wMan->getWindows().size(); ++i)
        {
            ShowWindow( hwindows[i], SW_SHOWDEFAULT );
            UpdateWindow( hwindows[i] );

            // Enter the message loop
            MSG msg;
            while( GetMessage( &msg, NULL, 0, 0 ) )

            {
                if (PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
                {
                TranslateMessage( &msg );
                DispatchMessage( &msg );
                }
                else
                {
                    Render(i);
                }
            }
        }
    }
}

LRESULT CALLBACK MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            //CleanUp();
            PostQuitMessage( 0 );
            return 0;

        case WM_PAINT:
            //Render();
            ValidateRect( hWnd, NULL );
            return 0;
    }

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

複数のウィンドウを作成するサンプル関数を作成しました。

void RunSample1()
{
    //Create the window manager.
    RAT_ENGINE::RAT_WindowManager* wMan = new RAT_ENGINE::RAT_WindowManager();

    //Create the render manager.
    RAT_ENGINE::RAT_RenderManager* rMan = new RAT_ENGINE::RAT_RenderManager();

    //Create a window.
    //This is currently needed to initialize the render manager and create a renderer.
    wMan->CreateRATWindow("Sample 1 - 1", 10, 20, 640, 480);
    wMan->CreateRATWindow("Sample 1 - 2", 150, 100, 480, 640);

    //Initialize the render manager.
    rMan->Init(wMan);

    //Show the window.
    rMan->getRenderer()->ShowWin();
}

複数のウィンドウを機能させるにはどうすればよいですか?

4

1 に答える 1