1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
use crate::bindings::Windows::Win32::Graphics::{Direct3D11::*, Dxgi::*}; use crate::*; use windows::{Abi, Interface}; #[derive(Clone, PartialEq, Eq)] pub struct RenderTarget(pub(crate) ID2D1Bitmap1); impl Target for RenderTarget { fn bitmap(&self) -> &ID2D1Bitmap1 { &self.0 } fn size(&self) -> Size { unsafe { let size = self.0.GetSize(); Size::new(size.width, size.height) } } fn physical_size(&self) -> gecl::Size<u32> { unsafe { let size = self.0.GetPixelSize(); gecl::Size::new(size.width, size.height) } } } pub struct Direct3D11 { d2d1_factory: ID2D1Factory1, device_context: ID2D1DeviceContext, } impl Direct3D11 { pub fn new(d3d11_device: &impl windows::Interface) -> windows::Result<Self> { unsafe { let d3d11_device: ID3D11Device = d3d11_device.cast().expect("cannot cast to ID3D11Device"); let d2d1_factory: ID2D1Factory1 = { let mut p = None; D2D1CreateFactory( D2D1_FACTORY_TYPE_SINGLE_THREADED, &ID2D1Factory1::IID, &D2D1_FACTORY_OPTIONS { debugLevel: D2D1_DEBUG_LEVEL_ERROR, }, p.set_abi(), ) .map(|_| p.unwrap())? }; let dxgi_device: IDXGIDevice = d3d11_device.cast()?; let d2d1_device = { d2d1_factory.CreateDevice(&dxgi_device)? }; let device_context = { d2d1_device.CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE)? }; Ok(Self { d2d1_factory, device_context, }) } } } impl Backend for Direct3D11 { type RenderTarget = RenderTarget; #[inline] fn device_context(&self) -> &ID2D1DeviceContext { &self.device_context } #[inline] fn d2d1_factory(&self) -> &ID2D1Factory1 { &self.d2d1_factory } fn back_buffers( &self, swap_chain: &IDXGISwapChain1, ) -> windows::Result<Vec<Self::RenderTarget>> { unsafe { let desc = { swap_chain.GetDesc1()? }; let surface: IDXGISurface = swap_chain.GetBuffer(0)?; let bitmap = { self.device_context.CreateBitmapFromDxgiSurface( &surface, &D2D1_BITMAP_PROPERTIES1 { pixelFormat: D2D1_PIXEL_FORMAT { format: desc.Format, alphaMode: D2D1_ALPHA_MODE_IGNORE, }, bitmapOptions: D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, dpiX: 96.0, dpiY: 96.0, ..Default::default() }, )? }; Ok(vec![RenderTarget(bitmap)]) } } fn render_target( &self, target: &impl windows::Interface, ) -> windows::Result<Self::RenderTarget> { let texture: ID3D11Texture2D = target.cast().expect("cannot cast to ID3D11Texture2D"); let desc = unsafe { let mut desc = D3D11_TEXTURE2D_DESC::default(); texture.GetDesc(&mut desc); desc }; if cfg!(debug_assertions) { assert!((desc.BindFlags & D3D11_BIND_RENDER_TARGET) == D3D11_BIND_RENDER_TARGET); } let surface: IDXGISurface = target.cast()?; let bitmap = unsafe { self.device_context.CreateBitmapFromDxgiSurface( &surface, &D2D1_BITMAP_PROPERTIES1 { pixelFormat: D2D1_PIXEL_FORMAT { format: desc.Format, alphaMode: D2D1_ALPHA_MODE_PREMULTIPLIED, }, bitmapOptions: D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, ..Default::default() }, )? }; Ok(RenderTarget(bitmap)) } fn begin_draw(&self, _target: &RenderTarget) {} fn end_draw(&self, _target: &RenderTarget) {} }