Reputation: 2428
I've already asked this question at https://gamedev.stackexchange.com/questions/50374/how-can-i-render-multiple-windows-with-directx-9-in-c but I have not yet received an answer.
I'm trying to render multiple windows, using DirectX 9 and swap chains, but even though I create 2 windows, I only see the first one that I've created. My RendererDX9 header is this:
#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);
};
}
And my .cpp file is this:
#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 );
}
I've made a sample function to make multiple windows:
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();
}
How do I get the multiple windows to work?
Upvotes: 4
Views: 4152
Reputation: 9611
The "Swap Chain" approach you used for rendering the multiple windows is sounds good compare to creating multiple devices for multiple screens.
Have you checked the codesampler tutorial for rendering the multiple windows using swap chain. If not, pls find the below link which has a working sample project for rendering the multiple windows using swap chain. This code is purely windows Directx 9 specific but you could added your wrapper to achieve platform agnostic.
Creating Multiple Devices
Using Swap Chain
http://www.codesampler.com/dx9src/dx9src_1.htm
Upvotes: 5