finetune transpanrency
This commit is contained in:
parent
b8314e74db
commit
602bd189f6
2 changed files with 15 additions and 146 deletions
|
@ -27,7 +27,6 @@ pub(crate) struct DirectXRenderer {
|
||||||
context: DirectXContext,
|
context: DirectXContext,
|
||||||
globals: DirectXGlobalElements,
|
globals: DirectXGlobalElements,
|
||||||
pipelines: DirectXRenderPipelines,
|
pipelines: DirectXRenderPipelines,
|
||||||
transparent: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -46,7 +45,7 @@ struct DirectXContext {
|
||||||
msaa_view: ID3D11RenderTargetView,
|
msaa_view: ID3D11RenderTargetView,
|
||||||
viewport: [D3D11_VIEWPORT; 1],
|
viewport: [D3D11_VIEWPORT; 1],
|
||||||
// #[cfg(not(feature = "enable-renderdoc"))]
|
// #[cfg(not(feature = "enable-renderdoc"))]
|
||||||
direct_composition: DirectComposition,
|
_direct_composition: DirectComposition,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DirectXRenderPipelines {
|
struct DirectXRenderPipelines {
|
||||||
|
@ -101,12 +100,12 @@ impl DirectXDevices {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DirectXRenderer {
|
impl DirectXRenderer {
|
||||||
pub(crate) fn new(devices: &DirectXDevices, hwnd: HWND, transparent: bool) -> Result<Self> {
|
pub(crate) fn new(devices: &DirectXDevices, hwnd: HWND) -> Result<Self> {
|
||||||
let atlas = Arc::new(DirectXAtlas::new(
|
let atlas = Arc::new(DirectXAtlas::new(
|
||||||
devices.device.clone(),
|
devices.device.clone(),
|
||||||
devices.device_context.clone(),
|
devices.device_context.clone(),
|
||||||
));
|
));
|
||||||
let context = DirectXContext::new(devices, hwnd, transparent)?;
|
let context = DirectXContext::new(devices, hwnd)?;
|
||||||
let globals = DirectXGlobalElements::new(&devices.device)?;
|
let globals = DirectXGlobalElements::new(&devices.device)?;
|
||||||
let pipelines = DirectXRenderPipelines::new(&devices.device)?;
|
let pipelines = DirectXRenderPipelines::new(&devices.device)?;
|
||||||
Ok(DirectXRenderer {
|
Ok(DirectXRenderer {
|
||||||
|
@ -115,7 +114,6 @@ impl DirectXRenderer {
|
||||||
context,
|
context,
|
||||||
globals,
|
globals,
|
||||||
pipelines,
|
pipelines,
|
||||||
transparent,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,93 +239,6 @@ impl DirectXRenderer {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[cfg(not(feature = "enable-renderdoc"))]
|
|
||||||
pub(crate) fn update_transparency(
|
|
||||||
&mut self,
|
|
||||||
background_appearance: WindowBackgroundAppearance,
|
|
||||||
) -> Result<()> {
|
|
||||||
let transparent = background_appearance != WindowBackgroundAppearance::Opaque;
|
|
||||||
if self.transparent == transparent {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
// self.transparent = transparent;
|
|
||||||
// let (width, height) = unsafe {
|
|
||||||
// self.devices.device_context.OMSetRenderTargets(None, None);
|
|
||||||
// ManuallyDrop::drop(&mut self.context.render_target);
|
|
||||||
// drop(self.context.render_target_view[0].take().unwrap());
|
|
||||||
// let desc = self.context.swap_chain.GetDesc1().unwrap();
|
|
||||||
// ManuallyDrop::drop(&mut self.context.swap_chain);
|
|
||||||
// (desc.Width, desc.Height)
|
|
||||||
// };
|
|
||||||
// self.context.swap_chain = create_swap_chain(
|
|
||||||
// &self.devices.dxgi_factory,
|
|
||||||
// &self.devices.device,
|
|
||||||
// transparent,
|
|
||||||
// width,
|
|
||||||
// height,
|
|
||||||
// )
|
|
||||||
// .unwrap();
|
|
||||||
// self.context
|
|
||||||
// .direct_composition
|
|
||||||
// .set_swap_chain(&self.context.swap_chain)
|
|
||||||
// .context("Failed to set swap chain for DirectComposition")?;
|
|
||||||
// let (render_target, render_target_view) =
|
|
||||||
// create_render_target_and_its_view(&self.context.swap_chain, &self.devices.device)
|
|
||||||
// .unwrap();
|
|
||||||
// self.context.render_target = render_target;
|
|
||||||
// self.context.render_target_view = render_target_view;
|
|
||||||
// unsafe {
|
|
||||||
// self.devices
|
|
||||||
// .device_context
|
|
||||||
// .OMSetRenderTargets(Some(&self.context.render_target_view), None);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let (msaa_target, msaa_view) =
|
|
||||||
// create_msaa_target_and_its_view(&self.devices.device, width, height)?;
|
|
||||||
// self.context.msaa_target = msaa_target;
|
|
||||||
// self.context.msaa_view = msaa_view;
|
|
||||||
|
|
||||||
// self.context.viewport = set_viewport(&self.devices.device_context, width as _, height as _);
|
|
||||||
// set_rasterizer_state(&self.devices.device, &self.devices.device_context)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// #[cfg(feature = "enable-renderdoc")]
|
|
||||||
// pub(crate) fn update_transparency(
|
|
||||||
// &mut self,
|
|
||||||
// background_appearance: WindowBackgroundAppearance,
|
|
||||||
// ) -> Result<()> {
|
|
||||||
// let transparent = background_appearance != WindowBackgroundAppearance::Opaque;
|
|
||||||
// if self.transparent == transparent {
|
|
||||||
// return Ok(());
|
|
||||||
// }
|
|
||||||
// self.transparent = transparent;
|
|
||||||
// unsafe {
|
|
||||||
// // recreate the swapchain
|
|
||||||
// self.devices.device_context.OMSetRenderTargets(None, None);
|
|
||||||
// drop(self.context.back_buffer[0].take().unwrap());
|
|
||||||
// ManuallyDrop::drop(&mut self.context.swap_chain);
|
|
||||||
// self.context.swap_chain = create_swap_chain_default(
|
|
||||||
// &self.devices.dxgi_factory,
|
|
||||||
// &self.devices.device,
|
|
||||||
// self.hwnd,
|
|
||||||
// transparent,
|
|
||||||
// )?;
|
|
||||||
// self.context.back_buffer = [Some(set_render_target_view(
|
|
||||||
// &self.context.swap_chain,
|
|
||||||
// &self.devices.device,
|
|
||||||
// &self.devices.device_context,
|
|
||||||
// )?)];
|
|
||||||
// self.context.viewport = set_viewport(
|
|
||||||
// &self.devices.device_context,
|
|
||||||
// self.context.viewport[0].Width,
|
|
||||||
// self.context.viewport[0].Height,
|
|
||||||
// );
|
|
||||||
// set_rasterizer_state(&self.devices.device, &self.devices.device_context)?;
|
|
||||||
// }
|
|
||||||
// Ok(())
|
|
||||||
// }
|
|
||||||
|
|
||||||
fn draw_shadows(&mut self, shadows: &[Shadow]) -> Result<()> {
|
fn draw_shadows(&mut self, shadows: &[Shadow]) -> Result<()> {
|
||||||
if shadows.is_empty() {
|
if shadows.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -480,7 +391,7 @@ impl DirectXRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DirectXContext {
|
impl DirectXContext {
|
||||||
pub fn new(devices: &DirectXDevices, hwnd: HWND, transparent: bool) -> Result<Self> {
|
pub fn new(devices: &DirectXDevices, hwnd: HWND) -> Result<Self> {
|
||||||
let (width, height) = unsafe {
|
let (width, height) = unsafe {
|
||||||
let mut rect = std::mem::zeroed();
|
let mut rect = std::mem::zeroed();
|
||||||
GetWindowRect(hwnd, &mut rect)?;
|
GetWindowRect(hwnd, &mut rect)?;
|
||||||
|
@ -494,7 +405,6 @@ impl DirectXContext {
|
||||||
let swap_chain = create_swap_chain(
|
let swap_chain = create_swap_chain(
|
||||||
&devices.dxgi_factory,
|
&devices.dxgi_factory,
|
||||||
&devices.device,
|
&devices.device,
|
||||||
transparent,
|
|
||||||
width as u32,
|
width as u32,
|
||||||
height as u32,
|
height as u32,
|
||||||
)?;
|
)?;
|
||||||
|
@ -525,7 +435,7 @@ impl DirectXContext {
|
||||||
msaa_view,
|
msaa_view,
|
||||||
viewport,
|
viewport,
|
||||||
// #[cfg(not(feature = "enable-renderdoc"))]
|
// #[cfg(not(feature = "enable-renderdoc"))]
|
||||||
direct_composition,
|
_direct_composition: direct_composition,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1068,17 +978,9 @@ fn get_comp_device(dxgi_device: &IDXGIDevice) -> Result<IDCompositionDevice> {
|
||||||
fn create_swap_chain(
|
fn create_swap_chain(
|
||||||
dxgi_factory: &IDXGIFactory6,
|
dxgi_factory: &IDXGIFactory6,
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
transparent: bool,
|
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
) -> Result<ManuallyDrop<IDXGISwapChain1>> {
|
) -> Result<ManuallyDrop<IDXGISwapChain1>> {
|
||||||
println!("Creating swap chain for DirectComposition: {}", transparent);
|
|
||||||
let transparent = true;
|
|
||||||
let alpha_mode = if transparent {
|
|
||||||
DXGI_ALPHA_MODE_PREMULTIPLIED
|
|
||||||
} else {
|
|
||||||
DXGI_ALPHA_MODE_IGNORE
|
|
||||||
};
|
|
||||||
let desc = DXGI_SWAP_CHAIN_DESC1 {
|
let desc = DXGI_SWAP_CHAIN_DESC1 {
|
||||||
Width: width,
|
Width: width,
|
||||||
Height: height,
|
Height: height,
|
||||||
|
@ -1093,7 +995,7 @@ fn create_swap_chain(
|
||||||
// Composition SwapChains only support the DXGI_SCALING_STRETCH Scaling.
|
// Composition SwapChains only support the DXGI_SCALING_STRETCH Scaling.
|
||||||
Scaling: DXGI_SCALING_STRETCH,
|
Scaling: DXGI_SCALING_STRETCH,
|
||||||
SwapEffect: DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL,
|
SwapEffect: DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL,
|
||||||
AlphaMode: alpha_mode,
|
AlphaMode: DXGI_ALPHA_MODE_PREMULTIPLIED,
|
||||||
Flags: 0,
|
Flags: 0,
|
||||||
};
|
};
|
||||||
Ok(ManuallyDrop::new(unsafe {
|
Ok(ManuallyDrop::new(unsafe {
|
||||||
|
@ -1149,24 +1051,6 @@ fn create_render_target_and_its_view(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn set_render_target_view(
|
|
||||||
swap_chain: &IDXGISwapChain1,
|
|
||||||
device: &ID3D11Device,
|
|
||||||
device_context: &ID3D11DeviceContext,
|
|
||||||
) -> Result<ID3D11RenderTargetView> {
|
|
||||||
// In dx11, ID3D11RenderTargetView is supposed to always point to the new back buffer.
|
|
||||||
// https://stackoverflow.com/questions/65246961/does-the-backbuffer-that-a-rendertargetview-points-to-automagically-change-after
|
|
||||||
let back_buffer = unsafe {
|
|
||||||
let resource: ID3D11Texture2D = swap_chain.GetBuffer(0)?;
|
|
||||||
let mut buffer: Option<ID3D11RenderTargetView> = None;
|
|
||||||
device.CreateRenderTargetView(&resource, None, Some(&mut buffer))?;
|
|
||||||
buffer.unwrap()
|
|
||||||
};
|
|
||||||
unsafe { device_context.OMSetRenderTargets(Some(&[Some(back_buffer.clone())]), None) };
|
|
||||||
Ok(back_buffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn create_msaa_target_and_its_view(
|
fn create_msaa_target_and_its_view(
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
|
|
|
@ -80,7 +80,6 @@ pub(crate) struct WindowsWindowStatePtr {
|
||||||
impl WindowsWindowState {
|
impl WindowsWindowState {
|
||||||
fn new(
|
fn new(
|
||||||
hwnd: HWND,
|
hwnd: HWND,
|
||||||
transparent: bool,
|
|
||||||
cs: &CREATESTRUCTW,
|
cs: &CREATESTRUCTW,
|
||||||
current_cursor: Option<HCURSOR>,
|
current_cursor: Option<HCURSOR>,
|
||||||
display: WindowsDisplay,
|
display: WindowsDisplay,
|
||||||
|
@ -104,7 +103,7 @@ impl WindowsWindowState {
|
||||||
let border_offset = WindowBorderOffset::default();
|
let border_offset = WindowBorderOffset::default();
|
||||||
let restore_from_minimized = None;
|
let restore_from_minimized = None;
|
||||||
// let renderer = windows_renderer::init(gpu_context, hwnd, transparent)?;
|
// let renderer = windows_renderer::init(gpu_context, hwnd, transparent)?;
|
||||||
let renderer = DirectXRenderer::new(gpu_context, hwnd, transparent)?;
|
let renderer = DirectXRenderer::new(gpu_context, hwnd)?;
|
||||||
let callbacks = Callbacks::default();
|
let callbacks = Callbacks::default();
|
||||||
let input_handler = None;
|
let input_handler = None;
|
||||||
let pending_surrogate = None;
|
let pending_surrogate = None;
|
||||||
|
@ -207,7 +206,6 @@ impl WindowsWindowStatePtr {
|
||||||
fn new(context: &WindowCreateContext, hwnd: HWND, cs: &CREATESTRUCTW) -> Result<Rc<Self>> {
|
fn new(context: &WindowCreateContext, hwnd: HWND, cs: &CREATESTRUCTW) -> Result<Rc<Self>> {
|
||||||
let state = RefCell::new(WindowsWindowState::new(
|
let state = RefCell::new(WindowsWindowState::new(
|
||||||
hwnd,
|
hwnd,
|
||||||
context.transparent,
|
|
||||||
cs,
|
cs,
|
||||||
context.current_cursor,
|
context.current_cursor,
|
||||||
context.display,
|
context.display,
|
||||||
|
@ -335,7 +333,6 @@ struct WindowCreateContext<'a> {
|
||||||
handle: AnyWindowHandle,
|
handle: AnyWindowHandle,
|
||||||
hide_title_bar: bool,
|
hide_title_bar: bool,
|
||||||
display: WindowsDisplay,
|
display: WindowsDisplay,
|
||||||
transparent: bool,
|
|
||||||
is_movable: bool,
|
is_movable: bool,
|
||||||
min_size: Option<Size<Pixels>>,
|
min_size: Option<Size<Pixels>>,
|
||||||
executor: ForegroundExecutor,
|
executor: ForegroundExecutor,
|
||||||
|
@ -381,11 +378,13 @@ impl WindowsWindow {
|
||||||
.unwrap_or(""),
|
.unwrap_or(""),
|
||||||
);
|
);
|
||||||
let (dwexstyle, mut dwstyle) = if params.kind == WindowKind::PopUp {
|
let (dwexstyle, mut dwstyle) = if params.kind == WindowKind::PopUp {
|
||||||
(WS_EX_TOOLWINDOW | WS_EX_LAYERED, WINDOW_STYLE(0x0))
|
(
|
||||||
|
WS_EX_TOOLWINDOW | WS_EX_NOREDIRECTIONBITMAP,
|
||||||
|
WINDOW_STYLE(0x0),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
WS_EX_APPWINDOW | WS_EX_NOREDIRECTIONBITMAP,
|
WS_EX_APPWINDOW | WS_EX_NOREDIRECTIONBITMAP,
|
||||||
// WS_EX_APPWINDOW | WS_EX_LAYERED,
|
|
||||||
WS_THICKFRAME | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX,
|
WS_THICKFRAME | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -403,7 +402,6 @@ impl WindowsWindow {
|
||||||
handle,
|
handle,
|
||||||
hide_title_bar,
|
hide_title_bar,
|
||||||
display,
|
display,
|
||||||
transparent: false,
|
|
||||||
is_movable: params.is_movable,
|
is_movable: params.is_movable,
|
||||||
min_size: params.window_min_size,
|
min_size: params.window_min_size,
|
||||||
executor,
|
executor,
|
||||||
|
@ -455,14 +453,6 @@ impl WindowsWindow {
|
||||||
state: WindowOpenState::Windowed,
|
state: WindowOpenState::Windowed,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// The render pipeline will perform compositing on the GPU when the
|
|
||||||
// swapchain is configured correctly (see downstream of
|
|
||||||
// update_transparency).
|
|
||||||
// The following configuration is a one-time setup to ensure that the
|
|
||||||
// window is going to be composited with per-pixel alpha, but the render
|
|
||||||
// pipeline is responsible for effectively calling UpdateLayeredWindow
|
|
||||||
// at the appropriate time.
|
|
||||||
// unsafe { SetLayeredWindowAttributes(hwnd, COLORREF(0), 255, LWA_ALPHA)? };
|
|
||||||
|
|
||||||
Ok(Self(state_ptr))
|
Ok(Self(state_ptr))
|
||||||
}
|
}
|
||||||
|
@ -707,26 +697,21 @@ impl PlatformWindow for WindowsWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_background_appearance(&self, background_appearance: WindowBackgroundAppearance) {
|
fn set_background_appearance(&self, background_appearance: WindowBackgroundAppearance) {
|
||||||
let mut window_state = self.0.state.borrow_mut();
|
let hwnd = self.0.hwnd;
|
||||||
window_state
|
|
||||||
.renderer
|
|
||||||
.update_transparency(background_appearance)
|
|
||||||
.context("Updating window transparency")
|
|
||||||
.log_err();
|
|
||||||
|
|
||||||
match background_appearance {
|
match background_appearance {
|
||||||
WindowBackgroundAppearance::Opaque => {
|
WindowBackgroundAppearance::Opaque => {
|
||||||
// ACCENT_DISABLED
|
// ACCENT_DISABLED
|
||||||
set_window_composition_attribute(window_state.hwnd, None, 0);
|
set_window_composition_attribute(hwnd, None, 0);
|
||||||
}
|
}
|
||||||
WindowBackgroundAppearance::Transparent => {
|
WindowBackgroundAppearance::Transparent => {
|
||||||
// Use ACCENT_ENABLE_TRANSPARENTGRADIENT for transparent background
|
// Use ACCENT_ENABLE_TRANSPARENTGRADIENT for transparent background
|
||||||
set_window_composition_attribute(window_state.hwnd, None, 2);
|
set_window_composition_attribute(hwnd, None, 2);
|
||||||
}
|
}
|
||||||
WindowBackgroundAppearance::Blurred => {
|
WindowBackgroundAppearance::Blurred => {
|
||||||
// Enable acrylic blur
|
// Enable acrylic blur
|
||||||
// ACCENT_ENABLE_ACRYLICBLURBEHIND
|
// ACCENT_ENABLE_ACRYLICBLURBEHIND
|
||||||
set_window_composition_attribute(window_state.hwnd, Some((0, 0, 0, 0)), 4);
|
set_window_composition_attribute(hwnd, Some((0, 0, 0, 0)), 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue