D3D11 を使用して Windows Phone 8 でシーンを表示しようとしています。深度バッファーなしで動作するようになりました (主に Windows phone SDK サンプルを使用)。しかし、実際には、シーンを正しくレンダリングするために深度バッファーが必要です。Windows Phone Emulator (win32 ビルド) で深度バッファーを使用して動作するようにしましたが、任意の Windows Phone (ARM ビルド) でテストすると、何も表示されません (黒い画面)。
したがって、コンピューターのグラフィックカードが理解できるものをヒットする必要があります(完全にエミュレートされていないWindows Phoneエミュレーターの唯一の部分だと思います)が、実際の電話のグラフィックカードは取得できません。
わからないことがあれば教えてください。これが私のコードです:
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_9_3
};
// Create the Direct3D 11 API device object and a corresponding context.
ComPtr<ID3D11Device> device;
ComPtr<ID3D11DeviceContext> context;
ThrowIfFailed(
D3D11CreateDevice(
nullptr, // Specify nullptr to use the default adapter.
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
creationFlags, // Set set debug and Direct2D compatibility flags.
featureLevels, // List of feature levels this app can support.
ARRAYSIZE(featureLevels),
D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION.
&device, // Returns the Direct3D device created.
&m_featureLevel, // Returns feature level of device created.
&context // Returns the device immediate context.
)
);
// Get the Direct3D 11.1 API device and context interfaces.
ThrowIfFailed(
device.As(&m_d3dDevice)
);
ThrowIfFailed(
context.As(&m_d3dContext)
);
深度バッファについては、次のようになります。
CD3D11_TEXTURE2D_DESC renderTargetDesc(
DXGI_FORMAT_B8G8R8A8_UNORM,
static_cast<UINT>(m_renderTargetSize.Width),
static_cast<UINT>(m_renderTargetSize.Height),
1,
1,
D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE
);
renderTargetDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
// Allocate a 2-D surface as the render target buffer.
ThrowIfFailed(
m_d3dDevice->CreateTexture2D(
&renderTargetDesc,
nullptr,
&m_renderTarget
)
);
ThrowIfFailed(
m_d3dDevice->CreateRenderTargetView(
m_renderTarget.Get(),
nullptr,
&m_renderTargetView
)
);
// Create a depth stencil view.
CD3D11_TEXTURE2D_DESC depthBufferDesc(
DXGI_FORMAT_D24_UNORM_S8_UINT,
static_cast<UINT>(m_renderTargetSize.Width),
static_cast<UINT>(m_renderTargetSize.Height),
1,
1,
D3D11_BIND_DEPTH_STENCIL); //tried with D3D11_BIND_RENDER_TARGET with a format DXGI_FORMAT_R24G8_TYPELESS in didn't change anything
ThrowIfFailed(
m_d3dDevice->CreateTexture2D(
&depthBufferDesc,
nullptr,
&m_depthStencilBuffer
)
);
D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
// Set up the description of the stencil state.
depthStencilDesc.DepthEnable = true;
depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
depthStencilDesc.StencilEnable = true;
depthStencilDesc.StencilReadMask = 0xFF;
depthStencilDesc.StencilWriteMask = 0xFF;
// Stencil operations if pixel is front-facing.
depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
// Stencil operations if pixel is back-facing.
depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
ThrowIfFailed(
m_d3dDevice->CreateDepthStencilState(
&depthStencilDesc,
&m_depthStencilState
)
);
m_d3dContext->OMSetDepthStencilState(m_depthStencilState.Get(), 1);
CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(
D3D11_DSV_DIMENSION_TEXTURE2D, DXGI_FORMAT_D24_UNORM_S8_UINT, 0);
ThrowIfFailed(
m_d3dDevice->CreateDepthStencilView(
m_depthStencilBuffer.Get(),
&depthStencilViewDesc,
&m_depthStencilView
)
);
m_d3dContext->OMSetRenderTargets(1, m_renderTargetView.GetAddressOf(), m_depthStencilView.Get());
CD3D11_VIEWPORT viewport(
0.0f,
0.0f,
m_renderTargetSize.Width,
m_renderTargetSize.Height
);
m_d3dContext->RSSetViewports(1, &viewport);
最後に、描画の直前に:
const float midnightBlue[] = { 245.0f/255.0f, 241.0/255.0f, 196.0f/255.0f, 1.000f };
m_d3dContext->ClearRenderTargetView(
m_renderTargetView.Get(),
midnightBlue
);
m_d3dContext->ClearDepthStencilView(
m_depthStencilView.Get(),
D3D11_CLEAR_DEPTH,
1.0f,
0
);
m_d3dContext->OMSetRenderTargets(1, m_renderTargetView.GetAddressOf(), m_depthStencilView.Get()); //This only works in the Emulator.
//m_d3dContext->OMSetRenderTargets(1, m_renderTargetView.GetAddressOf(), nullptr); This works fine but doesn't use the Depth buffer, so the scene is not very good.