Merge pull request #59481 from LunaticInAHat/gltf_texture_filter_fix_4

Respect texture filtering when importing GLTF
This commit is contained in:
Clay John 2022-10-03 16:33:11 -07:00 committed by GitHub
commit 4b52c6caef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 428 additions and 6 deletions

View file

@ -26,6 +26,7 @@ def get_doc_classes():
"GLTFSpecGloss",
"GLTFState",
"GLTFTexture",
"GLTFTextureSampler",
]

View file

@ -93,6 +93,12 @@
<description>
</description>
</method>
<method name="get_texture_samplers">
<return type="GLTFTextureSampler[]" />
<description>
Retrieves the array of texture samplers that are used by the textures contained in the GLTF.
</description>
</method>
<method name="get_textures">
<return type="GLTFTexture[]" />
<description>
@ -180,6 +186,13 @@
<description>
</description>
</method>
<method name="set_texture_samplers">
<return type="void" />
<param index="0" name="texture_samplers" type="GLTFTextureSampler[]" />
<description>
Sets the array of texture samplers that are used by the textures contained in the GLTF.
</description>
</method>
<method name="set_textures">
<return type="void" />
<param index="0" name="textures" type="GLTFTexture[]" />

View file

@ -7,6 +7,9 @@
<tutorials>
</tutorials>
<members>
<member name="sampler" type="int" setter="set_sampler" getter="get_sampler" default="-1">
ID of the texture sampler to use when sampling the image. If -1, then the default texture sampler is used (linear filtering, and repeat wrapping in both axes).
</member>
<member name="src_image" type="int" setter="set_src_image" getter="get_src_image" default="0">
</member>
</members>

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="GLTFTextureSampler" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
Represents a GLTF texture sampler
</brief_description>
<description>
Represents a texture sampler as defined by the base GLTF spec. Texture samplers in GLTF specify how to sample data from the texture's base image, when rendering the texture on an object.
</description>
<tutorials>
</tutorials>
<members>
<member name="mag_filter" type="int" setter="set_mag_filter" getter="get_mag_filter" default="9729">
Texture's magnification filter, used when texture appears larger on screen than the source image.
</member>
<member name="min_filter" type="int" setter="set_min_filter" getter="get_min_filter" default="9987">
Texture's minification filter, used when the texture appears smaller on screen than the source image.
</member>
<member name="wrap_s" type="int" setter="set_wrap_s" getter="get_wrap_s" default="10497">
Wrapping mode to use for S-axis (horizontal) texture coordinates.
</member>
<member name="wrap_t" type="int" setter="set_wrap_t" getter="get_wrap_t" default="10497">
Wrapping mode to use for T-axis (vertical) texture coordinates.
</member>
</members>
</class>

View file

