void LabelGeometry::render(RenderContext& rc, double /* clock */) const { bool hasIcon = !m_icon.isNull(); Vector3f labelOffset = Vector3f::Zero(); if (hasIcon) { labelOffset.x() = std::floor(m_iconSize / 2.0f) + 1.0f; } float opacity = 0.99f; if (m_fadeRange.isValid()) { float cameraDistance = rc.modelview().translation().norm(); float pixelSize = m_fadeSize / (rc.pixelSize() * cameraDistance); opacity *= m_fadeRange->opacity(pixelSize); } if (opacity == 0.0f) { return; } // Render during the opaque pass if opaque or during the translucent pass if not. if (rc.pass() == RenderContext::TranslucentPass) { // Keep the screen size of the icon fixed by adding a scale factor equal // to the distance from the eye. float distanceScale = rc.modelview().translation().norm(); // Draw the label string as long as it's not empty if (!m_text.empty()) { rc.drawText(labelOffset, m_text, m_font.ptr(), m_color, opacity); } if (hasIcon) { Material material; material.setEmission(m_iconColor); material.setOpacity(opacity); material.setBaseTexture(m_icon.ptr()); rc.bindMaterial(&material); rc.drawBillboard(Vector3f::Zero(), m_iconSize * rc.pixelSize() * distanceScale); } } }