diff --git a/openVulkanoCpp/Math/Math.hpp b/openVulkanoCpp/Math/Math.hpp index a6f0f03..9852a03 100644 --- a/openVulkanoCpp/Math/Math.hpp +++ b/openVulkanoCpp/Math/Math.hpp @@ -177,3 +177,15 @@ glm::vec operator / (const float lhs, const glm::vec& rhs) { return lhs / glm::vec(rhs); } + +template>> +glm::vec operator * (const float lhs, const glm::vec& rhs) +{ + return lhs * glm::vec(rhs); +} + +template>> +glm::vec operator * (const glm::vec& lhs, const T rhs) +{ + return lhs * static_cast(rhs); +} diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp index 89926ad..48fdf08 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.cpp @@ -15,8 +15,6 @@ namespace OpenVulkano::Scene { - using namespace Math; - namespace { Shader MakeLabelBgShader(const bool billboard) @@ -45,7 +43,6 @@ namespace OpenVulkano::Scene Shader MakeLabelTextShader(const FontAtlasType type, const bool billboard) { Shader shader = TextDrawable::MakeDefaultShader(type); - shader.depthTest = false; shader.depthCompareOp = CompareOp::LESS_OR_EQUAL; if (billboard) { @@ -117,20 +114,12 @@ namespace OpenVulkano::Scene // update position for next text entry m_position.y = m_bbox.GetMin().y - lineHeight; - const auto& min = m_bbox.GetMin(); - const auto& max = m_bbox.GetMax(); - Vertex v, v2, v3, v4; - const float offset = 0.001; - const float yOffset = m_settings.hasArrow ? m_settings.arrowLength : 0; - v.position = Vector3f(min.x - m_settings.horizontalOffset, min.y - m_settings.verticalOffset - yOffset, min.z - offset); - v2.position = Vector3f(max.x + m_settings.horizontalOffset, min.y - m_settings.verticalOffset - yOffset, min.z - offset); - v3.position = Vector3f(max.x + m_settings.horizontalOffset, max.y + m_settings.verticalOffset, min.z - offset); - v4.position = Vector3f(min.x - m_settings.horizontalOffset, max.y + m_settings.verticalOffset, min.z - offset); + Math::Vector2f padding = m_settings.padding * 2; + if (m_settings.hasArrow) padding.y += m_settings.arrowLength; - m_labelData.textSize.x = v2.position.x - v.position.x; - m_labelData.textSize.y = v3.position.y - v.position.y; - m_labelData.bboxCenter.x = (v2.position.x + v.position.x) / 2; - m_labelData.bboxCenter.y = (v3.position.y + v.position.y) / 2; + m_labelData.textSize = Math::Vector2f(m_bbox.GetSize()) + padding * 2; + m_labelData.bboxCenter = { m_bbox.GetCenter() }; + if (m_settings.hasArrow) m_labelData.bboxCenter.y -= m_settings.arrowLength; } void LabelDrawable::SetBillboardSettings(const BillboardControlBlock& settings) diff --git a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp index 4357b42..8bc64bc 100644 --- a/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp +++ b/openVulkanoCpp/Scene/Prefabs/LabelDrawable.hpp @@ -21,8 +21,7 @@ namespace OpenVulkano::Scene struct LabelDrawableSettings { Math::Vector4f backgroundColor = { 1, 0, 0, 1 }; - float horizontalOffset = 0.05f; - float verticalOffset = 0.05f; + Math::Vector2f padding = { 0.2f, 0.2f }; float cornerRadius = 0.05f; float arrowLength = 0.5f; float arrowWidth = 0.2f; @@ -32,9 +31,9 @@ namespace OpenVulkano::Scene struct LabelUniformData { - Math::Vector4f textSize = { 0, 0, 0, 0 }; Math::Vector4f color = { 0, 0, 0, 0 }; - Math::Vector4f bboxCenter = { 0, 0, 0, 0 }; + Math::Vector2f textSize = {}; + Math::Vector2f bboxCenter = {}; float cornerRadius = 0.f; float arrowLength = 0.f; float arrowWidth = 0.f; diff --git a/openVulkanoCpp/Shader/label.frag b/openVulkanoCpp/Shader/label.frag index 33c8fc5..aec26b0 100644 --- a/openVulkanoCpp/Shader/label.frag +++ b/openVulkanoCpp/Shader/label.frag @@ -5,69 +5,69 @@ layout(location = 0) out vec4 outColor; layout(set = 5, binding = 0) uniform LabelData { - vec4 textSize; - vec4 color; - vec4 bboxCenter; - float radius; - float arrowLength; - float arrowWidth; - bool hasRoundedCorners; - bool hasArrow; + vec4 color; + vec2 textSize; + vec2 bboxCenter; + float radius; + float arrowLength; + float arrowWidth; + bool hasRoundedCorners; + bool hasArrow; } labelInfo; void main() -{ - if (labelInfo.hasRoundedCorners || labelInfo.hasArrow) - { - vec2 bbox = vec2(labelInfo.textSize); - const float arrowLength = int(labelInfo.hasArrow) * labelInfo.arrowLength; - float arrowWidth = labelInfo.arrowWidth; - vec2 uvScaled = texCoord; +{ + if (labelInfo.hasRoundedCorners || labelInfo.hasArrow) + { + vec2 bbox = vec2(labelInfo.textSize); + const float arrowLength = int(labelInfo.hasArrow) * labelInfo.arrowLength; + float arrowWidth = labelInfo.arrowWidth; + vec2 uvScaled = texCoord; - float distX = min(uvScaled.x, bbox.x - uvScaled.x); - float distY = min(uvScaled.y - arrowLength, bbox.y - uvScaled.y); - float distanceFromCorner = distX * distY; + float distX = min(uvScaled.x, bbox.x - uvScaled.x); + float distY = min(uvScaled.y - arrowLength, bbox.y - uvScaled.y); + float distanceFromCorner = distX * distY; - if (distanceFromCorner < labelInfo.radius) - { - // plain arrow - if (labelInfo.hasArrow && !labelInfo.hasRoundedCorners) - { - // Some bias to prevent line between arrow and label + - // check that we are dealing with lower parts of the label where arrow should be drawn, - // to prevent discarding fragments from upper corners - if (distY <= 0.01 && uvScaled.y < (bbox.y - arrowWidth) && arrowLength != 0.0f) - { - arrowWidth = arrowWidth * ((arrowLength + distY) / arrowLength); - if (distX < (bbox.x - arrowWidth) * 0.5) - { - discard; - } - } - } - // TODO: rounded corners + rounded arrow. - // now renders rounded corners and sharp arrow - else if (labelInfo.hasArrow && labelInfo.hasRoundedCorners) - { - if (distY <= 0.05 && uvScaled.y < (bbox.y - arrowWidth) && arrowLength != 0.0f) - { - arrowWidth = arrowWidth * ((arrowLength + distY) / arrowLength); - if (distX < (bbox.x - arrowWidth) * 0.5) - { - discard; - } - } - else - { - discard; - } - } - // no arrow, rounded corners - else - { - discard; - } - } - } - outColor = labelInfo.color; + if (distanceFromCorner < labelInfo.radius) + { + // plain arrow + if (labelInfo.hasArrow && !labelInfo.hasRoundedCorners) + { + // Some bias to prevent line between arrow and label + + // check that we are dealing with lower parts of the label where arrow should be drawn, + // to prevent discarding fragments from upper corners + if (distY <= 0.01 && uvScaled.y < (bbox.y - arrowWidth) && arrowLength != 0.0f) + { + arrowWidth = arrowWidth * ((arrowLength + distY) / arrowLength); + if (distX < (bbox.x - arrowWidth) * 0.5) + { + discard; + } + } + } + // TODO: rounded corners + rounded arrow. + // now renders rounded corners and sharp arrow + else if (labelInfo.hasArrow && labelInfo.hasRoundedCorners) + { + if (distY <= 0.05 && uvScaled.y < (bbox.y - arrowWidth) && arrowLength != 0.0f) + { + arrowWidth = arrowWidth * ((arrowLength + distY) / arrowLength); + if (distX < (bbox.x - arrowWidth) * 0.5) + { + discard; + } + } + else + { + discard; + } + } + // no arrow, rounded corners + else + { + discard; + } + } + } + outColor = labelInfo.color; } \ No newline at end of file diff --git a/openVulkanoCpp/Shader/label.vert b/openVulkanoCpp/Shader/label.vert index ca0380d..fab71cd 100644 --- a/openVulkanoCpp/Shader/label.vert +++ b/openVulkanoCpp/Shader/label.vert @@ -8,18 +8,18 @@ layout(set = 0, binding = 0) uniform NodeData layout(set = 1, binding = 0) uniform CameraData { - mat4 viewProjection; + mat4 viewProjection; } cam; layout(set = 5, binding = 0) uniform LabelData { - vec4 textSize; - vec4 color; - vec4 bboxCenter; - float radius; - float arrowLength; - bool hasRoundedCorners; - bool hasArrow; + vec4 color; + vec2 textSize; + vec2 bboxCenter; + float radius; + float arrowLength; + bool hasRoundedCorners; + bool hasArrow; } labelInfo; layout(location = 0) out vec4 color; @@ -28,18 +28,18 @@ layout(location = 1) out vec2 textureCoordinates; // Background plane positions are in clipped space const vec4 PLANE[4] = vec4[]( vec4(-0.5, -0.5, 0, 1), vec4(0.5, -0.5, 0, 1), vec4(-0.5, 0.5, 0, 1), vec4(0.5, 0.5, 0, 1) - ); + const vec2 TEX_COORDS[4] = vec2[]( vec2(0, 0), vec2(1, 0), vec2(0, 1), vec2(1, 1) ); -void main() { - vec4 position = PLANE[gl_VertexIndex]; - vec2 bbox = labelInfo.textSize.xy; - position.xy *= bbox; - position.xy += vec2(labelInfo.bboxCenter); - position.z = -0.001; - gl_Position = cam.viewProjection * node.world * position; - textureCoordinates = TEX_COORDS[gl_VertexIndex] * bbox; +void main() +{ + vec4 position = PLANE[gl_VertexIndex]; + position.xy *= labelInfo.textSize; + position.xy += labelInfo.bboxCenter; + //position.z = -0.001; + gl_Position = cam.viewProjection * node.world * position; + textureCoordinates = TEX_COORDS[gl_VertexIndex] * labelInfo.textSize; } diff --git a/openVulkanoCpp/Shader/labelBillboard.vert b/openVulkanoCpp/Shader/labelBillboard.vert index 00e1d02..c528d0a 100644 --- a/openVulkanoCpp/Shader/labelBillboard.vert +++ b/openVulkanoCpp/Shader/labelBillboard.vert @@ -30,9 +30,9 @@ layout(set = 4, binding = 0) uniform BillboardData layout(set = 5, binding = 0) uniform LabelData { - vec4 textSize; vec4 color; - vec4 bboxCenter; + vec2 textSize; + vec2 bboxCenter; float radius; float arrowLength; bool hasRoundedCorners; @@ -53,11 +53,10 @@ const vec2 TEX_COORDS[4] = vec2[]( void main() { vec4 position = PLANE[gl_VertexIndex]; - vec2 bbox = labelInfo.textSize.xy; - position.xy *= bbox; - position.xy += vec2(labelInfo.bboxCenter); + position.xy *= labelInfo.textSize; + position.xy += labelInfo.bboxCenter; position.z = -0.001; - textureCoordinates = TEX_COORDS[gl_VertexIndex] * bbox; + textureCoordinates = TEX_COORDS[gl_VertexIndex] * labelInfo.textSize; if (!billboardInfo.isFixedSize) {