Refactor filaweb::Asset.

This commit is contained in:
Philip Rideout
2018-09-21 11:54:03 -07:00
parent 63f2fe4ebc
commit 665ff2cd8f
4 changed files with 43 additions and 56 deletions
+28 -39
View File
@@ -150,49 +150,43 @@ Asset getRawFile(const char* name) {
var name = UTF8ToString($1);
HEAP32[nbytes] = assets[name].data.byteLength;
stringToUTF8(assets[name].url, $2, $3);
}, &result.nbytes, name, &result.url[0], sizeof(result.url));
}, &result.rawSize, name, &result.rawUrl[0], sizeof(result.rawUrl));
// Move the data from JavaScript.
uint8_t* data = new uint8_t[result.nbytes];
uint8_t* data = new uint8_t[result.rawSize];
EM_ASM({
var data = $0;
var name = UTF8ToString($1);
HEAPU8.set(assets[name].data, data);
assets[name].data = null;
}, data, name);
result.data = decltype(Asset::data)(data);
result.rawData = decltype(Asset::rawData)(data);
return result;
}
static Asset getPngTexture(const Asset& rawfile) {
int width, height, ncomp;
stbi_info_from_memory(rawfile.data.get(), rawfile.nbytes, &width, &height, &ncomp);
stbi_info_from_memory(rawfile.rawData.get(), rawfile.rawSize, &width, &height, &ncomp);
const uint32_t nbytes = width * height * 4;
uint8_t* texels = new uint8_t[nbytes];
stbi_uc* decoded = stbi_load_from_memory(rawfile.data.get(), rawfile.nbytes, &width, &height,
&ncomp, 4);
memcpy(texels, decoded, nbytes);
stbi_uc* decoded = stbi_load_from_memory(rawfile.rawData.get(), rawfile.rawSize, &width,
&height, &ncomp, 4);
Asset result = {};
result.texture.reset(new KtxBundle(1, 1, false));
result.texture->setBlob({}, decoded, nbytes);
stbi_image_free(decoded);
return {
.data = decltype(Asset::data)(texels),
.ktx = {},
.nbytes = nbytes,
.width = uint32_t(width),
.height = uint32_t(height)
};
return result;
}
static Asset getKtxTexture(const Asset& rawfile) {
KtxBundle* bundle = new KtxBundle(rawfile.data.get(), rawfile.nbytes);
return {
.data = {},
.ktx = decltype(Asset::ktx)(bundle)
};
Asset result = {};
result.texture.reset(new KtxBundle(rawfile.rawData.get(), rawfile.rawSize));
return result;
}
Asset getTexture(const char* name) {
Asset rawfile = getRawFile(name);
string extension = Path(rawfile.url).getExtension();
string extension = Path(rawfile.rawUrl).getExtension();
fflush(stdout);
if (extension == "png" || extension == "rgbm") {
return getPngTexture(rawfile);
@@ -218,16 +212,11 @@ Asset getCubemap(const char* name) {
key = prefix + "sh.txt";
*shCoeffs = getRawFile(key.c_str());
return {
.data = {},
.ktx = {},
.nbytes = 0,
.width = 0,
.height = 0,
.envShCoeffs = decltype(Asset::envShCoeffs)(shCoeffs),
.envFaces = decltype(Asset::envFaces)(envFaces),
.skyFaces = decltype(Asset::skyFaces)(skyFaces),
};
Asset result = {};
result.envShCoeffs.reset(shCoeffs);
result.envIBL.reset(envFaces);
result.envSky.reset(skyFaces);
return result;
}
SkyLight getSkyLight(Engine& engine, const char* name) {
@@ -238,7 +227,7 @@ SkyLight getSkyLight(Engine& engine, const char* name) {
static auto asset = filaweb::getCubemap(name);
// Parse the coefficients.
std::istringstream shReader((const char*) asset.envShCoeffs->data.get());
std::istringstream shReader((const char*) asset.envShCoeffs->rawData.get());
shReader >> std::skipws;
std::string line;
for (size_t i = 0; i < 9; i++) {
@@ -251,8 +240,8 @@ SkyLight getSkyLight(Engine& engine, const char* name) {
}
// Copy over the miplevels for the indirect light.
auto info = asset.envFaces->ktx->getInfo();
uint32_t nmips = asset.envFaces->ktx->getNumMipLevels();
auto info = asset.envIBL->texture->getInfo();
uint32_t nmips = asset.envIBL->texture->getNumMipLevels();
Texture* texture = Texture::Builder()
.width(info.pixelWidth)
.height(info.pixelHeight)
@@ -280,11 +269,11 @@ SkyLight getSkyLight(Engine& engine, const char* name) {
uint8_t* pbdPixels = static_cast<uint8_t*>(buffer.buffer);
uint8_t* ktxPixels;
uint32_t ktxSize;
asset.envFaces->ktx->getBlob({mip}, &ktxPixels, &ktxSize);
asset.envIBL->texture->getBlob({mip}, &ktxPixels, &ktxSize);
memcpy(pbdPixels, ktxPixels, faceSize * 6);
texture->setImage(engine, mip, std::move(buffer), offsets);
}
asset.envFaces->ktx.reset();
asset.envIBL->texture.reset();
result.indirectLight = IndirectLight::Builder()
.reflections(texture)
@@ -293,7 +282,7 @@ SkyLight getSkyLight(Engine& engine, const char* name) {
.build(engine);
// Copy a single miplevel for the blurry skybox
info = asset.skyFaces->ktx->getInfo();
info = asset.envSky->texture->getInfo();
size = info.pixelWidth;
Texture* skybox = Texture::Builder()
.width(size)
@@ -320,11 +309,11 @@ SkyLight getSkyLight(Engine& engine, const char* name) {
uint8_t* pbdPixels = static_cast<uint8_t*>(buffer.buffer);
uint8_t* ktxPixels;
uint32_t ktxSize;
asset.skyFaces->ktx->getBlob({}, &ktxPixels, &ktxSize);
asset.envSky->texture->getBlob({}, &ktxPixels, &ktxSize);
memcpy(pbdPixels, ktxPixels, faceSize * 6);
skybox->setImage(engine, 0, std::move(buffer), offsets);
}
asset.skyFaces->ktx.reset();
asset.envSky->texture.reset();
result.skybox = Skybox::Builder().environment(skybox).build(engine);
return result;
+7 -9
View File
@@ -37,18 +37,16 @@
namespace filaweb {
// Filaweb defines three kinds of assets: raw files, textures, and cubemaps.
// Filaweb defines three kinds of assets: textures, environments, and raw files.
// For simplicity all three kinds are represented with a single struct.
struct Asset {
std::unique_ptr<uint8_t[]> data;
std::unique_ptr<image::KtxBundle> ktx;
uint32_t nbytes;
uint32_t width;
uint32_t height;
std::unique_ptr<image::KtxBundle> texture;
std::unique_ptr<Asset> envShCoeffs;
std::unique_ptr<Asset> envFaces;
std::unique_ptr<Asset> skyFaces;
char url[256];
std::unique_ptr<Asset> envIBL;
std::unique_ptr<Asset> envSky;
std::unique_ptr<uint8_t[]> rawData;
uint32_t rawSize;
char rawUrl[256];
};
Asset getRawFile(const char* name);
+2 -2
View File
@@ -79,10 +79,10 @@ void setup(Engine* engine, View* view, Scene* scene) {
static auto mesh = filaweb::getRawFile("mesh");
// Create mesh.
const uint8_t* mdata = mesh.data.get();
const uint8_t* mdata = mesh.rawData.get();
const auto destructor = [](void* buffer, size_t size, void* user) {
auto asset = (filaweb::Asset*) user;
asset->data.reset();
asset->rawData.reset();
};
MaterialInstance* materialInstance = app.params.materialInstance[MATERIAL_LIT];
app.filamesh = decodeMesh(*engine, mdata, 0, materialInstance, destructor, &mesh);
+6 -6
View File
@@ -59,11 +59,11 @@ static SuzanneApp app;
static Texture* setTextureParameter(Engine& engine, filaweb::Asset& asset, string name, bool linear,
TextureSampler const &sampler) {
const auto& info = asset.ktx->getInfo();
const auto& info = asset.texture->getInfo();
const auto destructor = [](void* buffer, size_t size, void* user) {
auto asset = (filaweb::Asset*) user;
asset->ktx.reset();
asset->texture.reset();
};
Texture::Format format;
@@ -76,7 +76,7 @@ static Texture* setTextureParameter(Engine& engine, filaweb::Asset& asset, strin
uint8_t* data;
uint32_t nbytes;
asset.ktx->getBlob({}, &data, &nbytes);
asset.texture->getBlob({}, &data, &nbytes);
Texture::PixelBufferDescriptor pb(data, nbytes, format, Texture::Type::UBYTE, destructor,
&asset);
@@ -119,11 +119,11 @@ void setup(Engine* engine, View* view, Scene* scene) {
static auto ao = filaweb::getTexture("ao");
// Create mesh.
printf("%s: %d bytes\n", "mesh", mesh.nbytes);
const uint8_t* mdata = mesh.data.get();
printf("%s: %d bytes\n", "mesh", mesh.rawSize);
const uint8_t* mdata = mesh.rawData.get();
const auto destructor = [](void* buffer, size_t size, void* user) {
auto asset = (filaweb::Asset*) user;
asset->data.reset();
asset->rawData.reset();
};
app.filamesh = decodeMesh(*engine, mdata, 0, app.mi, destructor, &mesh);
scene->addEntity(app.filamesh->renderable);