DecoratorShader.cpp 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #include "DecoratorShader.h"
  2. #include "../../Include/RmlUi/Core/ComputedValues.h"
  3. #include "../../Include/RmlUi/Core/Element.h"
  4. #include "../../Include/RmlUi/Core/Geometry.h"
  5. #include "../../Include/RmlUi/Core/MeshUtilities.h"
  6. #include "../../Include/RmlUi/Core/PropertyDefinition.h"
  7. #include "../../Include/RmlUi/Core/RenderManager.h"
  8. namespace Rml {
  9. Pool<ShaderElementData>& GetShaderElementDataPool()
  10. {
  11. static Pool<ShaderElementData> gradient_element_data_pool(20, true);
  12. return gradient_element_data_pool;
  13. }
  14. DecoratorShader::DecoratorShader() {}
  15. DecoratorShader::~DecoratorShader() {}
  16. bool DecoratorShader::Initialise(String&& in_value)
  17. {
  18. value = std::move(in_value);
  19. return true;
  20. }
  21. DecoratorDataHandle DecoratorShader::GenerateElementData(Element* element, BoxArea paint_area) const
  22. {
  23. RenderManager* render_manager = element->GetRenderManager();
  24. if (!render_manager)
  25. return INVALID_DECORATORDATAHANDLE;
  26. const RenderBox render_box = element->GetRenderBox(paint_area);
  27. const Vector2f dimensions = render_box.GetFillSize();
  28. CompiledShader shader = render_manager->CompileShader("shader", Dictionary{{"value", Variant(value)}, {"dimensions", Variant(dimensions)}});
  29. if (!shader)
  30. return INVALID_DECORATORDATAHANDLE;
  31. Mesh mesh;
  32. const ComputedValues& computed = element->GetComputedValues();
  33. const byte alpha = byte(computed.opacity() * 255.f);
  34. MeshUtilities::GenerateBackground(mesh, render_box, ColourbPremultiplied(alpha, alpha));
  35. const Vector2f offset = render_box.GetFillOffset();
  36. for (Vertex& vertex : mesh.vertices)
  37. vertex.tex_coord = (vertex.position - offset) / dimensions;
  38. ShaderElementData* element_data =
  39. GetShaderElementDataPool().AllocateAndConstruct(render_manager->MakeGeometry(std::move(mesh)), std::move(shader));
  40. return reinterpret_cast<DecoratorDataHandle>(element_data);
  41. }
  42. void DecoratorShader::ReleaseElementData(DecoratorDataHandle handle) const
  43. {
  44. ShaderElementData* element_data = reinterpret_cast<ShaderElementData*>(handle);
  45. GetShaderElementDataPool().DestroyAndDeallocate(element_data);
  46. }
  47. void DecoratorShader::RenderElement(Element* element, DecoratorDataHandle handle) const
  48. {
  49. ShaderElementData* element_data = reinterpret_cast<ShaderElementData*>(handle);
  50. element_data->geometry.Render(element->GetAbsoluteOffset(BoxArea::Border), {}, element_data->shader);
  51. }
  52. DecoratorShaderInstancer::DecoratorShaderInstancer()
  53. {
  54. ids.value = RegisterProperty("value", String()).AddParser("string").GetId();
  55. RegisterShorthand("decorator", "value", ShorthandType::FallThrough);
  56. }
  57. DecoratorShaderInstancer::~DecoratorShaderInstancer() {}
  58. SharedPtr<Decorator> DecoratorShaderInstancer::InstanceDecorator(const String& /*name*/, const PropertyDictionary& properties_,
  59. const DecoratorInstancerInterface& /*interface_*/)
  60. {
  61. const Property* p_value = properties_.GetProperty(ids.value);
  62. if (!p_value)
  63. return nullptr;
  64. String value = p_value->Get<String>();
  65. auto decorator = MakeShared<DecoratorShader>();
  66. if (decorator->Initialise(std::move(value)))
  67. return decorator;
  68. return nullptr;
  69. }
  70. } // namespace Rml