13 ShadowSpecification::ShadowSpecification(
const Sml::Vec2i& offset,
const Sml::Vec2f& scale,
14 int32_t blurRadius, Sml::Color color)
15 : m_Offset(offset), m_Scale(scale), m_Color(color)
17 m_BlurKernel = Sml::createGaussianBlurKernel(blurRadius);
21 ShadowSpecification::~ShadowSpecification()
23 if (m_BlurKernel !=
nullptr)
29 const Sml::Vec2i& ShadowSpecification::getOffset()
const {
return m_Offset; }
30 const Sml::Vec2f& ShadowSpecification::getScale()
const {
return m_Scale; }
31 int32_t ShadowSpecification::getBlurRadius()
const {
return m_BlurKernel->getRadius(); }
32 Sml::Color ShadowSpecification::getColor()
const {
return m_Color; }
36 if (m_Texture !=
nullptr)
42 Sml::Texture* Shadow::getTexture()
const {
return m_Texture; }
44 const ShadowSpecification* Shadow::getSpecification()
const {
return m_Specification; }
45 void Shadow::setSpecification(
const ShadowSpecification* specification) { m_Specification = specification; }
47 Shadow::Shadow(
const ShadowSpecification* specification) : m_Specification(specification) {}
49 void Shadow::update(
const Sml::Texture* srcTexture,
const Sml::Rectangle<int32_t>& objectRegion)
53 if (m_Specification ==
nullptr) {
return; }
55 if (m_Texture !=
nullptr)
60 int32_t blurRadius = m_Specification->getBlurRadius();
62 int32_t shadowWidth = objectRegion.width + 2 * blurRadius;
63 int32_t shadowHeight = objectRegion.height + 2 * blurRadius;
65 Sml::Color* srcPixels = srcTexture->readPixels(&objectRegion);
66 Sml::Color* dstPixels =
new Sml::Color[shadowWidth * shadowHeight];
67 memset(dstPixels, 0, shadowWidth * shadowHeight *
sizeof(Sml::Color));
69 float shadowColorAlpha =
static_cast<float>(Sml::colorGetA(m_Specification->getColor())) / (255.f * 255.f);
71 for (int32_t y = 0; y < objectRegion.height; ++y)
73 for (int32_t x = 0; x < objectRegion.width; ++x)
75 Sml::Color srcColor = srcPixels[x + y * objectRegion.width];
77 float curColorAlphaFloat = shadowColorAlpha *
static_cast<float>(Sml::colorGetA(srcColor));
78 uint8_t curColorAlpha = 255 * curColorAlphaFloat;
80 Sml::Color curColor = Sml::colorSetA(m_Specification->getColor(), curColorAlpha);
81 dstPixels[(x + blurRadius) + (y + blurRadius) * shadowWidth] = curColor;
85 Sml::Color* blurredPixels =
new Sml::Color[shadowWidth * shadowHeight];
87 Sml::applyKernel(m_Specification->m_BlurKernel,
93 m_Texture =
new Sml::Texture(shadowWidth, shadowHeight);
94 m_Texture->updatePixels(blurredPixels);
98 delete[] blurredPixels;
101 void Shadow::render(
const Sml::Rectangle<int32_t>&
object,
const Sml::Rectangle<int32_t>& targetRegion)
103 if (m_Texture ==
nullptr)
108 Sml::Rectangle<int32_t> shadowRegion{0,
110 static_cast<int32_t
>(m_Texture->getWidth()),
111 static_cast<int32_t
>(m_Texture->getHeight())};
113 shadowRegion = Sml::centerRegion(
object, shadowRegion);
114 shadowRegion.pos += m_Specification->getOffset() + targetRegion.pos;
116 int32_t scaledWidth =
static_cast<int32_t
>(m_Texture->getWidth());
117 int32_t scaledHeight =
static_cast<int32_t
>(m_Texture->getHeight());
119 shadowRegion.pos.x -= (scaledWidth - shadowRegion.width) / 2;
120 shadowRegion.pos.y -= (scaledHeight - shadowRegion.height) / 2;
121 shadowRegion.width = scaledWidth;
122 shadowRegion.height = scaledHeight;
124 Sml::renderTexture(*m_Texture, &shadowRegion,
nullptr);