From 7fdab4f62b13dd9be527818986bb4fec79900605 Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Sun, 22 Mar 2026 21:08:02 +0100 Subject: [PATCH] rendering update --- ...after.Graphics-RenderingElement2DBase.cppm | 11 ++++ interfaces/Crafter.Graphics-Rendertarget.cppm | 54 +++++-------------- interfaces/Crafter.Graphics-Transform2D.cppm | 5 +- interfaces/Crafter.Graphics-Types.cppm | 12 ++--- 4 files changed, 33 insertions(+), 49 deletions(-) diff --git a/interfaces/Crafter.Graphics-RenderingElement2DBase.cppm b/interfaces/Crafter.Graphics-RenderingElement2DBase.cppm index df29672..7b78164 100644 --- a/interfaces/Crafter.Graphics-RenderingElement2DBase.cppm +++ b/interfaces/Crafter.Graphics-RenderingElement2DBase.cppm @@ -115,5 +115,16 @@ export namespace Crafter { redraw[i] = true; } } + void CopyNearestNeighbor(Vector* dst, std::uint16_t dstSizeX, std::uint16_t dstScaledSizeX, std::uint16_t dstScaledSizeY, std::uint16_t offsetX, std::uint16_t offsetY) { + for (std::uint16_t y = 0; y < dstScaledSizeY; y++) { + std::uint16_t srcY = y * scaled.size.y / dstScaledSizeY; + std::uint16_t dstY = y + offsetY; + for (std::uint16_t x = 0; x < dstScaledSizeX; x++) { + std::uint16_t srcX = x * scaled.size.x / dstScaledSizeX; + std::uint16_t dstX = x + offsetX; + dst[dstY * dstSizeX + dstX] = buffer[srcY * this->scaled.size.x + srcX]; + } + } + } }; } \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-Rendertarget.cppm b/interfaces/Crafter.Graphics-Rendertarget.cppm index 5fc70c2..4dabef1 100644 --- a/interfaces/Crafter.Graphics-Rendertarget.cppm +++ b/interfaces/Crafter.Graphics-Rendertarget.cppm @@ -31,10 +31,10 @@ export namespace Crafter { std::vector> renderTimings; #endif Transform2D transform; - std::int32_t sizeX; - std::int32_t sizeY; + std::uint16_t sizeX; + std::uint16_t sizeY; RendertargetBase() = default; - RendertargetBase(std::int16_t sizeX, std::int16_t sizeY) : sizeX(sizeX), sizeY(sizeY), transform({0, 0, 1, 1, 0, 0, 0}){ + RendertargetBase(std::uint16_t sizeX, std::uint16_t sizeY) : sizeX(sizeX), sizeY(sizeY), transform({0, 0, 1, 1, 0, 0, 0}){ transform.scaled.size.x = sizeX; transform.scaled.size.y = sizeY; transform.scaled.position.x = 0; @@ -71,56 +71,30 @@ export namespace Crafter { std::int32_t src_height = element->scaled.size.y; switch (element->opaque) { - case OpaqueType::FullyOpaque: + case OpaqueType::FullyOpaque: { for (std::int32_t y = dirty.top; y < dirty.bottom; y++) { std::int32_t src_y = y - element->scaled.position.y; - - for (std::int32_t x = dirty.left; x < dirty.right; x++) { - std::int32_t src_x = x - element->scaled.position.x; - - this->buffer[frame][y * this->sizeX + x] = src_buffer[src_y * src_width + src_x]; - } + std::memcpy(&this->buffer[frame][y * this->sizeX], &src_buffer[src_y * src_width], dirty.right-dirty.left*sizeof(Vector)); } break; - - case OpaqueType::SemiOpaque: - // For semi-opaque, we can avoid blending when alpha is 0 or 255 - for (std::int32_t y = dirty.top; y < dirty.bottom; y++) { - std::int32_t src_y = y - element->scaled.position.y; - - for (std::int32_t x = dirty.left; x < dirty.right; x++) { - std::int32_t src_x = x - element->scaled.position.x; - Vector src_pixel = src_buffer[src_y * src_width + src_x]; - - if (src_pixel.a == 0) { - continue; - } - this->buffer[frame][y * this->sizeX + x] = src_pixel; - } - } - break; - + } case OpaqueType::Transparent: // For transparent, always perform blending - for (std::int32_t y = dirty.top; y < dirty.bottom; y++) { - std::int32_t src_y = y - element->scaled.position.y; - for (std::int32_t x = dirty.left; x < dirty.right; x++) { - std::int32_t src_x = x - element->scaled.position.x; + for (std::uint16_t y = dirty.top; y < dirty.bottom; y++) { + std::uint16_t src_y = y - element->scaled.position.y; + for (std::uint16_t x = dirty.left; x < dirty.right; x++) { + std::uint16_t src_x = x - element->scaled.position.x; Vector src = src_buffer[src_y * src_width + src_x]; Vector dst = buffer[frame][y * this->sizeX + x]; - - if(src.a == 0) { - continue; - } float srcA = src.a / 255.0f; - float dstA = dst.a / 255.0f; + float dstA = dst.a / 255.0f;k float outA = srcA + dstA * (1.0f - srcA); this->buffer[frame][y * this->sizeX + x] = Vector( - static_cast((src.r * srcA + dst.r * dstA * (1.0f - srcA)) / outA), - static_cast((src.g * srcA + dst.g * dstA * (1.0f - srcA)) / outA), - static_cast((src.b * srcA + dst.b * dstA * (1.0f - srcA)) / outA), + static_cast((src.r + dst.r * (1.0f - srcA)) / outA), + static_cast((src.g + dst.g * (1.0f - srcA)) / outA), + static_cast((src.b + dst.b * (1.0f - srcA)) / outA), static_cast(outA * 255) ); } diff --git a/interfaces/Crafter.Graphics-Transform2D.cppm b/interfaces/Crafter.Graphics-Transform2D.cppm index 96b4933..bab45e5 100644 --- a/interfaces/Crafter.Graphics-Transform2D.cppm +++ b/interfaces/Crafter.Graphics-Transform2D.cppm @@ -30,10 +30,10 @@ export namespace Crafter { float height; float offsetX; float offsetY; - std::int32_t z; + std::uint8_t z; bool maintainAspectRatio; Anchor2D() = default; - Anchor2D(float x, float y, float width, float height, float offsetX, float offsetY, std::int32_t z, bool maintainAspectRatio = false); + Anchor2D(float x, float y, float width, float height, float offsetX, float offsetY, std::uint8_t z, bool maintainAspectRatio = false); }; struct Transform2D { @@ -73,7 +73,6 @@ export namespace Crafter { scaled.size.y = anchor.height * parent.scaled.size.x; } } else { - scaled.size.x = anchor.width * parent.scaled.size.x; scaled.size.y = anchor.height * parent.scaled.size.y; } diff --git a/interfaces/Crafter.Graphics-Types.cppm b/interfaces/Crafter.Graphics-Types.cppm index 0bb3a23..a8d3cf7 100644 --- a/interfaces/Crafter.Graphics-Types.cppm +++ b/interfaces/Crafter.Graphics-Types.cppm @@ -33,15 +33,15 @@ export namespace Crafter { }; struct ScaleData2D { - Vector position; - Vector size; + Vector position; + Vector size; }; struct ClipRect { - std::int32_t left; - std::int32_t right; - std::int32_t top; - std::int32_t bottom; + std::uint16_t left; + std::uint16_t right; + std::uint16_t top; + std::uint16_t bottom; }; struct FrameTime {