From 37d8df478472f3e6d62f91d673a9c3b123c80ec7 Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 29 Mar 2020 13:32:32 -0600 Subject: [PATCH] Allow initializing empty TextureData with Blob; --- src/api/l_data.c | 16 +++++++++++----- src/modules/data/rasterizer.c | 2 +- src/modules/data/textureData.c | 17 ++++++++++++----- src/modules/data/textureData.h | 2 +- src/modules/graphics/font.c | 2 +- src/modules/graphics/opengl.c | 4 ++-- src/modules/headset/openvr.c | 2 +- 7 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/api/l_data.c b/src/api/l_data.c index cb7c9516..29dd5a45 100644 --- a/src/api/l_data.c +++ b/src/api/l_data.c @@ -119,12 +119,18 @@ static int l_lovrDataNewTextureData(lua_State* L) { int width = luaL_checkinteger(L, 1); int height = luaL_checkinteger(L, 2); TextureFormat format = luax_checkenum(L, 3, TextureFormats, "rgba", "TextureFormat"); - textureData = lovrTextureDataCreate(width, height, 0x0, format); + Blob* blob = lua_isnoneornil(L, 4) ? NULL : luax_checktype(L, 4, Blob); + textureData = lovrTextureDataCreate(width, height, blob, 0x0, format); } else { - Blob* blob = luax_readblob(L, 1, "Texture"); - bool flip = lua_isnoneornil(L, 2) ? true : lua_toboolean(L, 2); - textureData = lovrTextureDataCreateFromBlob(blob, flip); - lovrRelease(Blob, blob); + TextureData* source = luax_totype(L, 1, TextureData); + if (source) { + textureData = lovrTextureDataCreate(source->width, source->height, source->blob, 0x0, source->format); + } else { + Blob* blob = luax_readblob(L, 1, "Texture"); + bool flip = lua_isnoneornil(L, 2) ? true : lua_toboolean(L, 2); + textureData = lovrTextureDataCreateFromBlob(blob, flip); + lovrRelease(Blob, blob); + } } luax_pushtype(L, TextureData, textureData); diff --git a/src/modules/data/rasterizer.c b/src/modules/data/rasterizer.c index 5cc59b21..79fbcf27 100644 --- a/src/modules/data/rasterizer.c +++ b/src/modules/data/rasterizer.c @@ -125,7 +125,7 @@ void lovrRasterizerLoadGlyph(Rasterizer* rasterizer, uint32_t character, Glyph* glyph->dx = empty ? 0 : roundf(bearing * rasterizer->scale); glyph->dy = empty ? 0 : roundf(y1 * rasterizer->scale); glyph->advance = roundf(advance * rasterizer->scale); - glyph->data = lovrTextureDataCreate(glyph->tw, glyph->th, 0, FORMAT_RGB); + glyph->data = lovrTextureDataCreate(glyph->tw, glyph->th, NULL, 0, FORMAT_RGB); // Render SDF float tx = GLYPH_PADDING + -glyph->dx; diff --git a/src/modules/data/textureData.c b/src/modules/data/textureData.c index bd9db969..c3913c35 100644 --- a/src/modules/data/textureData.c +++ b/src/modules/data/textureData.c @@ -452,17 +452,22 @@ static bool parseASTC(uint8_t* bytes, size_t size, TextureData* textureData) { return true; } -TextureData* lovrTextureDataInit(TextureData* textureData, uint32_t width, uint32_t height, uint8_t value, TextureFormat format) { - lovrAssert(width > 0 && height > 0, "TextureData dimensions must be positive"); - lovrAssert(format < FORMAT_DXT1, "Blank TextureData cannot be compressed"); +TextureData* lovrTextureDataInit(TextureData* textureData, uint32_t width, uint32_t height, Blob* contents, uint8_t value, TextureFormat format) { size_t pixelSize = getPixelSize(format); size_t size = width * height * pixelSize; + lovrAssert(width > 0 && height > 0, "TextureData dimensions must be positive"); + lovrAssert(format < FORMAT_DXT1, "Blank TextureData cannot be compressed"); + lovrAssert(!contents || contents->size >= size, "TextureData Blob is too small (%d bytes needed, got %d)", size, contents->size); textureData->width = width; textureData->height = height; textureData->format = format; - void *data = malloc(size); + void* data = malloc(size); lovrAssert(data, "Out of memory"); - memset(data, value, size); + if (contents) { + memcpy(data, contents->data, size); + } else { + memset(data, value, size); + } textureData->blob = lovrBlobCreate(data, size, "TextureData plain"); return textureData; } @@ -489,9 +494,11 @@ TextureData* lovrTextureDataInitFromBlob(TextureData* textureData, Blob* blob, b if (stbi_is_hdr_from_memory(blob->data, length)) { textureData->format = FORMAT_RGBA32F; textureData->blob->data = stbi_loadf_from_memory(blob->data, length, &width, &height, NULL, 4); + textureData->blob->size = 16 * width * height; } else { textureData->format = FORMAT_RGBA; textureData->blob->data = stbi_load_from_memory(blob->data, length, &width, &height, NULL, 4); + textureData->blob->size = 4 * width * height; } if (!textureData->blob->data) { diff --git a/src/modules/data/textureData.h b/src/modules/data/textureData.h index fe7b160d..69f13c7a 100644 --- a/src/modules/data/textureData.h +++ b/src/modules/data/textureData.h @@ -57,7 +57,7 @@ typedef struct TextureData { uint32_t mipmapCount; } TextureData; -TextureData* lovrTextureDataInit(TextureData* textureData, uint32_t width, uint32_t height, uint8_t value, TextureFormat format); +TextureData* lovrTextureDataInit(TextureData* textureData, uint32_t width, uint32_t height, Blob* contents, uint8_t value, TextureFormat format); TextureData* lovrTextureDataInitFromBlob(TextureData* textureData, Blob* blob, bool flip); #define lovrTextureDataCreate(...) lovrTextureDataInit(lovrAlloc(TextureData), __VA_ARGS__) #define lovrTextureDataCreateFromBlob(...) lovrTextureDataInitFromBlob(lovrAlloc(TextureData), __VA_ARGS__) diff --git a/src/modules/graphics/font.c b/src/modules/graphics/font.c index 8cf8862e..99a5fb9c 100644 --- a/src/modules/graphics/font.c +++ b/src/modules/graphics/font.c @@ -368,7 +368,7 @@ static void lovrFontExpandTexture(Font* font) { // Could look into using glClearTexImage when supported to make this more efficient. static void lovrFontCreateTexture(Font* font) { lovrRelease(Texture, font->texture); - TextureData* textureData = lovrTextureDataCreate(font->atlas.width, font->atlas.height, 0x0, FORMAT_RGB); + TextureData* textureData = lovrTextureDataCreate(font->atlas.width, font->atlas.height, NULL, 0x0, FORMAT_RGB); font->texture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, false, false, 0); lovrTextureSetFilter(font->texture, (TextureFilter) { .mode = FILTER_BILINEAR }); lovrTextureSetWrap(font->texture, (TextureWrap) { .s = WRAP_CLAMP, .t = WRAP_CLAMP }); diff --git a/src/modules/graphics/opengl.c b/src/modules/graphics/opengl.c index 49e66a33..74c10502 100644 --- a/src/modules/graphics/opengl.c +++ b/src/modules/graphics/opengl.c @@ -1289,7 +1289,7 @@ void lovrGpuInit(void* (*getProcAddress)(const char*)) { arr_init(&state.incoherents[i]); } - TextureData* textureData = lovrTextureDataCreate(1, 1, 0xff, FORMAT_RGBA); + TextureData* textureData = lovrTextureDataCreate(1, 1, NULL, 0xff, FORMAT_RGBA); state.defaultTexture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, true, false, 0); lovrTextureSetFilter(state.defaultTexture, (TextureFilter) { .mode = FILTER_NEAREST }); lovrTextureSetWrap(state.defaultTexture, (TextureWrap) { WRAP_CLAMP, WRAP_CLAMP, WRAP_CLAMP }); @@ -2014,7 +2014,7 @@ TextureData* lovrCanvasNewTextureData(Canvas* canvas, uint32_t index) { glReadBuffer(index); } - TextureData* textureData = lovrTextureDataCreate(canvas->width, canvas->height, 0x0, FORMAT_RGBA); + TextureData* textureData = lovrTextureDataCreate(canvas->width, canvas->height, NULL, 0x0, FORMAT_RGBA); glReadPixels(0, 0, canvas->width, canvas->height, GL_RGBA, GL_UNSIGNED_BYTE, textureData->blob->data); if (index != 0) { diff --git a/src/modules/headset/openvr.c b/src/modules/headset/openvr.c index b0e781a5..de13f3ed 100755 --- a/src/modules/headset/openvr.c +++ b/src/modules/headset/openvr.c @@ -608,7 +608,7 @@ static ModelData* openvr_newModelData(Device device) { }; RenderModel_TextureMap_t* vrTexture = state.deviceTextures[index]; - model->textures[0] = lovrTextureDataCreate(vrTexture->unWidth, vrTexture->unHeight, 0, FORMAT_RGBA); + model->textures[0] = lovrTextureDataCreate(vrTexture->unWidth, vrTexture->unHeight, NULL, 0, FORMAT_RGBA); memcpy(model->textures[0]->blob->data, vrTexture->rubTextureMapData, vrTexture->unWidth * vrTexture->unHeight * 4); model->materials[0] = (ModelMaterial) {