vulkan2d fixes
This commit is contained in:
parent
1c1a142f52
commit
ea18f32300
4 changed files with 279 additions and 36 deletions
|
|
@ -31,6 +31,7 @@ import :VulkanBuffer;
|
|||
import :Types;
|
||||
import :Window;
|
||||
import :DescriptorHeapVulkan;
|
||||
import :Font;
|
||||
|
||||
export namespace Crafter {
|
||||
struct RenderingElement2DVulkanBase : Transform2D {
|
||||
|
|
@ -51,20 +52,36 @@ export namespace Crafter {
|
|||
|
||||
template<bool Owning, bool Mapped>
|
||||
struct RenderingElement2DVulkan : RenderingElement2DVulkanBase {
|
||||
RenderingElement2DVulkan(Anchor2D anchor, RendertargetBase& target, Transform2D& parent) requires(Owning) : RenderingElement2DVulkanBase(anchor) {
|
||||
RenderingElement2DVulkan(Anchor2D anchor, RendertargetBase& target, Transform2D& parent, bool single = false) requires(Owning) : RenderingElement2DVulkanBase(anchor) {
|
||||
GetScale(target, parent);
|
||||
this->bufferX = this->scaled.size.x;
|
||||
this->bufferY = this->scaled.size.y;
|
||||
for(std::uint8_t i = 0; i < Window::numFrames; i++) {
|
||||
buffers[i] = new VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>();
|
||||
static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffers[i])->Create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bufferX * bufferY);
|
||||
if(single) {
|
||||
buffers[0] = new VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>();
|
||||
static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffers[0])->Create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bufferX * bufferY);
|
||||
for(std::uint8_t i = 1; i < Window::numFrames; i++) {
|
||||
buffers[i] = buffers[0];
|
||||
}
|
||||
} else {
|
||||
for(std::uint8_t i = 0; i < Window::numFrames; i++) {
|
||||
buffers[i] = new VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>();
|
||||
static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffers[i])->Create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bufferX * bufferY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderingElement2DVulkan(Anchor2D anchor, std::uint16_t bufferX, std::uint16_t bufferY) requires(Owning) : RenderingElement2DVulkanBase(anchor, bufferX, bufferY) {
|
||||
for(std::uint8_t i = 0; i < Window::numFrames; i++) {
|
||||
buffers[i] = new VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>();
|
||||
static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffers[i])->Create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bufferX * bufferY);
|
||||
RenderingElement2DVulkan(Anchor2D anchor, std::uint16_t bufferX, std::uint16_t bufferY, bool single = false) requires(Owning) : RenderingElement2DVulkanBase(anchor, bufferX, bufferY) {
|
||||
if(single) {
|
||||
buffers[0] = new VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>();
|
||||
static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffers[0])->Create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bufferX * bufferY);
|
||||
for(std::uint8_t i = 1; i < Window::numFrames; i++) {
|
||||
buffers[i] = buffers[0];
|
||||
}
|
||||
} else {
|
||||
for(std::uint8_t i = 0; i < Window::numFrames; i++) {
|
||||
buffers[i] = new VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>();
|
||||
static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffers[i])->Create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bufferX * bufferY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +89,7 @@ export namespace Crafter {
|
|||
|
||||
}
|
||||
|
||||
RenderingElement2DVulkan(Anchor2D anchor, const std::filesystem::path& assetPath, bool single) requires(Owning && Mapped) : RenderingElement2DVulkanBase(anchor) {
|
||||
RenderingElement2DVulkan(Anchor2D anchor, const std::filesystem::path& assetPath, bool single = false) requires(Owning && Mapped) : RenderingElement2DVulkanBase(anchor) {
|
||||
TextureAssetInfo info = TextureAsset<_Float16>::LoadInfo(assetPath);
|
||||
this->bufferX = info.sizeX;
|
||||
this->bufferY = info.sizeY;
|
||||
|
|
@ -82,13 +99,13 @@ export namespace Crafter {
|
|||
for(std::uint8_t i = 1; i < Window::numFrames; i++) {
|
||||
buffers[i] = buffers[0];
|
||||
}
|
||||
TextureAsset<_Float16>::Load(assetPath, reinterpret_cast<_Float16*>(static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffers[0])->value), this->bufferX, this->bufferY);
|
||||
TextureAsset<Vector<_Float16, 4, 4>>::Load(assetPath, static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffers[0])->value, this->bufferX, this->bufferY);
|
||||
} else {
|
||||
for(std::uint8_t i = 0; i < Window::numFrames; i++) {
|
||||
buffers[i] = new VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>();
|
||||
static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffers[i])->Create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bufferX * bufferY);
|
||||
}
|
||||
TextureAsset<_Float16>::Load(assetPath, reinterpret_cast<_Float16*>(static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffers[0])->value), this->bufferX, this->bufferY);
|
||||
TextureAsset<Vector<_Float16, 4, 4>>::Load(assetPath, static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffers[0])->value, this->bufferX, this->bufferY);
|
||||
for(std::uint8_t i = 1; i < Window::numFrames; i++) {
|
||||
std::memcpy(static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffers[i])->value, static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffers[0])->value, this->bufferX * this->bufferY * sizeof(_Float16));
|
||||
}
|
||||
|
|
@ -122,6 +139,229 @@ export namespace Crafter {
|
|||
child->UpdatePosition(window, *this);
|
||||
}
|
||||
}
|
||||
|
||||
int utf8_decode(const char* s, int* bytes_consumed) {
|
||||
unsigned char c = s[0];
|
||||
if (c < 0x80) {
|
||||
*bytes_consumed = 1;
|
||||
return c;
|
||||
} else if ((c & 0xE0) == 0xC0) {
|
||||
*bytes_consumed = 2;
|
||||
return ((c & 0x1F) << 6) | (s[1] & 0x3F);
|
||||
} else if ((c & 0xF0) == 0xE0) {
|
||||
*bytes_consumed = 3;
|
||||
return ((c & 0x0F) << 12) | ((s[1] & 0x3F) << 6) | (s[2] & 0x3F);
|
||||
} else if ((c & 0xF8) == 0xF0) {
|
||||
*bytes_consumed = 4;
|
||||
return ((c & 0x07) << 18) | ((s[1] & 0x3F) << 12) | ((s[2] & 0x3F) << 6) | (s[3] & 0x3F);
|
||||
}
|
||||
*bytes_consumed = 1;
|
||||
return 0xFFFD; // replacement char
|
||||
}
|
||||
|
||||
void RenderText(std::span<const std::string_view> lines, float size, Vector<_Float16, 4> color, Font& font, TextAlignment alignment = TextAlignment::Left, std::uint32_t offsetX = 0, std::uint32_t offsetY = 0, OpaqueType opaque = OpaqueType::FullyOpaque) requires(Mapped) {
|
||||
float scale = stbtt_ScaleForPixelHeight(&font.font, size);
|
||||
int baseline = (int)(font.ascent * scale);
|
||||
std::uint32_t lineHeight = (font.ascent - font.descent) * scale;
|
||||
std::uint32_t currentY = baseline;
|
||||
for(std::string_view line : lines) {
|
||||
|
||||
std::uint32_t lineWidth = 0;
|
||||
for (const char c : line) {
|
||||
int advance, lsb;
|
||||
stbtt_GetCodepointHMetrics(&font.font, c, &advance, &lsb);
|
||||
lineWidth += (int)(advance * scale);
|
||||
}
|
||||
|
||||
std::uint32_t x = 0;
|
||||
switch (alignment) {
|
||||
case TextAlignment::Left:
|
||||
x = 0;
|
||||
break;
|
||||
case TextAlignment::Center:
|
||||
x = (this->scaled.size.x - lineWidth) / 2;
|
||||
break;
|
||||
case TextAlignment::Right:
|
||||
x = this->scaled.size.x - lineWidth;
|
||||
break;
|
||||
}
|
||||
|
||||
const char* p = line.data();
|
||||
const char* end = p + line.size();
|
||||
|
||||
while (p < end) {
|
||||
int bytes;
|
||||
int codepoint = utf8_decode(p, &bytes);
|
||||
p += bytes;
|
||||
|
||||
int ax;
|
||||
int lsb;
|
||||
stbtt_GetCodepointHMetrics(&font.font, codepoint, &ax, &lsb);
|
||||
|
||||
int c_x1, c_y1, c_x2, c_y2;
|
||||
stbtt_GetCodepointBitmapBox(&font.font, codepoint, scale, scale, &c_x1, &c_y1, &c_x2, &c_y2);
|
||||
|
||||
int w = c_x2 - c_x1;
|
||||
int h = c_y2 - c_y1;
|
||||
|
||||
std::vector<unsigned char> bitmap(w * h);
|
||||
stbtt_MakeCodepointBitmap(&font.font, bitmap.data(), w, h, w, scale, scale, codepoint);
|
||||
|
||||
// Only render characters that fit within the scaled bounds
|
||||
switch(opaque) {
|
||||
case OpaqueType::FullyOpaque: {
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
int bufferX = x + i + c_x1 + offsetX;
|
||||
int bufferY = currentY + j + c_y1 + offsetY;
|
||||
|
||||
if (bufferX >= 0 && bufferX < (int)this->bufferX && bufferY >= 0 && bufferY < (int)this->bufferY) {
|
||||
for(std::uint8_t frame = 0; frame < Window::numFrames; frame++) {
|
||||
static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, true>*>(buffers[frame])->value[bufferY * this->bufferX + bufferX] = {color.r, color.g, color.b, static_cast<_Float16>(bitmap[j * w + i])};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OpaqueType::SemiOpaque:
|
||||
case OpaqueType::Transparent: {
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
int bufferX = x + i + c_x1 + offsetX;
|
||||
int bufferY = currentY + j + c_y1 + offsetY;
|
||||
|
||||
if (bufferX >= 0 && bufferX < (int)this->bufferX && bufferY >= 0 && bufferY < (int)this->bufferY) {
|
||||
std::uint8_t alpha = bitmap[j * w + i];
|
||||
_Float16 srcA = (_Float16(alpha)/_Float16(255.0f))*color.a;
|
||||
for(std::uint8_t frame = 0; frame < Window::numFrames; frame++) {
|
||||
Vector<_Float16, 4, 4> dst = static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, true>*>(buffers[frame])->value[bufferY * this->bufferX + bufferX];
|
||||
|
||||
_Float16 outA = srcA + dst.a * (1.0f - srcA);
|
||||
static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, true>*>(buffers[frame])->value[bufferY * this->bufferX + bufferX] = Vector<_Float16, 4, 4>(
|
||||
(color.r * srcA + dst.r * dst.a * (1.0f - srcA)),
|
||||
(color.g * srcA + dst.g * dst.a * (1.0f - srcA)),
|
||||
(color.b * srcA + dst.b * dst.a * (1.0f - srcA)),
|
||||
outA
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
x += (int)(ax * scale);
|
||||
|
||||
if (p + 1 < end) {
|
||||
int next;
|
||||
x += (int)stbtt_GetGlyphKernAdvance(&font.font, codepoint, utf8_decode(p+1, &next));
|
||||
}
|
||||
}
|
||||
currentY += lineHeight;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderText(std::span<const std::string_view> lines, float size, Vector<_Float16, 4> color, Font& font, std::uint8_t frame, TextAlignment alignment = TextAlignment::Left, std::uint32_t offsetX = 0, std::uint32_t offsetY = 0, OpaqueType opaque = OpaqueType::FullyOpaque) requires(Mapped) {
|
||||
float scale = stbtt_ScaleForPixelHeight(&font.font, size);
|
||||
int baseline = (int)(font.ascent * scale);
|
||||
std::uint32_t lineHeight = (font.ascent - font.descent) * scale;
|
||||
std::uint32_t currentY = baseline;
|
||||
for(std::string_view line : lines) {
|
||||
|
||||
std::uint32_t lineWidth = 0;
|
||||
for (const char c : line) {
|
||||
int advance, lsb;
|
||||
stbtt_GetCodepointHMetrics(&font.font, c, &advance, &lsb);
|
||||
lineWidth += (int)(advance * scale);
|
||||
}
|
||||
|
||||
std::uint32_t x = 0;
|
||||
switch (alignment) {
|
||||
case TextAlignment::Left:
|
||||
x = 0;
|
||||
break;
|
||||
case TextAlignment::Center:
|
||||
x = (this->scaled.size.x - lineWidth) / 2;
|
||||
break;
|
||||
case TextAlignment::Right:
|
||||
x = this->scaled.size.x - lineWidth;
|
||||
break;
|
||||
}
|
||||
|
||||
const char* p = line.data();
|
||||
const char* end = p + line.size();
|
||||
|
||||
while (p < end) {
|
||||
int bytes;
|
||||
int codepoint = utf8_decode(p, &bytes);
|
||||
p += bytes;
|
||||
|
||||
int ax;
|
||||
int lsb;
|
||||
stbtt_GetCodepointHMetrics(&font.font, codepoint, &ax, &lsb);
|
||||
|
||||
int c_x1, c_y1, c_x2, c_y2;
|
||||
stbtt_GetCodepointBitmapBox(&font.font, codepoint, scale, scale, &c_x1, &c_y1, &c_x2, &c_y2);
|
||||
|
||||
int w = c_x2 - c_x1;
|
||||
int h = c_y2 - c_y1;
|
||||
|
||||
std::vector<unsigned char> bitmap(w * h);
|
||||
stbtt_MakeCodepointBitmap(&font.font, bitmap.data(), w, h, w, scale, scale, codepoint);
|
||||
|
||||
// Only render characters that fit within the scaled bounds
|
||||
switch(opaque) {
|
||||
case OpaqueType::FullyOpaque: {
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
int bufferX = x + i + c_x1 + offsetX;
|
||||
int bufferY = currentY + j + c_y1 + offsetY;
|
||||
|
||||
if (bufferX >= 0 && bufferX < (int)this->bufferX && bufferY >= 0 && bufferY < (int)this->bufferY) {
|
||||
static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, true>*>(buffers[frame])->value[bufferY * this->bufferX + bufferX] = {color.r, color.g, color.b, static_cast<_Float16>(bitmap[j * w + i])};
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OpaqueType::SemiOpaque:
|
||||
case OpaqueType::Transparent: {
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
int bufferX = x + i + c_x1 + offsetX;
|
||||
int bufferY = currentY + j + c_y1 + offsetY;
|
||||
|
||||
if (bufferX >= 0 && bufferX < (int)this->bufferX && bufferY >= 0 && bufferY < (int)this->bufferY) {
|
||||
std::uint8_t alpha = bitmap[j * w + i];
|
||||
_Float16 srcA = (_Float16(alpha)/_Float16(255.0f))*color.a;
|
||||
Vector<_Float16, 4, 4> dst = static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, true>*>(buffers[frame])->value[bufferY * this->bufferX + bufferX];
|
||||
|
||||
_Float16 outA = srcA + dst.a * (1.0f - srcA);
|
||||
static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, true>*>(buffers[frame])->value[bufferY * this->bufferX + bufferX] = Vector<_Float16, 4, 4>(
|
||||
(color.r * srcA + dst.r * dst.a * (1.0f - srcA)),
|
||||
(color.g * srcA + dst.g * dst.a * (1.0f - srcA)),
|
||||
(color.b * srcA + dst.b * dst.a * (1.0f - srcA)),
|
||||
outA
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
x += (int)(ax * scale);
|
||||
|
||||
if (p + 1 < end) {
|
||||
int next;
|
||||
x += (int)stbtt_GetGlyphKernAdvance(&font.font, codepoint, utf8_decode(p+1, &next));
|
||||
}
|
||||
}
|
||||
currentY += lineHeight;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
@ -71,6 +71,7 @@ export namespace Crafter {
|
|||
RendertargetVulkan() = default;
|
||||
RendertargetVulkan(std::uint16_t sizeX, std::uint16_t sizeY, std::vector<RenderingElement2DVulkanBase*>&& elements);
|
||||
RendertargetVulkan(std::uint16_t sizeX, std::uint16_t sizeY);
|
||||
void UpdateElements();
|
||||
void UpdateBuffer(std::uint8_t frame);
|
||||
void ReorderBuffer(std::uint8_t frame);
|
||||
void WriteDescriptors(std::span<VkResourceDescriptorInfoEXT> infos, std::span<VkHostAddressRangeEXT> ranges, std::uint16_t start, std::uint32_t bufferOffset, DescriptorHeapVulkan& descriptorHeap);
|
||||
|
|
@ -183,16 +184,16 @@ export namespace Crafter {
|
|||
void AddOldRects(Transform2D* elementTransform, std::uint8_t frame, std::vector<ClipRect>& clipRects) {
|
||||
RenderingElement2DBase<T, Frames>* element = dynamic_cast<RenderingElement2DBase<T, Frames>*>(elementTransform);
|
||||
if(element) {
|
||||
// if(element->scaled.position.x != element->oldScale[frame].position.x || element->scaled.position.y != element->oldScale[frame].position.y || element->scaled.size.x != element->oldScale[frame].size.x || element->scaled.size.y != element->oldScale[frame].size.y || element->redraw[frame]) {
|
||||
// clipRects.emplace_back(std::max(element->scaled.position.x, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.x + element->scaled.size.x), this->sizeX), std::max(element->scaled.position.y, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.y + element->scaled.size.y), this->sizeY));
|
||||
// clipRects.emplace_back(std::max(element->oldScale[frame].position.x, std::uint16_t(0)), std::min(std::uint16_t(element->oldScale[frame].position.x + element->oldScale[frame].size.x), this->sizeX), std::max(element->oldScale[frame].position.y, std::uint16_t(0)), std::min(std::uint16_t(element->oldScale[frame].position.y + element->oldScale[frame].size.y), this->sizeY));
|
||||
// element->oldScale[frame] = element->scaled;
|
||||
// element->redraw[frame] = false;
|
||||
// } else if(element->redraw[frame]) {
|
||||
// clipRects.emplace_back(std::max(element->scaled.position.x, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.x + element->scaled.size.x), this->sizeX), std::max(element->scaled.position.y, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.y + element->scaled.size.y), this->sizeY));
|
||||
// element->oldScale[frame] = element->scaled;
|
||||
// element->redraw[frame] = false;
|
||||
// }
|
||||
if(element->scaled.position.x != element->oldScale[frame].position.x || element->scaled.position.y != element->oldScale[frame].position.y || element->scaled.size.x != element->oldScale[frame].size.x || element->scaled.size.y != element->oldScale[frame].size.y || element->redraw[frame]) {
|
||||
clipRects.emplace_back(std::max(element->scaled.position.x, std::int16_t(0)), std::min(std::int16_t(element->scaled.position.x + element->scaled.size.x), std::int16_t(this->sizeX)), std::max(element->scaled.position.y, std::int16_t(0)), std::min(std::int16_t(element->scaled.position.y + element->scaled.size.y), std::int16_t(this->sizeY)));
|
||||
clipRects.emplace_back(std::max(element->oldScale[frame].position.x, std::int16_t(0)), std::min(std::int16_t(element->oldScale[frame].position.x + element->oldScale[frame].size.x), std::int16_t(this->sizeX)), std::max(element->oldScale[frame].position.y, std::int16_t(0)), std::min(std::int16_t(element->oldScale[frame].position.y + element->oldScale[frame].size.y), std::int16_t(this->sizeY)));
|
||||
element->oldScale[frame] = element->scaled;
|
||||
element->redraw[frame] = false;
|
||||
} else if(element->redraw[frame]) {
|
||||
clipRects.emplace_back(std::max(element->scaled.position.x, std::int16_t(0)), std::min(std::int16_t(element->scaled.position.x + element->scaled.size.x), std::int16_t(this->sizeX)), std::max(element->scaled.position.y, std::int16_t(0)), std::min(std::int16_t(element->scaled.position.y + element->scaled.size.y), std::int16_t(this->sizeY)));
|
||||
element->oldScale[frame] = element->scaled;
|
||||
element->redraw[frame] = false;
|
||||
}
|
||||
}
|
||||
for(Transform2D* child : elementTransform->children) {
|
||||
AddOldRects(child, frame, clipRects);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue