diff --git a/src/api/l_textureData.c b/src/api/l_textureData.c index 5fe62d34..86750e2f 100644 --- a/src/api/l_textureData.c +++ b/src/api/l_textureData.c @@ -34,6 +34,19 @@ static int l_lovrTextureDataGetFormat(lua_State* L) { return 1; } +static int l_lovrTextureDataPaste(lua_State* L) { + TextureData* textureData = luax_checktype(L, 1, TextureData); + TextureData* source = luax_checktype(L, 2, TextureData); + uint32_t dx = luaL_optinteger(L, 3, 0); + uint32_t dy = luaL_optinteger(L, 4, 0); + uint32_t sx = luaL_optinteger(L, 5, 0); + uint32_t sy = luaL_optinteger(L, 6, 0); + uint32_t w = luaL_optinteger(L, 7, source->width); + uint32_t h = luaL_optinteger(L, 8, source->height); + lovrTextureDataPaste(textureData, source, dx, dy, sx, sy, w, h); + return 0; +} + static int l_lovrTextureDataGetPixel(lua_State* L) { TextureData* textureData = luax_checktype(L, 1, TextureData); int x = luaL_checkinteger(L, 2); @@ -72,6 +85,7 @@ const luaL_Reg lovrTextureData[] = { { "getHeight", l_lovrTextureDataGetHeight }, { "getDimensions", l_lovrTextureDataGetDimensions }, { "getFormat", l_lovrTextureDataGetFormat }, + { "paste", l_lovrTextureDataPaste }, { "getPixel", l_lovrTextureDataGetPixel }, { "setPixel", l_lovrTextureDataSetPixel }, { "getPointer", l_lovrTextureDataGetPointer }, diff --git a/src/modules/data/textureData.c b/src/modules/data/textureData.c index 443700a4..d253aba9 100644 --- a/src/modules/data/textureData.c +++ b/src/modules/data/textureData.c @@ -563,6 +563,21 @@ bool lovrTextureDataEncode(TextureData* textureData, const char* filename) { return success; } +void lovrTextureDataPaste(TextureData* textureData, TextureData* source, uint32_t dx, uint32_t dy, uint32_t sx, uint32_t sy, uint32_t w, uint32_t h) { + lovrAssert(textureData->format == source->format, "Currently TextureData must have the same format to paste"); + lovrAssert(textureData->format < FORMAT_DXT1, "Compressed TextureData cannot be pasted"); + size_t pixelSize = getPixelSize(textureData->format); + lovrAssert(dx + w <= textureData->width && dy + h <= textureData->height, "Attempt to paste outside of destination TextureData bounds"); + lovrAssert(sx + w <= source->width && sy + h <= source->height, "Attempt to paste from outside of source TextureData bounds"); + uint8_t* src = (uint8_t*) source->blob.data + ((source->height - 1 - sy) * source->width + sx) * pixelSize; + uint8_t* dst = (uint8_t*) textureData->blob.data + ((textureData->height - 1 - dy) * textureData->width + sx) * pixelSize; + for (uint32_t y = 0; y < h; y++) { + memcpy(dst, src, w * pixelSize); + src -= source->width * pixelSize; + dst -= textureData->width * pixelSize; + } +} + void lovrTextureDataDestroy(void* ref) { TextureData* textureData = ref; lovrRelease(Blob, textureData->source); diff --git a/src/modules/data/textureData.h b/src/modules/data/textureData.h index 13d26b00..71ff107e 100644 --- a/src/modules/data/textureData.h +++ b/src/modules/data/textureData.h @@ -64,4 +64,5 @@ TextureData* lovrTextureDataInitFromBlob(TextureData* textureData, Blob* blob, b Color lovrTextureDataGetPixel(TextureData* textureData, uint32_t x, uint32_t y); void lovrTextureDataSetPixel(TextureData* textureData, uint32_t x, uint32_t y, Color color); bool lovrTextureDataEncode(TextureData* textureData, const char* filename); +void lovrTextureDataPaste(TextureData* textureData, TextureData* source, uint32_t dx, uint32_t dy, uint32_t sx, uint32_t sy, uint32_t w, uint32_t h); void lovrTextureDataDestroy(void* ref);