From c2b6f443e913918753464fc6686f8c6da2de034f Mon Sep 17 00:00:00 2001 From: Turanszki Janos Date: Sat, 12 Oct 2019 17:06:58 +0100 Subject: [PATCH] editor update: material selection outline; general fixes; --- Editor/Editor.cpp | 92 ++++++++++++++++++- Editor/Editor.h | 2 + Editor/MaterialWindow.cpp | 2 - Editor/SoundWindow.cpp | 2 +- WickedEngine/RenderPath3D.h | 6 +- WickedEngine/WickedEngine_SHARED.vcxitems | 1 + .../WickedEngine_SHARED.vcxitems.filters | 3 + WickedEngine/outlineCS.hlsl | 30 +++--- WickedEngine/wiRenderer.cpp | 7 +- WickedEngine/wiRenderer.h | 9 +- WickedEngine/wiSceneSystem.cpp | 3 + WickedEngine/wiSceneSystem.h | 4 +- WickedEngine/wiVersion.cpp | 2 +- 13 files changed, 135 insertions(+), 28 deletions(-) diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 5e0a43718..5faba401a 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -152,13 +152,31 @@ void EditorComponent::ChangeRenderPath(RENDERPATH path) oceanWnd.reset(new OceanWindow(&GetGUI())); } +void EditorComponent::ResizeBuffers() +{ + __super::ResizeBuffers(); + + TextureDesc desc; + desc.Width = wiRenderer::GetInternalResolution().x; + desc.Height = wiRenderer::GetInternalResolution().y; + + HRESULT hr; + desc.Format = wiRenderer::RTFormat_lineardepth; + desc.BindFlags = BIND_RENDER_TARGET | BIND_SHADER_RESOURCE; + hr = wiRenderer::GetDevice()->CreateTexture2D(&desc, nullptr, &rt_selectionOutline[0]); + assert(SUCCEEDED(hr)); + + desc.Format = wiRenderer::RTFormat_hdr; + desc.BindFlags = BIND_RENDER_TARGET | BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS; + hr = wiRenderer::GetDevice()->CreateTexture2D(&desc, nullptr, &rt_selectionOutline[1]); + assert(SUCCEEDED(hr)); +} void EditorComponent::Load() { __super::Load(); translator.enabled = false; - float screenW = (float)wiRenderer::GetDevice()->GetScreenWidth(); float screenH = (float)wiRenderer::GetDevice()->GetScreenHeight(); @@ -1144,6 +1162,7 @@ void EditorComponent::Update(float dt) // Union selection: list saved = selected; EndTranslate(); + selected.clear(); // endtranslate would clear it, but not if translator is not enabled for (const wiSceneSystem::PickResult& picked : saved) { AddSelected(picked); @@ -1232,6 +1251,31 @@ void EditorComponent::Update(float dt) } + // Clear material highlite state: + for (size_t i = 0; i < scene.materials.GetCount(); ++i) + { + scene.materials[i].SetUserStencilRef(EditorComponent::EDITORSTENCILREF_CLEAR); + } + for (auto& x : selected) + { + if (x.subsetIndex >= 0) + { + const ObjectComponent* object = scene.objects.GetComponent(x.entity); + if (object != nullptr) // maybe it was deleted... + { + const MeshComponent* mesh = scene.meshes.GetComponent(object->meshID); + if (mesh != nullptr && (int)mesh->subsets.size() > x.subsetIndex) + { + MaterialComponent* material = scene.materials.GetComponent(mesh->subsets[x.subsetIndex].materialID); + if (material != nullptr) + { + material->SetUserStencilRef(EDITORSTENCILREF_HIGHLIGHT); + } + } + } + } + } + // Delete if (wiInputManager::press(VK_DELETE)) { @@ -1490,6 +1534,45 @@ void EditorComponent::Render() const renderPath->Render(); + // Selection outline: + { + GraphicsDevice* device = wiRenderer::GetDevice(); + CommandList cmd = device->BeginCommandList(); + + device->EventBegin("Editor - Selection Outline", cmd); + + const Texture2D* rts[] = { + &rt_selectionOutline[0], + }; + device->BindRenderTargets(ARRAYSIZE(rts), rts, renderPath->GetDepthStencil(), cmd); + const float rgba[] = { 0,0,0,0 }; + device->ClearRenderTarget(rts[0], rgba, cmd); + + ViewPort vp; + vp.Width = (float)rt_selectionOutline[0].GetDesc().Width; + vp.Height = (float)rt_selectionOutline[0].GetDesc().Height; + device->BindViewports(1, &vp, cmd); + + wiImageParams fx; + fx.enableFullScreen(); + fx.stencilComp = STENCILMODE::STENCILMODE_EQUAL; + + // Draw solid blocks of selected materials with STENCILREF_DEFAULT engine stencil ref + fx.stencilRef = wiRenderer::CombineStencilrefs(STENCILREF_DEFAULT, EDITORSTENCILREF_HIGHLIGHT); + wiImage::Draw(wiTextureHelper::getWhite(), fx, cmd); + + // Draw solid blocks of selected materials with STENCILREF_SKIN engine stencil ref + fx.stencilRef = wiRenderer::CombineStencilrefs(STENCILREF_SKIN, EDITORSTENCILREF_HIGHLIGHT); + wiImage::Draw(wiTextureHelper::getWhite(), fx, cmd); + + // Outline the solid blocks: + device->ClearRenderTarget(&rt_selectionOutline[1], rgba, cmd); + wiRenderer::BindCommonResources(cmd); + wiRenderer::Postprocess_Outline(rt_selectionOutline[0], rt_selectionOutline[1], cmd, 0.1f, 1, XMFLOAT4(1, 0.6f, 0, 1)); + + device->EventEnd(cmd); + } + __super::Render(); } @@ -1502,6 +1585,13 @@ void EditorComponent::Compose(CommandList cmd) const return; } + // Compose the selection outline to the screen: + { + wiImageParams fx; + fx.enableFullScreen(); + wiImage::Draw(&rt_selectionOutline[1], fx, cmd); + } + const CameraComponent& camera = wiRenderer::GetCamera(); Scene& scene = wiSceneSystem::GetScene(); diff --git a/Editor/Editor.h b/Editor/Editor.h index 34ced7939..ea0b69a8d 100644 --- a/Editor/Editor.h +++ b/Editor/Editor.h @@ -69,6 +69,7 @@ public: }; void ChangeRenderPath(RENDERPATH path); + void ResizeBuffers() override; void Load() override; void Start() override; void FixedUpdate() override; @@ -84,6 +85,7 @@ public: EDITORSTENCILREF_HIGHLIGHT = 0x01, EDITORSTENCILREF_LAST = 0x0F, }; + wiGraphics::Texture2D rt_selectionOutline[2]; Translator translator; std::list selected; diff --git a/Editor/MaterialWindow.cpp b/Editor/MaterialWindow.cpp index 734d0ba9a..a73fe05fc 100644 --- a/Editor/MaterialWindow.cpp +++ b/Editor/MaterialWindow.cpp @@ -783,8 +783,6 @@ void MaterialWindow::SetEntity(Entity entity) if (material != nullptr) { - material->SetUserStencilRef(0); - const NameComponent& name = *scene.names.GetComponent(entity); stringstream ss(""); ss << name.name << " (" << entity << ")"; diff --git a/Editor/SoundWindow.cpp b/Editor/SoundWindow.cpp index e0a604970..3048d69de 100644 --- a/Editor/SoundWindow.cpp +++ b/Editor/SoundWindow.cpp @@ -80,7 +80,7 @@ SoundWindow::SoundWindow(wiGUI* gui) : GUI(gui) if (result.ok) { string fileName = result.filenames.front(); - Entity entity = GetScene().Entity_CreateSound(fileName); + Entity entity = GetScene().Entity_CreateSound("editorSound", fileName); } }); soundWindow->AddWidget(addButton); diff --git a/WickedEngine/RenderPath3D.h b/WickedEngine/RenderPath3D.h index e8767dc7b..a87f19112 100644 --- a/WickedEngine/RenderPath3D.h +++ b/WickedEngine/RenderPath3D.h @@ -15,7 +15,7 @@ private: float sharpenFilterAmount = 0.28f; float outlineThreshold = 0.2f; float outlineThickness = 1.0f; - XMFLOAT3 outlineColor = XMFLOAT3(0, 0, 0); + XMFLOAT4 outlineColor = XMFLOAT4(0, 0, 0, 1); float ssaoRange = 1.0f; UINT ssaoSampleCount = 16; float chromaticAberrationAmount = 2.0f; @@ -112,7 +112,7 @@ public: inline float getSharpenFilterAmount() const { return sharpenFilterAmount; } inline float getOutlineThreshold() const { return outlineThreshold; } inline float getOutlineThickness() const { return outlineThickness; } - inline XMFLOAT3 getOutlineColor() const { return outlineColor; } + inline XMFLOAT4 getOutlineColor() const { return outlineColor; } inline float getSSAORange() const { return ssaoRange; } inline UINT getSSAOSampleCount() const { return ssaoSampleCount; } inline float getChromaticAberrationAmount() const { return chromaticAberrationAmount; } @@ -151,7 +151,7 @@ public: inline void setSharpenFilterAmount(float value) { sharpenFilterAmount = value; } inline void setOutlineThreshold(float value) { outlineThreshold = value; } inline void setOutlineThickness(float value) { outlineThickness = value; } - inline void setOutlineColor(const XMFLOAT3& value) { outlineColor = value; } + inline void setOutlineColor(const XMFLOAT4& value) { outlineColor = value; } inline void setSSAORange(float value) { ssaoRange = value; } inline void setSSAOSampleCount(UINT value) { ssaoSampleCount = value; } inline void setChromaticAberrationAmount(float value) { chromaticAberrationAmount = value; } diff --git a/WickedEngine/WickedEngine_SHARED.vcxitems b/WickedEngine/WickedEngine_SHARED.vcxitems index 6b2a88607..7b07fc436 100644 --- a/WickedEngine/WickedEngine_SHARED.vcxitems +++ b/WickedEngine/WickedEngine_SHARED.vcxitems @@ -257,6 +257,7 @@ + diff --git a/WickedEngine/WickedEngine_SHARED.vcxitems.filters b/WickedEngine/WickedEngine_SHARED.vcxitems.filters index db01fdcf0..1d409a277 100644 --- a/WickedEngine/WickedEngine_SHARED.vcxitems.filters +++ b/WickedEngine/WickedEngine_SHARED.vcxitems.filters @@ -1128,6 +1128,9 @@ ENGINE\Network + + UTILITY + diff --git a/WickedEngine/outlineCS.hlsl b/WickedEngine/outlineCS.hlsl index fc8db9076..90b52adaf 100644 --- a/WickedEngine/outlineCS.hlsl +++ b/WickedEngine/outlineCS.hlsl @@ -1,6 +1,8 @@ #include "globals.hlsli" #include "ShaderInterop_Postprocess.h" +TEXTURE2D(input, float, TEXSLOT_ONDEMAND0); + RWTEXTURE2D(output, float4, 0); [numthreads(POSTPROCESS_BLOCKSIZE, POSTPROCESS_BLOCKSIZE, 1)] @@ -8,30 +10,30 @@ void main(uint3 DTid : SV_DispatchThreadID) { const float2 uv = (DTid.xy + 0.5f) * xPPResolution_rcp; - const float midDepth = texture_lineardepth.SampleLevel(sampler_linear_clamp, uv, 0); + const float middle = input.SampleLevel(sampler_linear_clamp, uv, 0); const float outlineThickness = xPPParams0.y; - const float3 outlineColor = xPPParams1.xyz; - const float outlineThreshold = xPPParams0.x * midDepth; + const float4 outlineColor = xPPParams1; + const float outlineThreshold = xPPParams0.x * middle; float2 dim; - texture_lineardepth.GetDimensions(dim.x, dim.y); + input.GetDimensions(dim.x, dim.y); float2 ox = float2(outlineThickness / dim.x, 0.0); float2 oy = float2(0.0, outlineThickness / dim.y); float2 PP = uv - oy; - float CC = texture_lineardepth.SampleLevel(sampler_linear_clamp, (PP - ox), 0); float g00 = (CC); - CC = texture_lineardepth.SampleLevel(sampler_linear_clamp, PP, 0); float g01 = (CC); - CC = texture_lineardepth.SampleLevel(sampler_linear_clamp, (PP + ox), 0); float g02 = (CC); + float CC = input.SampleLevel(sampler_linear_clamp, (PP - ox), 0); float g00 = (CC); + CC = input.SampleLevel(sampler_linear_clamp, PP, 0); float g01 = (CC); + CC = input.SampleLevel(sampler_linear_clamp, (PP + ox), 0); float g02 = (CC); PP = uv; - CC = texture_lineardepth.SampleLevel(sampler_linear_clamp, (PP - ox), 0); float g10 = (CC); - CC = midDepth; float g11 = (CC)*0.01f; - CC = texture_lineardepth.SampleLevel(sampler_linear_clamp, (PP + ox), 0); float g12 = (CC); + CC = input.SampleLevel(sampler_linear_clamp, (PP - ox), 0); float g10 = (CC); + CC = middle; float g11 = (CC) * 0.01f; + CC = input.SampleLevel(sampler_linear_clamp, (PP + ox), 0); float g12 = (CC); PP = uv + oy; - CC = texture_lineardepth.SampleLevel(sampler_linear_clamp, (PP - ox), 0); float g20 = (CC); - CC = texture_lineardepth.SampleLevel(sampler_linear_clamp, PP, 0); float g21 = (CC); - CC = texture_lineardepth.SampleLevel(sampler_linear_clamp, (PP + ox), 0); float g22 = (CC); + CC = input.SampleLevel(sampler_linear_clamp, (PP - ox), 0); float g20 = (CC); + CC = input.SampleLevel(sampler_linear_clamp, PP, 0); float g21 = (CC); + CC = input.SampleLevel(sampler_linear_clamp, (PP + ox), 0); float g22 = (CC); float K00 = -1; float K01 = -2; float K02 = -1; @@ -66,5 +68,5 @@ void main(uint3 DTid : SV_DispatchThreadID) float edge = dist > outlineThreshold ? 1 : 0; float4 color_prev = output[DTid.xy]; - output[DTid.xy] = lerp(color_prev, float4(outlineColor.rgb, color_prev.a), edge); + output[DTid.xy] = lerp(color_prev, outlineColor, edge); } diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index ccf43184f..635c60efc 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -9025,12 +9025,12 @@ void Postprocess_DepthOfField( device->EventEnd(cmd); } void Postprocess_Outline( - const Texture2D& lineardepth, + const Texture2D& input, const Texture2D& output, CommandList cmd, float threshold, float thickness, - const XMFLOAT3& color + const XMFLOAT4& color ) { GraphicsDevice* device = GetDevice(); @@ -9042,7 +9042,7 @@ void Postprocess_Outline( device->BindComputeShader(computeShaders[CSTYPE_POSTPROCESS_OUTLINE], cmd); - device->BindResource(CS, &lineardepth, TEXSLOT_LINEARDEPTH, cmd); + device->BindResource(CS, &input, TEXSLOT_ONDEMAND0, cmd); const TextureDesc& desc = output.GetDesc(); @@ -9056,6 +9056,7 @@ void Postprocess_Outline( cb.xPPParams1.x = color.x; cb.xPPParams1.y = color.y; cb.xPPParams1.z = color.z; + cb.xPPParams1.w = color.w; device->UpdateBuffer(&constantBuffers[CBTYPE_POSTPROCESS], &cb, cmd); device->BindConstantBuffer(CS, &constantBuffers[CBTYPE_POSTPROCESS], CB_GETBINDSLOT(PostProcessCB), cmd); diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index 07973683e..b62544f40 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -32,6 +32,11 @@ namespace wiRenderer static const wiGraphics::FORMAT DSFormat_small = wiGraphics::FORMAT_D16_UNORM; static const wiGraphics::FORMAT DSFormat_small_alias = wiGraphics::FORMAT_R16_TYPELESS; + inline UINT CombineStencilrefs(STENCILREF engineStencilRef, uint8_t userStencilRef) + { + return (userStencilRef << 4) | static_cast(engineStencilRef); + } + const wiGraphics::Sampler* GetSampler(int slot); const wiGraphics::VertexShader* GetVertexShader(VSTYPES id); const wiGraphics::HullShader* GetHullShader(VSTYPES id); @@ -244,12 +249,12 @@ namespace wiRenderer float focus = 10.0f ); void Postprocess_Outline( - const wiGraphics::Texture2D& lineardepth, + const wiGraphics::Texture2D& input, const wiGraphics::Texture2D& output, wiGraphics::CommandList cmd, float threshold = 0.1f, float thickness = 1.0f, - const XMFLOAT3& color = XMFLOAT3(0, 0, 0) + const XMFLOAT4& color = XMFLOAT4(0, 0, 0, 1) ); void Postprocess_MotionBlur( const wiGraphics::Texture2D& input, diff --git a/WickedEngine/wiSceneSystem.cpp b/WickedEngine/wiSceneSystem.cpp index c438dfde4..c91bce97c 100644 --- a/WickedEngine/wiSceneSystem.cpp +++ b/WickedEngine/wiSceneSystem.cpp @@ -1396,12 +1396,15 @@ namespace wiSceneSystem return entity; } Entity Scene::Entity_CreateSound( + const std::string& name, const std::string& filename, const XMFLOAT3& position ) { Entity entity = CreateEntity(); + names.Create(entity) = name; + SoundComponent& sound = sounds.Create(entity); sound.filename = filename; sound.sound = (wiAudio::Sound*)wiResourceManager::GetGlobal().add(filename); diff --git a/WickedEngine/wiSceneSystem.h b/WickedEngine/wiSceneSystem.h index eab4e8ed8..c549ce015 100644 --- a/WickedEngine/wiSceneSystem.h +++ b/WickedEngine/wiSceneSystem.h @@ -7,6 +7,7 @@ #include "ShaderInterop_Renderer.h" #include "wiJobSystem.h" #include "wiAudio.h" +#include "wiRenderer.h" #include "wiECS.h" #include "wiSceneSystem_Decl.h" @@ -168,7 +169,7 @@ namespace wiSceneSystem } inline UINT GetStencilRef() const { - return (userStencilRef << 4) | static_cast(engineStencilRef); + return wiRenderer::CombineStencilrefs(engineStencilRef, userStencilRef); } const wiGraphics::Texture2D* GetBaseColorMap() const; @@ -1075,6 +1076,7 @@ namespace wiSceneSystem const XMFLOAT3& position = XMFLOAT3(0, 0, 0) ); wiECS::Entity Entity_CreateSound( + const std::string& name, const std::string& filename, const XMFLOAT3& position = XMFLOAT3(0, 0, 0) ); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 32f514829..1126aaa4e 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 30; // minor bug fixes, alterations, refactors, updates - const int revision = 2; + const int revision = 3; long GetVersion()