std::shared_ptr<DepthStencilStateProvider> D3DGraphicContextProvider::create_depth_stencil_state(const DepthStencilStateDescription &desc) { std::map<DepthStencilStateDescription, std::shared_ptr<DepthStencilStateProvider> >::iterator it = depth_stencil_states.find(desc); if (it != depth_stencil_states.end()) { return it->second; } else { std::shared_ptr<DepthStencilStateProvider> state(new D3DDepthStencilStateProvider(window->get_device(), desc)); depth_stencil_states[desc.clone()] = state; return state; } }
std::shared_ptr<DepthStencilStateProvider> GL1GraphicContextProvider::create_depth_stencil_state(const DepthStencilStateDescription &desc) { auto it = depth_stencil_states.find(desc); if (it != depth_stencil_states.end()) { return it->second; } else { std::shared_ptr<DepthStencilStateProvider> state(new OpenGLDepthStencilStateProvider(desc)); depth_stencil_states[desc.clone()] = state; return state; } }
D3DDepthStencilStateProvider::D3DDepthStencilStateProvider(const ComPtr<ID3D11Device> &device, const DepthStencilStateDescription &desc) { CompareFunction front, back; int front_ref, front_mask, back_ref, back_mask; desc.get_stencil_compare_front(front, front_ref, front_mask); desc.get_stencil_compare_back(back, back_ref, back_mask); unsigned char front_write_mask, back_write_mask; desc.get_stencil_write_mask(front_write_mask, back_write_mask); StencilOp fail_front, pass_depth_fail_front, pass_depth_pass_front; StencilOp fail_back, pass_depth_fail_back, pass_depth_pass_back; desc.get_stencil_op_front(fail_front, pass_depth_fail_front, pass_depth_pass_front); desc.get_stencil_op_back(fail_back, pass_depth_fail_back, pass_depth_pass_back); D3D11_DEPTH_STENCIL_DESC d3d_desc; d3d_desc.DepthEnable = desc.is_depth_test_enabled() ? TRUE : FALSE; d3d_desc.DepthWriteMask = desc.is_depth_write_enabled() ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; d3d_desc.DepthFunc = to_d3d_compare_func(desc.get_depth_compare_function()); d3d_desc.StencilEnable = desc.is_stencil_test_enabled(); d3d_desc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; // To do: should this use the write masks instead? d3d_desc.StencilWriteMask = front_write_mask | back_write_mask; d3d_desc.FrontFace.StencilFunc = to_d3d_compare_func(front); d3d_desc.FrontFace.StencilDepthFailOp = to_d3d_stencil_op(pass_depth_fail_front); d3d_desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; d3d_desc.FrontFace.StencilFailOp = to_d3d_stencil_op(fail_front); d3d_desc.BackFace.StencilFunc = to_d3d_compare_func(back); d3d_desc.BackFace.StencilDepthFailOp = to_d3d_stencil_op(pass_depth_fail_back); d3d_desc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; d3d_desc.BackFace.StencilFailOp = to_d3d_stencil_op(fail_back); HRESULT result = device->CreateDepthStencilState(&d3d_desc, state.output_variable()); D3DTarget::throw_if_failed("D3D11Device.CreateDepthStencilState failed", result); // "The formats that support stenciling are DXGI_FORMAT_D24_UNORM_S8_UINT and DXGI_FORMAT_D32_FLOAT_S8X24_UINT." }