GLTF: Now parsing texture sampler options.
Some checks failed
CMake on multiple platforms / build (Release, cl, cl, windows-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, clang, clang++, macos-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, clang, clang++, ubuntu-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, gcc, g++, ubuntu-latest) (push) Has been cancelled

Extended materials to support texture wrapping and sampler options.
This commit is contained in:
2026-05-10 15:43:05 -07:00
parent 744e73991e
commit 87689013e7
3 changed files with 255 additions and 4 deletions

View File

@@ -114,6 +114,99 @@ KRBundle* LoadGltf(KRContext& context, simdjson::ondemand::object& jsonRoot, std
}
}
struct SamplerInfo
{
KRMaterial::texture_wrap_type wrapS = KRMaterial::texture_wrap_type::KRMATERIAL_TEXTURE_REPEAT;
KRMaterial::texture_wrap_type wrapT = KRMaterial::texture_wrap_type::KRMATERIAL_TEXTURE_REPEAT;
KRMaterial::texture_mag_filter_type magFilter = KRMaterial::texture_mag_filter_type::KRMATERIAL_TEXTURE_MAG_LINEAR;
KRMaterial::texture_min_filter_type minFilter = KRMaterial::texture_min_filter_type::KRMATERIAL_TEXTURE_MIN_LINEAR_MIPMAP_LINEAR;
};
std::vector<SamplerInfo> samplers;
simdjson::ondemand::array jsonSamplers;
if(tryJson(jsonRoot["samplers"].get_array().get(jsonSamplers))) {
for (auto jsonSampler : jsonSamplers) {
SamplerInfo& sampler = samplers.emplace_back();
int jsonWrapS = 10497; // REPEAT
int jsonWrapT = 10497; // REPEAT
int jsonMinFilter = 9987; // LINEAR_MIPMAP_LINEAR
int jsonMagFilter = 9729; // LINEAR
tryJson(jsonSampler["wrapS"].get(jsonWrapS));
tryJson(jsonSampler["wrapT"].get(jsonWrapT));
tryJson(jsonSampler["minFilter"].get(jsonMinFilter));
tryJson(jsonSampler["magFilter"].get(jsonMagFilter));
switch(jsonWrapS)
{
case 33071: // CLAMP_TO_EDGE
sampler.wrapS = KRMaterial::texture_wrap_type::KRMATERIAL_TEXTURE_CLAMP;
break;
case 10497: // REPEAT
sampler.wrapS = KRMaterial::texture_wrap_type::KRMATERIAL_TEXTURE_REPEAT;
break;
case 33648: // MIRRORED_REPEAT
sampler.wrapS = KRMaterial::texture_wrap_type::KRMATERIAL_TEXTURE_MIRROR_REPEAT;
break;
default:
KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Kraken - GLTF: Sampler with unknown sampler wrap: %i", jsonWrapS);
break;
}
switch(jsonWrapT)
{
case 33071: // CLAMP_TO_EDGE
sampler.wrapT = KRMaterial::texture_wrap_type::KRMATERIAL_TEXTURE_CLAMP;
break;
case 10497: // REPEAT
sampler.wrapT = KRMaterial::texture_wrap_type::KRMATERIAL_TEXTURE_REPEAT;
break;
case 33648: // MIRRORED_REPEAT
sampler.wrapT = KRMaterial::texture_wrap_type::KRMATERIAL_TEXTURE_MIRROR_REPEAT;
break;
default:
KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Kraken - GLTF: Sampler with unknown sampler wrap: %i", jsonWrapT);
break;
}
switch(jsonMinFilter)
{
case 9728: // NEAREST
sampler.minFilter = KRMaterial::texture_min_filter_type::KRMATERIAL_TEXTURE_MIN_NEAREST;
break;
case 9729: // LINEAR
sampler.minFilter = KRMaterial::texture_min_filter_type::KRMATERIAL_TEXTURE_MIN_LINEAR;
break;
case 9984: // NEAREST_MIPMAP_NEAREST
sampler.minFilter = KRMaterial::texture_min_filter_type::KRMATERIAL_TEXTURE_MIN_NEAREST_MIPMAP_NEAREST;
break;
case 9985: // LINEAR_MIPMAP_NEAREST
sampler.minFilter = KRMaterial::texture_min_filter_type::KRMATERIAL_TEXTURE_MIN_LINEAR_MIPMAP_NEAREST;
break;
case 9986: // NEAREST_MIPMAP_LINEAR
sampler.minFilter = KRMaterial::texture_min_filter_type::KRMATERIAL_TEXTURE_MIN_NEAREST_MIPMAP_LINEAR;
break;
case 9987: // LINEAR_MIPMAP_LINEAR
sampler.minFilter = KRMaterial::texture_min_filter_type::KRMATERIAL_TEXTURE_MIN_LINEAR_MIPMAP_LINEAR;
break;
default:
KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Kraken - GLTF: Sampler with unknown minFilter: %i", jsonMinFilter);
break;
}
switch(jsonMagFilter)
{
case 9728: // NEAREST
sampler.magFilter = KRMaterial::texture_mag_filter_type::KRMATERIAL_TEXTURE_MAG_NEAREST;
break;
case 9729: // LINEAR
sampler.magFilter = KRMaterial::texture_mag_filter_type::KRMATERIAL_TEXTURE_MAG_LINEAR;
break;
default:
KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Kraken - GLTF: Sampler with unknown magFilter: %i", jsonMagFilter);
break;
}
}
}
struct TextureInfo
{
std::string name;
@@ -122,6 +215,8 @@ KRBundle* LoadGltf(KRContext& context, simdjson::ondemand::object& jsonRoot, std
hydra::Vector2 scale{ 1.f, 1.f };
hydra::Vector2 offset{ 0.f, 0.f };
float rotation{ 0.f };
SamplerInfo sampler;
};
std::vector<TextureInfo> textures;
simdjson::ondemand::array jsonTextures;
@@ -142,7 +237,11 @@ KRBundle* LoadGltf(KRContext& context, simdjson::ondemand::object& jsonRoot, std
int samplerIndex = -1;
if (tryJson(jsonTexture["sampler"].get(samplerIndex))) {
KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Kraken - GLTF: Sampler options not supported for texture: %s", texture.name.c_str());
// TODO - Implement texture sampler options
if (samplerIndex < 0 || samplerIndex >= samplers.size()) {
KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Kraken - GLTF: Could not load texture with a sampler index that is out of range: %s", texture.name.c_str());
continue;
}
texture.sampler = samplers[samplerIndex];
}
int imageIndex = -1;
if (!tryJson(jsonTexture["source"].get(imageIndex))) {
@@ -167,9 +266,6 @@ KRBundle* LoadGltf(KRContext& context, simdjson::ondemand::object& jsonRoot, std
}
}
simdjson::ondemand::array samplers;
tryJson(jsonRoot["samplers"].get_array().get(samplers));
KRBundle* bundle = new KRBundle(context, baseName);
std::vector<KRMaterial*> materials;
@@ -204,6 +300,10 @@ KRBundle* LoadGltf(KRContext& context, simdjson::ondemand::object& jsonRoot, std
textureMap.scale = texture.scale;
textureMap.offset = texture.offset;
textureMap.rotation = texture.rotation;
textureMap.wrapS = texture.sampler.wrapS;
textureMap.wrapT = texture.sampler.wrapT;
textureMap.minFilter = texture.sampler.minFilter;
textureMap.magFilter = texture.sampler.magFilter;
textureMap.texture.set(texture.texture);
}
}

View File

@@ -55,6 +55,60 @@ void tag_invoke(serialize_tag, builder_type& builder, const KRMaterial::TextureM
builder.template append_key_value<"scale">(texture.scale);
builder.append_comma();
builder.template append_key_value<"rotation">(texture.rotation);
builder.append_comma();
switch(texture.wrapS) {
case KRMaterial::texture_wrap_type::KRMATERIAL_TEXTURE_CLAMP:
builder.template append_key_value<"wrapS">("clamp");
break;
case KRMaterial::texture_wrap_type::KRMATERIAL_TEXTURE_REPEAT:
builder.template append_key_value<"wrapS">("repeat");
break;
case KRMaterial::texture_wrap_type::KRMATERIAL_TEXTURE_MIRROR_REPEAT:
builder.template append_key_value<"wrapS">("repeat_mirror");
break;
}
builder.append_comma();
switch(texture.wrapT) {
case KRMaterial::texture_wrap_type::KRMATERIAL_TEXTURE_CLAMP:
builder.template append_key_value<"wrapT">("clamp");
break;
case KRMaterial::texture_wrap_type::KRMATERIAL_TEXTURE_REPEAT:
builder.template append_key_value<"wrapT">("repeat");
break;
case KRMaterial::texture_wrap_type::KRMATERIAL_TEXTURE_MIRROR_REPEAT:
builder.template append_key_value<"wrapT">("repeat_mirror");
break;
}
builder.append_comma();
switch(texture.magFilter) {
case KRMaterial::texture_mag_filter_type::KRMATERIAL_TEXTURE_MAG_NEAREST:
builder.template append_key_value<"magFilter">("nearest");
break;
case KRMaterial::texture_mag_filter_type::KRMATERIAL_TEXTURE_MAG_LINEAR:
builder.template append_key_value<"magFilter">("linear");
break;
}
builder.append_comma();
switch(texture.minFilter) {
case KRMaterial::texture_min_filter_type::KRMATERIAL_TEXTURE_MIN_NEAREST:
builder.template append_key_value<"minFilter">("nearest");
break;
case KRMaterial::texture_min_filter_type::KRMATERIAL_TEXTURE_MIN_LINEAR:
builder.template append_key_value<"minFilter">("linear");
break;
case KRMaterial::texture_min_filter_type::KRMATERIAL_TEXTURE_MIN_NEAREST_MIPMAP_NEAREST:
builder.template append_key_value<"minFilter">("nearest_mipmap_nearest");
break;
case KRMaterial::texture_min_filter_type::KRMATERIAL_TEXTURE_MIN_LINEAR_MIPMAP_NEAREST:
builder.template append_key_value<"minFilter">("linear_mipmap_nearest");
break;
case KRMaterial::texture_min_filter_type::KRMATERIAL_TEXTURE_MIN_NEAREST_MIPMAP_LINEAR:
builder.template append_key_value<"minFilter">("nearest_mipmap_linear");
break;
case KRMaterial::texture_min_filter_type::KRMATERIAL_TEXTURE_MIN_LINEAR_MIPMAP_LINEAR:
builder.template append_key_value<"minFilter">("linear_mipmap_linear");
break;
}
builder.end_object();
}
@@ -86,6 +140,75 @@ simdjson::error_code KRMaterial::TextureMap::parse(simdjson::ondemand::value &va
return error;
}
std::string strWrapS;
std::string strWrapT;
std::string strMinFilter;
std::string strMagFilter;
if ((error = obj["wrapS"].get(strWrapS))) {
return error;
}
if (strWrapS == "clamp") {
wrapS = KRMATERIAL_TEXTURE_CLAMP;
} else if(strWrapS == "repeat") {
wrapS = KRMATERIAL_TEXTURE_REPEAT;
} else if(strWrapS == "repeat_mirror") {
wrapS = KRMATERIAL_TEXTURE_MIRROR_REPEAT;
} else {
KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Kraken - Unknown material texture wrap: %s.", strWrapS.c_str());
wrapS = KRMATERIAL_TEXTURE_REPEAT;
}
if ((error = obj["wrapT"].get(strWrapT))) {
return error;
}
if (strWrapT == "clamp") {
wrapT = KRMATERIAL_TEXTURE_CLAMP;
} else if(strWrapT == "repeat") {
wrapT = KRMATERIAL_TEXTURE_REPEAT;
} else if(strWrapT == "repeat_mirror") {
wrapT = KRMATERIAL_TEXTURE_MIRROR_REPEAT;
} else {
KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Kraken - Unknown material texture wrap: %s.", strWrapT.c_str());
wrapS = KRMATERIAL_TEXTURE_REPEAT;
}
if ((error = obj["minFilter"].get(strMinFilter))) {
return error;
}
if (strMinFilter == "nearest") {
minFilter = KRMATERIAL_TEXTURE_MIN_NEAREST;
} else if (strMinFilter =="linear") {
minFilter = KRMATERIAL_TEXTURE_MIN_LINEAR;
} else if (strMinFilter == "nearest_mipmap_nearest") {
minFilter = KRMATERIAL_TEXTURE_MIN_NEAREST_MIPMAP_NEAREST;
} else if (strMinFilter == "linear_mipmap_nearest") {
minFilter = KRMATERIAL_TEXTURE_MIN_LINEAR_MIPMAP_NEAREST;
} else if (strMinFilter == "nearest_mipmap_linear") {
minFilter = KRMATERIAL_TEXTURE_MIN_NEAREST_MIPMAP_LINEAR;
} else if (strMinFilter == "linear_mipmap_linear") {
minFilter = KRMATERIAL_TEXTURE_MIN_LINEAR_MIPMAP_LINEAR;
} else {
KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Kraken - Unknown material texture min filter: %s.", strMinFilter.c_str());
minFilter = KRMATERIAL_TEXTURE_MIN_LINEAR;
}
if ((error = obj["magFilter"].get(strMagFilter))) {
return error;
}
if (strMagFilter == "nearest") {
magFilter = KRMATERIAL_TEXTURE_MAG_NEAREST;
} else if (strMagFilter == "linear") {
magFilter = KRMATERIAL_TEXTURE_MAG_LINEAR;
} else {
KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Kraken - Unknown material texture mag filter: %s.", strMagFilter.c_str());
magFilter = KRMATERIAL_TEXTURE_MAG_LINEAR;
}
return simdjson::SUCCESS;
}

