Merge pull request #734 from aws-lumberyard-dev/nvsickle/DebugInfoDisplay
Restore debug rendering to the viewport
This commit is contained in:
@@ -145,6 +145,7 @@ struct STextDrawContext
|
||||
Vec2 m_size;
|
||||
Vec2i m_requestSize;
|
||||
float m_widthScale;
|
||||
float m_lineSpacing;
|
||||
|
||||
float m_clipX;
|
||||
float m_clipY;
|
||||
@@ -175,6 +176,7 @@ struct STextDrawContext
|
||||
, m_size(16.0f, 16.0f)
|
||||
, m_requestSize(static_cast<int32>(m_size.x), static_cast<int32>(m_size.y))
|
||||
, m_widthScale(1.0f)
|
||||
, m_lineSpacing(0.f)
|
||||
, m_clipX(0)
|
||||
, m_clipY(0)
|
||||
, m_clipWidth(0)
|
||||
@@ -209,11 +211,13 @@ struct STextDrawContext
|
||||
void SetTransform(const Matrix34& transform) { m_transform = transform; }
|
||||
void SetBaseState(int baseState) { m_baseState = baseState; }
|
||||
void SetOverrideViewProjMatrices(bool overrideViewProjMatrices) { m_overrideViewProjMatrices = overrideViewProjMatrices; }
|
||||
void SetLineSpacing(float lineSpacing) { m_lineSpacing = lineSpacing; }
|
||||
|
||||
float GetCharWidth() const { return m_size.x; }
|
||||
float GetCharHeight() const { return m_size.y; }
|
||||
float GetCharWidthScale() const { return m_widthScale; }
|
||||
int GetFlags() const { return m_drawTextFlags; }
|
||||
float GetLineSpacing() const { return m_lineSpacing; }
|
||||
|
||||
bool IsColorOverridden() const { return m_colorOverride.a != 0; }
|
||||
};
|
||||
|
||||
@@ -24,9 +24,7 @@ namespace AZ
|
||||
AZ_TYPE_INFO_SPECIALIZE(AZStd::chrono::system_clock::time_point, "{5C48FD59-7267-405D-9C06-1EA31379FE82}");
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper that reflects a AZStd::chrono::system_clock::time_point to script.
|
||||
*/
|
||||
//! Wrapper that reflects a AZStd::chrono::system_clock::time_point to script.
|
||||
class ScriptTimePoint
|
||||
{
|
||||
public:
|
||||
@@ -38,33 +36,45 @@ namespace AZ
|
||||
explicit ScriptTimePoint(AZStd::chrono::system_clock::time_point timePoint)
|
||||
: m_timePoint(timePoint) {}
|
||||
|
||||
AZStd::string ToString() const
|
||||
{
|
||||
return AZStd::string::format("Time %llu", m_timePoint.time_since_epoch().count());
|
||||
}
|
||||
//! Formats the time point in a string formatted as: "Time <seconds since epoch>".
|
||||
AZStd::string ToString() const;
|
||||
|
||||
const AZStd::chrono::system_clock::time_point& Get() { return m_timePoint; }
|
||||
//! Returns the time point.
|
||||
const AZStd::chrono::system_clock::time_point& Get() const;
|
||||
|
||||
// Returns the time point in seconds
|
||||
double GetSeconds() const
|
||||
{
|
||||
typedef AZStd::chrono::duration<double> double_seconds;
|
||||
return AZStd::chrono::duration_cast<double_seconds>(m_timePoint.time_since_epoch()).count();
|
||||
}
|
||||
//! Returns the time point in seconds
|
||||
double GetSeconds() const;
|
||||
|
||||
// Returns the time point in milliseconds
|
||||
double GetMilliseconds() const
|
||||
{
|
||||
typedef AZStd::chrono::duration<double, AZStd::milli> double_ms;
|
||||
return AZStd::chrono::duration_cast<double_ms>(m_timePoint.time_since_epoch()).count();
|
||||
}
|
||||
//! Returns the time point in milliseconds
|
||||
double GetMilliseconds() const;
|
||||
|
||||
static void Reflect(ReflectContext* reflection);
|
||||
|
||||
protected:
|
||||
|
||||
AZStd::chrono::system_clock::time_point m_timePoint;
|
||||
};
|
||||
|
||||
inline AZStd::string ScriptTimePoint::ToString() const
|
||||
{
|
||||
return AZStd::string::format("Time %llu", m_timePoint.time_since_epoch().count());
|
||||
}
|
||||
|
||||
inline const AZStd::chrono::system_clock::time_point& ScriptTimePoint::Get() const
|
||||
{
|
||||
return m_timePoint;
|
||||
}
|
||||
|
||||
inline double ScriptTimePoint::GetSeconds() const
|
||||
{
|
||||
typedef AZStd::chrono::duration<double> double_seconds;
|
||||
return AZStd::chrono::duration_cast<double_seconds>(m_timePoint.time_since_epoch()).count();
|
||||
}
|
||||
|
||||
inline double ScriptTimePoint::GetMilliseconds() const
|
||||
{
|
||||
typedef AZStd::chrono::duration<double, AZStd::milli> double_ms;
|
||||
return AZStd::chrono::duration_cast<double_ms>(m_timePoint.time_since_epoch()).count();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -40,17 +40,18 @@ namespace AzFramework
|
||||
//! Standard parameters for drawing text on screen
|
||||
struct TextDrawParameters
|
||||
{
|
||||
ViewportId m_drawViewportId = InvalidViewportId; //! Viewport to draw into
|
||||
AZ::Vector3 m_position; //! world space position for 3d draws, screen space x,y,depth for 2d.
|
||||
AZ::Color m_color = AZ::Colors::White; //! Color to draw the text
|
||||
AZ::Vector2 m_scale = AZ::Vector2(1.0f); //! font scale
|
||||
TextHorizontalAlignment m_hAlign = TextHorizontalAlignment::Left; //! Horizontal text alignment
|
||||
TextVerticalAlignment m_vAlign = TextVerticalAlignment::Top; //! Vertical text alignment
|
||||
bool m_monospace = false; //! disable character proportional spacing
|
||||
bool m_depthTest = false; //! Test character against the depth buffer
|
||||
bool m_virtual800x600ScreenSize = true; //! Text placement and size are scaled relative to a virtual 800x600 resolution
|
||||
bool m_scaleWithWindow = false; //! Font gets bigger as the window gets bigger
|
||||
bool m_multiline = true; //! text respects ascii newline characters
|
||||
ViewportId m_drawViewportId = InvalidViewportId; //!< Viewport to draw into
|
||||
AZ::Vector3 m_position; //!< world space position for 3d draws, screen space x,y,depth for 2d.
|
||||
AZ::Color m_color = AZ::Colors::White; //!< Color to draw the text
|
||||
AZ::Vector2 m_scale = AZ::Vector2(1.0f); //!< font scale
|
||||
float m_lineSpacing; //!< Spacing between new lines, as a percentage of m_scale.
|
||||
TextHorizontalAlignment m_hAlign = TextHorizontalAlignment::Left; //!< Horizontal text alignment
|
||||
TextVerticalAlignment m_vAlign = TextVerticalAlignment::Top; //!< Vertical text alignment
|
||||
bool m_monospace = false; //!< disable character proportional spacing
|
||||
bool m_depthTest = false; //!< Test character against the depth buffer
|
||||
bool m_virtual800x600ScreenSize = true; //!< Text placement and size are scaled relative to a virtual 800x600 resolution
|
||||
bool m_scaleWithWindow = false; //!< Font gets bigger as the window gets bigger
|
||||
bool m_multiline = true; //!< text respects ascii newline characters
|
||||
};
|
||||
|
||||
class FontDrawInterface
|
||||
@@ -63,10 +64,13 @@ namespace AzFramework
|
||||
|
||||
virtual void DrawScreenAlignedText2d(
|
||||
const TextDrawParameters& params,
|
||||
const AZStd::string_view& string) = 0;
|
||||
AZStd::string_view text) = 0;
|
||||
virtual void DrawScreenAlignedText3d(
|
||||
const TextDrawParameters& params,
|
||||
const AZStd::string_view& string) = 0;
|
||||
AZStd::string_view text) = 0;
|
||||
virtual AZ::Vector2 GetTextSize(
|
||||
const TextDrawParameters& params,
|
||||
AZStd::string_view text) = 0;
|
||||
};
|
||||
|
||||
class FontQueryInterface
|
||||
|
||||
+17
-1
@@ -254,7 +254,7 @@ namespace AzToolsFramework
|
||||
m_localTransformDirty = true;
|
||||
m_worldTransformDirty = true;
|
||||
|
||||
if (GetEntity())
|
||||
if (const AZ::Entity* entity = GetEntity())
|
||||
{
|
||||
SetDirty();
|
||||
|
||||
@@ -273,6 +273,22 @@ namespace AzToolsFramework
|
||||
{
|
||||
boundsUnion->OnTransformUpdated(GetEntity());
|
||||
}
|
||||
// Fire a property changed notification for this component
|
||||
if (const AZ::Component* component = entity->FindComponent<Components::TransformComponent>())
|
||||
{
|
||||
PropertyEditorEntityChangeNotificationBus::Event(
|
||||
GetEntityId(), &PropertyEditorEntityChangeNotifications::OnEntityComponentPropertyChanged, component->GetId());
|
||||
}
|
||||
|
||||
// Refresh the property editor if we're selected
|
||||
bool selected = false;
|
||||
ToolsApplicationRequestBus::BroadcastResult(
|
||||
selected, &AzToolsFramework::ToolsApplicationRequests::IsSelected, GetEntityId());
|
||||
if (selected)
|
||||
{
|
||||
ToolsApplicationEvents::Bus::Broadcast(
|
||||
&ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_Values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ ly_add_target(
|
||||
Gem::Atom_RPI.Public
|
||||
Gem::Atom_Feature_Common.Static
|
||||
Gem::AtomToolsFramework.Static
|
||||
Gem::AtomViewportDisplayInfo
|
||||
${additional_dependencies}
|
||||
PUBLIC
|
||||
3rdParty::AWSNativeSDK::Core
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
// Description : CViewportTitleDlg implementation file
|
||||
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "ViewportTitleDlg.h"
|
||||
@@ -36,10 +36,13 @@
|
||||
#include "UsedResources.h"
|
||||
#include "Include/IObjectManager.h"
|
||||
|
||||
#include <AtomLyIntegration/AtomViewportDisplayInfo/AtomViewportInfoDisplayBus.h>
|
||||
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#include "ui_ViewportTitleDlg.h"
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#endif //!defined(Q_MOC_RUN)
|
||||
|
||||
|
||||
// CViewportTitleDlg dialog
|
||||
@@ -63,6 +66,32 @@ inline namespace Helpers
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class CViewportTitleDlgDisplayInfoHelper
|
||||
: public QObject
|
||||
, public AZ::AtomBridge::AtomViewportInfoDisplayNotificationBus::Handler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CViewportTitleDlgDisplayInfoHelper(CViewportTitleDlg* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
AZ::AtomBridge::AtomViewportInfoDisplayNotificationBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
signals:
|
||||
void ViewportInfoStatusUpdated(int newIndex);
|
||||
|
||||
private:
|
||||
void OnViewportInfoDisplayStateChanged(AZ::AtomBridge::ViewportInfoDisplayState state)
|
||||
{
|
||||
emit ViewportInfoStatusUpdated(static_cast<int>(state));
|
||||
}
|
||||
};
|
||||
} //end anonymous namespace
|
||||
|
||||
CViewportTitleDlg::CViewportTitleDlg(QWidget* pParent)
|
||||
: QWidget(pParent)
|
||||
, m_ui(new Ui::ViewportTitleDlg)
|
||||
@@ -115,14 +144,11 @@ void CViewportTitleDlg::OnInitDialog()
|
||||
|
||||
m_ui->m_toggleHelpersBtn->setChecked(GetIEditor()->GetDisplaySettings()->IsDisplayHelpers());
|
||||
|
||||
ICVar* pDisplayInfo(gEnv->pConsole->GetCVar("r_displayInfo"));
|
||||
if (pDisplayInfo)
|
||||
{
|
||||
SFunctor oFunctor;
|
||||
oFunctor.Set(OnChangedDisplayInfo, pDisplayInfo, m_ui->m_toggleDisplayInfoBtn);
|
||||
m_displayInfoCallbackIndex = pDisplayInfo->AddOnChangeFunctor(oFunctor);
|
||||
OnChangedDisplayInfo(pDisplayInfo, m_ui->m_toggleDisplayInfoBtn);
|
||||
}
|
||||
|
||||
// Add a child parented to us that listens for r_displayInfo changes.
|
||||
auto displayInfoHelper = new CViewportTitleDlgDisplayInfoHelper(this);
|
||||
connect(displayInfoHelper, &CViewportTitleDlgDisplayInfoHelper::ViewportInfoStatusUpdated, this, &CViewportTitleDlg::UpdateDisplayInfo);
|
||||
UpdateDisplayInfo();
|
||||
|
||||
connect(m_ui->m_toggleHelpersBtn, &QToolButton::clicked, this, &CViewportTitleDlg::OnToggleHelpers);
|
||||
connect(m_ui->m_toggleDisplayInfoBtn, &QToolButton::clicked, this, &CViewportTitleDlg::OnToggleDisplayInfo);
|
||||
@@ -156,6 +182,29 @@ void CViewportTitleDlg::OnToggleHelpers()
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CViewportTitleDlg::OnToggleDisplayInfo()
|
||||
{
|
||||
AZ::AtomBridge::ViewportInfoDisplayState state = AZ::AtomBridge::ViewportInfoDisplayState::NoInfo;
|
||||
AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::BroadcastResult(
|
||||
state,
|
||||
&AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Events::GetDisplayState
|
||||
);
|
||||
state = aznumeric_cast<AZ::AtomBridge::ViewportInfoDisplayState>(
|
||||
(aznumeric_cast<int>(state)+1) % aznumeric_cast<int>(AZ::AtomBridge::ViewportInfoDisplayState::Invalid));
|
||||
// SetDisplayState will fire OnViewportInfoDisplayStateChanged and notify us, no need to call UpdateDisplayInfo.
|
||||
AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Broadcast(
|
||||
&AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Events::SetDisplayState,
|
||||
state
|
||||
);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CViewportTitleDlg::UpdateDisplayInfo()
|
||||
{
|
||||
AZ::AtomBridge::ViewportInfoDisplayState state = AZ::AtomBridge::ViewportInfoDisplayState::NoInfo;
|
||||
AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::BroadcastResult(
|
||||
state,
|
||||
&AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Events::GetDisplayState
|
||||
);
|
||||
m_ui->m_toggleDisplayInfoBtn->setChecked(state != AZ::AtomBridge::ViewportInfoDisplayState::NoInfo);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -544,10 +593,6 @@ void CViewportTitleDlg::UpdateCustomPresets(const QString& text, QStringList& cu
|
||||
}
|
||||
}
|
||||
|
||||
void CViewportTitleDlg::OnChangedDisplayInfo([[maybe_unused]] ICVar* pDisplayInfo, [[maybe_unused]] QAbstractButton* pDisplayInfoButton)
|
||||
{
|
||||
}
|
||||
|
||||
bool CViewportTitleDlg::eventFilter(QObject* object, QEvent* event)
|
||||
{
|
||||
bool consumeEvent = false;
|
||||
@@ -609,4 +654,5 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
#include "ViewportTitleDlg.moc"
|
||||
#include <moc_ViewportTitleDlg.cpp>
|
||||
|
||||
@@ -60,7 +60,6 @@ public:
|
||||
static void LoadCustomPresets(const QString& section, const QString& keyName, QStringList& outCustompresets);
|
||||
static void SaveCustomPresets(const QString& section, const QString& keyName, const QStringList& custompresets);
|
||||
static void UpdateCustomPresets(const QString& text, QStringList& custompresets);
|
||||
static void OnChangedDisplayInfo(ICVar* pDisplayInfo, QAbstractButton* pDisplayInfoButton);
|
||||
|
||||
bool eventFilter(QObject* object, QEvent* event) override;
|
||||
|
||||
@@ -77,6 +76,7 @@ protected:
|
||||
void OnMaximize();
|
||||
void OnToggleHelpers();
|
||||
void OnToggleDisplayInfo();
|
||||
void UpdateDisplayInfo();
|
||||
|
||||
QString m_title;
|
||||
|
||||
@@ -87,8 +87,6 @@ protected:
|
||||
QStringList m_customFOVPresets;
|
||||
QStringList m_customAspectRatioPresets;
|
||||
|
||||
uint64 m_displayInfoCallbackIndex;
|
||||
|
||||
void OnMenuFOVCustom();
|
||||
|
||||
void CreateFOVMenu();
|
||||
|
||||
@@ -609,14 +609,6 @@ void CComponentEntityObject::InvalidateTM(int nWhyFlags)
|
||||
{
|
||||
Matrix34 worldTransform = GetWorldTM();
|
||||
EBUS_EVENT_ID(m_entityId, AZ::TransformBus, SetWorldTM, LYTransformToAZTransform(worldTransform));
|
||||
|
||||
// When transformed via the editor, make sure the entity is marked dirty for undo capture.
|
||||
EBUS_EVENT(AzToolsFramework::ToolsApplicationRequests::Bus, AddDirtyEntity, m_entityId);
|
||||
|
||||
if (CheckFlags(OBJFLAG_SELECTED))
|
||||
{
|
||||
EBUS_EVENT(AzToolsFramework::ToolsApplicationEvents::Bus, InvalidatePropertyDisplay, AzToolsFramework::Refresh_Values);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,8 @@ namespace AZ
|
||||
const AZ::Matrix4x4& GetViewToWorldMatrix() const;
|
||||
const AZ::Matrix4x4& GetViewToClipMatrix() const;
|
||||
const AZ::Matrix4x4& GetWorldToClipMatrix() const;
|
||||
//! Get the camera's world transform, converted from the viewToWorld matrix's native y-up to z-up
|
||||
AZ::Transform GetCameraTransform() const;
|
||||
|
||||
//! Finalize draw lists in this view. This function should only be called when all
|
||||
//! draw packets for current frame are added.
|
||||
|
||||
@@ -92,6 +92,8 @@ namespace AZ
|
||||
virtual ViewPtr GetCurrentView(const Name& contextName) const = 0;
|
||||
};
|
||||
|
||||
using ViewportContextRequests = AZ::Interface<ViewportContextRequestsInterface>;
|
||||
|
||||
class ViewportContextManagerNotifications
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
|
||||
@@ -110,6 +110,15 @@ namespace AZ
|
||||
InvalidateSrg();
|
||||
}
|
||||
|
||||
AZ::Transform View::GetCameraTransform() const
|
||||
{
|
||||
static const Quaternion yUpToZUp = Quaternion::CreateRotationX(-AZ::Constants::HalfPi);
|
||||
return AZ::Transform::CreateFromQuaternionAndTranslation(
|
||||
Quaternion::CreateFromMatrix4x4(m_viewToWorldMatrix) * yUpToZUp,
|
||||
m_viewToWorldMatrix.GetTranslation()
|
||||
).GetOrthogonalized();
|
||||
}
|
||||
|
||||
void View::SetCameraTransform(const AZ::Matrix3x4& cameraTransform)
|
||||
{
|
||||
m_position = cameraTransform.GetTranslation();
|
||||
@@ -118,7 +127,7 @@ namespace AZ
|
||||
// is in a Z-up world and an identity matrix means that it faces along the positive-Y axis and Z is up.
|
||||
// An identity view matrix on the other hand looks along the negative Z-axis.
|
||||
// So we adjust for this by rotating the camera world matrix by 90 degrees around the X axis.
|
||||
AZ::Matrix3x4 zUpToYUp = AZ::Matrix3x4::CreateRotationX(AZ::Constants::HalfPi);
|
||||
static AZ::Matrix3x4 zUpToYUp = AZ::Matrix3x4::CreateRotationX(AZ::Constants::HalfPi);
|
||||
AZ::Matrix3x4 yUpWorld = cameraTransform * zUpToYUp;
|
||||
|
||||
float viewToWorldMatrixRaw[16] = {
|
||||
|
||||
@@ -194,12 +194,7 @@ namespace AZ
|
||||
|
||||
AZ::Transform ViewportContext::GetCameraTransform() const
|
||||
{
|
||||
const Matrix4x4& worldToViewMatrix = GetDefaultView()->GetViewToWorldMatrix();
|
||||
const Quaternion zUpToYUp = Quaternion::CreateRotationX(-AZ::Constants::HalfPi);
|
||||
return AZ::Transform::CreateFromQuaternionAndTranslation(
|
||||
Quaternion::CreateFromMatrix4x4(worldToViewMatrix) * zUpToYUp,
|
||||
worldToViewMatrix.GetTranslation()
|
||||
).GetOrthogonalized();
|
||||
return GetDefaultView()->GetCameraTransform();
|
||||
}
|
||||
|
||||
void ViewportContext::SetCameraTransform(const AZ::Transform& transform)
|
||||
|
||||
@@ -63,6 +63,7 @@ ly_add_target(
|
||||
Gem::EMotionFX_Atom
|
||||
Gem::ImguiAtom
|
||||
Gem::AtomFont
|
||||
Gem::AtomViewportDisplayInfo
|
||||
)
|
||||
|
||||
if(PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
@@ -104,5 +105,6 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
Gem::ImguiAtom
|
||||
Gem::AtomFont
|
||||
Gem::AtomToolsFramework.Editor
|
||||
Gem::AtomViewportDisplayInfo
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -207,11 +207,15 @@ namespace AZ
|
||||
// AzFramework::FontDrawInterface implementation
|
||||
void DrawScreenAlignedText2d(
|
||||
const AzFramework::TextDrawParameters& params,
|
||||
const AZStd::string_view& string) override;
|
||||
AZStd::string_view text) override;
|
||||
|
||||
void DrawScreenAlignedText3d(
|
||||
const AzFramework::TextDrawParameters& params,
|
||||
const AZStd::string_view& string) override;
|
||||
AZStd::string_view text) override;
|
||||
|
||||
AZ::Vector2 GetTextSize(
|
||||
const AzFramework::TextDrawParameters& params,
|
||||
AZStd::string_view text) override;
|
||||
|
||||
public:
|
||||
FFont(AtomFont* atomFont, const char* fontName);
|
||||
@@ -233,7 +237,7 @@ namespace AZ
|
||||
void Prepare(const char* str, bool updateTexture, const AtomFont::GlyphSize& glyphSize = AtomFont::defaultGlyphSize);
|
||||
void DrawStringUInternal(
|
||||
const RHI::Viewport& viewport,
|
||||
RPI::ViewportContext* viewportContext,
|
||||
RPI::ViewportContextPtr viewportContext,
|
||||
float x,
|
||||
float y,
|
||||
float z,
|
||||
@@ -282,6 +286,16 @@ namespace AZ
|
||||
RPI::WindowContextSharedPtr GetDefaultWindowContext() const;
|
||||
RPI::ViewportContextPtr GetDefaultViewportContext() const;
|
||||
|
||||
struct DrawParameters
|
||||
{
|
||||
TextDrawContext m_ctx;
|
||||
AZ::Vector2 m_position;
|
||||
AZ::Vector2 m_size;
|
||||
AZ::RPI::ViewportContextPtr m_viewportContext;
|
||||
const AZ::RHI::Viewport* m_viewport;
|
||||
};
|
||||
DrawParameters ExtractDrawParameters(const AzFramework::TextDrawParameters& params, AZStd::string_view text, bool forceCalculateSize);
|
||||
|
||||
private:
|
||||
static constexpr uint32_t NumBuffers = 2;
|
||||
static constexpr float WindowScaleWidth = 800.0f;
|
||||
|
||||
@@ -280,7 +280,7 @@ void AZ::FFont::DrawString(float x, float y, const char* str, const bool asciiMu
|
||||
return;
|
||||
}
|
||||
|
||||
DrawStringUInternal(GetDefaultWindowContext()->GetViewport(), GetDefaultViewportContext().get(), x, y, 1.0f, str, asciiMultiLine, ctx);
|
||||
DrawStringUInternal(GetDefaultWindowContext()->GetViewport(), GetDefaultViewportContext(), x, y, 1.0f, str, asciiMultiLine, ctx);
|
||||
}
|
||||
|
||||
void AZ::FFont::DrawString(float x, float y, float z, const char* str, const bool asciiMultiLine, const TextDrawContext& ctx)
|
||||
@@ -290,12 +290,12 @@ void AZ::FFont::DrawString(float x, float y, float z, const char* str, const boo
|
||||
return;
|
||||
}
|
||||
|
||||
DrawStringUInternal(GetDefaultWindowContext()->GetViewport(), GetDefaultViewportContext().get(), x, y, z, str, asciiMultiLine, ctx);
|
||||
DrawStringUInternal(GetDefaultWindowContext()->GetViewport(), GetDefaultViewportContext(), x, y, z, str, asciiMultiLine, ctx);
|
||||
}
|
||||
|
||||
void AZ::FFont::DrawStringUInternal(
|
||||
const RHI::Viewport& viewport,
|
||||
RPI::ViewportContext* viewportContext,
|
||||
RPI::ViewportContextPtr viewportContext,
|
||||
float x,
|
||||
float y,
|
||||
float z,
|
||||
@@ -505,7 +505,7 @@ Vec2 AZ::FFont::GetTextSizeUInternal(
|
||||
}
|
||||
|
||||
charX = offset.x;
|
||||
charY += size.y;
|
||||
charY += size.y * (1.f + ctx.GetLineSpacing());
|
||||
|
||||
if (charY > maxH)
|
||||
{
|
||||
@@ -944,7 +944,7 @@ int AZ::FFont::CreateQuadsForText(const RHI::Viewport& viewport, float x, float
|
||||
case '\n':
|
||||
{
|
||||
charX = baseXY.x + offset.x;
|
||||
charY += size.y;
|
||||
charY += size.y * (1.f + ctx.GetLineSpacing());
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@@ -1675,47 +1675,46 @@ static void SetCommonContextFlags(AZ::TextDrawContext& ctx, const AzFramework::T
|
||||
}
|
||||
}
|
||||
|
||||
void AZ::FFont::DrawScreenAlignedText2d(
|
||||
const AzFramework::TextDrawParameters& params,
|
||||
const AZStd::string_view& string)
|
||||
AZ::FFont::DrawParameters AZ::FFont::ExtractDrawParameters(const AzFramework::TextDrawParameters& params, AZStd::string_view text, bool forceCalculateSize)
|
||||
{
|
||||
DrawParameters internalParams;
|
||||
if (params.m_drawViewportId == AzFramework::InvalidViewportId ||
|
||||
string.empty())
|
||||
text.empty())
|
||||
{
|
||||
return;
|
||||
return internalParams;
|
||||
}
|
||||
|
||||
//Code mostly duplicated from CRenderer::Draw2dTextWithDepth
|
||||
float posX = params.m_position.GetX();
|
||||
float posY = params.m_position.GetY();
|
||||
AZ::RPI::ViewportContext* viewportContext = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get()->GetViewportContextById(params.m_drawViewportId).get();
|
||||
const AZ::RHI::Viewport& viewport = viewportContext->GetWindowContext()->GetViewport();
|
||||
internalParams.m_viewportContext = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get()->GetViewportContextById(params.m_drawViewportId);
|
||||
const AZ::RHI::Viewport& viewport = internalParams.m_viewportContext->GetWindowContext()->GetViewport();
|
||||
internalParams.m_viewport = &viewport;
|
||||
if (params.m_virtual800x600ScreenSize)
|
||||
{
|
||||
posX *= WindowScaleWidth / (viewport.m_maxX - viewport.m_minX);
|
||||
posY *= WindowScaleHeight / (viewport.m_maxY - viewport.m_minY);
|
||||
}
|
||||
TextDrawContext ctx;
|
||||
ctx.SetBaseState(GS_NODEPTHTEST);
|
||||
ctx.SetColor(AZColorToLYColorF(params.m_color));
|
||||
ctx.SetCharWidthScale((params.m_monospace || params.m_scaleWithWindow) ? 0.5f : 1.0f);
|
||||
ctx.EnableFrame(false);
|
||||
ctx.SetProportional(!params.m_monospace && params.m_scaleWithWindow);
|
||||
ctx.SetSizeIn800x600(params.m_scaleWithWindow && params.m_virtual800x600ScreenSize);
|
||||
ctx.SetSize(AZVec2ToLYVec2(UiDraw_TextSizeFactor * params.m_scale));
|
||||
internalParams.m_ctx.SetBaseState(GS_NODEPTHTEST);
|
||||
internalParams.m_ctx.SetColor(AZColorToLYColorF(params.m_color));
|
||||
internalParams.m_ctx.SetCharWidthScale((params.m_monospace || params.m_scaleWithWindow) ? 0.5f : 1.0f);
|
||||
internalParams.m_ctx.EnableFrame(false);
|
||||
internalParams.m_ctx.SetProportional(!params.m_monospace && params.m_scaleWithWindow);
|
||||
internalParams.m_ctx.SetSizeIn800x600(params.m_scaleWithWindow && params.m_virtual800x600ScreenSize);
|
||||
internalParams.m_ctx.SetSize(AZVec2ToLYVec2(UiDraw_TextSizeFactor * params.m_scale));
|
||||
internalParams.m_ctx.SetLineSpacing(params.m_lineSpacing);
|
||||
if (params.m_monospace || !params.m_scaleWithWindow)
|
||||
{
|
||||
ScaleCoord(viewport, posX, posY);
|
||||
}
|
||||
|
||||
if (params.m_hAlign != AzFramework::TextHorizontalAlignment::Left ||
|
||||
params.m_vAlign != AzFramework::TextVerticalAlignment::Top)
|
||||
params.m_vAlign != AzFramework::TextVerticalAlignment::Top ||
|
||||
forceCalculateSize)
|
||||
{
|
||||
Vec2 textSize = GetTextSizeUInternal(viewport, string.data(), params.m_multiline, ctx);
|
||||
|
||||
Vec2 textSize = GetTextSizeUInternal(viewport, text.data(), params.m_multiline, internalParams.m_ctx);
|
||||
// If we're using virtual 800x600 coordinates, convert the text size from
|
||||
// pixels to that before using it as an offset.
|
||||
if (ctx.m_sizeIn800x600)
|
||||
if (internalParams.m_ctx.m_sizeIn800x600)
|
||||
{
|
||||
float width = 1.0f;
|
||||
float height = 1.0f;
|
||||
@@ -1741,33 +1740,46 @@ void AZ::FFont::DrawScreenAlignedText2d(
|
||||
{
|
||||
posY -= textSize.y;
|
||||
}
|
||||
internalParams.m_size = AZ::Vector2{textSize.x, textSize.y};
|
||||
}
|
||||
SetCommonContextFlags(internalParams.m_ctx, params);
|
||||
internalParams.m_ctx.m_drawTextFlags |= eDrawText_2D;
|
||||
internalParams.m_position = AZ::Vector2{posX, posY};
|
||||
return internalParams;
|
||||
}
|
||||
|
||||
void AZ::FFont::DrawScreenAlignedText2d(
|
||||
const AzFramework::TextDrawParameters& params,
|
||||
AZStd::string_view text)
|
||||
{
|
||||
DrawParameters internalParams = ExtractDrawParameters(params, text, false);
|
||||
if (!internalParams.m_viewportContext)
|
||||
{
|
||||
return;
|
||||
}
|
||||
SetCommonContextFlags(ctx, params);
|
||||
ctx.m_drawTextFlags |= eDrawText_2D;
|
||||
|
||||
DrawStringUInternal(
|
||||
viewport,
|
||||
viewportContext,
|
||||
posX,
|
||||
posY,
|
||||
*internalParams.m_viewport,
|
||||
internalParams.m_viewportContext,
|
||||
internalParams.m_position.GetX(),
|
||||
internalParams.m_position.GetY(),
|
||||
params.m_position.GetZ(), // Z
|
||||
string.data(),
|
||||
text.data(),
|
||||
params.m_multiline,
|
||||
ctx
|
||||
internalParams.m_ctx
|
||||
);
|
||||
}
|
||||
|
||||
void AZ::FFont::DrawScreenAlignedText3d(
|
||||
const AzFramework::TextDrawParameters& params,
|
||||
const AZStd::string_view& string)
|
||||
AZStd::string_view text)
|
||||
{
|
||||
if (params.m_drawViewportId == AzFramework::InvalidViewportId ||
|
||||
string.empty())
|
||||
DrawParameters internalParams = ExtractDrawParameters(params, text, false);
|
||||
if (!internalParams.m_viewportContext)
|
||||
{
|
||||
return;
|
||||
}
|
||||
AZ::RPI::ViewportContext* viewportContext = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get()->GetViewportContextById(params.m_drawViewportId).get();
|
||||
AZ::RPI::ViewPtr currentView = viewportContext->GetDefaultView();
|
||||
AZ::RPI::ViewPtr currentView = internalParams.m_viewportContext->GetDefaultView();
|
||||
if (!currentView)
|
||||
{
|
||||
return;
|
||||
@@ -1779,7 +1791,23 @@ void AZ::FFont::DrawScreenAlignedText3d(
|
||||
);
|
||||
AzFramework::TextDrawParameters param2d = params;
|
||||
param2d.m_position = positionNDC;
|
||||
DrawScreenAlignedText2d(param2d, string);
|
||||
|
||||
DrawStringUInternal(
|
||||
*internalParams.m_viewport,
|
||||
internalParams.m_viewportContext,
|
||||
internalParams.m_position.GetX(),
|
||||
internalParams.m_position.GetY(),
|
||||
params.m_position.GetZ(), // Z
|
||||
text.data(),
|
||||
params.m_multiline,
|
||||
internalParams.m_ctx
|
||||
);
|
||||
}
|
||||
|
||||
AZ::Vector2 AZ::FFont::GetTextSize(const AzFramework::TextDrawParameters& params, AZStd::string_view text)
|
||||
{
|
||||
DrawParameters sizeParams = ExtractDrawParameters(params, text, true);
|
||||
return sizeParams.m_size;
|
||||
}
|
||||
|
||||
#endif //USE_NULLFONT_ALWAYS
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
add_subdirectory(Code)
|
||||
@@ -0,0 +1,52 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
ly_add_target(
|
||||
NAME AtomViewportDisplayInfo GEM_MODULE
|
||||
NAMESPACE Gem
|
||||
FILES_CMAKE
|
||||
atomviewportdisplayinfo_files.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
PRIVATE
|
||||
Source
|
||||
PUBLIC
|
||||
Include
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
AZ::AzCore
|
||||
AZ::AtomCore
|
||||
Legacy::CryCommon
|
||||
Gem::Atom_RHI.Reflect
|
||||
Gem::Atom_RPI.Public
|
||||
)
|
||||
|
||||
################################################################################
|
||||
# Tests
|
||||
################################################################################
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
ly_add_target(
|
||||
NAME AtomViewportDisplayInfo.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
|
||||
NAMESPACE Gem
|
||||
FILES_CMAKE
|
||||
atomviewportdisplayinfo_test_files.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
PRIVATE
|
||||
Include
|
||||
Tests
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
AZ::AzTest
|
||||
)
|
||||
ly_add_googletest(
|
||||
NAME Gem::AtomViewportDisplayInfo.Tests
|
||||
)
|
||||
endif()
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace AtomBridge
|
||||
{
|
||||
//! The level of information to display in the viewport info display overlay.
|
||||
enum class ViewportInfoDisplayState : int
|
||||
{
|
||||
NoInfo = 0,
|
||||
NormalInfo = 1,
|
||||
FullInfo = 2,
|
||||
CompactInfo = 3,
|
||||
Invalid
|
||||
};
|
||||
|
||||
//! This bus is used to request changes to the viewport info display overlay.
|
||||
class AtomViewportInfoDisplayRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Single;
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = EBusAddressPolicy::Single;
|
||||
|
||||
//! Gets the current viewport info overlay state.
|
||||
virtual ViewportInfoDisplayState GetDisplayState() const = 0;
|
||||
//! Sets the current viewport info overlay state.
|
||||
//! The overlay will be drawn to the default viewport context every frame, if enabled.
|
||||
virtual void SetDisplayState(ViewportInfoDisplayState state) = 0;
|
||||
};
|
||||
|
||||
using AtomViewportInfoDisplayRequestBus = AZ::EBus<AtomViewportInfoDisplayRequests>;
|
||||
|
||||
//! This bus is used to listen for state changes in the viewport info display overlay.
|
||||
class AtomViewportInfoDisplayNotifications
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Multiple;
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = EBusAddressPolicy::Single;
|
||||
|
||||
//! Called when the ViewportInfoDisplayState (via the r_displayInfo CVar) has changed.
|
||||
virtual void OnViewportInfoDisplayStateChanged([[maybe_unused]]ViewportInfoDisplayState state){}
|
||||
};
|
||||
|
||||
using AtomViewportInfoDisplayNotificationBus = AZ::EBus<AtomViewportInfoDisplayNotifications>;
|
||||
}
|
||||
}
|
||||
+316
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "AtomViewportDisplayInfoSystemComponent.h"
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/EditContextConstants.inl>
|
||||
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <Atom/RPI.Public/ViewportContextBus.h>
|
||||
#include <Atom/RPI.Public/ViewportContext.h>
|
||||
#include <Atom/RPI.Public/View.h>
|
||||
#include <Atom/RPI.Public/Pass/ParentPass.h>
|
||||
#include <Atom/RHI/Factory.h>
|
||||
|
||||
#include <CryCommon/ISystem.h>
|
||||
#include <CryCommon/IConsole.h>
|
||||
|
||||
namespace AZ::Render
|
||||
{
|
||||
AZ_CVAR(int, r_displayInfo, 1, [](const int& newDisplayInfoVal)->void
|
||||
{
|
||||
// Forward this event to the system component so it can update accordingly.
|
||||
// This callback only gets triggered by console commands, so this will not recurse.
|
||||
AtomBridge::AtomViewportInfoDisplayRequestBus::Broadcast(
|
||||
&AtomBridge::AtomViewportInfoDisplayRequestBus::Events::SetDisplayState,
|
||||
aznumeric_cast<AtomBridge::ViewportInfoDisplayState>(newDisplayInfoVal)
|
||||
);
|
||||
}, AZ::ConsoleFunctorFlags::DontReplicate,
|
||||
"Toggles debugging information display.\n"
|
||||
"Usage: r_displayInfo [0=off/1=show/2=enhanced/3=compact]"
|
||||
);
|
||||
AZ_CVAR(float, r_fpsCalcInterval, 1.0f, nullptr, AZ::ConsoleFunctorFlags::DontReplicate,
|
||||
"The time period over which to calculate the framerate for r_displayInfo."
|
||||
);
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serialize->Class<AtomViewportDisplayInfoSystemComponent, AZ::Component>()
|
||||
->Version(0)
|
||||
;
|
||||
|
||||
if (AZ::EditContext* ec = serialize->GetEditContext())
|
||||
{
|
||||
ec->Class<AtomViewportDisplayInfoSystemComponent>("Viewport Display Info", "Manages debug viewport information through r_displayInfo")
|
||||
->ClassElement(Edit::ClassElements::EditorData, "")
|
||||
->Attribute(Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
|
||||
->Attribute(Edit::Attributes::AutoExpand, true)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
{
|
||||
provided.push_back(AZ_CRC("ViewportDisplayInfoService"));
|
||||
}
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC("ViewportDisplayInfoService"));
|
||||
}
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
|
||||
{
|
||||
required.push_back(AZ_CRC("RPISystem", 0xf2add773));
|
||||
}
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
|
||||
{
|
||||
}
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::Activate()
|
||||
{
|
||||
AZ::Name apiName = AZ::RHI::Factory::Get().GetName();
|
||||
if (!apiName.IsEmpty())
|
||||
{
|
||||
m_rendererDescription = AZStd::string::format("Atom using %s RHI", apiName.GetCStr());
|
||||
}
|
||||
|
||||
AZ::RPI::ViewportContextNotificationBus::Handler::BusConnect(
|
||||
AZ::RPI::ViewportContextRequests::Get()->GetDefaultViewportContextName());
|
||||
AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::Deactivate()
|
||||
{
|
||||
AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Handler::BusDisconnect();
|
||||
AZ::RPI::ViewportContextNotificationBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
AZ::RPI::ViewportContextPtr AtomViewportDisplayInfoSystemComponent::GetViewportContext() const
|
||||
{
|
||||
return AZ::RPI::ViewportContextRequests::Get()->GetDefaultViewportContext();
|
||||
}
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::DrawLine(AZStd::string_view line, AZ::Color color)
|
||||
{
|
||||
m_drawParams.m_color = color;
|
||||
AZ::Vector2 textSize = m_fontDrawInterface->GetTextSize(m_drawParams, line);
|
||||
m_fontDrawInterface->DrawScreenAlignedText2d(m_drawParams, line);
|
||||
m_drawParams.m_position.SetY(m_drawParams.m_position.GetY() + textSize.GetY() + m_lineSpacing);
|
||||
}
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::OnRenderTick()
|
||||
{
|
||||
if (!m_fontDrawInterface)
|
||||
{
|
||||
auto fontQueryInterface = AZ::Interface<AzFramework::FontQueryInterface>::Get();
|
||||
if (!fontQueryInterface)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_fontDrawInterface =
|
||||
fontQueryInterface->GetDefaultFontDrawInterface();
|
||||
}
|
||||
AZ::RPI::ViewportContextPtr viewportContext = GetViewportContext();
|
||||
|
||||
if (!m_fontDrawInterface || !viewportContext || !viewportContext->GetRenderScene())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_fpsInterval = AZStd::chrono::seconds(r_fpsCalcInterval);
|
||||
|
||||
UpdateFramerate();
|
||||
|
||||
const AtomBridge::ViewportInfoDisplayState displayLevel = GetDisplayState();
|
||||
if (displayLevel == AtomBridge::ViewportInfoDisplayState::NoInfo)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_updateRootPassQuery)
|
||||
{
|
||||
if (auto rootPass = AZ::RPI::PassSystemInterface::Get()->GetRootPass())
|
||||
{
|
||||
rootPass->SetPipelineStatisticsQueryEnabled(displayLevel != AtomBridge::ViewportInfoDisplayState::CompactInfo);
|
||||
m_updateRootPassQuery = false;
|
||||
}
|
||||
}
|
||||
|
||||
m_drawParams.m_drawViewportId = viewportContext->GetId();
|
||||
auto viewportSize = viewportContext->GetViewportSize();
|
||||
m_drawParams.m_position = AZ::Vector3(viewportSize.m_width, 0.f, 1.f);
|
||||
m_drawParams.m_color = AZ::Colors::White;
|
||||
m_drawParams.m_scale = AZ::Vector2(0.7f);
|
||||
m_drawParams.m_hAlign = AzFramework::TextHorizontalAlignment::Right;
|
||||
m_drawParams.m_monospace = false;
|
||||
m_drawParams.m_depthTest = false;
|
||||
m_drawParams.m_virtual800x600ScreenSize = true;
|
||||
m_drawParams.m_scaleWithWindow = false;
|
||||
m_drawParams.m_multiline = true;
|
||||
m_drawParams.m_lineSpacing = 0.5f;
|
||||
|
||||
// Calculate line spacing based on the font's actual line height
|
||||
const float lineHeight = m_fontDrawInterface->GetTextSize(m_drawParams, " ").GetY();
|
||||
m_lineSpacing = lineHeight * m_drawParams.m_lineSpacing;
|
||||
|
||||
DrawRendererInfo();
|
||||
if (displayLevel == AtomBridge::ViewportInfoDisplayState::FullInfo)
|
||||
{
|
||||
DrawCameraInfo();
|
||||
}
|
||||
if (displayLevel != AtomBridge::ViewportInfoDisplayState::CompactInfo)
|
||||
{
|
||||
DrawPassInfo();
|
||||
}
|
||||
DrawFramerate();
|
||||
}
|
||||
|
||||
AtomBridge::ViewportInfoDisplayState AtomViewportDisplayInfoSystemComponent::GetDisplayState() const
|
||||
{
|
||||
return aznumeric_cast<AtomBridge::ViewportInfoDisplayState>(r_displayInfo.operator int());
|
||||
}
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::SetDisplayState(AtomBridge::ViewportInfoDisplayState state)
|
||||
{
|
||||
r_displayInfo = aznumeric_cast<int>(state);
|
||||
AtomBridge::AtomViewportInfoDisplayNotificationBus::Broadcast(
|
||||
&AtomBridge::AtomViewportInfoDisplayNotificationBus::Events::OnViewportInfoDisplayStateChanged,
|
||||
state);
|
||||
m_updateRootPassQuery = true;
|
||||
}
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::DrawRendererInfo()
|
||||
{
|
||||
DrawLine(m_rendererDescription, AZ::Colors::Yellow);
|
||||
}
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::DrawCameraInfo()
|
||||
{
|
||||
AZ::RPI::ViewportContextPtr viewportContext = GetViewportContext();
|
||||
AZ::RPI::ViewPtr currentView = viewportContext->GetDefaultView();
|
||||
if (currentView == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto viewportSize = viewportContext->GetViewportSize();
|
||||
AzFramework::CameraState cameraState;
|
||||
AzFramework::SetCameraClippingVolumeFromPerspectiveFovMatrixRH(cameraState, currentView->GetViewToClipMatrix());
|
||||
const AZ::Transform transform = currentView->GetCameraTransform();
|
||||
const AZ::Vector3 translation = transform.GetTranslation();
|
||||
const AZ::Vector3 rotation = transform.GetEulerDegrees();
|
||||
DrawLine(AZStd::string::format(
|
||||
"CamPos=%.2f %.2f %.2f Angl=%3.0f %3.0f %4.0f ZN=%.2f ZF=%.0f",
|
||||
translation.GetX(), translation.GetY(), translation.GetZ(),
|
||||
rotation.GetX(), rotation.GetY(), rotation.GetZ(),
|
||||
cameraState.m_nearClip, cameraState.m_farClip
|
||||
));
|
||||
}
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::DrawPassInfo()
|
||||
{
|
||||
auto rootPass = AZ::RPI::PassSystemInterface::Get()->GetRootPass();
|
||||
const RPI::PipelineStatisticsResult stats = rootPass->GetLatestPipelineStatisticsResult();
|
||||
AZStd::function<int(const AZ::RPI::Ptr<AZ::RPI::Pass>)> containingPassCount = [&containingPassCount](const AZ::RPI::Ptr<AZ::RPI::Pass> pass)
|
||||
{
|
||||
int count = 1;
|
||||
if (auto passAsParent = pass->AsParent())
|
||||
{
|
||||
for (const auto& child : passAsParent->GetChildren())
|
||||
{
|
||||
count += containingPassCount(child);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
};
|
||||
const int numPasses = containingPassCount(rootPass);
|
||||
DrawLine(AZStd::string::format(
|
||||
"Total Passes: %d Vertex Count: %lld Primitive Count: %lld",
|
||||
numPasses,
|
||||
aznumeric_cast<long long>(stats.m_vertexCount),
|
||||
aznumeric_cast<long long>(stats.m_primitiveCount)
|
||||
));
|
||||
}
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::UpdateFramerate()
|
||||
{
|
||||
if (!m_tickRequests)
|
||||
{
|
||||
m_tickRequests = AZ::TickRequestBus::FindFirstHandler();
|
||||
if (!m_tickRequests)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AZ::ScriptTimePoint currentTime = m_tickRequests->GetTimeAtCurrentTick();
|
||||
// Only keep as much sampling data as is required by our FPS history.
|
||||
while (!m_fpsHistory.empty() && (currentTime.Get() - m_fpsHistory.front().Get()) > m_fpsInterval)
|
||||
{
|
||||
m_fpsHistory.pop_front();
|
||||
}
|
||||
|
||||
// Discard entries with a zero time-delta (can happen when we don't have window focus).
|
||||
if (m_fpsHistory.empty() || (currentTime.Get() - m_fpsHistory.back().Get()) != AZStd::chrono::seconds(0))
|
||||
{
|
||||
m_fpsHistory.push_back(currentTime);
|
||||
}
|
||||
}
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::DrawFramerate()
|
||||
{
|
||||
AZStd::chrono::duration<double> actualInterval = AZStd::chrono::seconds(0);
|
||||
AZStd::optional<AZ::ScriptTimePoint> lastTime;
|
||||
AZStd::optional<double> minFPS;
|
||||
AZStd::optional<double> maxFPS;
|
||||
for (const AZ::ScriptTimePoint& time : m_fpsHistory)
|
||||
{
|
||||
if (lastTime.has_value())
|
||||
{
|
||||
AZStd::chrono::duration<double> deltaTime = time.Get() - lastTime.value().Get();
|
||||
double fps = AZStd::chrono::seconds(1) / deltaTime;
|
||||
if (!minFPS.has_value())
|
||||
{
|
||||
minFPS = fps;
|
||||
maxFPS = fps;
|
||||
}
|
||||
else
|
||||
{
|
||||
minFPS = AZStd::min(minFPS.value(), fps);
|
||||
maxFPS = AZStd::max(maxFPS.value(), fps);
|
||||
}
|
||||
actualInterval += deltaTime;
|
||||
}
|
||||
lastTime = time;
|
||||
}
|
||||
|
||||
const double averageFPS = aznumeric_cast<double>(m_fpsHistory.size()) / actualInterval.count();
|
||||
const double frameIntervalSeconds = m_fpsInterval.count();
|
||||
|
||||
DrawLine(
|
||||
AZStd::string::format(
|
||||
"FPS %.1f [%.0f..%.0f], frame avg over %.1fs",
|
||||
averageFPS,
|
||||
minFPS.value_or(0.0),
|
||||
maxFPS.value_or(0.0),
|
||||
frameIntervalSeconds),
|
||||
AZ::Colors::Yellow);
|
||||
}
|
||||
} // namespace AZ::Render
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/Component.h>
|
||||
|
||||
#include <CryCommon/CrySystemBus.h>
|
||||
#include <AzCore/Script/ScriptTimePoint.h>
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <AzFramework/Font/FontInterface.h>
|
||||
#include <Atom/RPI.Public/Base.h>
|
||||
#include <Atom/RPI.Public/ViewportContextBus.h>
|
||||
#include <AtomLyIntegration/AtomViewportDisplayInfo/AtomViewportInfoDisplayBus.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class TickRequests;
|
||||
|
||||
namespace Render
|
||||
{
|
||||
class AtomViewportDisplayInfoSystemComponent
|
||||
: public AZ::Component
|
||||
, public AZ::RPI::ViewportContextNotificationBus::Handler
|
||||
, public AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(AtomViewportDisplayInfoSystemComponent, "{AC32F173-E7E2-4943-8E6C-7C3091978221}");
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
|
||||
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
|
||||
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
|
||||
|
||||
protected:
|
||||
// AZ::Component overrides...
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
|
||||
// AZ::RPI::ViewportContextNotificationBus::Handler overrides...
|
||||
void OnRenderTick() override;
|
||||
|
||||
// AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Handler overrides...
|
||||
AtomBridge::ViewportInfoDisplayState GetDisplayState() const override;
|
||||
void SetDisplayState(AtomBridge::ViewportInfoDisplayState state) override;
|
||||
|
||||
private:
|
||||
AZ::RPI::ViewportContextPtr GetViewportContext() const;
|
||||
void DrawLine(AZStd::string_view line, AZ::Color color = AZ::Colors::White);
|
||||
|
||||
void UpdateFramerate();
|
||||
|
||||
void DrawRendererInfo();
|
||||
void DrawCameraInfo();
|
||||
void DrawPassInfo();
|
||||
void DrawFramerate();
|
||||
|
||||
AZStd::string m_rendererDescription;
|
||||
AzFramework::TextDrawParameters m_drawParams;
|
||||
AzFramework::FontDrawInterface* m_fontDrawInterface = nullptr;
|
||||
float m_lineSpacing;
|
||||
AZStd::chrono::duration<double> m_fpsInterval = AZStd::chrono::seconds(1);
|
||||
AZStd::deque<AZ::ScriptTimePoint> m_fpsHistory;
|
||||
AZStd::optional<AZStd::chrono::system_clock::time_point> m_lastMemoryUpdate;
|
||||
AZ::TickRequests* m_tickRequests = nullptr;
|
||||
bool m_updateRootPassQuery = true;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
#include <AzCore/Module/Module.h>
|
||||
|
||||
#include "AtomViewportDisplayInfoSystemComponent.h"
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
class AtomViewportDisplayInfoModule
|
||||
: public AZ::Module
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(AtomViewportDisplayInfoModule, "{B10C0E55-03A1-4A46-AE3E-D3615AEAA659}", AZ::Module);
|
||||
AZ_CLASS_ALLOCATOR(AtomViewportDisplayInfoModule, AZ::SystemAllocator, 0);
|
||||
|
||||
AtomViewportDisplayInfoModule()
|
||||
: AZ::Module()
|
||||
{
|
||||
m_descriptors.insert(m_descriptors.end(), {
|
||||
AtomViewportDisplayInfoSystemComponent::CreateDescriptor(),
|
||||
});
|
||||
}
|
||||
|
||||
AZ::ComponentTypeList GetRequiredSystemComponents() const override
|
||||
{
|
||||
return AZ::ComponentTypeList{
|
||||
azrtti_typeid<AtomViewportDisplayInfoSystemComponent>(),
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
// DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM
|
||||
// The first parameter should be GemName_GemIdLower
|
||||
// The second should be the fully qualified name of the class above
|
||||
AZ_DECLARE_MODULE_CLASS(Gem_AtomViewportDisplayInfo, AZ::Render::AtomViewportDisplayInfoModule)
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzTest/AzTest.h>
|
||||
|
||||
AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);
|
||||
|
||||
TEST(AtomViewportDisplayInfoSanityTest, Sanity)
|
||||
{
|
||||
EXPECT_EQ(1, 1);
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
set(FILES
|
||||
Source/AtomViewportDisplayInfoSystemComponent.cpp
|
||||
Source/AtomViewportDisplayInfoSystemComponent.h
|
||||
Source/Module.cpp
|
||||
)
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
set(FILES
|
||||
Source/Tests/test_Main.cpp
|
||||
)
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"gem_name": "AtomLyIntegration_AtomViewportDisplayInfo",
|
||||
"display_name": "Atom Viewport Display Info Overlay",
|
||||
"summary": "Provides a diagnostic viewport overlay for the default O3DE Atom viewport.",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
"user_tags": [
|
||||
"AtomLyIntegration",
|
||||
"AtomViewportDisplayInfo"
|
||||
]
|
||||
}
|
||||
@@ -16,3 +16,4 @@ add_subdirectory(EMotionFXAtom)
|
||||
add_subdirectory(AtomFont)
|
||||
add_subdirectory(TechnicalArt)
|
||||
add_subdirectory(AtomBridge)
|
||||
add_subdirectory(AtomViewportDisplayInfo)
|
||||
|
||||
@@ -160,6 +160,17 @@ namespace Camera
|
||||
incompatible.push_back(AZ_CRC("CameraService", 0x1dd1caa4));
|
||||
}
|
||||
|
||||
void CameraComponentController::Init()
|
||||
{
|
||||
m_onViewMatrixChanged = AZ::Event<const AZ::Matrix4x4&>::Handler([this](const AZ::Matrix4x4&)
|
||||
{
|
||||
if (!m_updatingTransformFromEntity)
|
||||
{
|
||||
AZ::TransformBus::Event(m_entityId, &AZ::TransformInterface::SetWorldTM, m_atomCamera->GetCameraTransform());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void CameraComponentController::Activate(AZ::EntityId entityId)
|
||||
{
|
||||
m_entityId = entityId;
|
||||
@@ -218,6 +229,8 @@ namespace Camera
|
||||
}
|
||||
}
|
||||
AZ::RPI::ViewProviderBus::Handler::BusConnect(m_entityId);
|
||||
|
||||
m_atomCamera->ConnectWorldToViewMatrixChangedHandler(m_onViewMatrixChanged);
|
||||
}
|
||||
|
||||
UpdateCamera();
|
||||
@@ -258,6 +271,7 @@ namespace Camera
|
||||
if (atomViewportRequests)
|
||||
{
|
||||
AZ::RPI::ViewProviderBus::Handler::BusDisconnect(m_entityId);
|
||||
m_onViewMatrixChanged.Disconnect();
|
||||
}
|
||||
|
||||
DeactivateAtomView();
|
||||
@@ -376,7 +390,9 @@ namespace Camera
|
||||
|
||||
if (m_atomCamera)
|
||||
{
|
||||
m_updatingTransformFromEntity = true;
|
||||
m_atomCamera->SetCameraTransform(AZ::Matrix3x4::CreateFromTransform(world.GetOrthogonalized()));
|
||||
m_updatingTransformFromEntity = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,7 +441,9 @@ namespace Camera
|
||||
m_config.m_nearClipDistance,
|
||||
m_config.m_farClipDistance,
|
||||
true);
|
||||
m_updatingTransformFromEntity = true;
|
||||
m_atomCamera->SetViewToClipMatrix(viewToClipMatrix);
|
||||
m_updatingTransformFromEntity = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ namespace Camera
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
|
||||
|
||||
void Init();
|
||||
void Activate(AZ::EntityId entityId);
|
||||
void Deactivate();
|
||||
void SetConfiguration(const CameraComponentConfig& config);
|
||||
@@ -121,6 +122,8 @@ namespace Camera
|
||||
// Atom integration
|
||||
AZ::RPI::ViewPtr m_atomCamera;
|
||||
AZ::RPI::AuxGeomDrawPtr m_atomAuxGeom;
|
||||
AZ::Event<const AZ::Matrix4x4&>::Handler m_onViewMatrixChanged;
|
||||
bool m_updatingTransformFromEntity = false;
|
||||
|
||||
// Cry view integration
|
||||
IView* m_view = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user