Skip to content

Commit

Permalink
Support for embedded FBX textures
Browse files Browse the repository at this point in the history
  • Loading branch information
DBauer15 committed Apr 3, 2024
1 parent 94b9c91 commit 07a1233
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 15 deletions.
57 changes: 57 additions & 0 deletions src/backstage/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,63 @@ Image::Image(std::string filename, bool is_hdr) : m_is_hdr(is_hdr) {
}
}

Image::Image(uint8_t* blob, size_t size, bool is_hdr) {
m_is_hdr = is_hdr;
uint8_t* image = nullptr;
size_t image_size = 0;

// Try stbi first, assuming the image is not EXR
stbi_set_flip_vertically_on_load(true);
if (is_hdr)
image = (uint8_t*)stbi_loadf_from_memory(blob, size, &m_width, &m_height, &m_channels, 4);
else
image = stbi_load_from_memory(blob, size, &m_width, &m_height, &m_channels, 4);
m_channels = 4;
image_size = (is_hdr ? sizeof(float) : sizeof(uint8_t)) * m_width * m_height * m_channels;

// If the blob failed to load with stbi, try tinyexr
if (image == nullptr) {
const char* err = nullptr;
float* image_float;
int ret = LoadEXRFromMemory(&image_float, &m_width, &m_height, blob, size, &err);
if (ret != TINYEXR_SUCCESS) {
ERR("Unable to load image blob");
if (err) {
ERR(err);
FreeEXRErrorMessage(err);
}
return;
}

// Flip y axis
tbb::parallel_for(tbb::blocked_range<uint32_t>(0, m_height/2), [&](const auto& r) {
for (uint32_t row = r.begin(); row != r.end(); row++) {
tbb::parallel_for(tbb::blocked_range<uint32_t>(0, m_width * m_channels), [&](const auto& rr) {
for (uint32_t el = rr.begin(); el != rr.end(); el++) {
uint32_t id_a = row * m_width * m_channels + el;
uint32_t id_b = (m_height - row - 1) * m_width * m_channels + el;
std::swap(image_float[id_a], image_float[id_b]);
}
});
}
});

m_is_hdr = true;
image = (uint8_t*)image_float;
image_size = sizeof(float) * m_width * m_height * m_channels;
}


if (image == nullptr) {
ERR("Unable to load image blob");
return;
}

m_image = (uint8_t*)std::malloc(image_size);
std::memcpy(m_image, image, image_size);
std::free(image);
}

Image::Image(stage_vec3f color) {
m_image = (uint8_t*)std::malloc(sizeof(uint8_t) * 4);
m_image[0] = color.x * 255;
Expand Down
2 changes: 1 addition & 1 deletion src/backstage/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ struct Image {

public:
Image(std::string filename, bool is_hdr = false);
Image(uint8_t* blob, size_t size, bool is_hdr = false);
Image(stage_vec3f color);
Image(Image& other) = delete;
Image(Image&& other);
Expand Down Expand Up @@ -40,7 +41,6 @@ struct Image {
int32_t m_channels;

bool m_is_hdr { false };

};

}
Expand Down
40 changes: 26 additions & 14 deletions src/backstage/scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -995,23 +995,15 @@ void FBXScene::loadFBX(std::string scene) {

// Load textures
if (fbx_material->pbr.base_color.texture_enabled) {
std::string filename(fbx_material->pbr.base_color.texture->absolute_filename.data);
Image texture(filename);
if (texture.isValid()) {
m_textures.push_back(std::move(texture));
if (loadFBXTexture(fbx_material->pbr.base_color.texture)) {
material.base_color_texid = m_textures.size() - 1;
}
LOG("Read texture image '" + filename + "'");
}

if (fbx_material->pbr.opacity.texture_enabled) {
std::string filename(fbx_material->pbr.opacity.texture->absolute_filename.data);
Image texture(filename);
if (texture.isValid()) {
m_textures.push_back(std::move(texture));
if (loadFBXTexture(fbx_material->pbr.opacity.texture)) {
material.geometry_opacity_texid = m_textures.size() - 1;
}
LOG("Read opacity image '" + filename + "'");
}

m_materials.push_back(material);
Expand Down Expand Up @@ -1050,17 +1042,14 @@ void FBXScene::loadFBX(std::string scene) {

ufbx_vec3 position = ufbx_get_vertex_vec3(&fbx_mesh->vertex_position, index);
ufbx_vec3 normal = ufbx_get_vertex_vec3(&fbx_mesh->vertex_normal, index);
ufbx_vec2 uv = fbx_mesh->vertex_uv.exists ? ufbx_get_vertex_vec2(&fbx_mesh->vertex_uv, index) : ufbx_vec2{0, 0};
ufbx_vec2 uv = fbx_mesh->vertex_uv.exists ? ufbx_get_vertex_vec2(&fbx_mesh->vertex_uv, index) : ufbx_vec2({0, 0});
AligendVertex vertex;
// vertex.position = make_vec3(&position.x);
vertex.position.x = position.x;
vertex.position.y = position.y;
vertex.position.z = position.z;
// vertex.normal = make_vec3(&normal.x);
vertex.normal.x = normal.x;
vertex.normal.y = normal.y;
vertex.normal.z = normal.z;
// vertex.uv = make_vec2(&uv.x);
vertex.uv.x = uv.x;
vertex.uv.y = uv.y;

Expand Down Expand Up @@ -1110,5 +1099,28 @@ void FBXScene::loadFBX(std::string scene) {

ufbx_free_scene(fbx_scene);
}

bool
FBXScene::loadFBXTexture(ufbx_texture *texture)
{
std::unique_ptr<Image> image;
if (texture->content.size > 0)
{
image = std::make_unique<Image>((uint8_t*)texture->content.data, texture->content.size);
if (image->isValid()) LOG("Read texture image blob");
}
else
{
std::filesystem::path filepath = getAbsolutePath(texture->relative_filename.data);
image = std::make_unique<Image>(filepath.string());
if (image->isValid()) LOG("Read texture image '" + filename + "'");
}
if (image->isValid())
{
m_textures.push_back(std::move(*image));
return true;
}
return false;
}
}
}
3 changes: 3 additions & 0 deletions src/backstage/scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ namespace pbrt {
struct Spectrum;
}

struct ufbx_texture;

namespace stage {
namespace backstage {

Expand Down Expand Up @@ -144,6 +146,7 @@ struct FBXScene : public Scene {

private:
void loadFBX(std::string scene);
bool loadFBXTexture(ufbx_texture* texture);
};

std::unique_ptr<Scene> createScene(std::string scene);
Expand Down

0 comments on commit 07a1233

Please sign in to comment.