View File

@@ -70,6 +70,29 @@ public:
KRMATERIAL_SHADING_MODEL_PBR
} shading_model_type;
typedef enum
{
KRMATERIAL_TEXTURE_CLAMP,
KRMATERIAL_TEXTURE_REPEAT,
KRMATERIAL_TEXTURE_MIRROR_REPEAT
} texture_wrap_type;
typedef enum
{
KRMATERIAL_TEXTURE_MAG_NEAREST,
KRMATERIAL_TEXTURE_MAG_LINEAR
} texture_mag_filter_type;
typedef enum
{
KRMATERIAL_TEXTURE_MIN_NEAREST,
KRMATERIAL_TEXTURE_MIN_LINEAR,
KRMATERIAL_TEXTURE_MIN_NEAREST_MIPMAP_NEAREST,
KRMATERIAL_TEXTURE_MIN_LINEAR_MIPMAP_NEAREST,
KRMATERIAL_TEXTURE_MIN_NEAREST_MIPMAP_LINEAR,
KRMATERIAL_TEXTURE_MIN_LINEAR_MIPMAP_LINEAR
} texture_min_filter_type;
struct TextureMap
{
KRTextureBinding texture;
@@ -78,6 +101,11 @@ public:
hydra::Vector2 offset{ 0.f, 0.f };
float rotation{ 0.f };
texture_wrap_type wrapS = KRMATERIAL_TEXTURE_REPEAT;
texture_wrap_type wrapT = KRMATERIAL_TEXTURE_REPEAT;
texture_mag_filter_type magFilter = KRMATERIAL_TEXTURE_MAG_LINEAR;
texture_min_filter_type minFilter = KRMATERIAL_TEXTURE_MIN_LINEAR_MIPMAP_LINEAR;
TextureMap(KRTexture::texture_usage_t usage)
: texture{ usage }
{