diff --git a/Editor/CameraComponentWindow.cpp b/Editor/CameraComponentWindow.cpp index 3d7c8c6c9..1e2409c61 100644 --- a/Editor/CameraComponentWindow.cpp +++ b/Editor/CameraComponentWindow.cpp @@ -4,6 +4,62 @@ using namespace wi::ecs; using namespace wi::scene; +void CameraPreview::RenderPreview() +{ + if (renderpath.scene != nullptr) + { + // Camera pointers can change because they are stored in ComponentManager array, so get its pointer every time: + CameraComponent* camera = renderpath.scene->cameras.GetComponent(entity); + if (camera != nullptr) + { + renderpath.camera = camera; + scale_local.y = scale_local.x * renderpath.camera->height / renderpath.camera->width; + renderpath.setSceneUpdateEnabled(false); // we just view our scene with this that's updated by the main rernderpath + renderpath.PreUpdate(); + renderpath.Update(0); + renderpath.PostUpdate(); + renderpath.Render(); + } + else + { + renderpath.camera = nullptr; + } + } +} +void CameraPreview::Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const +{ + wi::gui::Widget::Render(canvas, cmd); + + if (renderpath.scene != nullptr && renderpath.camera != nullptr) + { + wi::image::Params params; + params.pos = translation; + params.siz = XMFLOAT2(scale.x, scale.y); + params.color = shadow_color; + params.blendFlag = wi::enums::BLENDMODE_ALPHA; + params.enableCornerRounding(); + params.corners_rounding[0].radius = 10; + params.corners_rounding[1].radius = 10; + params.corners_rounding[2].radius = 10; + params.corners_rounding[3].radius = 10; + wi::image::Draw(wi::texturehelper::getWhite(), params, cmd); + + params.pos.x += 4; + params.pos.y += 4; + params.siz.x -= 8; + params.siz.y -= 8; + params.corners_rounding[0].radius = 8; + params.corners_rounding[1].radius = 8; + params.corners_rounding[2].radius = 8; + params.corners_rounding[3].radius = 8; + params.color = wi::Color::White(); + params.blendFlag = wi::enums::BLENDMODE_OPAQUE; + wi::image::Draw(renderpath.GetLastPostprocessRT(), params, cmd); + + wi::font::Draw("Camera preview:", wi::font::Params(params.pos.x + 2, params.pos.y + 2), cmd); + } +} + void CameraComponentWindow::Create(EditorComponent* _editor) { editor = _editor; @@ -11,7 +67,7 @@ void CameraComponentWindow::Create(EditorComponent* _editor) editor->GetCurrentEditorScene().camera_transform.MatrixTransform(editor->GetCurrentEditorScene().camera.GetInvView()); editor->GetCurrentEditorScene().camera_transform.UpdateTransform(); - SetSize(XMFLOAT2(320, 200)); + SetSize(XMFLOAT2(320, 400)); closeButton.SetTooltip("Delete CameraComponent"); OnClose([=](wi::gui::EventArgs args) { @@ -135,6 +191,9 @@ void CameraComponentWindow::Create(EditorComponent* _editor) AddWidget(&apertureShapeYSlider); + AddWidget(&preview); + + SetEntity(INVALID_ENTITY); SetPos(XMFLOAT2(100, 100)); @@ -144,10 +203,11 @@ void CameraComponentWindow::Create(EditorComponent* _editor) void CameraComponentWindow::SetEntity(Entity entity) { + bool changed = this->entity != entity; this->entity = entity; Scene& scene = editor->GetCurrentScene(); - const CameraComponent* camera = scene.cameras.GetComponent(entity); + CameraComponent* camera = scene.cameras.GetComponent(entity); if (camera != nullptr) { @@ -158,6 +218,18 @@ void CameraComponentWindow::SetEntity(Entity entity) apertureSizeSlider.SetValue(camera->aperture_size); apertureShapeXSlider.SetValue(camera->aperture_shape.x); apertureShapeYSlider.SetValue(camera->aperture_shape.y); + + preview.entity = entity; + preview.renderpath.scene = &scene; + preview.renderpath.width = 480; + preview.renderpath.height = 272; + } + else if (changed) + { + preview.entity = INVALID_ENTITY; + preview.renderpath.scene = nullptr; + preview.renderpath.camera = nullptr; + preview.renderpath.DeleteGPUResources(); } } @@ -205,5 +277,6 @@ void CameraComponentWindow::ResizeLayout() add(apertureSizeSlider); add(apertureShapeXSlider); add(apertureShapeYSlider); + add_fullwidth(preview); } diff --git a/Editor/CameraComponentWindow.h b/Editor/CameraComponentWindow.h index 81eba3a14..791f4adea 100644 --- a/Editor/CameraComponentWindow.h +++ b/Editor/CameraComponentWindow.h @@ -1,6 +1,17 @@ #pragma once class EditorComponent; +class CameraPreview : public wi::gui::Widget +{ +public: + wi::RenderPath3D renderpath; + wi::ecs::Entity entity = wi::ecs::INVALID_ENTITY; + + void RenderPreview(); + + void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const override; +}; + class CameraComponentWindow : public wi::gui::Window { public: @@ -18,6 +29,8 @@ public: wi::gui::Slider apertureShapeXSlider; wi::gui::Slider apertureShapeYSlider; + CameraPreview preview; + void ResizeLayout() override; }; diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 7bcf85b9e..8939eeea2 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -1925,6 +1925,13 @@ void EditorComponent::PostUpdate() RenderPath2D::PostUpdate(); renderPath->PostUpdate(); + + // This needs to be after scene was updated fully by EditorComponent's renderPath + // Because this will just render the scene without updating its resources + if (renderPath->getSceneUpdateEnabled()) // only update preview if scene was updated at all by main renderPath + { + componentsWnd.cameraComponentWnd.preview.RenderPreview(); + } } void EditorComponent::Render() const { diff --git a/WickedEngine/wiRenderPath2D.cpp b/WickedEngine/wiRenderPath2D.cpp index 0ea3c1d54..cc013d24f 100644 --- a/WickedEngine/wiRenderPath2D.cpp +++ b/WickedEngine/wiRenderPath2D.cpp @@ -8,6 +8,15 @@ using namespace wi::graphics; namespace wi { + void RenderPath2D::DeleteGPUResources() + { + current_buffersize = {}; + current_layoutscale = 0; // invalidate layout + + rtFinal = {}; + rtStenciled = {}; + rtStenciled_resolved = {}; + } void RenderPath2D::ResizeBuffers() { diff --git a/WickedEngine/wiRenderPath2D.h b/WickedEngine/wiRenderPath2D.h index 3abe34508..bc1c48341 100644 --- a/WickedEngine/wiRenderPath2D.h +++ b/WickedEngine/wiRenderPath2D.h @@ -26,6 +26,8 @@ namespace wi float hdr_scaling = 9.0f; public: + // Delete GPU resources and initialize them to default + virtual void DeleteGPUResources(); // create resolution dependent resources, such as render targets virtual void ResizeBuffers(); // update DPI dependent elements, such as GUI elements, sprites diff --git a/WickedEngine/wiRenderPath3D.cpp b/WickedEngine/wiRenderPath3D.cpp index e5544a285..f7a6eb75b 100644 --- a/WickedEngine/wiRenderPath3D.cpp +++ b/WickedEngine/wiRenderPath3D.cpp @@ -14,6 +14,8 @@ namespace wi void RenderPath3D::DeleteGPUResources() { + RenderPath2D::DeleteGPUResources(); + rtMain = {}; rtMain_render = {}; rtPrimitiveID = {}; @@ -355,31 +357,31 @@ namespace wi scene->camera = *camera; scene->Update(dt * wi::renderer::GetGameSpeed()); + } - // Frustum culling for main camera: - visibility_main.layerMask = getLayerMask(); - visibility_main.scene = scene; - visibility_main.camera = camera; - visibility_main.flags = wi::renderer::Visibility::ALLOW_EVERYTHING; - wi::renderer::UpdateVisibility(visibility_main); + // Frustum culling for main camera: + visibility_main.layerMask = getLayerMask(); + visibility_main.scene = scene; + visibility_main.camera = camera; + visibility_main.flags = wi::renderer::Visibility::ALLOW_EVERYTHING; + wi::renderer::UpdateVisibility(visibility_main); - if (visibility_main.planar_reflection_visible) - { - // Frustum culling for planar reflections: - camera_reflection = *camera; - camera_reflection.jitter = XMFLOAT2(0, 0); - camera_reflection.Reflect(visibility_main.reflectionPlane); - visibility_reflection.layerMask = getLayerMask(); - visibility_reflection.scene = scene; - visibility_reflection.camera = &camera_reflection; - visibility_reflection.flags = - wi::renderer::Visibility::ALLOW_OBJECTS | - wi::renderer::Visibility::ALLOW_EMITTERS | - wi::renderer::Visibility::ALLOW_HAIRS | - wi::renderer::Visibility::ALLOW_LIGHTS - ; - wi::renderer::UpdateVisibility(visibility_reflection); - } + if (visibility_main.planar_reflection_visible) + { + // Frustum culling for planar reflections: + camera_reflection = *camera; + camera_reflection.jitter = XMFLOAT2(0, 0); + camera_reflection.Reflect(visibility_main.reflectionPlane); + visibility_reflection.layerMask = getLayerMask(); + visibility_reflection.scene = scene; + visibility_reflection.camera = &camera_reflection; + visibility_reflection.flags = + wi::renderer::Visibility::ALLOW_OBJECTS | + wi::renderer::Visibility::ALLOW_EMITTERS | + wi::renderer::Visibility::ALLOW_HAIRS | + wi::renderer::Visibility::ALLOW_LIGHTS + ; + wi::renderer::UpdateVisibility(visibility_reflection); } XMUINT2 internalResolution = GetInternalResolution(); @@ -683,7 +685,7 @@ namespace wi camera_reflection.texture_vxgi_specular_index = -1; video_cmd = {}; - if (scene->videos.GetCount() > 0) + if (getSceneUpdateEnabled() && scene->videos.GetCount() > 0) { for (size_t i = 0; i < scene->videos.GetCount(); ++i) { diff --git a/WickedEngine/wiRenderPath3D.h b/WickedEngine/wiRenderPath3D.h index 722fbde47..5815a345c 100644 --- a/WickedEngine/wiRenderPath3D.h +++ b/WickedEngine/wiRenderPath3D.h @@ -161,7 +161,7 @@ namespace wi virtual void RenderTransparents(wi::graphics::CommandList cmd) const; virtual void RenderPostprocessChain(wi::graphics::CommandList cmd) const; - void DeleteGPUResources(); + void DeleteGPUResources() override; void ResizeBuffers() override; wi::scene::CameraComponent* camera = &wi::scene::GetCamera(); diff --git a/WickedEngine/wiRenderPath3D_PathTracing.cpp b/WickedEngine/wiRenderPath3D_PathTracing.cpp index ddf901da3..7b937123c 100644 --- a/WickedEngine/wiRenderPath3D_PathTracing.cpp +++ b/WickedEngine/wiRenderPath3D_PathTracing.cpp @@ -389,9 +389,9 @@ namespace wi cmd, denoiserAlbedo.IsValid() ? &denoiserAlbedo : nullptr, denoiserNormal.IsValid() ? &denoiserNormal : nullptr, - traceDepth.IsValid() ? &traceDepth : nullptr, - traceStencil.IsValid() ? &traceStencil : nullptr, - depthBuffer_Main.IsValid() ? &depthBuffer_Main : nullptr + &traceDepth, + &traceStencil, + &depthBuffer_Main ); wi::profiler::EndRange(range); // Traced Scene @@ -471,21 +471,11 @@ namespace wi // Composite other effects on top: { - if (depthBuffer_Main.IsValid()) - { - RenderPassImage rp[] = { - RenderPassImage::DepthStencil(&depthBuffer_Main, RenderPassImage::LoadOp::LOAD), - RenderPassImage::RenderTarget(&rtMain, RenderPassImage::LoadOp::CLEAR) - }; - device->RenderPassBegin(rp, arraysize(rp), cmd); - } - else - { - RenderPassImage rp[] = { - RenderPassImage::RenderTarget(&rtMain, RenderPassImage::LoadOp::CLEAR) - }; - device->RenderPassBegin(rp, arraysize(rp), cmd); - } + RenderPassImage rp[] = { + RenderPassImage::DepthStencil(&depthBuffer_Main, RenderPassImage::LoadOp::LOAD), + RenderPassImage::RenderTarget(&rtMain, RenderPassImage::LoadOp::CLEAR) + }; + device->RenderPassBegin(rp, arraysize(rp), cmd); Viewport vp; vp.width = (float)rtMain.GetDesc().width; diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 6f247762d..67a3667d6 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -3009,8 +3009,9 @@ void UpdateVisibility(Visibility& vis) if (vis.flags & Visibility::ALLOW_LIGHTS) { // Cull lights: - vis.visibleLights.resize(vis.scene->aabb_lights.size()); - wi::jobsystem::Dispatch(ctx, (uint32_t)vis.scene->aabb_lights.size(), groupSize, [&](wi::jobsystem::JobArgs args) { + const uint32_t light_loop = (uint32_t)std::min(vis.scene->aabb_lights.size(), vis.scene->lights.GetCount()); + vis.visibleLights.resize(light_loop); + wi::jobsystem::Dispatch(ctx, light_loop, groupSize, [&](wi::jobsystem::JobArgs args) { // Setup stream compaction: uint32_t& group_count = *(uint32_t*)args.sharedmemory; @@ -3062,8 +3063,9 @@ void UpdateVisibility(Visibility& vis) if (vis.flags & Visibility::ALLOW_OBJECTS) { // Cull objects: - vis.visibleObjects.resize(vis.scene->aabb_objects.size()); - wi::jobsystem::Dispatch(ctx, (uint32_t)vis.scene->aabb_objects.size(), groupSize, [&](wi::jobsystem::JobArgs args) { + const uint32_t object_loop = (uint32_t)std::min(vis.scene->aabb_objects.size(), vis.scene->objects.GetCount()); + vis.visibleObjects.resize(object_loop); + wi::jobsystem::Dispatch(ctx, object_loop, groupSize, [&](wi::jobsystem::JobArgs args) { // Setup stream compaction: uint32_t& group_count = *(uint32_t*)args.sharedmemory; @@ -3135,8 +3137,9 @@ void UpdateVisibility(Visibility& vis) if (vis.flags & Visibility::ALLOW_DECALS) { - vis.visibleDecals.resize(vis.scene->aabb_decals.size()); - wi::jobsystem::Dispatch(ctx, (uint32_t)vis.scene->aabb_decals.size(), groupSize, [&](wi::jobsystem::JobArgs args) { + const uint32_t decal_loop = (uint32_t)std::min(vis.scene->aabb_decals.size(), vis.scene->decals.GetCount()); + vis.visibleDecals.resize(decal_loop); + wi::jobsystem::Dispatch(ctx, decal_loop, groupSize, [&](wi::jobsystem::JobArgs args) { // Setup stream compaction: uint32_t& group_count = *(uint32_t*)args.sharedmemory; diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 3f21a480b..568455d45 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 373; + const int revision = 374; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision); @@ -115,6 +115,7 @@ Willow Aldo lokimx K. Osterman +Nomad )"; return credits;