diff --git a/include/openspace/rendering/screenspacerenderable.h b/include/openspace/rendering/screenspacerenderable.h index 93b03efe17..886e16c109 100644 --- a/include/openspace/rendering/screenspacerenderable.h +++ b/include/openspace/rendering/screenspacerenderable.h @@ -129,6 +129,10 @@ protected: // Local rotation (roll, pitch, yaw) properties::Vec3Property _localRotation; + // Border + properties::FloatProperty _borderWidth; + properties::Vec3Property _borderColor; + properties::FloatProperty _scale; properties::FloatProperty _gamma; properties::Vec3Property _multiplyColor; @@ -136,7 +140,8 @@ protected: properties::TriggerProperty _delete; glm::ivec2 _objectSize = glm::ivec2(0); - UniformCache(color, opacity, mvp, texture, backgroundColor, gamma) _uniformCache; + UniformCache(color, opacity, mvp, texture, backgroundColor, gamma, + borderColor, borderWidth) _uniformCache; std::unique_ptr _shader; }; diff --git a/modules/base/shaders/screenspace_fs.glsl b/modules/base/shaders/screenspace_fs.glsl index 21af960401..6478a93dab 100644 --- a/modules/base/shaders/screenspace_fs.glsl +++ b/modules/base/shaders/screenspace_fs.glsl @@ -33,6 +33,8 @@ uniform vec3 color = vec3(1.0); uniform float opacity = 1.0; uniform vec4 backgroundColor = vec4(0.0); uniform float gamma = 1.0; +uniform vec2 borderWidth = vec2(0.1); +uniform vec3 borderColor = vec3(0.0); Fragment getFragment() { @@ -41,6 +43,13 @@ Fragment getFragment() { vec4 texColor = texture(tex, vs_st) * vec4(color, opacity); frag.color = texColor.a * texColor + (1.0 - texColor.a) * backgroundColor; + + // Set border color + if (vs_st.x < borderWidth.x || vs_st.x > 1 - borderWidth.x || + vs_st.y < borderWidth.y || vs_st.y > 1 - borderWidth.y) { + frag.color = vec4(borderColor, 1.0); + } + if (frag.color.a == 0.0) { discard; } diff --git a/modules/skybrowser/include/wwtcommunicator.h b/modules/skybrowser/include/wwtcommunicator.h index 61f3e2ac65..bc2235dc92 100644 --- a/modules/skybrowser/include/wwtcommunicator.h +++ b/modules/skybrowser/include/wwtcommunicator.h @@ -76,7 +76,7 @@ protected: properties::DoubleProperty _verticalFov; double _borderRadius = 0.0; - glm::ivec3 _borderColor = glm::ivec3(70); + glm::ivec3 _wwtBorderColor = glm::ivec3(70); glm::dvec2 _equatorialAim = glm::dvec2(0.0); double _targetRoll = 0.0; bool _isImageCollectionLoaded = false; diff --git a/modules/skybrowser/src/screenspaceskybrowser.cpp b/modules/skybrowser/src/screenspaceskybrowser.cpp index 21b11fb99e..4ea4aa90b0 100644 --- a/modules/skybrowser/src/screenspaceskybrowser.cpp +++ b/modules/skybrowser/src/screenspaceskybrowser.cpp @@ -143,7 +143,7 @@ ScreenSpaceSkyBrowser::ScreenSpaceSkyBrowser(const ghoul::Dictionary& dictionary _textureQuality.onChange([this]() { _isDimensionsDirty = true; }); if (global::windowDelegate->isMaster()) { - _borderColor = randomBorderColor(); + _wwtBorderColor = randomBorderColor(); } _useRadiusAzimuthElevation.onChange( diff --git a/modules/skybrowser/src/wwtcommunicator.cpp b/modules/skybrowser/src/wwtcommunicator.cpp index 674609710d..67c7224f98 100644 --- a/modules/skybrowser/src/wwtcommunicator.cpp +++ b/modules/skybrowser/src/wwtcommunicator.cpp @@ -242,7 +242,7 @@ void WwtCommunicator::setEquatorialAim(glm::dvec2 equatorial) { } void WwtCommunicator::setBorderColor(glm::ivec3 color) { - _borderColor = std::move(color); + _wwtBorderColor = std::move(color); _borderColorIsDirty = true; } @@ -255,7 +255,7 @@ void WwtCommunicator::setBorderRadius(double radius) { void WwtCommunicator::updateBorderColor() const { std::string script = fmt::format( "setBackgroundColor('rgb({},{},{})');", - _borderColor.x, _borderColor.y, _borderColor.z + _wwtBorderColor.x, _wwtBorderColor.y, _wwtBorderColor.z ); executeJavascript(script); } @@ -355,7 +355,7 @@ void WwtCommunicator::setIdInBrowser(const std::string& id) const { } glm::ivec3 WwtCommunicator::borderColor() const { - return _borderColor; + return _wwtBorderColor; } double WwtCommunicator::verticalFov() const { diff --git a/src/rendering/screenspacerenderable.cpp b/src/rendering/screenspacerenderable.cpp index b615c75380..07f6f1c744 100644 --- a/src/rendering/screenspacerenderable.cpp +++ b/src/rendering/screenspacerenderable.cpp @@ -43,8 +43,9 @@ #include namespace { - constexpr std::array UniformNames = { - "color", "opacity", "mvpMatrix", "tex", "backgroundColor", "gamma" + constexpr std::array UniformNames = { + "color", "opacity", "mvpMatrix", "tex", "backgroundColor", "gamma", "borderColor", + "borderWidth" }; constexpr openspace::properties::Property::PropertyInfo EnabledInfo = { @@ -153,6 +154,20 @@ namespace { openspace::properties::Property::Visibility::AdvancedUser }; + constexpr openspace::properties::Property::PropertyInfo BorderWidthInfo = { + "BorderWidth", + "Border Width", + "The width of the border", + openspace::properties::Property::Visibility::NoviceUser + }; + + constexpr openspace::properties::Property::PropertyInfo BorderColorInfo = { + "BorderColor", + "Border Color", + "Sets the color of the border", + openspace::properties::Property::Visibility::NoviceUser + }; + float wrap(float value, float min, float max) { return glm::mod(value - min, max - min) + min; } @@ -188,6 +203,12 @@ namespace { // [[codegen::verbatim(GammaInfo.description)]] std::optional radiusAzimuthElevation; + // [[codegen::verbatim(BorderWidthInfo.description)]] + std::optional borderWidth; + + // [[codegen::verbatim(BorderColorInfo.description)]] + std::optional borderColor [[codegen::color()]]; + // [[codegen::verbatim(ScaleInfo.description)]] std::optional scale; @@ -292,6 +313,8 @@ ScreenSpaceRenderable::ScreenSpaceRenderable(const ghoul::Dictionary& dictionary glm::vec4(1.f) ) , _delete(DeleteInfo) + , _borderWidth(BorderWidthInfo, 0.f, 0.f, 1000.f) + , _borderColor(BorderColorInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(1.f)) { const Parameters p = codegen::bake(dictionary); @@ -328,6 +351,13 @@ ScreenSpaceRenderable::ScreenSpaceRenderable(const ghoul::Dictionary& dictionary addProperty(Fadeable::_fade); addProperty(_localRotation); + addProperty(_borderColor); + addProperty(_borderWidth); + + _borderWidth = p.borderWidth.value_or(_borderWidth); + + _borderColor = p.borderColor.value_or(_borderColor); + _borderColor.setViewOption(properties::Property::ViewOptions::Color); _multiplyColor = p.multiplyColor.value_or(_multiplyColor); _multiplyColor.setViewOption(properties::Property::ViewOptions::Color); @@ -498,7 +528,7 @@ glm::vec2 ScreenSpaceRenderable::screenSpacePosition() { return glm::vec2(_cartesianPosition.value()); } -glm::vec2 ScreenSpaceRenderable::screenSpaceDimensions() { +glm::vec2 ScreenSpaceRenderable::screenSpaceDimensions() { float ratio = static_cast(_objectSize.x) / static_cast(_objectSize.y); return glm::vec2(2.f * _scale * ratio, 2.f * _scale); } @@ -596,11 +626,18 @@ void ScreenSpaceRenderable::draw(glm::mat4 modelTransform) { glDisable(GL_CULL_FACE); _shader->activate(); + // Calculate the border from pixels to UV coordinates + glm::vec2 borderUV = glm::vec2( + _borderWidth / static_cast(_objectSize.x), + _borderWidth / static_cast(_objectSize.y) + ); _shader->setUniform(_uniformCache.color, _multiplyColor); _shader->setUniform(_uniformCache.opacity, opacity()); _shader->setUniform(_uniformCache.backgroundColor, _backgroundColor); _shader->setUniform(_uniformCache.gamma, _gamma); + _shader->setUniform(_uniformCache.borderWidth, borderUV); + _shader->setUniform(_uniformCache.borderColor, _borderColor); _shader->setUniform( _uniformCache.mvp, global::renderEngine->scene()->camera()->viewProjectionMatrix() * modelTransform