3
我已经在https://gamedev.stackexchange.com/questions/50374/how-can-i-render-multiple-windows-with-directx-9-in-c提问了这个问题,但我还没有收到答案。如何在C中使用DirectX 9渲染多个窗口?
我试图渲染多个窗口,使用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();
}
我如何让多个窗口工作?
第一个结果在谷歌:http://www.mvps.org/directx/articles/rendering_to_multiple_windows。 htm,这是DX8,但DX9非常好。 – 2013-03-05 08:34:22
该链接显示的代码看起来与我的代码基本相似,但是窗口(它们也是单独的)有一个HWND句柄。由于我想让引擎尽可能平台中立,因此我决定将HWND窗口放在渲染器中,并根据我的RAT_Window输入重新创建它们。我认为我已经适应了渲染器,足以让它工作,但显然并非如此。 我想知道的是为什么它不起作用,以及如何解决这个问题,而不必将DX9/Windows特定代码放入我的RAT_Window类中。 – Friso 2013-03-06 00:52:03
请定义“平台中性”。我很困惑。 – 2013-03-06 06:33:48