diff --git a/nucleus/graphics/backend/direct3d12/direct3d12_shader.cpp b/nucleus/graphics/backend/direct3d12/direct3d12_shader.cpp index 622c681..8dc7d40 100644 --- a/nucleus/graphics/backend/direct3d12/direct3d12_shader.cpp +++ b/nucleus/graphics/backend/direct3d12/direct3d12_shader.cpp @@ -131,6 +131,9 @@ void Direct3D12Shader::appendOutput(Literal typeId, Literal resultId) { if (builtinType == BUILTIN_VERTEXID || builtinType == BUILTIN_INSTANCEID) { type = "uint"; } + if (builtinType == BUILTIN_POSITION) { + idBuiltinPosition = resultId; + } sourceOutput += format(PADDING "%s v%d : %s;\n", type.c_str(), resultId, getBuiltin(builtinType)); return; } @@ -515,6 +518,12 @@ std::string Direct3D12Shader::compile(Function* function) { source += compile(block); } if (idEntryPoint == funcId) { + if (shaderType == SHADER_TYPE_VERTEX) { + // Correct coordinate system on Z-axis (TODO: Implement proper system to detect BUILTIN_POSITION's) + if (idBuiltinPosition != 0) { + source += format(PADDING "output.v%d.z *= -1.0f;\n", idBuiltinPosition); + } + } source += PADDING "return output;\n"; } source += "}\n\n"; @@ -599,7 +608,7 @@ bool Direct3D12Shader::initialize(const ShaderDesc& desc) { idCache.resize(module->idInstructions.size()); std::string source = compile(module); - std::cout << source << std::endl; + // std::cout << source << std::endl; LPCSTR target; switch (desc.type) { diff --git a/nucleus/graphics/backend/direct3d12/direct3d12_shader.h b/nucleus/graphics/backend/direct3d12/direct3d12_shader.h index 10c0141..6c1d32e 100644 --- a/nucleus/graphics/backend/direct3d12/direct3d12_shader.h +++ b/nucleus/graphics/backend/direct3d12/direct3d12_shader.h @@ -36,6 +36,7 @@ class Direct3D12Shader : public Shader { int countArbitraryOutput; int countArbitraryCBV; hir::Literal idEntryPoint; + hir::Literal idBuiltinPosition; std::unordered_map> idDecoration; const char* getBuiltin(hir::Literal builtinDecoration); diff --git a/nucleus/ui/screens/screen_emulator.cpp b/nucleus/ui/screens/screen_emulator.cpp index 06ebbfd..e266243 100644 --- a/nucleus/ui/screens/screen_emulator.cpp +++ b/nucleus/ui/screens/screen_emulator.cpp @@ -19,6 +19,7 @@ ScreenEmulator::ScreenEmulator(UI* manager) : Screen(manager) { app->manager = manager; app->style.width = 100_pct; app->style.height = 100_pct; + app->opacityMin = 1.0f; body.addElement(app); } diff --git a/nucleus/ui/widget.h b/nucleus/ui/widget.h index ad04299..ccd3627 100644 --- a/nucleus/ui/widget.h +++ b/nucleus/ui/widget.h @@ -46,6 +46,7 @@ struct WidgetImageInput { float texcoord[2]; float zindex; float opacity; + float opacityMin; } vertex[4]; }; struct WidgetTextInput { diff --git a/nucleus/ui/widgets/widget_image.cpp b/nucleus/ui/widgets/widget_image.cpp index 741df2f..9807034 100644 --- a/nucleus/ui/widgets/widget_image.cpp +++ b/nucleus/ui/widgets/widget_image.cpp @@ -39,6 +39,7 @@ gfx::Pipeline* WidgetImage::createPipeline(gfx::IBackend& backend) { { 1, gfx::FORMAT_R32G32_FLOAT, 0, 8, 0, 0, gfx::INPUT_CLASSIFICATION_PER_VERTEX, 0 }, // TexCoord { 2, gfx::FORMAT_R32_FLOAT, 0, 16, 0, 0, gfx::INPUT_CLASSIFICATION_PER_VERTEX, 0 }, // Z-Index { 3, gfx::FORMAT_R32_FLOAT, 0, 20, 0, 0, gfx::INPUT_CLASSIFICATION_PER_VERTEX, 0 }, // Opacity + { 4, gfx::FORMAT_R32_FLOAT, 0, 24, 0, 0, gfx::INPUT_CLASSIFICATION_PER_VERTEX, 0 }, // OpacityMin }; pipelineDesc.cbState.colorTarget[0] = { true, false, @@ -151,6 +152,10 @@ void WidgetImage::render() { V1.opacity = style.opacity; V2.opacity = style.opacity; V3.opacity = style.opacity; + V0.opacityMin = opacityMin; + V1.opacityMin = opacityMin; + V2.opacityMin = opacityMin; + V3.opacityMin = opacityMin; // Texture coordinates assume top-left is (0,0) and bottom-right is (1,1) V0.texcoord[0] = 0.0; V0.texcoord[1] = 1.0; diff --git a/nucleus/ui/widgets/widget_image.h b/nucleus/ui/widgets/widget_image.h index 889910c..354d126 100644 --- a/nucleus/ui/widgets/widget_image.h +++ b/nucleus/ui/widgets/widget_image.h @@ -28,6 +28,11 @@ private: public: bool isColorTarget = false; + // Minimum opacity value + // The alpha channel of some images (e.g. guest GPU render targets) + // should be ignored while displaying the buffer on screen. + float opacityMin = 0.0; + WidgetImage() {} WidgetImage(const std::string& id) : Widget(id) {} WidgetImage(Widget* parent, const std::string& id = "") : Widget(parent, id) {} diff --git a/resources/shaders/ui_widget_image_ps.glsl b/resources/shaders/ui_widget_image_ps.glsl index 41aaf31..786949c 100644 --- a/resources/shaders/ui_widget_image_ps.glsl +++ b/resources/shaders/ui_widget_image_ps.glsl @@ -5,6 +5,7 @@ in vec4 gl_FragCoord; layout (location = 0) in vec2 iTexcoord; layout (location = 1) in float iZindex; layout (location = 2) in float iOpacity; +layout (location = 3) in float iOpacityMin; // Outputs layout (location = 0) out vec4 result; @@ -15,4 +16,5 @@ layout (binding = 0) uniform sampler2D s; void main() { result = texture(s, iTexcoord.xy); result.a *= iOpacity; + result.a += iOpacityMin; } diff --git a/resources/shaders/ui_widget_image_ps.spv b/resources/shaders/ui_widget_image_ps.spv index 45b8b1a..e95782a 100644 Binary files a/resources/shaders/ui_widget_image_ps.spv and b/resources/shaders/ui_widget_image_ps.spv differ diff --git a/resources/shaders/ui_widget_image_vs.glsl b/resources/shaders/ui_widget_image_vs.glsl index 14426da..77d0ea6 100644 --- a/resources/shaders/ui_widget_image_vs.glsl +++ b/resources/shaders/ui_widget_image_vs.glsl @@ -4,14 +4,17 @@ layout (location = 0) in vec2 iPosition; layout (location = 1) in vec2 iTexcoord; layout (location = 2) in float iZindex; layout (location = 3) in float iOpacity; +layout (location = 4) in float iOpacityMin; layout (location = 0) out vec2 oTexcoord; layout (location = 1) out float oZindex; layout (location = 2) out float oOpacity; +layout (location = 3) out float oOpacityMin; void main() { gl_Position = vec4(iPosition, 0.0, 1.0); oTexcoord = iTexcoord; oZindex = iZindex; oOpacity = iOpacity; + oOpacityMin = iOpacityMin; } diff --git a/resources/shaders/ui_widget_image_vs.spv b/resources/shaders/ui_widget_image_vs.spv index 28dff21..53c2483 100644 Binary files a/resources/shaders/ui_widget_image_vs.spv and b/resources/shaders/ui_widget_image_vs.spv differ