mirror of
https://github.com/azahar-emu/azahar
synced 2025-11-07 07:29:58 +01:00
renderer_vulkan: Add second screen opacity support
& Update bottom screen opacity label in UI
This commit is contained in:
parent
5c5b1cdf45
commit
64f5277789
@ -1185,8 +1185,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||||||
"%",
|
"%",
|
||||||
FloatSetting.SECOND_SCREEN_OPACITY.key,
|
FloatSetting.SECOND_SCREEN_OPACITY.key,
|
||||||
FloatSetting.SECOND_SCREEN_OPACITY.defaultValue,
|
FloatSetting.SECOND_SCREEN_OPACITY.defaultValue,
|
||||||
// TODO: Remove graphics API check when #895 is merged
|
isEnabled = IntSetting.SCREEN_LAYOUT.int == 5
|
||||||
isEnabled = IntSetting.SCREEN_LAYOUT.int == 5 && IntSetting.GRAPHICS_API.int == 1
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(HeaderSetting(R.string.bg_color, R.string.bg_color_description))
|
add(HeaderSetting(R.string.bg_color, R.string.bg_color_description))
|
||||||
|
|||||||
@ -170,7 +170,7 @@ bg_red =
|
|||||||
bg_blue =
|
bg_blue =
|
||||||
bg_green =
|
bg_green =
|
||||||
|
|
||||||
# Opacity of second layer when using custom layout option (bottom screen unless swapped). Useful if positioning on top of the first layer. OpenGL only.
|
# Opacity of second layer when using custom layout option (bottom screen unless swapped). Useful if positioning on top of the first layer.
|
||||||
custom_second_layer_opacity =
|
custom_second_layer_opacity =
|
||||||
|
|
||||||
# Whether and how Stereoscopic 3D should be rendered
|
# Whether and how Stereoscopic 3D should be rendered
|
||||||
|
|||||||
@ -455,7 +455,7 @@
|
|||||||
<string name="bg_red">Red</string>
|
<string name="bg_red">Red</string>
|
||||||
<string name="bg_green">Green</string>
|
<string name="bg_green">Green</string>
|
||||||
<string name="bg_blue">Blue</string>
|
<string name="bg_blue">Blue</string>
|
||||||
<string name="second_screen_opacity">Custom Layout Second Screen Opacity (OpenGL Only)</string>
|
<string name="second_screen_opacity">Custom Layout Second Screen Opacity</string>
|
||||||
<string name="second_screen_opacity_description">The opacity of the second 3DS screen when using a custom screen layout. Useful if the second screen is to be positioned on top of the first screen.</string>
|
<string name="second_screen_opacity_description">The opacity of the second 3DS screen when using a custom screen layout. Useful if the second screen is to be positioned on top of the first screen.</string>
|
||||||
<string name="emulation_small_screen_position">Small Screen Position</string>
|
<string name="emulation_small_screen_position">Small Screen Position</string>
|
||||||
<string name="small_screen_position_description">Where should the small screen appear relative to the large one in Large Screen Layout?</string>
|
<string name="small_screen_position_description">Where should the small screen appear relative to the large one in Large Screen Layout?</string>
|
||||||
|
|||||||
@ -531,7 +531,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="lb_opacity_second_layer">
|
<widget class="QLabel" name="lb_opacity_second_layer">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><html><head/><body><p>Bottom Screen Opacity % (OpenGL Only)</p></body></html></string>
|
<string><html><head/><body><p>Bottom Screen Opacity %</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@ -376,7 +376,13 @@ void RendererVulkan::BuildPipelines() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const vk::PipelineColorBlendAttachmentState colorblend_attachment = {
|
const vk::PipelineColorBlendAttachmentState colorblend_attachment = {
|
||||||
.blendEnable = false,
|
.blendEnable = true,
|
||||||
|
.srcColorBlendFactor = vk::BlendFactor::eConstantAlpha,
|
||||||
|
.dstColorBlendFactor = vk::BlendFactor::eOneMinusConstantAlpha,
|
||||||
|
.colorBlendOp = vk::BlendOp::eAdd,
|
||||||
|
.srcAlphaBlendFactor = vk::BlendFactor::eConstantAlpha,
|
||||||
|
.dstAlphaBlendFactor = vk::BlendFactor::eOneMinusConstantAlpha,
|
||||||
|
.alphaBlendOp = vk::BlendOp::eAdd,
|
||||||
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG |
|
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG |
|
||||||
vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA,
|
vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA,
|
||||||
};
|
};
|
||||||
@ -385,7 +391,6 @@ void RendererVulkan::BuildPipelines() {
|
|||||||
.logicOpEnable = false,
|
.logicOpEnable = false,
|
||||||
.attachmentCount = 1,
|
.attachmentCount = 1,
|
||||||
.pAttachments = &colorblend_attachment,
|
.pAttachments = &colorblend_attachment,
|
||||||
.blendConstants = std::array{1.0f, 1.0f, 1.0f, 1.0f},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const vk::Viewport placeholder_viewport = vk::Viewport{0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f};
|
const vk::Viewport placeholder_viewport = vk::Viewport{0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f};
|
||||||
@ -398,6 +403,7 @@ void RendererVulkan::BuildPipelines() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const std::array dynamic_states = {
|
const std::array dynamic_states = {
|
||||||
|
vk::DynamicState::eBlendConstants,
|
||||||
vk::DynamicState::eViewport,
|
vk::DynamicState::eViewport,
|
||||||
vk::DynamicState::eScissor,
|
vk::DynamicState::eScissor,
|
||||||
};
|
};
|
||||||
@ -729,6 +735,13 @@ void RendererVulkan::DrawSingleScreenStereo(u32 screen_id_l, u32 screen_id_r, fl
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RendererVulkan::ApplySecondLayerOpacity(float alpha) {
|
||||||
|
scheduler.Record([alpha](vk::CommandBuffer cmdbuf) {
|
||||||
|
const std::array<float, 4> blend_constants = {0.0f, 0.0f, 0.0f, alpha};
|
||||||
|
cmdbuf.setBlendConstants(blend_constants.data());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void RendererVulkan::DrawTopScreen(const Layout::FramebufferLayout& layout,
|
void RendererVulkan::DrawTopScreen(const Layout::FramebufferLayout& layout,
|
||||||
const Common::Rectangle<u32>& top_screen) {
|
const Common::Rectangle<u32>& top_screen) {
|
||||||
if (!layout.top_screen_enabled) {
|
if (!layout.top_screen_enabled) {
|
||||||
@ -867,13 +880,30 @@ void RendererVulkan::DrawScreens(Frame* frame, const Layout::FramebufferLayout&
|
|||||||
draw_info.modelview = MakeOrthographicMatrix(layout.width, layout.height);
|
draw_info.modelview = MakeOrthographicMatrix(layout.width, layout.height);
|
||||||
|
|
||||||
draw_info.layer = 0;
|
draw_info.layer = 0;
|
||||||
|
|
||||||
|
// Apply the initial default opacity value; Needed to avoid flickering
|
||||||
|
ApplySecondLayerOpacity(1.0f);
|
||||||
|
|
||||||
|
bool use_custom_opacity =
|
||||||
|
Settings::values.layout_option.GetValue() == Settings::LayoutOption::CustomLayout &&
|
||||||
|
Settings::values.custom_second_layer_opacity.GetValue() < 100;
|
||||||
|
float second_alpha = use_custom_opacity
|
||||||
|
? Settings::values.custom_second_layer_opacity.GetValue() / 100.0f
|
||||||
|
: 1.0f;
|
||||||
|
|
||||||
if (!Settings::values.swap_screen.GetValue()) {
|
if (!Settings::values.swap_screen.GetValue()) {
|
||||||
DrawTopScreen(layout, top_screen);
|
DrawTopScreen(layout, top_screen);
|
||||||
draw_info.layer = 0;
|
draw_info.layer = 0;
|
||||||
|
if (use_custom_opacity) {
|
||||||
|
ApplySecondLayerOpacity(second_alpha);
|
||||||
|
}
|
||||||
DrawBottomScreen(layout, bottom_screen);
|
DrawBottomScreen(layout, bottom_screen);
|
||||||
} else {
|
} else {
|
||||||
DrawBottomScreen(layout, bottom_screen);
|
DrawBottomScreen(layout, bottom_screen);
|
||||||
draw_info.layer = 0;
|
draw_info.layer = 0;
|
||||||
|
if (use_custom_opacity) {
|
||||||
|
ApplySecondLayerOpacity(second_alpha);
|
||||||
|
}
|
||||||
DrawTopScreen(layout, top_screen);
|
DrawTopScreen(layout, top_screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -98,12 +98,16 @@ private:
|
|||||||
void DrawScreens(Frame* frame, const Layout::FramebufferLayout& layout, bool flipped);
|
void DrawScreens(Frame* frame, const Layout::FramebufferLayout& layout, bool flipped);
|
||||||
void DrawBottomScreen(const Layout::FramebufferLayout& layout,
|
void DrawBottomScreen(const Layout::FramebufferLayout& layout,
|
||||||
const Common::Rectangle<u32>& bottom_screen);
|
const Common::Rectangle<u32>& bottom_screen);
|
||||||
|
|
||||||
void DrawTopScreen(const Layout::FramebufferLayout& layout,
|
void DrawTopScreen(const Layout::FramebufferLayout& layout,
|
||||||
const Common::Rectangle<u32>& top_screen);
|
const Common::Rectangle<u32>& top_screen);
|
||||||
void DrawSingleScreen(u32 screen_id, float x, float y, float w, float h,
|
void DrawSingleScreen(u32 screen_id, float x, float y, float w, float h,
|
||||||
Layout::DisplayOrientation orientation);
|
Layout::DisplayOrientation orientation);
|
||||||
void DrawSingleScreenStereo(u32 screen_id_l, u32 screen_id_r, float x, float y, float w,
|
void DrawSingleScreenStereo(u32 screen_id_l, u32 screen_id_r, float x, float y, float w,
|
||||||
float h, Layout::DisplayOrientation orientation);
|
float h, Layout::DisplayOrientation orientation);
|
||||||
|
|
||||||
|
void ApplySecondLayerOpacity(float alpha);
|
||||||
|
|
||||||
void LoadFBToScreenInfo(const Pica::FramebufferConfig& framebuffer, ScreenInfo& screen_info,
|
void LoadFBToScreenInfo(const Pica::FramebufferConfig& framebuffer, ScreenInfo& screen_info,
|
||||||
bool right_eye);
|
bool right_eye);
|
||||||
void FillScreen(Common::Vec3<u8> color, const TextureInfo& texture);
|
void FillScreen(Common::Vec3<u8> color, const TextureInfo& texture);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user