int Engine::Init(wxWindow* handle, bool windowed)
{
m_WindowHandle = handle;
wxRect rc = handle->GetClientRect();
int width = rc.width;
int height = rc.height;
//Set up DX swapchain
DXGI_SWAP_CHAIN_DESC swapChainDesc;
memset(&swapChainDesc, 0, sizeof(swapChainDesc));
swapChainDesc.BufferCount = 2;
swapChainDesc.BufferDesc.Width = width;
swapChainDesc.BufferDesc.Height = height;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
//refresh rate
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
//sampling setting
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.SampleDesc.Count = 1;
//target window
HWND hWnd = (HWND) handle->GetHandle();
swapChainDesc.OutputWindow = hWnd;
swapChainDesc.Windowed = windowed;
//Create D3D device
if (FAILED(D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &swapChainDesc, &m_SwapChain, &m_D3DDevice)))
return false;
//Rasterizer Stage Setup
m_Viewport.Width = width;
m_Viewport.Height = height;
m_Viewport.MinDepth = 0.0f;
m_Viewport.MaxDepth = 1.0f;
m_Viewport.TopLeftX = 0;
m_Viewport.TopLeftY = 0;
m_D3DDevice->RSSetViewports(1, &m_Viewport);
D3D10_RASTERIZER_DESC rasterState;
rasterState.CullMode = D3D10_CULL_NONE;
rasterState.FillMode = D3D10_FILL_SOLID;
rasterState.FrontCounterClockwise = true;
rasterState.DepthBias = false;
rasterState.DepthBiasClamp = 0;
rasterState.SlopeScaledDepthBias = 0;
rasterState.DepthClipEnable = true;
rasterState.ScissorEnable = false;
rasterState.MultisampleEnable = false;
rasterState.AntialiasedLineEnable = true;
m_D3DDevice->CreateRasterizerState(&rasterState, &m_RasterizerState);
m_D3DDevice->RSSetState(m_RasterizerState);
//OM Stage
ID3D10Texture2D* backBuffer;
if (FAILED(m_SwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*) &backBuffer)))
return false;
if (FAILED(m_D3DDevice->CreateRenderTargetView(backBuffer, NULL, &m_RenderTargetView)))
return false;
m_D3DDevice->OMSetRenderTargets(1, &m_RenderTargetView, NULL);
//Setup the view and projection matrices
D3DXVECTOR3 camera[3] = { D3DXVECTOR3(0, 0, -5),
D3DXVECTOR3(0, 0, 1),
D3DXVECTOR3(0, 1, 0) };
D3DXMatrixLookAtLH(&m_ViewMatrix, &camera[0], &camera[1], &camera[2]);
D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, (float)D3DX_PI * 0.5f, (float)width/(float)height, 0.1f, 1000.f);
return true;
}
上面的代碼中,核心是窗口句柄的取得,其他對DirectX10的初始化來說,都是一樣的。也就是,DirectX10只知道窗口句柄,知道窗口句柄後,就能得到窗口的DC,得到窗口的DC後,窗口的內容佔有的視屏位置也就知道了。
類似上面的代碼初始化後,我們用wxWidgets的窗口的話,還需要重載這個窗口類的OnPaint()
void wxDXView::OnPaint(wxPaintEvent& evt)
{
m_Engine->Clear();
}
m_Engine的Clear代碼如下:
void Engine::Clear()
{
float color[4] = { 0, 0.5, 1, 1};
m_D3DDevice->ClearRenderTargetView(m_RenderTargetView, color);
m_SwapChain->Present(0, 0);
}
這樣的話,隨着clear被調用,我們的窗口就被繪製成了需要的顏色。就可以看到DX的輸出了。後續的場景繪製,都放在OnPaint()中,Clear()後,注意的是,Engine->Clear()中的m_SwapChain->Present()需要放到別的位置。