Fix viewport icon rendering on high DPI devices (#1006)
* Clarify ViewportWorldToScreen being in widget space and add DeviceScalingFactor * -Fix viewport icons being draw wrong on high DPI displays -Fix loading viewport icons from absolute paths, which * Address review feedback, fix build
This commit is contained in:
committed by
GitHub
parent
16286fb43b
commit
5e87250f67
+1
@@ -41,6 +41,7 @@ namespace AzManipulatorTestFramework
|
||||
AZStd::optional<AZ::Vector3> ViewportScreenToWorld(const AzFramework::ScreenPoint& screenPosition, float depth) override;
|
||||
AZStd::optional<AzToolsFramework::ViewportInteraction::ProjectedViewportRay> ViewportScreenToWorldRay(
|
||||
const AzFramework::ScreenPoint& screenPosition) override;
|
||||
float DeviceScalingFactor() override;
|
||||
private:
|
||||
// ViewportInteractionRequestBus ...
|
||||
bool GridSnappingEnabled();
|
||||
|
||||
@@ -127,4 +127,9 @@ namespace AzManipulatorTestFramework
|
||||
{
|
||||
return {};
|
||||
}
|
||||
} // namespace AzManipulatorTestFramework
|
||||
|
||||
float ViewportInteraction::DeviceScalingFactor()
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
}// namespace AzManipulatorTestFramework
|
||||
|
||||
@@ -165,15 +165,18 @@ namespace AzToolsFramework
|
||||
virtual bool AngleSnappingEnabled() = 0;
|
||||
/// Return the angle snapping/step size.
|
||||
virtual float AngleStep() = 0;
|
||||
/// Transform a point in world space to screen space coordinates.
|
||||
/// Transform a point in world space to screen space coordinates in Qt Widget space.
|
||||
/// Multiply by DeviceScalingFactor to get the position in viewport pixel space.
|
||||
virtual AzFramework::ScreenPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition) = 0;
|
||||
/// Transform a point in screen space coordinates to a vector in world space based on clip space depth.
|
||||
/// Transform a point from Qt widget screen space to world space based on the given clip space depth.
|
||||
/// Depth specifies a relative camera depth to project in the range of [0.f, 1.f].
|
||||
/// Returns the world space position if successful.
|
||||
virtual AZStd::optional<AZ::Vector3> ViewportScreenToWorld(const AzFramework::ScreenPoint& screenPosition, float depth) = 0;
|
||||
/// Casts a point in screen space to a ray in world space originating from the viewport camera frustum's near plane.
|
||||
/// Returns a ray containing the ray's origin and a direction normal, if successful.
|
||||
virtual AZStd::optional<ProjectedViewportRay> ViewportScreenToWorldRay(const AzFramework::ScreenPoint& screenPosition) = 0;
|
||||
/// Gets the DPI scaling factor that translates Qt widget space into viewport pixel space.
|
||||
virtual float DeviceScalingFactor() = 0;
|
||||
|
||||
protected:
|
||||
~ViewportInteractionRequests() = default;
|
||||
|
||||
@@ -200,6 +200,7 @@ public:
|
||||
{
|
||||
return {};
|
||||
}
|
||||
float DeviceScalingFactor() override { return 1.0f; }
|
||||
|
||||
// AzToolsFramework::ViewportFreezeRequestBus
|
||||
bool IsViewportInputFrozen() override;
|
||||
|
||||
+1
@@ -98,6 +98,7 @@ namespace AtomToolsFramework
|
||||
AZStd::optional<AZ::Vector3> ViewportScreenToWorld(const AzFramework::ScreenPoint& screenPosition, float depth) override;
|
||||
AZStd::optional<AzToolsFramework::ViewportInteraction::ProjectedViewportRay> ViewportScreenToWorldRay(
|
||||
const AzFramework::ScreenPoint& screenPosition) override;
|
||||
float DeviceScalingFactor() override;
|
||||
|
||||
//! Set interface for providing viewport specific settings (e.g. snapping properties).
|
||||
void SetViewportSettings(const AzToolsFramework::ViewportInteraction::ViewportSettings* viewportSettings);
|
||||
|
||||
@@ -313,8 +313,7 @@ namespace AtomToolsFramework
|
||||
// Scale the size by the DPI of the platform to
|
||||
// get the proper size in pixels.
|
||||
const QSize uiWindowSize = size();
|
||||
const qreal deficePixelRatio = devicePixelRatioF();
|
||||
const QSize windowSize = uiWindowSize * deficePixelRatio;
|
||||
const QSize windowSize = uiWindowSize * devicePixelRatioF();
|
||||
|
||||
const AzFramework::NativeWindowHandle windowId = reinterpret_cast<AzFramework::NativeWindowHandle>(winId());
|
||||
AzFramework::WindowNotificationBus::Event(windowId, &AzFramework::WindowNotifications::OnWindowResized, windowSize.width(), windowSize.height());
|
||||
@@ -465,6 +464,11 @@ namespace AtomToolsFramework
|
||||
return AzToolsFramework::ViewportInteraction::ProjectedViewportRay{rayOrigin, rayDirection};
|
||||
}
|
||||
|
||||
float RenderViewportWidget::DeviceScalingFactor()
|
||||
{
|
||||
return aznumeric_cast<float>(devicePixelRatioF());
|
||||
}
|
||||
|
||||
AzFramework::ScreenPoint RenderViewportWidget::ViewportCursorScreenPosition()
|
||||
{
|
||||
return AzToolsFramework::ViewportInteraction::ScreenPointFromQPoint(m_mousePosition.toPoint());
|
||||
|
||||
+32
-14
@@ -18,6 +18,7 @@
|
||||
#include <AzCore/std/containers/array.h>
|
||||
|
||||
#include <AzFramework/Asset/AssetSystemBus.h>
|
||||
#include <AzFramework/Viewport/ViewportScreen.h>
|
||||
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
@@ -145,12 +146,24 @@ namespace AZ::Render
|
||||
}
|
||||
|
||||
// Initialize our shader
|
||||
auto viewportSize = viewportContext->GetViewportSize();
|
||||
AZ::Vector2 viewportSize;
|
||||
{
|
||||
AzFramework::WindowSize viewportWindowSize = viewportContext->GetViewportSize();
|
||||
viewportSize = AZ::Vector2{aznumeric_cast<float>(viewportWindowSize.m_width), aznumeric_cast<float>(viewportWindowSize.m_height)};
|
||||
}
|
||||
AZ::Data::Instance<AZ::RPI::ShaderResourceGroup> drawSrg = dynamicDraw->NewDrawSrg();
|
||||
drawSrg->SetConstant(m_viewportSizeIndex, AZ::Vector2(aznumeric_cast<float>(viewportSize.m_width), aznumeric_cast<float>(viewportSize.m_height)));
|
||||
drawSrg->SetConstant(m_viewportSizeIndex,viewportSize);
|
||||
drawSrg->SetImageView(m_textureParameterIndex, image->GetImageView());
|
||||
drawSrg->Compile();
|
||||
|
||||
// Scale icons by screen DPI
|
||||
float scalingFactor = 1.0f;
|
||||
{
|
||||
using ViewportRequestBus = AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus;
|
||||
ViewportRequestBus::EventResult(
|
||||
scalingFactor, drawParameters.m_viewport, &ViewportRequestBus::Events::DeviceScalingFactor);
|
||||
}
|
||||
|
||||
AZ::Vector3 screenPosition;
|
||||
if (drawParameters.m_positionSpace == CoordinateSpace::ScreenSpace)
|
||||
{
|
||||
@@ -158,9 +171,11 @@ namespace AZ::Render
|
||||
}
|
||||
else if (drawParameters.m_positionSpace == CoordinateSpace::WorldSpace)
|
||||
{
|
||||
using ViewportRequestBus = AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus;
|
||||
AzFramework::ScreenPoint position;
|
||||
ViewportRequestBus::EventResult(position, drawParameters.m_viewport, &ViewportRequestBus::Events::ViewportWorldToScreen, drawParameters.m_position);
|
||||
// Calculate our screen space position using the viewport size
|
||||
// We want this instead of RenderViewportWidget::WorldToScreen which works in QWidget virtual coordinate space
|
||||
AzFramework::ScreenPoint position = AzFramework::WorldToScreen(
|
||||
drawParameters.m_position, viewportContext->GetCameraViewMatrix(), viewportContext->GetCameraProjectionMatrix(),
|
||||
viewportSize);
|
||||
screenPosition.SetX(aznumeric_cast<float>(position.m_x));
|
||||
screenPosition.SetY(aznumeric_cast<float>(position.m_y));
|
||||
}
|
||||
@@ -179,8 +194,8 @@ namespace AZ::Render
|
||||
{
|
||||
Vertex vertex;
|
||||
screenPosition.StoreToFloat3(vertex.m_position);
|
||||
vertex.m_position[0] += offsetX * drawParameters.m_size.GetX();
|
||||
vertex.m_position[1] += offsetY * drawParameters.m_size.GetY();
|
||||
vertex.m_position[0] += offsetX * drawParameters.m_size.GetX() * scalingFactor;
|
||||
vertex.m_position[1] += offsetY * drawParameters.m_size.GetY() * scalingFactor;
|
||||
vertex.m_color = drawParameters.m_color.ToU32();
|
||||
vertex.m_uv[0] = u;
|
||||
vertex.m_uv[1] = v;
|
||||
@@ -197,8 +212,15 @@ namespace AZ::Render
|
||||
dynamicDraw->DrawIndexed(&vertices, vertices.size(), &indices, indices.size(), RHI::IndexFormat::Uint16, drawSrg);
|
||||
}
|
||||
|
||||
QString AtomViewportDisplayIconsSystemComponent::FindAssetPath(const QString& sourceRelativePath) const
|
||||
QString AtomViewportDisplayIconsSystemComponent::FindAssetPath(const QString& path) const
|
||||
{
|
||||
// If we get an absolute path, just use it.
|
||||
QFileInfo pathInfo(path);
|
||||
if (pathInfo.isAbsolute())
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
AZStd::vector<AZStd::string> scanFolders;
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
|
||||
@@ -212,9 +234,9 @@ namespace AZ::Render
|
||||
for (const auto& folder : scanFolders)
|
||||
{
|
||||
QDir dir(folder.data());
|
||||
if (dir.exists(sourceRelativePath))
|
||||
if (dir.exists(path))
|
||||
{
|
||||
return dir.absoluteFilePath(sourceRelativePath);
|
||||
return dir.absoluteFilePath(path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,10 +278,6 @@ namespace AZ::Render
|
||||
AzToolsFramework::EditorViewportIconDisplayInterface::IconId AtomViewportDisplayIconsSystemComponent::GetOrLoadIconForPath(
|
||||
AZStd::string_view path)
|
||||
{
|
||||
AZ_Error(
|
||||
"AtomViewportDisplayIconsSystemComponent", AzFramework::StringFunc::Path::IsRelative(path.data()),
|
||||
"GetOrLoadIconForPath assumes that it will always be given a relative path, but got '%s'", path.data());
|
||||
|
||||
// Check our cache to see if the image is already loaded
|
||||
auto existingEntryIt = AZStd::find_if(m_iconData.begin(), m_iconData.end(), [&path](const auto& iconData)
|
||||
{
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ namespace AZ
|
||||
static constexpr QSize MinimumRenderedSvgSize = QSize(128, 128);
|
||||
static constexpr QImage::Format QtImageFormat = QImage::Format_RGBA8888;
|
||||
|
||||
QString FindAssetPath(const QString& sourceRelativePath) const;
|
||||
QString FindAssetPath(const QString& path) const;
|
||||
QImage RenderSvgToImage(const QString& svgPath) const;
|
||||
AZ::Data::Instance<AZ::RPI::Image> ConvertToAtomImage(AZ::Uuid assetId, QImage image) const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user