diff --git a/Editor/Source/Editor/Windows/EditorInterface.cpp b/Editor/Source/Editor/Windows/EditorInterface.cpp index f9c8db98..5487066b 100644 --- a/Editor/Source/Editor/Windows/EditorInterface.cpp +++ b/Editor/Source/Editor/Windows/EditorInterface.cpp @@ -2881,7 +2881,7 @@ namespace Nuake { } auto& editorCam = Engine::GetCurrentScene()->m_EditorCamera; - isControllingCamera = editorCam->Update(ts, m_IsHoveringViewport && m_IsViewportFocused); + // isControllingCamera = editorCam->Update(ts, m_IsHoveringViewport && m_IsViewportFocused); const bool entityIsSelected = Selection.Type == EditorSelectionType::Entity && Selection.Entity.IsValid(); if (entityIsSelected && Input::IsKeyPressed(Key::F)) diff --git a/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.cpp b/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.cpp index e351c2b0..529189f9 100644 --- a/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.cpp +++ b/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.cpp @@ -30,6 +30,8 @@ ViewportWidget::~ViewportWidget() void ViewportWidget::Update(float ts) { editorContext.GetScene()->Update(ts); + auto& editorCam = editorContext.GetScene()->m_EditorCamera; + editorCam->Update(ts, isHoveringViewport); } void ViewportWidget::Draw() @@ -45,13 +47,12 @@ void ViewportWidget::Draw() ImVec2 regionAvail = ImGui::GetContentRegionAvail(); Vector2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); - sceneViewport->QueueResize(viewportPanelSize); + bool needsResize = sceneViewport->QueueResize(viewportPanelSize); // This is important for make UI mouse coord relative to viewport // Nuake::Input::SetViewportDimensions(m_ViewportPos, viewportPanelSize); VkDescriptorSet textureDesc = sceneViewport->GetRenderTarget()->GetImGuiDescriptorSet(); - //VkDescriptorSet textureDesc = VkRenderer::Get().DrawImage->GetImGuiDescriptorSet(); ImVec2 imagePos = ImGui::GetWindowPos() + ImGui::GetCursorPos(); // Input::SetEditorViewportSize(m_ViewportPos, viewportPanelSize); @@ -67,7 +68,7 @@ void ViewportWidget::Draw() const ImVec2& windowSize = ImGui::GetWindowSize(); const bool isInsideWidth = mousePos.x > windowPos.x && mousePos.x < windowPos.x + windowSize.x; const bool isInsideHeight = mousePos.y > windowPos.y && mousePos.y < windowPos.y + windowSize.y; - // m_IsHoveringViewport = isInsideWidth && isInsideHeight; + this->isHoveringViewport = isInsideWidth && isInsideHeight; // TODO(antopilo) drag n drop ImGuizmo::SetDrawlist(); diff --git a/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.h b/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.h index 08d9de61..2caf88f9 100644 --- a/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.h +++ b/Editor/Source/Editor/Windows/SceneEditor/Widgets/ViewportWidget.h @@ -21,6 +21,7 @@ private: bool UseSnapping = true; Nuake::Vector3 CurrentSnapping = { 0.05f, 0.05f, 0.05f }; + bool isHoveringViewport; public: ViewportWidget(EditorContext& context); ~ViewportWidget(); diff --git a/Nuake/Source/Nuake/Rendering/Vulkan/SceneViewport.cpp b/Nuake/Source/Nuake/Rendering/Vulkan/SceneViewport.cpp index 29b5397c..3a605d3b 100644 --- a/Nuake/Source/Nuake/Rendering/Vulkan/SceneViewport.cpp +++ b/Nuake/Source/Nuake/Rendering/Vulkan/SceneViewport.cpp @@ -20,6 +20,7 @@ bool Viewport::Resize() viewportSize = queuedResize; renderTarget = CreateRef(ImageFormat::RGBA16F, viewportSize); + renderTarget->GetImGuiDescriptorSet(); return true; } diff --git a/Nuake/Source/Nuake/Rendering/Vulkan/SceneViewport.h b/Nuake/Source/Nuake/Rendering/Vulkan/SceneViewport.h index 8cbe14d1..c0c7869e 100644 --- a/Nuake/Source/Nuake/Rendering/Vulkan/SceneViewport.h +++ b/Nuake/Source/Nuake/Rendering/Vulkan/SceneViewport.h @@ -32,9 +32,11 @@ namespace Nuake viewportSize = size; } - void QueueResize(const Vector2& inSize) + bool QueueResize(const Vector2& inSize) { queuedResize = inSize; + + return queuedResize != viewportSize; } Ref GetRenderTarget() const { return renderTarget; } diff --git a/Nuake/Source/Nuake/Rendering/Vulkan/VulkanRenderer.cpp b/Nuake/Source/Nuake/Rendering/Vulkan/VulkanRenderer.cpp index 4bcb9ddb..0a503724 100644 --- a/Nuake/Source/Nuake/Rendering/Vulkan/VulkanRenderer.cpp +++ b/Nuake/Source/Nuake/Rendering/Vulkan/VulkanRenderer.cpp @@ -368,8 +368,6 @@ void VkRenderer::DrawScenes() Ref viewport = Viewports[view]; assert(viewport && "Viewport is null"); - viewport->Resize(); - ctx.CameraID = viewport->GetViewID(); ctx.Size = viewport->GetRenderTarget()->GetSize(); ctx.ViewportImage = viewport->GetRenderTarget(); @@ -379,6 +377,18 @@ void VkRenderer::DrawScenes() } } +void VkRenderer::ResizeViewports() +{ + for (auto& [scene, views] : SceneViewports) + { + for (auto& view : views) + { + Ref viewport = Viewports[view]; + viewport->Resize(); + } + } +} + void VkRenderer::DrawScene(RenderContext ctx) { //SceneRenderer->BeginScene(ctx); @@ -739,6 +749,8 @@ void VkRenderer::EndDraw() presentInfo.pImageIndices = &swapchainImageIndex; + ResizeViewports(); + VK_CALL(vkQueuePresentKHR(GPUQueue, &presentInfo)); auto& io = ImGui::GetIO(); diff --git a/Nuake/Source/Nuake/Rendering/Vulkan/VulkanRenderer.h b/Nuake/Source/Nuake/Rendering/Vulkan/VulkanRenderer.h index a9373098..5650db1a 100644 --- a/Nuake/Source/Nuake/Rendering/Vulkan/VulkanRenderer.h +++ b/Nuake/Source/Nuake/Rendering/Vulkan/VulkanRenderer.h @@ -227,6 +227,7 @@ namespace Nuake public: void PrepareSceneData(RenderContext ctx); void DrawScenes(); + void ResizeViewports(); void BeginScene(const UUID& camera); bool Draw(); diff --git a/Nuake/Source/Nuake/Rendering/Vulkan/VulkanSceneRenderer.cpp b/Nuake/Source/Nuake/Rendering/Vulkan/VulkanSceneRenderer.cpp index d067262c..4f43ee37 100644 --- a/Nuake/Source/Nuake/Rendering/Vulkan/VulkanSceneRenderer.cpp +++ b/Nuake/Source/Nuake/Rendering/Vulkan/VulkanSceneRenderer.cpp @@ -95,6 +95,9 @@ void VkSceneRenderer::PrepareScenes(const std::vector>& scenes, Rende .Near = camera->Near, .Far = camera->Far, }; + Vector3 pos = cameraView.View[3]; + std::string msg = std::string("Pos X:") + std::to_string(pos.x) + " Y:" + std::to_string(pos.y) + " Z:" + std::to_string(pos.z); + Logger::Log(msg, "camera", VERBOSE); gpu.AddCamera(camera->ID, std::move(cameraView)); auto view = scene->m_Registry.view(); @@ -323,271 +326,5 @@ void VkSceneRenderer::DrawSceneView(RenderContext inContext) inContext.CommandBuffer.CopyImageToImage(sceneRenderPipeline->GetOutput(), inContext.ViewportImage); inContext.CommandBuffer.TransitionImageLayout(inContext.ViewportImage, VK_IMAGE_LAYOUT_GENERAL); inContext.CommandBuffer.TransitionImageLayout(sceneRenderPipeline->GetOutput(), VK_IMAGE_LAYOUT_GENERAL); - inContext.CommandBuffer.TransitionImageLayout(inContext.ViewportImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); } - -// This will prepare all the data and upload it to the GPU before rendering the scene. -//void VkSceneRenderer::BeginScene(RenderContext inContext) -//{ -// Context.CommandBuffer = inContext.CommandBuffer; -// Context.CurrentScene = inContext.CurrentScene; -// Context.CameraID = inContext.CameraID; -// -// auto& scene = Context.CurrentScene; -// auto& gpu = GPUResources::Get(); -// -// uint32_t currentIndex = 0; -// uint32_t currentMaterialIndex = 0; -// std::array allTransforms; -// std::array allMaterials; -// -// // CameraView -// { -// // Clear last frame's cameras -// gpu.ClearCameras(); -// -// // Editor camera, maybe strip this out in runtime? -// const auto& camera = scene->m_EditorCamera; -// CameraView cameraView -// { -// .View = camera->GetTransform(), -// .Projection = camera->GetPerspective(), -// .InverseView = glm::inverse(cameraView.View), -// .InverseProjection = glm::inverse(cameraView.Projection), -// .Position = camera->GetTranslation(), -// .Near = camera->Near, -// .Far = camera->Far, -// }; -// gpu.AddCamera(camera->ID, std::move(cameraView)); -// -// // Add scene cameras -// auto view = scene->m_Registry.view(); -// for (auto e : view) -// { -// const auto& [transform, cameraComponent] = view.get(e); -// const Ref camera = cameraComponent.CameraInstance; -// -// CameraView cameraView -// { -// .View = camera->GetTransform(), -// .Projection = camera->GetPerspective(), -// .InverseView = glm::inverse(cameraView.View), -// .InverseProjection = glm::inverse(cameraView.Projection), -// .Position = camera->GetTranslation(), -// .Near = camera->Near, -// .Far = camera->Far, -// }; -// gpu.AddCamera(camera->ID, std::move(cameraView)); -// } -// } -// -// // CSM Light's view -// { -// auto view = scene->m_Registry.view(); -// for (auto e : view) -// { -// auto [transform, light] = view.get(e); -// for (auto& view : light.m_LightViews) -// { -// CameraView cameraView -// { -// .View = view.View, -// .Projection = view.Proj, -// .InverseView = glm::inverse(view.View), -// .InverseProjection = glm::inverse(view.Proj), -// .Position = transform.GetGlobalTransform()[3], -// .Near = 0, -// .Far = 0, -// }; -// gpu.AddCamera(view.CameraID, std::move(cameraView)); -// } -// } -// } -// -// // All transforms & materials -// { -// auto view = scene->m_Registry.view(); -// for (auto e : view) -// { -// // Check if we've reached the maximum capacity of the array -// if (currentIndex >= MAX_MODEL_MATRIX) -// { -// assert(false && "Max model matrix reached!"); -// break; -// } -// -// auto [transform, mesh, visibility] = view.get(e); -// -// // Get() will load the resource if its not loaded already -// Ref modelResource = mesh.ModelResource.Get(); -// if (!modelResource || !visibility.Visible) -// { -// continue; -// } -// -// // Upload transforms to GPU resources -// allTransforms[currentIndex] = transform.GetGlobalTransform(); -// gpu.ModelMatrixMapping[Entity((entt::entity)e, scene.get()).GetID()] = currentIndex; -// -// // Upload mesh material to GPU resources -// for (auto& m : modelResource->GetMeshes()) -// { -// // TODO: Avoid duplicated materials -// Ref material = m->GetMaterial(); -// if (!material) -// { -// // insert missing material. -// static Ref missingMaterial = CreateRef(); -// missingMaterial->AlbedoImage = TextureManager::Get()->GetTexture2("missing_texture")->GetID(); -// -// material = missingMaterial; -// } -// -// MaterialBufferStruct materialBuffer -// { -// .HasAlbedo = material->HasAlbedo(), -// .AlbedoColor = material->data.m_AlbedoColor, -// .HasNormal = material->HasNormal(), -// .HasMetalness = material->HasMetalness(), -// .HasRoughness = material->HasRoughness(), -// .HasAO = material->HasAO(), -// .MetalnessValue = material->data.u_MetalnessValue, -// .RoughnessValue = material->data.u_RoughnessValue, -// .AoValue = material->data.u_AOValue, -// .AlbedoTextureId = material->HasAlbedo() ? gpu.GetBindlessTextureID(material->AlbedoImage) : 0, -// .NormalTextureId = material->HasNormal() ? gpu.GetBindlessTextureID(material->NormalImage) : 0, -// .MetalnessTextureId = material->HasMetalness() ? gpu.GetBindlessTextureID(material->MetalnessImage) : 0, -// .RoughnessTextureId = material->HasRoughness() ? gpu.GetBindlessTextureID(material->RoughnessImage) : 0, -// .AoTextureId = material->HasAO() ? gpu.GetBindlessTextureID(material->AOImage) : 0, -// }; -// -// // Save bindless mapping index -// allMaterials[currentMaterialIndex] = std::move(materialBuffer); -// gpu.MeshMaterialMapping[m->GetVkMesh()->GetID()] = currentMaterialIndex; -// currentMaterialIndex++; -// } -// -// currentIndex++; -// } -// } -// -// gpu.ModelTransforms = ModelData{ allTransforms }; -// gpu.MaterialDataContainer = MaterialData{ allMaterials }; -// -// // All lights -// { -// uint32_t lightCount = 0; -// std::array allLights; -// auto lightView = scene->m_Registry.view(); -// for (auto e : lightView) -// { -// if (lightCount >= MAX_LIGHTS) -// { -// assert(false && "Max amount of light reached!"); -// break; -// } -// -// auto [transform, lightComp] = lightView.get(e); -// -// // Update light direction with transform, shouldn't be here! -// // TODO: Move to transform system -// lightComp.Direction = transform.GetGlobalRotation() * Vector3(0, 0, -1); -// -// LightData light -// { -// .Position = Vector3(transform.GetGlobalTransform()[3]), -// .Type = lightComp.Type, -// .Color = Vector4(lightComp.Color * lightComp.Strength, 1.0), -// .Direction = lightComp.Direction, -// .OuterConeAngle = glm::cos(Rad(lightComp.OuterCutoff)), -// .InnerConeAngle = glm::cos(Rad(lightComp.Cutoff)), -// .CastShadow = lightComp.CastShadows, -// }; -// -// if (lightComp.CastShadows && lightComp.Type == LightType::Directional) -// { -// for (int i = 0; i < CSM_AMOUNT; i++) -// { -// light.TransformId[i] = gpu.GetBindlessCameraID(lightComp.m_LightViews[i].CameraID); -// light.ShadowMapTextureId[i] = gpu.GetBindlessTextureID(lightComp.m_ShadowMaps[i]->GetID()); -// } -// } -// -// allLights[lightCount] = std::move(light); -// -// lightCount++; -// } -// -// gpu.LightDataContainerArray = LightDataContainer{ allLights }; -// gpu.LightCount = lightCount; -// } -// -// -// // Update transforms, materials and lights. -// // We need to push lights first to have bindless mapping for CSM -// gpu.UpdateBuffers(); -// -// // Update light CSM -// { -// auto view = scene->m_Registry.view(); -// for (auto e : view) -// { -// auto [transform, light] = view.get(e); -// auto cam = gpu.GetCamera(inContext.CameraID); -// -// if (light.Type == LightType::Directional) -// { -// light.CalculateViewProjection(cam.View, cam.Projection); -// } -// } -// } -// -// gpu.RecreateBindlessCameras(); -// -// // Execute light -// PassRenderContext passCtx = { }; -// passCtx.scene = inContext.CurrentScene; -// passCtx.commandBuffer = inContext.CommandBuffer; -// passCtx.resolution = Context.Size; -// passCtx.cameraID = GPUResources::Get().GetBindlessCameraID(inContext.CameraID); -// -// auto view = scene->m_Registry.view(); -// for (auto e : view) -// { -// auto [transform, light] = view.get(e); -// -// if (light.Type != LightType::Directional || !light.CastShadows) -// { -// continue; -// } -// -// light.LightMapIDs.clear(); -// for (int i = 0; i < CSM_AMOUNT; i++) -// { -// light.LightMapIDs.push_back(light.m_ShadowMaps[i]->GetID()); -// passCtx.cameraID = GPUResources::Get().GetBindlessCameraID(light.m_LightViews[i].CameraID); -// passCtx.resolution = Vector2{ 4096, 4096 }; -// shadowRenderPipeline->Render(passCtx, light.m_ShadowMaps[i]); -// } -// } -// -// // Set back the camera ID to the actual desired camera. -// passCtx.cameraID = GPUResources::Get().GetBindlessCameraID(inContext.CameraID); -// passCtx.resolution = Context.Size; -// sceneRenderPipeline->Render(passCtx); -//} - -//void VkSceneRenderer::EndScene() -//{ -// // Copy final output to DrawImage. -// Ref drawImage = VkRenderer::Get().GetDrawImage(); -// Ref output = sceneRenderPipeline->GetOutput(); -// -// Cmd& cmd = Context.CommandBuffer; -// cmd.TransitionImageLayout(output, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); -// cmd.TransitionImageLayout(drawImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); -// cmd.CopyImageToImage(output, drawImage); -// cmd.TransitionImageLayout(drawImage, VK_IMAGE_LAYOUT_GENERAL); -// cmd.TransitionImageLayout(output, VK_IMAGE_LAYOUT_GENERAL); -//} diff --git a/Nuake/Source/Nuake/Scene/EditorCamera.cpp b/Nuake/Source/Nuake/Scene/EditorCamera.cpp index 58bc4ac6..f68cbaaa 100644 --- a/Nuake/Source/Nuake/Scene/EditorCamera.cpp +++ b/Nuake/Source/Nuake/Scene/EditorCamera.cpp @@ -252,6 +252,7 @@ namespace Nuake SetDirection(glm::normalize(Direction)); + mouseLastX = x; mouseLastY = y;