diff --git a/include/mesh.h b/include/mesh.h index a8271ad..276eb82 100644 --- a/include/mesh.h +++ b/include/mesh.h @@ -8,6 +8,7 @@ #include #include "util.h" +#include "util_image.h" struct meMeshInfo { diff --git a/include/render_group.h b/include/render_group.h index 7aa429b..7673a94 100644 --- a/include/render_group.h +++ b/include/render_group.h @@ -5,6 +5,7 @@ #include #include "util.h" +#include "util_image.h" // TODO: can these structs be used as opaque pointers? diff --git a/include/util.h b/include/util.h index 263111a..b8323bf 100644 --- a/include/util.h +++ b/include/util.h @@ -56,25 +56,6 @@ struct v4i int32 y1; }; -struct util_RGBA -{ - real32 R; - real32 G; - real32 B; - real32 A; -}; - -struct util_image -{ - int32 w; - int32 h; - int32 bits_per_channel; - int32 num_channels; - uint data_len; - uint8* pixels; - char file_path[256]; -}; - inline real32 SafeRatio(real32 dividend, real32 divisor) { @@ -132,11 +113,3 @@ char* utilDumpTextFile(const char* filename); bool utilWriteTextFile(const char* filename, const char* text); -//----------------- -// utilImage - -util_image utilLoadImage(const char* base_dir, const char* filename); - -void utilFreeImage(util_image image); - -v2f utilGetPaletteCoords(util_image& palette_image, uint color_index); diff --git a/include/util_image.h b/include/util_image.h new file mode 100644 index 0000000..da11604 --- /dev/null +++ b/include/util_image.h @@ -0,0 +1,30 @@ + +#pragma once + +#include "util.h" + + +// NOTE: wrapper for stb_image +struct util_image +{ + int32 w; + int32 h; + int32 bits_per_channel; + int32 num_channels; + uint data_len; + uint8* pixels; + char file_path[256]; +}; + +struct util_RGBA +{ + real32 R; + real32 G; + real32 B; + real32 A; +}; + +util_image utilLoadImage(const char* base_dir, const char* filename); + +void utilFreeImage(util_image image); + diff --git a/src/mesh.cpp b/src/mesh.cpp index de30731..2669684 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -155,7 +155,11 @@ loadDiffuseTexture(const char* data_dir, const aiScene* scene, aiMesh* mesh, meM const aiTexture* tex = scene->GetEmbeddedTexture(file_name.C_Str()); if (tex != nullptr) { LOG(Info) << "has embedded texture\n"; + // TODO: load binary texture data with stb_image + LOG(Info) << "format hint: " << tex->achFormatHint << "\n"; + + } else { LOG(Info) << "Loading texture file: " << file_name.C_Str() << "\n"; mi->diffuse_texture = utilLoadImage(data_dir, file_name.C_Str()); diff --git a/src/util.cpp b/src/util.cpp index 2e08be2..406b434 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -5,16 +5,10 @@ #include #include -#define STB_IMAGE_IMPLEMENTATION -#include "stb_image.h" - #include "dumbLog.h" #include "util.h" -#define PALETTE_ROWS 16 -#define PALETTE_COLUMNS 16 -#define PALETTE_BORDER 1 const uint MAX_FILESIZE = 2 * 1024 * 1024; // 2MB const uint MAX_STRING_LENGTH = 1024; @@ -153,82 +147,3 @@ utilWriteTextFile(const char* filename, const char* text) return false; } -//----------------- -// utilImage - -util_image -utilLoadImage(const char* base_dir, const char* filename) -{ - const uint max_path = 256; // NOTE: util_image.file_path is char[256] - const char* base_name = utilBaseName(filename); - // NOTE: +1 for '/' char, +1 for null - uint l = std::strlen(base_dir) + std::strlen(base_name) + 2; - assert(l < max_path); - char full_path[l]; - std::memcpy(full_path, base_dir, std::strlen(base_dir) + 1); - std::strcat(std::strcat(full_path, "/"), base_name); - LOG(Info) << "Loading Image: " << full_path << "\n"; - - util_image image; - std::memcpy(image.file_path, full_path, std::strlen(full_path) + 1); - stbi_set_flip_vertically_on_load(1); - image.pixels = stbi_load(full_path, &image.w, &image.h, &image.num_channels, 0); - image.bits_per_channel = 8; - image.data_len = image.w * image.h * image.num_channels; // NOTE: assumes 8 bits per channel - - if (image.pixels == 0) { - LOG(Error) << stbi_failure_reason() << "\n"; - utilFreeImage(image); - return image; - } - - LOG(Info) << "Image properties, data_len: " << image.data_len - << ", width: " << image.w << ", height: " << image.h << "\n"; - - return image; -} - -void -utilFreeImage(util_image image) -{ - image.w = image.h = image.data_len = 0; - image.bits_per_channel = 8; - image.num_channels = 4; - std::memset(image.file_path, 0, std::strlen(image.file_path) + 1); - utilSafeFree(image.pixels); -} - -// need to init default values from scene file, or finally make default config? -v2f -utilGetPaletteCoords(util_image& palette_image, uint color_index) -{ - v2i tex_coords; - v2f normalized; - - if (PALETTE_ROWS * PALETTE_COLUMNS < color_index) { - LOG(Error) << "index out of range\n"; - return normalized; - } - - if (palette_image.pixels == nullptr) { - LOG(Error) << "palatte image not loaded\n"; - return normalized; - } - - // NOTE: we're aiming to sample near the middle of the palette 'square' so GL_NEAREST - // doesn't try to sample the border color - v2i palette_square; - palette_square.x = palette_image.w / PALETTE_ROWS; - palette_square.y = palette_image.h / PALETTE_COLUMNS; - uint v_row = (uint) std::floor(color_index / PALETTE_ROWS); - uint u_column = color_index % PALETTE_ROWS; - tex_coords.x = u_column * palette_square.x + palette_square.x / 2; - tex_coords.y = v_row * palette_square.y + palette_square.y / 2; - // NOTE: flip y coord - tex_coords.y = palette_image.h - tex_coords.y; - - normalized.x = (float) tex_coords.x / palette_image.w; - normalized.y = (float) tex_coords.y / palette_image.h; - - return normalized; -} diff --git a/src/util_image.cpp b/src/util_image.cpp new file mode 100644 index 0000000..0bf4b34 --- /dev/null +++ b/src/util_image.cpp @@ -0,0 +1,52 @@ + +#include + +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" + +#include "dumbLog.h" +#include "util_image.h" + + +util_image +utilLoadImage(const char* base_dir, const char* filename) +{ + const uint max_path = 256; // NOTE: util_image.file_path is char[256] + const char* base_name = utilBaseName(filename); + // NOTE: +1 for '/' char, +1 for null + uint l = std::strlen(base_dir) + std::strlen(base_name) + 2; + assert(l < max_path); + char full_path[l]; + std::memcpy(full_path, base_dir, std::strlen(base_dir) + 1); + std::strcat(std::strcat(full_path, "/"), base_name); + LOG(Info) << "Loading Image: " << full_path << "\n"; + + util_image image; + std::memcpy(image.file_path, full_path, std::strlen(full_path) + 1); + stbi_set_flip_vertically_on_load(1); + image.pixels = stbi_load(full_path, &image.w, &image.h, &image.num_channels, 0); + image.bits_per_channel = 8; + image.data_len = image.w * image.h * image.num_channels; // NOTE: assumes 8 bits per channel + + if (image.pixels == 0) { + LOG(Error) << stbi_failure_reason() << "\n"; + utilFreeImage(image); + return image; + } + + LOG(Info) << "Image properties, data_len: " << image.data_len + << ", width: " << image.w << ", height: " << image.h << "\n"; + + return image; +} + +void +utilFreeImage(util_image image) +{ + image.w = image.h = image.data_len = 0; + image.bits_per_channel = 8; + image.num_channels = 4; + std::memset(image.file_path, 0, std::strlen(image.file_path) + 1); + utilSafeFree(image.pixels); +} +