@ -58,6 +58,7 @@ class GLTFSkin;
class GLTFSpecGloss;
class GLTFState;
class GLTFTexture;
class GLTFTextureSampler;
// GLTF index aliases.
using GLTFAccessorIndex = int;
@ -73,6 +74,7 @@ using GLTFNodeIndex = int;
using GLTFSkeletonIndex = int;
using GLTFSkinIndex = int;
using GLTFTextureIndex = int;
using GLTFTextureSamplerIndex = int;
enum GLTFType {
TYPE_SCALAR,

View file

@ -145,6 +145,12 @@ Error GLTFDocument::_serialize(Ref<GLTFState> state, const String &p_path) {
return Error::FAILED;
}
/* STEP SERIALIZE TEXTURE SAMPLERS */
err = _serialize_texture_samplers(state);
if (err != OK) {
return Error::FAILED;
}
/* STEP SERIALIZE ANIMATIONS */
err = _serialize_animations(state);
if (err != OK) {
@ -3219,6 +3225,11 @@ Error GLTFDocument::_serialize_textures(Ref<GLTFState> state) {
Ref<GLTFTexture> t = state->textures[i];
ERR_CONTINUE(t->get_src_image() == -1);
d["source"] = t->get_src_image();
GLTFTextureSamplerIndex sampler_index = t->get_sampler();
if (sampler_index != -1) {
d["sampler"] = sampler_index;
}
textures.push_back(d);
}
state->json["textures"] = textures;
@ -3240,13 +3251,18 @@ Error GLTFDocument::_parse_textures(Ref<GLTFState> state) {
Ref<GLTFTexture> t;
t.instantiate();
t->set_src_image(d["source"]);
if (d.has("sampler")) {
t->set_sampler(d["sampler"]);
} else {
t->set_sampler(-1);
}
state->textures.push_back(t);
}
return OK;
}
GLTFTextureIndex GLTFDocument::_set_texture(Ref<GLTFState> state, Ref<Texture2D> p_texture) {
GLTFTextureIndex GLTFDocument::_set_texture(Ref<GLTFState> state, Ref<Texture2D> p_texture, StandardMaterial3D::TextureFilter p_filter_mode, bool p_repeats) {
ERR_FAIL_COND_V(p_texture.is_null(), -1);
Ref<GLTFTexture> gltf_texture;
gltf_texture.instantiate();
@ -3254,6 +3270,7 @@ GLTFTextureIndex GLTFDocument::_set_texture(Ref<GLTFState> state, Ref<Texture2D>
GLTFImageIndex gltf_src_image_i = state->images.size();
state->images.push_back(p_texture);
gltf_texture->set_src_image(gltf_src_image_i);
gltf_texture->set_sampler(_set_sampler_for_mode(state, p_filter_mode, p_repeats));
GLTFTextureIndex gltf_texture_i = state->textures.size();
state->textures.push_back(gltf_texture);
return gltf_texture_i;
@ -3268,6 +3285,102 @@ Ref<Texture2D> GLTFDocument::_get_texture(Ref<GLTFState> state, const GLTFTextur
return state->images[image];
}
GLTFTextureSamplerIndex GLTFDocument::_set_sampler_for_mode(Ref<GLTFState> state, StandardMaterial3D::TextureFilter p_filter_mode, bool p_repeats) {
for (int i = 0; i < state->texture_samplers.size(); ++i) {
if (state->texture_samplers[i]->get_filter_mode() == p_filter_mode) {
return i;
}
}
GLTFTextureSamplerIndex gltf_sampler_i = state->texture_samplers.size();
Ref<GLTFTextureSampler> gltf_sampler;
gltf_sampler.instantiate();
gltf_sampler->set_filter_mode(p_filter_mode);
gltf_sampler->set_wrap_mode(p_repeats);
state->texture_samplers.push_back(gltf_sampler);
return gltf_sampler_i;
}
Ref<GLTFTextureSampler> GLTFDocument::_get_sampler_for_texture(Ref<GLTFState> state, const GLTFTextureIndex p_texture) {
ERR_FAIL_INDEX_V(p_texture, state->textures.size(), Ref<Texture2D>());
const GLTFTextureSamplerIndex sampler = state->textures[p_texture]->get_sampler();
if (sampler == -1) {
return state->default_texture_sampler;
} else {
ERR_FAIL_INDEX_V(sampler, state->texture_samplers.size(), Ref<GLTFTextureSampler>());
return state->texture_samplers[sampler];
}
}
Error GLTFDocument::_serialize_texture_samplers(Ref<GLTFState> state) {
if (!state->texture_samplers.size()) {
return OK;
}
Array samplers;
for (int32_t i = 0; i < state->texture_samplers.size(); ++i) {
Dictionary d;
Ref<GLTFTextureSampler> s = state->texture_samplers[i];
d["magFilter"] = s->get_mag_filter();
d["minFilter"] = s->get_min_filter();
d["wrapS"] = s->get_wrap_s();
d["wrapT"] = s->get_wrap_t();
samplers.push_back(d);
}
state->json["samplers"] = samplers;
return OK;
}
Error GLTFDocument::_parse_texture_samplers(Ref<GLTFState> state) {
state->default_texture_sampler.instantiate();
state->default_texture_sampler->set_min_filter(GLTFTextureSampler::FilterMode::LINEAR_MIPMAP_LINEAR);
state->default_texture_sampler->set_mag_filter(GLTFTextureSampler::FilterMode::LINEAR);
state->default_texture_sampler->set_wrap_s(GLTFTextureSampler::WrapMode::REPEAT);
state->default_texture_sampler->set_wrap_t(GLTFTextureSampler::WrapMode::REPEAT);
if (!state->json.has("samplers")) {
return OK;
}
const Array &samplers = state->json["samplers"];
for (int i = 0; i < samplers.size(); ++i) {
const Dictionary &d = samplers[i];
Ref<GLTFTextureSampler> sampler;
sampler.instantiate();
if (d.has("minFilter")) {
sampler->set_min_filter(d["minFilter"]);
} else {
sampler->set_min_filter(GLTFTextureSampler::FilterMode::LINEAR_MIPMAP_LINEAR);
}
if (d.has("magFilter")) {
sampler->set_mag_filter(d["magFilter"]);
} else {
sampler->set_mag_filter(GLTFTextureSampler::FilterMode::LINEAR);
}
if (d.has("wrapS")) {
sampler->set_wrap_s(d["wrapS"]);
} else {
sampler->set_wrap_s(GLTFTextureSampler::WrapMode::DEFAULT);
}
if (d.has("wrapT")) {
sampler->set_wrap_t(d["wrapT"]);
} else {
sampler->set_wrap_t(GLTFTextureSampler::WrapMode::DEFAULT);
}
state->texture_samplers.push_back(sampler);
}
return OK;
}
Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
Array materials;
for (int32_t i = 0; i < state->materials.size(); i++) {
@ -3299,7 +3412,7 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) {
albedo_texture->set_name(material->get_name() + "_albedo");
gltf_texture_index = _set_texture(state, albedo_texture);
gltf_texture_index = _set_texture(state, albedo_texture, material->get_texture_filter(), material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
}
if (gltf_texture_index != -1) {
bct["index"] = gltf_texture_index;
@ -3429,7 +3542,7 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
GLTFTextureIndex orm_texture_index = -1;
if (has_ao || has_roughness || has_metalness) {
orm_texture->set_name(material->get_name() + "_orm");
orm_texture_index = _set_texture(state, orm_texture);
orm_texture_index = _set_texture(state, orm_texture, material->get_texture_filter(), material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
}
if (has_ao) {
Dictionary occt;
@ -3484,7 +3597,7 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
GLTFTextureIndex gltf_texture_index = -1;
if (tex.is_valid() && tex->get_image().is_valid()) {
tex->set_name(material->get_name() + "_normal");
gltf_texture_index = _set_texture(state, tex);
gltf_texture_index = _set_texture(state, tex, material->get_texture_filter(), material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
}
nt["scale"] = material->get_normal_scale();
if (gltf_texture_index != -1) {
@ -3507,7 +3620,7 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
GLTFTextureIndex gltf_texture_index = -1;
if (emission_texture.is_valid() && emission_texture->get_image().is_valid()) {
emission_texture->set_name(material->get_name() + "_emission");
gltf_texture_index = _set_texture(state, emission_texture);
gltf_texture_index = _set_texture(state, emission_texture, material->get_texture_filter(), material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
}
if (gltf_texture_index != -1) {
@ -3566,6 +3679,11 @@ Error GLTFDocument::_parse_materials(Ref<GLTFState> state) {
if (sgm.has("diffuseTexture")) {
const Dictionary &diffuse_texture_dict = sgm["diffuseTexture"];
if (diffuse_texture_dict.has("index")) {
Ref<GLTFTextureSampler> diffuse_sampler = _get_sampler_for_texture(state, diffuse_texture_dict["index"]);
if (diffuse_sampler.is_valid()) {
material->set_texture_filter(diffuse_sampler->get_filter_mode());
material->set_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT, diffuse_sampler->get_wrap_mode());
}
Ref<Texture2D> diffuse_texture = _get_texture(state, diffuse_texture_dict["index"]);
if (diffuse_texture.is_valid()) {
spec_gloss->diffuse_img = diffuse_texture->get_image();
@ -3614,6 +3732,9 @@ Error GLTFDocument::_parse_materials(Ref<GLTFState> state) {
if (mr.has("baseColorTexture")) {
const Dictionary &bct = mr["baseColorTexture"];
if (bct.has("index")) {
Ref<GLTFTextureSampler> bct_sampler = _get_sampler_for_texture(state, bct["index"]);
material->set_texture_filter(bct_sampler->get_filter_mode());
material->set_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT, bct_sampler->get_wrap_mode());
material->set_texture(BaseMaterial3D::TEXTURE_ALBEDO, _get_texture(state, bct["index"]));
}
if (!mr.has("baseColorFactor")) {
@ -6477,8 +6598,10 @@ Error GLTFDocument::_parse(Ref<GLTFState> state, String p_path, Ref<FileAccess>
err = ext->import_preflight(state);
ERR_FAIL_COND_V(err != OK, err);
}
err = _parse_gltf_state(state, p_path, p_bake_fps);
ERR_FAIL_COND_V(err != OK, err);
return OK;
}
@ -6834,6 +6957,11 @@ Error GLTFDocument::_parse_gltf_state(Ref<GLTFState> state, const String &p_sear
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
/* PARSE TEXTURE SAMPLERS */
err = _parse_texture_samplers(state);
ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR);
/* PARSE TEXTURES */
err = _parse_textures(state);

View file

@ -95,9 +95,14 @@ private:
String _gen_unique_bone_name(Ref<GLTFState> state,
const GLTFSkeletonIndex skel_i,
const String &p_name);
GLTFTextureIndex _set_texture(Ref<GLTFState> state, Ref<Texture2D> p_texture);
GLTFTextureIndex _set_texture(Ref<GLTFState> state, Ref<Texture2D> p_texture,
StandardMaterial3D::TextureFilter p_filter_mode, bool p_repeats);
Ref<Texture2D> _get_texture(Ref<GLTFState> state,
const GLTFTextureIndex p_texture);
GLTFTextureSamplerIndex _set_sampler_for_mode(Ref<GLTFState> state,
StandardMaterial3D::TextureFilter p_filter_mode, bool p_repeats);
Ref<GLTFTextureSampler> _get_sampler_for_texture(Ref<GLTFState> state,
const GLTFTextureIndex p_texture);
Error _parse_json(const String &p_path, Ref<GLTFState> state);
Error _parse_glb(Ref<FileAccess> f, Ref<GLTFState> state);
void _compute_node_heights(Ref<GLTFState> state);
@ -145,10 +150,12 @@ private:
const bool p_for_vertex);
Error _parse_meshes(Ref<GLTFState> state);
Error _serialize_textures(Ref<GLTFState> state);
Error _serialize_texture_samplers(Ref<GLTFState> state);
Error _serialize_images(Ref<GLTFState> state, const String &p_path);
Error _serialize_lights(Ref<GLTFState> state);
Error _parse_images(Ref<GLTFState> state, const String &p_base_path);
Error _parse_textures(Ref<GLTFState> state);
Error _parse_texture_samplers(Ref<GLTFState> state);
Error _parse_materials(Ref<GLTFState> state);
void _set_texture_transform_uv1(const Dictionary &d, Ref<BaseMaterial3D> material);
void spec_gloss_to_rough_metal(Ref<GLTFSpecGloss> r_spec_gloss,

View file

@ -64,6 +64,8 @@ void GLTFState::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_root_nodes", "root_nodes"), &GLTFState::set_root_nodes);
ClassDB::bind_method(D_METHOD("get_textures"), &GLTFState::get_textures);
ClassDB::bind_method(D_METHOD("set_textures", "textures"), &GLTFState::set_textures);
ClassDB::bind_method(D_METHOD("get_texture_samplers"), &GLTFState::get_texture_samplers);
ClassDB::bind_method(D_METHOD("set_texture_samplers", "texture_samplers"), &GLTFState::set_texture_samplers);
ClassDB::bind_method(D_METHOD("get_images"), &GLTFState::get_images);
ClassDB::bind_method(D_METHOD("set_images", "images"), &GLTFState::set_images);
ClassDB::bind_method(D_METHOD("get_skins"), &GLTFState::get_skins);
@ -101,6 +103,7 @@ void GLTFState::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_path"), "set_base_path", "get_base_path"); // String
ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "root_nodes"), "set_root_nodes", "get_root_nodes"); // Vector<int>
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "textures", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_textures", "get_textures"); // Vector<Ref<GLTFTexture>>
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "texture_samplers", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_texture_samplers", "get_texture_samplers"); //Vector<Ref<GLTFTextureSampler>>
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "images", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_images", "get_images"); // Vector<Ref<Texture>
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "skins", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_skins", "get_skins"); // Vector<Ref<GLTFSkin>>
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "cameras", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_cameras", "get_cameras"); // Vector<Ref<GLTFCamera>>
@ -236,6 +239,14 @@ void GLTFState::set_textures(TypedArray<GLTFTexture> p_textures) {
GLTFTemplateConvert::set_from_array(textures, p_textures);
}
TypedArray<GLTFTextureSampler> GLTFState::get_texture_samplers() {
return GLTFTemplateConvert::to_array(texture_samplers);
}
void GLTFState::set_texture_samplers(TypedArray<GLTFTextureSampler> p_texture_samplers) {
GLTFTemplateConvert::set_from_array(texture_samplers, p_texture_samplers);
}
TypedArray<Texture2D> GLTFState::get_images() {
return GLTFTemplateConvert::to_array(images);
}

View file

@ -42,6 +42,7 @@
#include "structures/gltf_skeleton.h"
#include "structures/gltf_skin.h"
#include "structures/gltf_texture.h"
#include "structures/gltf_texture_sampler.h"
#include "core/templates/rb_map.h"
#include "scene/animation/animation_player.h"
@ -77,6 +78,8 @@ class GLTFState : public Resource {
String scene_name;
Vector<int> root_nodes;
Vector<Ref<GLTFTexture>> textures;
Vector<Ref<GLTFTextureSampler>> texture_samplers;
Ref<GLTFTextureSampler> default_texture_sampler;
Vector<Ref<Texture2D>> images;
Vector<String> extensions_used;
Vector<String> extensions_required;
@ -149,6 +152,9 @@ public:
TypedArray<GLTFTexture> get_textures();
void set_textures(TypedArray<GLTFTexture> p_textures);
TypedArray<GLTFTextureSampler> get_texture_samplers();
void set_texture_samplers(TypedArray<GLTFTextureSampler> p_texture_samplers);
TypedArray<Texture2D> get_images();
void set_images(TypedArray<Texture2D> p_images);

View file

@ -47,6 +47,7 @@
#include "structures/gltf_skeleton.h"
#include "structures/gltf_skin.h"
#include "structures/gltf_texture.h"
#include "structures/gltf_texture_sampler.h"
#ifdef TOOLS_ENABLED
#include "core/config/project_settings.h"
@ -126,6 +127,7 @@ void initialize_gltf_module(ModuleInitializationLevel p_level) {
GDREGISTER_CLASS(GLTFSpecGloss);
GDREGISTER_CLASS(GLTFState);
GDREGISTER_CLASS(GLTFTexture);
GDREGISTER_CLASS(GLTFTextureSampler);
}
#ifdef TOOLS_ENABLED

View file

@ -33,8 +33,11 @@
void GLTFTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_src_image"), &GLTFTexture::get_src_image);
ClassDB::bind_method(D_METHOD("set_src_image", "src_image"), &GLTFTexture::set_src_image);
ClassDB::bind_method(D_METHOD("get_sampler"), &GLTFTexture::get_sampler);
ClassDB::bind_method(D_METHOD("set_sampler", "sampler"), &GLTFTexture::set_sampler);
ADD_PROPERTY(PropertyInfo(Variant::INT, "src_image"), "set_src_image", "get_src_image"); // int
ADD_PROPERTY(PropertyInfo(Variant::INT, "sampler"), "set_sampler", "get_sampler"); // int
}
GLTFImageIndex GLTFTexture::get_src_image() const {
@ -44,3 +47,11 @@ GLTFImageIndex GLTFTexture::get_src_image() const {
void GLTFTexture::set_src_image(GLTFImageIndex val) {
src_image = val;
}
GLTFTextureSamplerIndex GLTFTexture::get_sampler() const {
return sampler;
}
void GLTFTexture::set_sampler(GLTFTextureSamplerIndex val) {
sampler = val;
}

View file

@ -39,6 +39,7 @@ class GLTFTexture : public Resource {
private:
GLTFImageIndex src_image = 0;
GLTFTextureSamplerIndex sampler = -1;
protected:
static void _bind_methods();
@ -46,6 +47,8 @@ protected:
public:
GLTFImageIndex get_src_image() const;
void set_src_image(GLTFImageIndex val);
GLTFTextureSamplerIndex get_sampler() const;
void set_sampler(GLTFTextureSamplerIndex val);
};
#endif // GLTF_TEXTURE_H

View file

@ -0,0 +1,47 @@
/*************************************************************************/
/* gltf_texture_sampler.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "gltf_texture_sampler.h"
void GLTFTextureSampler::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_mag_filter"), &GLTFTextureSampler::get_mag_filter);
ClassDB::bind_method(D_METHOD("set_mag_filter", "filter_mode"), &GLTFTextureSampler::set_mag_filter);
ClassDB::bind_method(D_METHOD("get_min_filter"), &GLTFTextureSampler::get_min_filter);
ClassDB::bind_method(D_METHOD("set_min_filter", "filter_mode"), &GLTFTextureSampler::set_min_filter);
ClassDB::bind_method(D_METHOD("get_wrap_s"), &GLTFTextureSampler::get_wrap_s);
ClassDB::bind_method(D_METHOD("set_wrap_s", "wrap_mode"), &GLTFTextureSampler::set_wrap_s);
ClassDB::bind_method(D_METHOD("get_wrap_t"), &GLTFTextureSampler::get_wrap_t);
ClassDB::bind_method(D_METHOD("set_wrap_t", "wrap_mode"), &GLTFTextureSampler::set_wrap_t);
ADD_PROPERTY(PropertyInfo(Variant::INT, "mag_filter"), "set_mag_filter", "get_mag_filter");
ADD_PROPERTY(PropertyInfo(Variant::INT, "min_filter"), "set_min_filter", "get_min_filter");
ADD_PROPERTY(PropertyInfo(Variant::INT, "wrap_s"), "set_wrap_s", "get_wrap_s");
ADD_PROPERTY(PropertyInfo(Variant::INT, "wrap_t"), "set_wrap_t", "get_wrap_t");
}

View file

@ -0,0 +1,163 @@
/*************************************************************************/
/* gltf_texture_sampler.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef GLTF_TEXTURE_SAMPLER_H
#define GLTF_TEXTURE_SAMPLER_H
#include "core/io/resource.h"
#include "scene/resources/material.h"
class GLTFTextureSampler : public Resource {
GDCLASS(GLTFTextureSampler, Resource);
public:
enum FilterMode {
NEAREST = 9728,
LINEAR = 9729,
NEAREST_MIPMAP_NEAREST = 9984,
LINEAR_MIPMAP_NEAREST = 9985,
NEAREST_MIPMAP_LINEAR = 9986,
LINEAR_MIPMAP_LINEAR = 9987
};
enum WrapMode {
CLAMP_TO_EDGE = 33071,
MIRRORED_REPEAT = 33648,
REPEAT = 10497,
DEFAULT = REPEAT
};
int get_mag_filter() const {
return mag_filter;
}
void set_mag_filter(const int filter_mode) {
mag_filter = (FilterMode)filter_mode;
}
int get_min_filter() const {
return min_filter;
}
void set_min_filter(const int filter_mode) {
min_filter = (FilterMode)filter_mode;
}
int get_wrap_s() const {
return wrap_s;
}
void set_wrap_s(const int wrap_mode) {
wrap_s = (WrapMode)wrap_mode;
}
int get_wrap_t() const {
return wrap_t;
}
void set_wrap_t(const int wrap_mode) {
wrap_s = (WrapMode)wrap_mode;
}
StandardMaterial3D::TextureFilter get_filter_mode() const {
using TextureFilter = StandardMaterial3D::TextureFilter;
switch (min_filter) {
case NEAREST:
return TextureFilter::TEXTURE_FILTER_NEAREST;
case LINEAR:
return TextureFilter::TEXTURE_FILTER_LINEAR;
case NEAREST_MIPMAP_NEAREST:
case NEAREST_MIPMAP_LINEAR:
return TextureFilter::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS;
case LINEAR_MIPMAP_NEAREST:
case LINEAR_MIPMAP_LINEAR:
default:
return TextureFilter::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS;
}
}
void set_filter_mode(StandardMaterial3D::TextureFilter mode) {
using TextureFilter = StandardMaterial3D::TextureFilter;
switch (mode) {
case TextureFilter::TEXTURE_FILTER_NEAREST:
min_filter = FilterMode::NEAREST;
mag_filter = FilterMode::NEAREST;
break;
case TextureFilter::TEXTURE_FILTER_LINEAR:
min_filter = FilterMode::LINEAR;
mag_filter = FilterMode::LINEAR;
break;
case TextureFilter::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS:
case TextureFilter::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC:
min_filter = FilterMode::NEAREST_MIPMAP_LINEAR;
mag_filter = FilterMode::NEAREST;
break;
case TextureFilter::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS:
case TextureFilter::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC:
default:
min_filter = FilterMode::LINEAR_MIPMAP_LINEAR;
mag_filter = FilterMode::LINEAR;
break;
}
}
bool get_wrap_mode() const {
// BaseMaterial3D presents wrapping as a boolean property. Either the texture is repeated
// in both dimensions, non-mirrored, or it isn't repeated at all. This will cause oddities
// when people import models having other wrapping mode combinations.
return (wrap_s == WrapMode::REPEAT) && (wrap_t == WrapMode::REPEAT);
}
void set_wrap_mode(bool mat_repeats) {
if (mat_repeats) {
wrap_s = WrapMode::REPEAT;
wrap_t = WrapMode::REPEAT;
} else {
wrap_s = WrapMode::CLAMP_TO_EDGE;
wrap_t = WrapMode::CLAMP_TO_EDGE;
}
}
protected:
static void _bind_methods();
private:
FilterMode mag_filter = FilterMode::LINEAR;
FilterMode min_filter = FilterMode::LINEAR_MIPMAP_LINEAR;
WrapMode wrap_s = WrapMode::REPEAT;
WrapMode wrap_t = WrapMode::REPEAT;
};
VARIANT_ENUM_CAST(GLTFTextureSampler::FilterMode);
VARIANT_ENUM_CAST(GLTFTextureSampler::WrapMode);
#endif // GLTF_TEXTURE_SAMPLER_H