diff --git a/data/assets/examples/dashboarditem/dashboarditemdate/date_no-decoration.asset b/data/assets/examples/dashboarditem/dashboarditemdate/date_no-decoration.asset index 9ef1348dff..cf781099ba 100644 --- a/data/assets/examples/dashboarditem/dashboarditemdate/date_no-decoration.asset +++ b/data/assets/examples/dashboarditem/dashboarditemdate/date_no-decoration.asset @@ -1,6 +1,6 @@ -- No Decorations -- This example adds a new DashboardItem that shows the current in-game simulation date --- without any additional text surrounding the current date +-- without any additional text surrounding the current date. local Item = { Identifier = "DashboardItemDate_Example_NoDecoration", diff --git a/data/assets/examples/screenspacerenderable/screenspacedate/date.asset b/data/assets/examples/screenspacerenderable/screenspacedate/date.asset new file mode 100644 index 0000000000..d5dbcd34b0 --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspacedate/date.asset @@ -0,0 +1,16 @@ +-- Basic +-- This example creates a screen space renderable that shows the current simulation time. + +local Object = { + Type = "ScreenSpaceDate", + Identifier = "ScreenSpaceDate_Example", + Name = "ScreenSpace Date Example - Basic" +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(Object) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(Object) +end) diff --git a/data/assets/examples/screenspacerenderable/screenspacedate/date_day-of-year.asset b/data/assets/examples/screenspacerenderable/screenspacedate/date_day-of-year.asset new file mode 100644 index 0000000000..5963451ac6 --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspacedate/date_day-of-year.asset @@ -0,0 +1,18 @@ +-- Day of Year +-- This example creates a screen space renderable that shows the current simulation time +-- with the current year and the number of days that have passed in the year. + +local Object = { + Type = "ScreenSpaceDate", + Identifier = "ScreenSpaceDate_Example_DayOfYear", + Name = "ScreenSpace Date Example - Day of Year", + TimeFormat = "YYYY DOY" +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(Object) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(Object) +end) diff --git a/data/assets/examples/screenspacerenderable/screenspacedate/date_font.asset b/data/assets/examples/screenspacerenderable/screenspacedate/date_font.asset new file mode 100644 index 0000000000..f0b0531312 --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspacedate/date_font.asset @@ -0,0 +1,19 @@ +-- Font +-- This example creates a screen space renderable that shows the current simulation time +-- with a non-standard font. This is using one of the fonts that is loaded by default in the +-- openspace.cfg file. + +local Object = { + Type = "ScreenSpaceDate", + Identifier = "ScreenSpaceDate_Example_Font", + Name = "ScreenSpace Date Example - Font", + FontName = "Light" +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(Object) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(Object) +end) diff --git a/data/assets/examples/screenspacerenderable/screenspacedate/date_fontsize.asset b/data/assets/examples/screenspacerenderable/screenspacedate/date_fontsize.asset new file mode 100644 index 0000000000..244d01df2e --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspacedate/date_fontsize.asset @@ -0,0 +1,21 @@ +-- Font Size +-- This example creates a screen space renderable that shows the current simulation time +-- with a larger font. The FontSize parameter is increased to improve the fidelity of the +-- text being rendered. The Scale parameter will make the text show up larger on the +-- screen. + +local Object = { + Type = "ScreenSpaceDate", + Identifier = "ScreenSpaceDate_Example_FontSize", + Name = "ScreenSpace Date Example - Font Size", + Scale = 0.5, + FontSize = 72 +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(Object) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(Object) +end) diff --git a/data/assets/examples/screenspacerenderable/screenspacedate/date_no-decoration.asset b/data/assets/examples/screenspacerenderable/screenspacedate/date_no-decoration.asset new file mode 100644 index 0000000000..5127bb2a7a --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspacedate/date_no-decoration.asset @@ -0,0 +1,18 @@ +-- No Decorations +-- This example creates a screen space renderable that shows the current simulation time +-- without any additional text surrounding the current date. + +local Object = { + Type = "ScreenSpaceDate", + Identifier = "ScreenSpaceDate_Example_NoDecoration", + Name = "ScreenSpace Date Example - No Decoration", + FormatString = "{}" +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(Object) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(Object) +end) diff --git a/data/assets/examples/screenspacerenderable/screenspacedate/date_timezone.asset b/data/assets/examples/screenspacerenderable/screenspacedate/date_timezone.asset new file mode 100644 index 0000000000..de7b4e8c57 --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspacedate/date_timezone.asset @@ -0,0 +1,18 @@ +-- Timezone +-- This example creates a screen space renderable that shows the current simulation time +-- with a timezone of UTC-7 (=PDT) + +local Object = { + Type = "ScreenSpaceDate", + Identifier = "ScreenSpaceDate_Example_Timezone", + Name = "ScreenSpace Date Example - Timezone", + TimeFormat = "YYYY MON DD HR:MN:SC.### PDT ::UTC-7" +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(Object) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(Object) +end) diff --git a/data/assets/examples/screenspacerenderable/screenspacedate/date_year-month-day.asset b/data/assets/examples/screenspacerenderable/screenspacedate/date_year-month-day.asset new file mode 100644 index 0000000000..8df9bc5222 --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspacedate/date_year-month-day.asset @@ -0,0 +1,18 @@ +-- Year Month Day +-- This example creates a screen space renderable that shows the current simulation time +-- with a resolution of days. + +local Object = { + Type = "ScreenSpaceDate", + Identifier = "ScreenSpaceDate_Example_YearMonthDay", + Name = "ScreenSpace Date Example - Year/Month/Day", + TimeFormat = "YYYY MON DD" +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(Object) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(Object) +end) diff --git a/data/assets/examples/screenspacerenderable/screenspaceinsetblackout/insetblackout.asset b/data/assets/examples/screenspacerenderable/screenspaceinsetblackout/insetblackout.asset index d5a5dff740..6ab08c8610 100644 --- a/data/assets/examples/screenspacerenderable/screenspaceinsetblackout/insetblackout.asset +++ b/data/assets/examples/screenspacerenderable/screenspaceinsetblackout/insetblackout.asset @@ -7,7 +7,7 @@ local inset = { Type = "ScreenSpaceInsetBlackout", Name = "ScreenSpaceInsetBlackout Example - Basic", Blackoutshape = { - -- Must always contain four corners in the following order: + -- Must always contain four corners in the following order: -- top-left, top-right, bottom-right, bottom-left Corners = { {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {0.0, 0.0} } }, diff --git a/data/assets/examples/screenspacerenderable/screenspacetext/text.asset b/data/assets/examples/screenspacerenderable/screenspacetext/text.asset new file mode 100644 index 0000000000..270f3c31f4 --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspacetext/text.asset @@ -0,0 +1,16 @@ +-- Basic +-- This example creates a screen space renderable that displays a static text. + +local Object = { + Type = "ScreenSpaceText", + Identifier = "ScreenSpaceText_Example", + Text = "Example Text" +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(Object) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(Object) +end) diff --git a/data/assets/examples/screenspacerenderable/screenspacetext/text_font.asset b/data/assets/examples/screenspacerenderable/screenspacetext/text_font.asset new file mode 100644 index 0000000000..e5503c2a2c --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspacetext/text_font.asset @@ -0,0 +1,19 @@ +-- Basic +-- This example creates a screen space renderable that displays a static text with a +-- non-standard font. This is using one of the fonts that is loaded by default in the +-- openspace.cfg file. + +local Object = { + Type = "ScreenSpaceText", + Identifier = "ScreenSpaceText_Example_Font", + Text = "Example Text - Font", + FontName = "Light" +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(Object) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(Object) +end) diff --git a/data/assets/examples/screenspacerenderable/screenspacetext/text_fontsize.asset b/data/assets/examples/screenspacerenderable/screenspacetext/text_fontsize.asset new file mode 100644 index 0000000000..43fd35f742 --- /dev/null +++ b/data/assets/examples/screenspacerenderable/screenspacetext/text_fontsize.asset @@ -0,0 +1,20 @@ +-- Basic +-- This example creates a screen space renderable that displays a static text with a +-- larger font. The FontSize parameter is increased to improve the fidelity of the text +-- being rendered. The Scale parameter will make the text show up larger on the screen. + +local Object = { + Type = "ScreenSpaceText", + Identifier = "ScreenSpaceText_Example_FontSize", + Text = "Example Text - Font Size", + Scale = 0.5, + FontSize = 72 +} + +asset.onInitialize(function() + openspace.addScreenSpaceRenderable(Object) +end) + +asset.onDeinitialize(function() + openspace.removeScreenSpaceRenderable(Object) +end) diff --git a/modules/base/rendering/screenspaceframebuffer.h b/include/openspace/rendering/screenspacerenderableframebuffer.h similarity index 89% rename from modules/base/rendering/screenspaceframebuffer.h rename to include/openspace/rendering/screenspacerenderableframebuffer.h index ec0c7be83d..13f8f6f89f 100644 --- a/modules/base/rendering/screenspaceframebuffer.h +++ b/include/openspace/rendering/screenspacerenderableframebuffer.h @@ -22,8 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __OPENSPACE_MODULE_BASE___SCREENSPACEFRAMEBUFFER___H__ -#define __OPENSPACE_MODULE_BASE___SCREENSPACEFRAMEBUFFER___H__ +#ifndef __OPENSPACE_CORE___SCREENSPACEFRAMEBUFFER___H__ +#define __OPENSPACE_CORE___SCREENSPACEFRAMEBUFFER___H__ #include @@ -44,19 +44,18 @@ namespace documentation { struct Documentation; } * an attached texture. The texture is then used on a screen space plane that works both * in fisheye and flat screens. */ -class ScreenSpaceFramebuffer : public ScreenSpaceRenderable { +class ScreenSpaceRenderableFramebuffer : public ScreenSpaceRenderable { public: using RenderFunction = std::function; - explicit ScreenSpaceFramebuffer(const ghoul::Dictionary& dictionary); - virtual ~ScreenSpaceFramebuffer() override; + explicit ScreenSpaceRenderableFramebuffer(const ghoul::Dictionary& dictionary); + virtual ~ScreenSpaceRenderableFramebuffer() override; void initializeGL() override; void deinitializeGL() override; void render(const RenderData& renderData) override; bool isReady() const override; - void setSize(glm::vec2 size); void addRenderFunction(RenderFunction renderFunction); void removeAllRenderFunctions(); @@ -79,4 +78,4 @@ private: } //namespace openspace -#endif // __OPENSPACE_MODULE_BASE___SCREENSPACEFRAMEBUFFER___H__ +#endif // __OPENSPACE_CORE___SCREENSPACEFRAMEBUFFER___H__ diff --git a/include/openspace/rendering/screenspacerenderabletext.h b/include/openspace/rendering/screenspacerenderabletext.h new file mode 100644 index 0000000000..ed5f10429e --- /dev/null +++ b/include/openspace/rendering/screenspacerenderabletext.h @@ -0,0 +1,77 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2025 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_CORE___SCREENSPACERENDERABLETEXT___H__ +#define __OPENSPACE_CORE___SCREENSPACERENDERABLETEXT___H__ + +#include + +#include +#include +#include + +namespace ghoul { class Dictionary; } +namespace ghoul::opengl { + class FramebufferObject; + class Texture; +} // namespace ghoul::opengl +namespace ghoul::fontrendering { class Font; } + +namespace openspace { + +namespace documentation { struct Documentation; } + +class ScreenSpaceRenderableText : public ScreenSpaceRenderable { +public: + explicit ScreenSpaceRenderableText(const ghoul::Dictionary& dictionary); + + void initializeGL() override; + void deinitializeGL() override; + bool isReady() const override; + + void update() override; + void render(const RenderData& renderData) override; + + static documentation::Documentation Documentation(); + +protected: + std::string _buffer; + +private: + void updateFramebuffer(); + void bindTexture() override; + + properties::StringProperty _fontName; + properties::FloatProperty _fontSize; + + std::shared_ptr _font; + std::unique_ptr _fontRenderer; + + std::unique_ptr _framebuffer; + std::unique_ptr _texture; +}; + +} //namespace openspace + +#endif // __OPENSPACE_CORE___SCREENSPACERENDERABLETEXT___H__ diff --git a/modules/base/CMakeLists.txt b/modules/base/CMakeLists.txt index 0a00290254..07a8bc007c 100644 --- a/modules/base/CMakeLists.txt +++ b/modules/base/CMakeLists.txt @@ -71,11 +71,12 @@ set(HEADER_FILES rendering/renderabletrailorbit.h rendering/renderabletrailtrajectory.h rendering/screenspacedashboard.h - rendering/screenspaceframebuffer.h + rendering/screenspacedate.h rendering/screenspaceimagelocal.h rendering/screenspaceimageonline.h rendering/screenspaceinsetblackout.h rendering/screenspacerenderablerenderable.h + rendering/screenspacetext.h rendering/screenspacetimevaryingimageonline.h rotation/timelinerotation.h rotation/constantrotation.h @@ -149,11 +150,12 @@ set(SOURCE_FILES rendering/renderabletrailtrajectory.cpp rendering/screenspacedashboard.cpp rendering/screenspacedashboard_lua.inl - rendering/screenspaceframebuffer.cpp + rendering/screenspacedate.cpp rendering/screenspaceimagelocal.cpp rendering/screenspaceimageonline.cpp rendering/screenspaceinsetblackout.cpp rendering/screenspacerenderablerenderable.cpp + rendering/screenspacetext.cpp rendering/screenspacetimevaryingimageonline.cpp rotation/timelinerotation.cpp rotation/constantrotation.cpp diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index f37d0b9961..22f16a8437 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -67,11 +67,12 @@ #include #include #include -#include #include #include #include #include +#include +#include #include #include #include @@ -115,7 +116,6 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) { ghoul_assert(fSsRenderable, "ScreenSpaceRenderable factory was not created"); fSsRenderable->registerClass("ScreenSpaceDashboard"); - fSsRenderable->registerClass("ScreenSpaceFramebuffer"); fSsRenderable->registerClass("ScreenSpaceImageLocal"); fSsRenderable->registerClass("ScreenSpaceImageOnline"); fSsRenderable->registerClass("ScreenSpaceInsetBlackout"); @@ -125,6 +125,8 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) { fSsRenderable->registerClass( "ScreenSpaceTimeVaryingImageOnline" ); + fSsRenderable->registerClass("ScreenSpaceDate"); + fSsRenderable->registerClass("ScreenSpaceText"); ghoul::TemplateFactory* fDashboard = @@ -308,11 +310,12 @@ std::vector BaseModule::documentations() const { SizeMappingComponent::Documentation(), ScreenSpaceDashboard::Documentation(), - ScreenSpaceFramebuffer::Documentation(), + ScreenSpaceDate::Documentation(), ScreenSpaceImageLocal::Documentation(), ScreenSpaceImageOnline::Documentation(), ScreenSpaceInsetBlackout::Documentation(), ScreenSpaceRenderableRenderable::Documentation(), + ScreenSpaceText::Documentation(), ScreenSpaceTimeVaryingImageOnline::Documentation(), ConstantRotation::Documentation(), diff --git a/modules/base/rendering/screenspacedashboard.cpp b/modules/base/rendering/screenspacedashboard.cpp index 5ee3eb0e53..2492f87fc4 100644 --- a/modules/base/rendering/screenspacedashboard.cpp +++ b/modules/base/rendering/screenspacedashboard.cpp @@ -69,7 +69,7 @@ documentation::Documentation ScreenSpaceDashboard::Documentation() { } ScreenSpaceDashboard::ScreenSpaceDashboard(const ghoul::Dictionary& dictionary) - : ScreenSpaceFramebuffer(dictionary) + : ScreenSpaceRenderableFramebuffer(dictionary) , _useMainDashboard(UseMainInfo, false) { const Parameters p = codegen::bake(dictionary); @@ -98,7 +98,7 @@ ScreenSpaceDashboard::ScreenSpaceDashboard(const ghoul::Dictionary& dictionary) } void ScreenSpaceDashboard::initializeGL() { - ScreenSpaceFramebuffer::initializeGL(); + ScreenSpaceRenderableFramebuffer::initializeGL(); addRenderFunction([this]() { glm::vec2 penPosition = glm::vec2(0.f, _size.value().x); diff --git a/modules/base/rendering/screenspacedashboard.h b/modules/base/rendering/screenspacedashboard.h index 9a2cf07575..21579a4a54 100644 --- a/modules/base/rendering/screenspacedashboard.h +++ b/modules/base/rendering/screenspacedashboard.h @@ -25,7 +25,7 @@ #ifndef __OPENSPACE_MODULE_BASE___SCREENSPACEDASHBOARD___H__ #define __OPENSPACE_MODULE_BASE___SCREENSPACEDASHBOARD___H__ -#include +#include #include #include @@ -40,7 +40,7 @@ namespace openspace { namespace documentation { struct Documentation; } namespace scripting { struct LuaLibrary; } -class ScreenSpaceDashboard : public ScreenSpaceFramebuffer { +class ScreenSpaceDashboard : public ScreenSpaceRenderableFramebuffer { public: explicit ScreenSpaceDashboard(const ghoul::Dictionary& dictionary); virtual ~ScreenSpaceDashboard() override = default; diff --git a/modules/base/rendering/screenspacedate.cpp b/modules/base/rendering/screenspacedate.cpp new file mode 100644 index 0000000000..a4fd2aaf0e --- /dev/null +++ b/modules/base/rendering/screenspacedate.cpp @@ -0,0 +1,108 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2025 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +namespace { + constexpr openspace::properties::Property::PropertyInfo FormatStringInfo = { + "FormatString", + "Format string", + "The format text describing how this dashboard item renders its text. This text " + "must contain exactly one {} which is a placeholder that will contain the date " + "in the format as specified by `TimeFormat`.", + openspace::properties::Property::Visibility::AdvancedUser + }; + + constexpr openspace::properties::Property::PropertyInfo TimeFormatInfo = { + "TimeFormat", + "Time format", + "The format string used for formatting the date/time before being passed to the " + "string in FormatString. See " + "https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/timout_c.html for full " + "information about how to structure this format.", + openspace::properties::Property::Visibility::User + }; + + // This `ScreenSpaceRenderable` shows the current in-game simulation time. The + // `FormatString` and the `TimeFormat` options provide the ability to customize the + // output that is printed. See these two parameters for more information on how to + // structure the inputs. + struct [[codegen::Dictionary(ScreenSpaceTextDate)]] Parameters { + // [[codegen::verbatim(FormatStringInfo.description)]] + std::optional formatString; + + // [[codegen::verbatim(TimeFormatInfo.description)]] + std::optional timeFormat; + }; +#include "screenspacedate_codegen.cpp" +} // namespace + +namespace openspace { + +documentation::Documentation ScreenSpaceDate::Documentation() { + return codegen::doc( + "base_screenspace_date", + ScreenSpaceRenderableText::Documentation() + ); +} + +ScreenSpaceDate::ScreenSpaceDate(const ghoul::Dictionary& dictionary) + : ScreenSpaceRenderableText(dictionary) + , _formatString(FormatStringInfo, "Date: {}") + , _timeFormat(TimeFormatInfo, "YYYY MON DD HR:MN:SC.### UTC ::RND") +{ + const Parameters p = codegen::bake(dictionary); + + _formatString = p.formatString.value_or(_formatString); + addProperty(_formatString); + + _timeFormat = p.timeFormat.value_or(_timeFormat); + addProperty(_timeFormat); +} + +void ScreenSpaceDate::update() { + std::string time = SpiceManager::ref().dateFromEphemerisTime( + global::timeManager->time().j2000Seconds(), + _timeFormat.value().c_str() + ); + + try { + // @CPP26(abock): This can be replaced with std::runtime_format + _buffer = std::vformat(_formatString.value(), std::make_format_args(time)); + } + catch (const std::format_error&) { + LERRORC("ScreenSpaceDate", "Illegal format string"); + } + + ScreenSpaceRenderableText::update(); +} + +} // namespace openspace diff --git a/modules/base/rendering/screenspacedate.h b/modules/base/rendering/screenspacedate.h new file mode 100644 index 0000000000..e96e276129 --- /dev/null +++ b/modules/base/rendering/screenspacedate.h @@ -0,0 +1,49 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2025 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_BASE___SCREENSPACEDATE___H__ +#define __OPENSPACE_MODULE_BASE___SCREENSPACEDATE___H__ + +#include + +#include + +namespace openspace { + +class ScreenSpaceDate : public ScreenSpaceRenderableText { +public: + explicit ScreenSpaceDate(const ghoul::Dictionary& dictionary); + + void update() override; + + static documentation::Documentation Documentation(); + +private: + properties::StringProperty _formatString; + properties::StringProperty _timeFormat; +}; + +} // namespace openspace + +#endif // __OPENSPACE_MODULE_BASE___SCREENSPACEDATE___H__ diff --git a/modules/base/rendering/screenspacerenderablerenderable.cpp b/modules/base/rendering/screenspacerenderablerenderable.cpp index ee5c8967ad..48927938c9 100644 --- a/modules/base/rendering/screenspacerenderablerenderable.cpp +++ b/modules/base/rendering/screenspacerenderablerenderable.cpp @@ -143,13 +143,13 @@ namespace openspace { documentation::Documentation ScreenSpaceRenderableRenderable::Documentation() { return codegen::doc( "base_screenspace_renderable", - ScreenSpaceFramebuffer::Documentation() + ScreenSpaceRenderableFramebuffer::Documentation() ); } ScreenSpaceRenderableRenderable::ScreenSpaceRenderableRenderable( const ghoul::Dictionary& dictionary) - : ScreenSpaceFramebuffer(dictionary) + : ScreenSpaceRenderableFramebuffer(dictionary) , _time( TimeInfo, 0.0, @@ -232,7 +232,7 @@ ScreenSpaceRenderableRenderable::ScreenSpaceRenderableRenderable( ScreenSpaceRenderableRenderable::~ScreenSpaceRenderableRenderable() {} void ScreenSpaceRenderableRenderable::initialize() { - ScreenSpaceFramebuffer::initialize(); + ScreenSpaceRenderableFramebuffer::initialize(); _transform.translation->initialize(); _transform.rotation->initialize(); _transform.scale->initialize(); @@ -240,7 +240,7 @@ void ScreenSpaceRenderableRenderable::initialize() { } void ScreenSpaceRenderableRenderable::initializeGL() { - ScreenSpaceFramebuffer::initializeGL(); + ScreenSpaceRenderableFramebuffer::initializeGL(); _renderable->initializeGL(); @@ -288,7 +288,7 @@ void ScreenSpaceRenderableRenderable::deinitializeGL() { _renderable->deinitializeGL(); _renderable->deinitialize(); - ScreenSpaceFramebuffer::deinitializeGL(); + ScreenSpaceRenderableFramebuffer::deinitializeGL(); } void ScreenSpaceRenderableRenderable::update() { diff --git a/modules/base/rendering/screenspacerenderablerenderable.h b/modules/base/rendering/screenspacerenderablerenderable.h index ee5a55d6e8..7905eee1fe 100644 --- a/modules/base/rendering/screenspacerenderablerenderable.h +++ b/modules/base/rendering/screenspacerenderablerenderable.h @@ -25,7 +25,7 @@ #ifndef __OPENSPACE_MODULE_BASE___SCREENSPACERENDERABLERENDERABLE___H__ #define __OPENSPACE_MODULE_BASE___SCREENSPACERENDERABLERENDERABLE___H__ -#include +#include #include #include @@ -43,7 +43,7 @@ class Translation; namespace documentation { struct Documentation; } -class ScreenSpaceRenderableRenderable : public ScreenSpaceFramebuffer { +class ScreenSpaceRenderableRenderable : public ScreenSpaceRenderableFramebuffer { public: using RenderFunction = std::function; diff --git a/modules/base/rendering/screenspacetext.cpp b/modules/base/rendering/screenspacetext.cpp new file mode 100644 index 0000000000..aa45a0461a --- /dev/null +++ b/modules/base/rendering/screenspacetext.cpp @@ -0,0 +1,71 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2025 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include + +namespace { + constexpr openspace::properties::Property::PropertyInfo TextInfo = { + "Text", + "Text", + "The text to be displayed.", + openspace::properties::Property::Visibility::User + }; + + // This `ScreenSpaceRenderable` shows a static text that can be changed via a + // property. + struct [[codegen::Dictionary(DashboardItemText)]] Parameters { + // [[codegen::verbatim(TextInfo.description)]] + std::optional text; + }; +#include "screenspacetext_codegen.cpp" +} // namespace + +namespace openspace { + +documentation::Documentation ScreenSpaceText::Documentation() { + return codegen::doc( + "base_screenspace_text", + ScreenSpaceRenderableText::Documentation() + ); +} + +ScreenSpaceText::ScreenSpaceText(const ghoul::Dictionary& dictionary) + : ScreenSpaceRenderableText(dictionary) + , _text(TextInfo, "") +{ + const Parameters p = codegen::bake(dictionary); + _text = p.text.value_or(_text); + addProperty(_text); +} + +void ScreenSpaceText::update() { + _buffer = _text.value(); + + ScreenSpaceRenderableText::update(); +} + +} // namespace openspace diff --git a/modules/base/rendering/screenspacetext.h b/modules/base/rendering/screenspacetext.h new file mode 100644 index 0000000000..740394d053 --- /dev/null +++ b/modules/base/rendering/screenspacetext.h @@ -0,0 +1,48 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2025 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_BASE___SCREENSPACETEXT___H__ +#define __OPENSPACE_MODULE_BASE___SCREENSPACETEXT___H__ + +#include + +#include + +namespace openspace { + +class ScreenSpaceText : public ScreenSpaceRenderableText { +public: + explicit ScreenSpaceText(const ghoul::Dictionary& dictionary); + + void update() override; + + static documentation::Documentation Documentation(); + +private: + properties::StringProperty _text; +}; + +} // namespace openspace + +#endif // __OPENSPACE_MODULE_BASE___SCREENSPACETEXT___H__ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 10fc821867..3bb78ce255 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -142,7 +142,9 @@ set(OPENSPACE_SOURCE rendering/renderable.cpp rendering/renderengine.cpp rendering/renderengine_lua.inl + rendering/screenspacerenderableframebuffer.cpp rendering/screenspacerenderable.cpp + rendering/screenspacerenderabletext.cpp rendering/texturecomponent.cpp rendering/transferfunction.cpp rendering/volumeraycaster.cpp @@ -339,7 +341,9 @@ set(OPENSPACE_HEADER ${PROJECT_SOURCE_DIR}/include/openspace/rendering/raycastermanager.h ${PROJECT_SOURCE_DIR}/include/openspace/rendering/renderable.h ${PROJECT_SOURCE_DIR}/include/openspace/rendering/renderengine.h + ${PROJECT_SOURCE_DIR}/include/openspace/rendering/screenspacerenderableframebuffer.h ${PROJECT_SOURCE_DIR}/include/openspace/rendering/screenspacerenderable.h + ${PROJECT_SOURCE_DIR}/include/openspace/rendering/screenspacerenderabletext.h ${PROJECT_SOURCE_DIR}/include/openspace/rendering/texturecomponent.h ${PROJECT_SOURCE_DIR}/include/openspace/rendering/transferfunction.h ${PROJECT_SOURCE_DIR}/include/openspace/rendering/volumeraycaster.h diff --git a/modules/base/rendering/screenspaceframebuffer.cpp b/src/rendering/screenspacerenderableframebuffer.cpp similarity index 81% rename from modules/base/rendering/screenspaceframebuffer.cpp rename to src/rendering/screenspacerenderableframebuffer.cpp index 71a3f60dbc..fb530835a8 100644 --- a/modules/base/rendering/screenspaceframebuffer.cpp +++ b/src/rendering/screenspacerenderableframebuffer.cpp @@ -22,7 +22,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include #include #include @@ -43,17 +43,16 @@ namespace { namespace openspace { -documentation::Documentation ScreenSpaceFramebuffer::Documentation() { +documentation::Documentation ScreenSpaceRenderableFramebuffer::Documentation() { using namespace documentation; return { - "ScreenSpaceFramebuffer", - "base_screenspace_framebuffer", - "", - {} + "ScreenSpaceRenderableFramebuffer", + "screenspace_framebuffer" }; } -ScreenSpaceFramebuffer::ScreenSpaceFramebuffer(const ghoul::Dictionary& dictionary) +ScreenSpaceRenderableFramebuffer::ScreenSpaceRenderableFramebuffer( + const ghoul::Dictionary& dictionary) : ScreenSpaceRenderable(dictionary) , _size(SizeInfo, glm::vec2(16), glm::vec2(16), glm::vec2(16384)) { @@ -63,15 +62,14 @@ ScreenSpaceFramebuffer::ScreenSpaceFramebuffer(const ghoul::Dictionary& dictiona "ScreenSpaceFramebuffer" ); - int iIdentifier = 0; if (_identifier.empty()) { - iIdentifier = id(); + int idCounter = id(); - if (iIdentifier == 0) { - setIdentifier("ScreenSpaceFramebuffer"); + if (idCounter == 0) { + setIdentifier("ScreenSpaceRenderableFramebuffer"); } else { - setIdentifier("ScreenSpaceFramebuffer" + std::to_string(iIdentifier)); + setIdentifier(std::format("ScreenSpaceRenderableFramebuffer{}", idCounter)); } } @@ -79,24 +77,24 @@ ScreenSpaceFramebuffer::ScreenSpaceFramebuffer(const ghoul::Dictionary& dictiona addProperty(_size); } -ScreenSpaceFramebuffer::~ScreenSpaceFramebuffer() {} +ScreenSpaceRenderableFramebuffer::~ScreenSpaceRenderableFramebuffer() {} -void ScreenSpaceFramebuffer::initializeGL() { +void ScreenSpaceRenderableFramebuffer::initializeGL() { ScreenSpaceRenderable::initializeGL(); createFramebuffer(); } -void ScreenSpaceFramebuffer::deinitializeGL() { +void ScreenSpaceRenderableFramebuffer::deinitializeGL() { _framebuffer->activate(); _framebuffer->detachAll(); ghoul::opengl::FramebufferObject::deactivate(); removeAllRenderFunctions(); - ScreenSpaceRenderable::deinitializeGL(); + ScreenSpaceRenderableFramebuffer::deinitializeGL(); } -void ScreenSpaceFramebuffer::render(const RenderData& renderData) { +void ScreenSpaceRenderableFramebuffer::render(const RenderData& renderData) { const glm::vec2& resolution = global::windowDelegate->currentDrawBufferResolution(); const glm::vec2& size = _size.value(); const glm::vec2 ratio = resolution / size; @@ -131,23 +129,19 @@ void ScreenSpaceFramebuffer::render(const RenderData& renderData) { } } -bool ScreenSpaceFramebuffer::isReady() const { +bool ScreenSpaceRenderableFramebuffer::isReady() const { return _shader && _texture; } -void ScreenSpaceFramebuffer::setSize(glm::vec2 size) { - _size = std::move(size); -} - -void ScreenSpaceFramebuffer::addRenderFunction(RenderFunction renderFunction) { +void ScreenSpaceRenderableFramebuffer::addRenderFunction(RenderFunction renderFunction) { _renderFunctions.push_back(std::move(renderFunction)); } -void ScreenSpaceFramebuffer::removeAllRenderFunctions() { +void ScreenSpaceRenderableFramebuffer::removeAllRenderFunctions() { _renderFunctions.clear(); } -void ScreenSpaceFramebuffer::createFramebuffer() { +void ScreenSpaceRenderableFramebuffer::createFramebuffer() { const glm::vec2 resolution = global::windowDelegate->currentDrawBufferResolution(); _framebuffer = std::make_unique(); @@ -165,12 +159,12 @@ void ScreenSpaceFramebuffer::createFramebuffer() { ghoul::opengl::FramebufferObject::deactivate(); } -int ScreenSpaceFramebuffer::id() { +int ScreenSpaceRenderableFramebuffer::id() { static int id = 0; return id++; } -void ScreenSpaceFramebuffer::bindTexture() { +void ScreenSpaceRenderableFramebuffer::bindTexture() { _texture->bind(); } diff --git a/src/rendering/screenspacerenderabletext.cpp b/src/rendering/screenspacerenderabletext.cpp new file mode 100644 index 0000000000..9986ec9cf1 --- /dev/null +++ b/src/rendering/screenspacerenderabletext.cpp @@ -0,0 +1,180 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2025 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + constexpr openspace::properties::Property::PropertyInfo FontNameInfo = { + "FontName", + "Font name", + "This value is the name of the font that is used. It can either refer to an " + "internal name registered previously, or it can refer to a path that is used.", + openspace::properties::Property::Visibility::User + }; + + constexpr openspace::properties::Property::PropertyInfo FontSizeInfo = { + "FontSize", + "Font size", + "This value determines the size of the font that is used to render the distance.", + openspace::properties::Property::Visibility::User + }; + + struct [[codegen::Dictionary(DashboardTextItem)]] Parameters { + // [[codegen::verbatim(FontNameInfo.description)]] + std::optional fontName; + + // [[codegen::verbatim(FontSizeInfo.description)]] + std::optional fontSize; + }; +#include "screenspacerenderabletext_codegen.cpp" +} // namespace + +namespace openspace { + +documentation::Documentation ScreenSpaceRenderableText::Documentation() { + return codegen::doc("screenspace_text"); +} + +ScreenSpaceRenderableText::ScreenSpaceRenderableText(const ghoul::Dictionary& dictionary) + : ScreenSpaceRenderable(dictionary) + , _fontName(FontNameInfo, "Mono") + , _fontSize(FontSizeInfo, 15.f, 6.f, 144.f, 1.f) + , _fontRenderer(ghoul::fontrendering::FontRenderer::createDefault()) +{ + const Parameters p = codegen::bake(dictionary); + + _fontName = p.fontName.value_or(_fontName); + _fontName.onChange([this]() { + _font = global::fontManager->font(_fontName, _fontSize); + }); + addProperty(_fontName); + + _fontSize = p.fontSize.value_or(_fontSize); + _fontSize.onChange([this]() { + _font = global::fontManager->font(_fontName, _fontSize); + }); + addProperty(_fontSize); + + _font = global::fontManager->font(_fontName, _fontSize); +} + +void ScreenSpaceRenderableText::initializeGL() { + ScreenSpaceRenderable::initializeGL(); + + _framebuffer = std::make_unique(); +} + +void ScreenSpaceRenderableText::deinitializeGL() { + _framebuffer->activate(); + _framebuffer->detachAll(); + ghoul::opengl::FramebufferObject::deactivate(); + + _texture = nullptr; + + ScreenSpaceRenderable::deinitializeGL(); +} + +bool ScreenSpaceRenderableText::isReady() const { + return _shader && _font && _texture; +} + +void ScreenSpaceRenderableText::update() { + updateFramebuffer(); +} + +void ScreenSpaceRenderableText::render(const RenderData& renderData) { + const glm::vec2& resolution = global::windowDelegate->currentDrawBufferResolution(); + glm::vec2 size = _texture->dimensions(); + const glm::vec2 ratio = resolution / size; + + std::array viewport; + glGetIntegerv(GL_VIEWPORT, viewport.data()); + glViewport( + 0, + 0, + static_cast(size.x), + static_cast(size.y) + ); + + const GLint defaultFBO = ghoul::opengl::FramebufferObject::getActiveObject(); + _framebuffer->activate(); + + glClearColor(0.f, 0.f, 0.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glm::vec2 pos = glm::vec2(0.f, size.y / 4); + _fontRenderer->render(*_font, pos, _buffer); + ghoul::opengl::FramebufferObject::deactivate(); + + glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); + glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + + const glm::mat4 globalRotation = globalRotationMatrix(); + const glm::mat4 translation = translationMatrix(); + const glm::mat4 localRotation = localRotationMatrix(); + const glm::mat4 scale = scaleMatrix(); + const glm::mat4 modelTransform = globalRotation * translation * localRotation * scale; + draw(modelTransform, renderData); +} + +void ScreenSpaceRenderableText::updateFramebuffer() { + const glm::vec2 bbox = _font->boundingBox(_buffer); + const glm::uvec3 box = glm::uvec3(bbox.x, bbox.y, 1); + const glm::uvec3 dim = _texture ? _texture->dimensions() : glm::uvec3(0); + if (box.x <= dim.x || box.y <= dim.y) { + // The size has not changed + return; + } + + _objectSize = glm::ivec2(bbox.x, bbox.y); + _fontRenderer->setFramebufferSize(_objectSize); + + _framebuffer->activate(); + // Create a texture that has 2 times the size to create a buffer + _texture = std::make_unique( + glm::uvec3(bbox.x, bbox.y, 1), + GL_TEXTURE_2D + ); + + _texture->uploadTexture(); + _texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); + _texture->purgeFromRAM(); + _framebuffer->attachTexture(_texture.get(), GL_COLOR_ATTACHMENT0); + ghoul::opengl::FramebufferObject::deactivate(); +} + +void ScreenSpaceRenderableText::bindTexture() { + _texture->bind(); +} + +} //namespace openspace diff --git a/visualtests/example/screenspacerenderable/screenspacedate/date.ostest b/visualtests/example/screenspacerenderable/screenspacedate/date.ostest new file mode 100644 index 0000000000..83018f44a2 --- /dev/null +++ b/visualtests/example/screenspacerenderable/screenspacedate/date.ostest @@ -0,0 +1,30 @@ +{ + "profile": "empty", + "commands": [ + { + "type": "asset", + "value": "examples/screenspacerenderable/screenspacedate/date.asset" + }, + { + "type": "time", + "value": "2025-09-13T02:03:04.567" + }, + { + "type": "property", + "value": { + "property": "ScreenSpace.ScreenSpaceDate_Example.Scale", + "value": 0.75 + } + }, + { + "type": "property", + "value": { + "property": "ScreenSpace.ScreenSpaceDate_Example.FontSize", + "value": 25.0 + } + }, + { + "type": "screenshot" + } + ] +} diff --git a/visualtests/example/screenspacerenderable/screenspacedate/date_day-of-year.ostest b/visualtests/example/screenspacerenderable/screenspacedate/date_day-of-year.ostest new file mode 100644 index 0000000000..c6658f6fc6 --- /dev/null +++ b/visualtests/example/screenspacerenderable/screenspacedate/date_day-of-year.ostest @@ -0,0 +1,30 @@ +{ + "profile": "empty", + "commands": [ + { + "type": "asset", + "value": "examples/screenspacerenderable/screenspacedate/date_day-of-year.asset" + }, + { + "type": "time", + "value": "2025-09-13T02:03:04.567" + }, + { + "type": "property", + "value": { + "property": "ScreenSpace.ScreenSpaceDate_Example_DayOfYear.Scale", + "value": 0.75 + } + }, + { + "type": "property", + "value": { + "property": "ScreenSpace.ScreenSpaceDate_Example_DayOfYear.FontSize", + "value": 25.0 + } + }, + { + "type": "screenshot" + } + ] +} diff --git a/visualtests/example/screenspacerenderable/screenspacedate/date_no-decoration.ostest b/visualtests/example/screenspacerenderable/screenspacedate/date_no-decoration.ostest new file mode 100644 index 0000000000..c4fb336b02 --- /dev/null +++ b/visualtests/example/screenspacerenderable/screenspacedate/date_no-decoration.ostest @@ -0,0 +1,30 @@ +{ + "profile": "empty", + "commands": [ + { + "type": "asset", + "value": "examples/screenspacerenderable/screenspacedate/date_no-decoration.asset" + }, + { + "type": "time", + "value": "2025-09-13T02:03:04.567" + }, + { + "type": "property", + "value": { + "property": "ScreenSpace.ScreenSpaceDate_Example_NoDecoration.Scale", + "value": 0.75 + } + }, + { + "type": "property", + "value": { + "property": "ScreenSpace.ScreenSpaceDate_Example_NoDecoration.FontSize", + "value": 25.0 + } + }, + { + "type": "screenshot" + } + ] +} diff --git a/visualtests/example/screenspacerenderable/screenspacedate/date_timezone.ostest b/visualtests/example/screenspacerenderable/screenspacedate/date_timezone.ostest new file mode 100644 index 0000000000..ccac9da2d0 --- /dev/null +++ b/visualtests/example/screenspacerenderable/screenspacedate/date_timezone.ostest @@ -0,0 +1,30 @@ +{ + "profile": "empty", + "commands": [ + { + "type": "asset", + "value": "examples/screenspacerenderable/screenspacedate/date_timezone.asset" + }, + { + "type": "time", + "value": "2025-09-13T02:03:04.567" + }, + { + "type": "property", + "value": { + "property": "ScreenSpace.ScreenSpaceDate_Example_Timezone.Scale", + "value": 0.75 + } + }, + { + "type": "property", + "value": { + "property": "ScreenSpace.ScreenSpaceDate_Example_Timezone.FontSize", + "value": 25.0 + } + }, + { + "type": "screenshot" + } + ] +} diff --git a/visualtests/example/screenspacerenderable/screenspacedate/date_year-month-day.ostest b/visualtests/example/screenspacerenderable/screenspacedate/date_year-month-day.ostest new file mode 100644 index 0000000000..82abc0a13f --- /dev/null +++ b/visualtests/example/screenspacerenderable/screenspacedate/date_year-month-day.ostest @@ -0,0 +1,30 @@ +{ + "profile": "empty", + "commands": [ + { + "type": "asset", + "value": "examples/screenspacerenderable/screenspacedate/date_year-month-day.asset" + }, + { + "type": "time", + "value": "2025-09-13T02:03:04.567" + }, + { + "type": "property", + "value": { + "property": "ScreenSpace.ScreenSpaceDate_Example_YearMonthDay.Scale", + "value": 0.75 + } + }, + { + "type": "property", + "value": { + "property": "ScreenSpace.ScreenSpaceDate_Example_YearMonthDay.FontSize", + "value": 25.0 + } + }, + { + "type": "screenshot" + } + ] +} diff --git a/visualtests/example/screenspacerenderable/screenspacetext/text.ostest b/visualtests/example/screenspacerenderable/screenspacetext/text.ostest new file mode 100644 index 0000000000..9dd36ff240 --- /dev/null +++ b/visualtests/example/screenspacerenderable/screenspacetext/text.ostest @@ -0,0 +1,26 @@ +{ + "profile": "empty", + "commands": [ + { + "type": "asset", + "value": "examples/screenspacerenderable/screenspacetext/text.asset" + }, + { + "type": "property", + "value": { + "property": "ScreenSpace.ScreenSpaceText_Example.Scale", + "value": 0.75 + } + }, + { + "type": "property", + "value": { + "property": "ScreenSpace.ScreenSpaceText_Example.FontSize", + "value": 55.0 + } + }, + { + "type": "screenshot" + } + ] +}