diff --git a/src/modules/image/CMakeLists.txt b/src/modules/image/CMakeLists.txt index 20f8df27c..9781fbc55 100644 --- a/src/modules/image/CMakeLists.txt +++ b/src/modules/image/CMakeLists.txt @@ -2,7 +2,7 @@ set(SRCS Image.cpp Image.h ) set(LIB image) -engine_add_module(TARGET ${LIB} SRCS ${SRCS} DEPENDENCIES io) +engine_add_module(TARGET ${LIB} SRCS ${SRCS} DEPENDENCIES io util) if (USE_CLANG) target_compile_options(${LIB} PRIVATE -Wno-unused-function) endif() diff --git a/src/modules/image/Image.cpp b/src/modules/image/Image.cpp index 4dab689ab..b168ced99 100644 --- a/src/modules/image/Image.cpp +++ b/src/modules/image/Image.cpp @@ -8,10 +8,12 @@ #include "core/StringUtil.h" #include "core/concurrent/ThreadPool.h" #include "core/Assert.h" +#include "io/BufferedReadWriteStream.h" #include "io/Filesystem.h" #include "core/StandardLib.h" #include "io/FormatDescription.h" #include "io/Stream.h" +#include "util/Base64.h" #define STBI_ASSERT core_assert #define STBI_MALLOC core_malloc @@ -182,4 +184,13 @@ bool Image::writePng() const { return stbi_write_png(_name.c_str(), _width, _height, _depth, (const void*)_data, _width * _depth) != 0; } +core::String Image::pngBase64() const { + io::BufferedReadWriteStream s; + if (!writePng(s, _data, _width, _height, _depth)) { + return ""; + } + s.seek(0); + return util::Base64::encode(s); +} + } diff --git a/src/modules/image/Image.h b/src/modules/image/Image.h index 1bd02dc48..bdc7d6569 100644 --- a/src/modules/image/Image.h +++ b/src/modules/image/Image.h @@ -37,6 +37,7 @@ public: static bool writePng(io::SeekableWriteStream &stream, const uint8_t* buffer, int width, int height, int depth); static bool writePng(const char *name, const uint8_t *buffer, int width, int height, int depth); bool writePng() const; + core::String pngBase64() const; const uint8_t* at(int x, int y) const; diff --git a/src/modules/voxelformat/GLTFFormat.cpp b/src/modules/voxelformat/GLTFFormat.cpp index 4c531787e..593704c22 100644 --- a/src/modules/voxelformat/GLTFFormat.cpp +++ b/src/modules/voxelformat/GLTFFormat.cpp @@ -12,10 +12,12 @@ #include "core/StringUtil.h" #include "core/concurrent/Lock.h" #include "engine-config.h" +#include "image/Image.h" #include "io/StdStreamBuf.h" #include "io/Filesystem.h" #include "voxel/MaterialColor.h" #include "voxel/Mesh.h" +#include "voxel/Palette.h" #include "voxel/VoxelVertex.h" #include "core/collection/DynamicArray.h" #include "voxelformat/SceneGraph.h" @@ -111,20 +113,18 @@ bool GLTFFormat::saveMeshes(const core::Map &meshIdxNodeMap, const Sce Log::debug("Re-use material id %i for hash %" PRIu64, materialId, palette.hash()); } else { const core::String hashId = core::String::format("%" PRIu64, palette.hash()); - core::String palettename = core::string::stripExtension(filename); - palettename.append(hashId); - palettename.append(".png"); const int imageIndex = (int)m.images.size(); { tinygltf::Image colorPaletteImg; - colorPaletteImg.uri = core::string::extractFilenameWithExtension(palettename).c_str(); + image::Image image("pal"); + image.loadRGBA((const unsigned char *)palette.colors, sizeof(palette.colors), voxel::PaletteMaxColors, 1); + const core::String &pal64 = image.pngBase64(); + colorPaletteImg.uri = "data:image/png;base64,"; + colorPaletteImg.uri += pal64.c_str(); m.images.emplace_back(core::move(colorPaletteImg)); } - if (!palette.save(palettename.c_str())) { - Log::error("Failed to save palette data"); - } const int textureIndex = (int)m.textures.size(); { tinygltf::Texture paletteTexture;