GLTF imports & exports material texture filters
This commit is contained in:
parent
364071c2c4
commit
bb34c55b3c
13 changed files with 454 additions and 29 deletions
|
@ -22,6 +22,7 @@ def get_doc_classes():
|
|||
"GLTFSpecGloss",
|
||||
"GLTFState",
|
||||
"GLTFTexture",
|
||||
"GLTFTextureSampler",
|
||||
"PackedSceneGLTF",
|
||||
]
|
||||
|
||||
|
|
|
@ -86,6 +86,12 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_texture_samplers">
|
||||
<return type="Array" />
|
||||
<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="Array" />
|
||||
<description>
|
||||
|
@ -173,6 +179,13 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_texture_samplers">
|
||||
<return type="void" />
|
||||
<argument index="0" name="texture_samplers" type="Array" />
|
||||
<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" />
|
||||
<argument index="0" name="textures" type="Array" />
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
<methods>
|
||||
</methods>
|
||||
<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>
|
||||
|
|
29
modules/gltf/doc_classes/GLTFTextureSampler.xml
Normal file
29
modules/gltf/doc_classes/GLTFTextureSampler.xml
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="GLTFTextureSampler" inherits="Resource" version="3.6" 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>
|
||||
<methods>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="mag_filter" type="int" setter="set_mag_filter" getter="get_mag_filter" default="9729">
|
||||
Texture's magnification filter, used when the 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>
|
||||
<constants>
|
||||
</constants>
|
||||
</class>
|
|
@ -131,71 +131,71 @@ Error GLTFDocument::serialize(Ref<GLTFState> state, Node *p_root, const String &
|
|||
return Error::FAILED;
|
||||
}
|
||||
|
||||
/* STEP 7 SERIALIZE ANIMATIONS */
|
||||
/* STEP 7 SERIALIZE TEXTURE SAMPLERS */
|
||||
err = _serialize_texture_samplers(state);
|
||||
if (err != OK) {
|
||||
return Error::FAILED;
|
||||
}
|
||||
|
||||
/* STEP 8 SERIALIZE ANIMATIONS */
|
||||
err = _serialize_animations(state);
|
||||
if (err != OK) {
|
||||
return Error::FAILED;
|
||||
}
|
||||
|
||||
/* STEP 8 SERIALIZE ACCESSORS */
|
||||
/* STEP 9 SERIALIZE ACCESSORS */
|
||||
err = _encode_accessors(state);
|
||||
if (err != OK) {
|
||||
return Error::FAILED;
|
||||
}
|
||||
|
||||
/* STEP 9 SERIALIZE IMAGES */
|
||||
/* STEP 10 SERIALIZE IMAGES */
|
||||
err = _serialize_images(state, p_path);
|
||||
if (err != OK) {
|
||||
return Error::FAILED;
|
||||
}
|
||||
|
||||
/* STEP 10 SERIALIZE TEXTURES */
|
||||
err = _serialize_textures(state);
|
||||
if (err != OK) {
|
||||
return Error::FAILED;
|
||||
}
|
||||
|
||||
for (GLTFBufferViewIndex i = 0; i < state->buffer_views.size(); i++) {
|
||||
state->buffer_views.write[i]->buffer = 0;
|
||||
}
|
||||
|
||||
/* STEP 11 SERIALIZE BUFFER VIEWS */
|
||||
/* STEP 12 SERIALIZE BUFFER VIEWS */
|
||||
err = _encode_buffer_views(state);
|
||||
if (err != OK) {
|
||||
return Error::FAILED;
|
||||
}
|
||||
|
||||
/* STEP 12 SERIALIZE NODES */
|
||||
/* STEP 13 SERIALIZE NODES */
|
||||
err = _serialize_nodes(state);
|
||||
if (err != OK) {
|
||||
return Error::FAILED;
|
||||
}
|
||||
|
||||
/* STEP 13 SERIALIZE SCENE */
|
||||
/* STEP 15 SERIALIZE SCENE */
|
||||
err = _serialize_scenes(state);
|
||||
if (err != OK) {
|
||||
return Error::FAILED;
|
||||
}
|
||||
|
||||
/* STEP 14 SERIALIZE SCENE */
|
||||
/* STEP 16 SERIALIZE SCENE */
|
||||
err = _serialize_lights(state);
|
||||
if (err != OK) {
|
||||
return Error::FAILED;
|
||||
}
|
||||
|
||||
/* STEP 15 SERIALIZE EXTENSIONS */
|
||||
/* STEP 17 SERIALIZE EXTENSIONS */
|
||||
err = _serialize_extensions(state);
|
||||
if (err != OK) {
|
||||
return Error::FAILED;
|
||||
}
|
||||
|
||||
/* STEP 16 SERIALIZE VERSION */
|
||||
/* STEP 18 SERIALIZE VERSION */
|
||||
err = _serialize_version(state);
|
||||
if (err != OK) {
|
||||
return Error::FAILED;
|
||||
}
|
||||
|
||||
/* STEP 17 SERIALIZE FILE */
|
||||
/* STEP 19 SERIALIZE FILE */
|
||||
err = _serialize_file(state, p_path);
|
||||
if (err != OK) {
|
||||
return Error::FAILED;
|
||||
|
@ -2946,7 +2946,7 @@ Error GLTFDocument::_serialize_images(Ref<GLTFState> state, const String &p_path
|
|||
|
||||
ERR_CONTINUE(state->images[i].is_null());
|
||||
|
||||
Ref<Image> image = state->images[i]->get_data();
|
||||
Ref<Image> image = state->images[i];
|
||||
ERR_CONTINUE(image.is_null());
|
||||
|
||||
if (p_path.to_lower().ends_with("glb")) {
|
||||
|
@ -3151,11 +3151,7 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> state, const String &p_base_pat
|
|||
continue;
|
||||
}
|
||||
|
||||
Ref<ImageTexture> t;
|
||||
t.instance();
|
||||
t->create_from_image(img);
|
||||
|
||||
state->images.push_back(t);
|
||||
state->images.push_back(img);
|
||||
}
|
||||
|
||||
print_verbose("glTF: Total images: " + itos(state->images.size()));
|
||||
|
@ -3174,6 +3170,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;
|
||||
|
@ -3195,7 +3196,24 @@ Error GLTFDocument::_parse_textures(Ref<GLTFState> state) {
|
|||
Ref<GLTFTexture> t;
|
||||
t.instance();
|
||||
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);
|
||||
|
||||
// Create and cache the texture used in the engine
|
||||
Ref<ImageTexture> imgTex;
|
||||
imgTex.instance();
|
||||
imgTex->create_from_image(state->images[t->get_src_image()]);
|
||||
|
||||
// Set texture filter and repeat based on sampler settings
|
||||
const Ref<GLTFTextureSampler> sampler = _get_sampler_for_texture(state, t->get_sampler());
|
||||
Texture::Flags flags = sampler->get_texture_flags();
|
||||
imgTex->set_flags(flags);
|
||||
|
||||
state->texture_cache.insert(i, imgTex);
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
@ -3203,24 +3221,124 @@ Error GLTFDocument::_parse_textures(Ref<GLTFState> state) {
|
|||
|
||||
GLTFTextureIndex GLTFDocument::_set_texture(Ref<GLTFState> state, Ref<Texture> p_texture) {
|
||||
ERR_FAIL_COND_V(p_texture.is_null(), -1);
|
||||
ERR_FAIL_COND_V(p_texture->get_data().is_null(), -1);
|
||||
|
||||
// Create GLTF data structures for the new texture
|
||||
Ref<GLTFTexture> gltf_texture;
|
||||
gltf_texture.instance();
|
||||
ERR_FAIL_COND_V(p_texture->get_data().is_null(), -1);
|
||||
GLTFImageIndex gltf_src_image_i = state->images.size();
|
||||
state->images.push_back(p_texture);
|
||||
|
||||
state->images.push_back(p_texture->get_data());
|
||||
|
||||
GLTFTextureSamplerIndex gltf_sampler_i = _set_sampler_for_mode(state, p_texture->get_flags());
|
||||
|
||||
gltf_texture->set_src_image(gltf_src_image_i);
|
||||
gltf_texture->set_sampler(gltf_sampler_i);
|
||||
|
||||
GLTFTextureIndex gltf_texture_i = state->textures.size();
|
||||
state->textures.push_back(gltf_texture);
|
||||
state->texture_cache[gltf_texture_i] = p_texture;
|
||||
return gltf_texture_i;
|
||||
}
|
||||
|
||||
Ref<Texture> GLTFDocument::_get_texture(Ref<GLTFState> state, const GLTFTextureIndex p_texture) {
|
||||
ERR_FAIL_INDEX_V(p_texture, state->textures.size(), Ref<Texture>());
|
||||
const GLTFImageIndex image = state->textures[p_texture]->get_src_image();
|
||||
return state->texture_cache[p_texture];
|
||||
}
|
||||
|
||||
ERR_FAIL_INDEX_V(image, state->images.size(), Ref<Texture>());
|
||||
GLTFTextureSamplerIndex GLTFDocument::_set_sampler_for_mode(Ref<GLTFState> state, uint32_t p_mode) {
|
||||
for (int i = 0; i < state->texture_samplers.size(); ++i) {
|
||||
if (state->texture_samplers[i]->get_texture_flags() == p_mode) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return state->images[image];
|
||||
GLTFTextureSamplerIndex gltf_sampler_i = state->texture_samplers.size();
|
||||
Ref<GLTFTextureSampler> gltf_sampler;
|
||||
gltf_sampler.instance();
|
||||
gltf_sampler->set_texture_flags(p_mode);
|
||||
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<Texture>());
|
||||
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.instance();
|
||||
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.instance();
|
||||
|
||||
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::REPEAT);
|
||||
}
|
||||
|
||||
if (d.has("wrapT")) {
|
||||
sampler->set_wrap_t(d["wrapT"]);
|
||||
} else {
|
||||
sampler->set_wrap_t(GLTFTextureSampler::WrapMode::REPEAT);
|
||||
}
|
||||
|
||||
state->texture_samplers.push_back(sampler);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
|
||||
|
@ -6645,13 +6763,19 @@ Error GLTFDocument::parse(Ref<GLTFState> state, String p_path, bool p_read_binar
|
|||
return Error::FAILED;
|
||||
}
|
||||
|
||||
/* PARSE TEXTURE SAMPLERS */
|
||||
err = _parse_texture_samplers(state);
|
||||
if (err != OK) {
|
||||
return Error::FAILED;
|
||||
}
|
||||
|
||||
/* PARSE TEXTURES */
|
||||
err = _parse_textures(state);
|
||||
if (err != OK) {
|
||||
return Error::FAILED;
|
||||
}
|
||||
|
||||
/* PARSE TEXTURES */
|
||||
/* PARSE MATERIALS */
|
||||
err = _parse_materials(state);
|
||||
if (err != OK) {
|
||||
return Error::FAILED;
|
||||
|
|
|
@ -50,6 +50,7 @@ class GLTFSkin;
|
|||
class GLTFNode;
|
||||
class GLTFSpecGloss;
|
||||
class GLTFSkeleton;
|
||||
class GLTFTextureSampler;
|
||||
class MultiMeshInstance;
|
||||
|
||||
#ifdef MODULE_CSG_ENABLED
|
||||
|
@ -72,6 +73,7 @@ using GLTFNodeIndex = int;
|
|||
using GLTFSkeletonIndex = int;
|
||||
using GLTFSkinIndex = int;
|
||||
using GLTFTextureIndex = int;
|
||||
using GLTFTextureSamplerIndex = int;
|
||||
|
||||
class GLTFDocument : public Resource {
|
||||
GDCLASS(GLTFDocument, Resource);
|
||||
|
@ -183,6 +185,10 @@ private:
|
|||
GLTFTextureIndex _set_texture(Ref<GLTFState> state, Ref<Texture> p_texture);
|
||||
Ref<Texture> _get_texture(Ref<GLTFState> state,
|
||||
const GLTFTextureIndex p_texture);
|
||||
GLTFTextureSamplerIndex _set_sampler_for_mode(Ref<GLTFState> state,
|
||||
uint32_t p_mode);
|
||||
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(const String &p_path, Ref<GLTFState> state);
|
||||
void _compute_node_heights(Ref<GLTFState> state);
|
||||
|
@ -230,10 +236,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<SpatialMaterial> material);
|
||||
void spec_gloss_to_rough_metal(Ref<GLTFSpecGloss> r_spec_gloss,
|
||||
|
|
|
@ -61,6 +61,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);
|
||||
|
@ -95,6 +97,7 @@ void GLTFState::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "scene_name"), "set_scene_name", "get_scene_name"); // String
|
||||
ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_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>>
|
||||
|
@ -218,6 +221,14 @@ void GLTFState::set_textures(Array p_textures) {
|
|||
GLTFDocument::set_from_array(textures, p_textures);
|
||||
}
|
||||
|
||||
Array GLTFState::get_texture_samplers() {
|
||||
return GLTFDocument::to_array(texture_samplers);
|
||||
}
|
||||
|
||||
void GLTFState::set_texture_samplers(Array p_texture_samplers) {
|
||||
GLTFDocument::set_from_array(texture_samplers, p_texture_samplers);
|
||||
}
|
||||
|
||||
Array GLTFState::get_images() {
|
||||
return GLTFDocument::to_array(images);
|
||||
}
|
||||
|
|
|
@ -48,6 +48,9 @@
|
|||
#include "gltf_skeleton.h"
|
||||
#include "gltf_skin.h"
|
||||
#include "gltf_texture.h"
|
||||
#include "gltf_texture_sampler.h"
|
||||
#include "scene/animation/animation_player.h"
|
||||
#include "scene/resources/texture.h"
|
||||
|
||||
class GLTFState : public Resource {
|
||||
GDCLASS(GLTFState, Resource);
|
||||
|
@ -78,7 +81,10 @@ class GLTFState : public Resource {
|
|||
String scene_name;
|
||||
Vector<int> root_nodes;
|
||||
Vector<Ref<GLTFTexture>> textures;
|
||||
Vector<Ref<Texture>> images;
|
||||
Vector<Ref<GLTFTextureSampler>> texture_samplers;
|
||||
Ref<GLTFTextureSampler> default_texture_sampler;
|
||||
Vector<Ref<Image>> images;
|
||||
Map<GLTFTextureIndex, Ref<Texture>> texture_cache;
|
||||
|
||||
Vector<Ref<GLTFSkin>> skins;
|
||||
Vector<Ref<GLTFCamera>> cameras;
|
||||
|
@ -140,6 +146,9 @@ public:
|
|||
Array get_textures();
|
||||
void set_textures(Array p_textures);
|
||||
|
||||
Array get_texture_samplers();
|
||||
void set_texture_samplers(Array p_texture_samplers);
|
||||
|
||||
Array get_images();
|
||||
void set_images(Array p_images);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ class GLTFTexture : public Resource {
|
|||
|
||||
private:
|
||||
GLTFImageIndex src_image = 0;
|
||||
GLTFTextureSamplerIndex sampler = -1;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
@ -47,6 +48,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
|
||||
|
|
47
modules/gltf/gltf_texture_sampler.cpp
Normal file
47
modules/gltf/gltf_texture_sampler.cpp
Normal 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");
|
||||
}
|
165
modules/gltf/gltf_texture_sampler.h
Normal file
165
modules/gltf/gltf_texture_sampler.h
Normal file
|
@ -0,0 +1,165 @@
|
|||
/*************************************************************************/
|
||||
/* 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/resource.h"
|
||||
#include "scene/resources/texture.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
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Texture::Flags get_filter_mode() const {
|
||||
switch (min_filter) {
|
||||
case NEAREST:
|
||||
return (Texture::Flags)0;
|
||||
case LINEAR:
|
||||
return Texture::Flags::FLAG_FILTER;
|
||||
case NEAREST_MIPMAP_NEAREST:
|
||||
case NEAREST_MIPMAP_LINEAR:
|
||||
return Texture::Flags::FLAG_MIPMAPS;
|
||||
case LINEAR_MIPMAP_NEAREST:
|
||||
case LINEAR_MIPMAP_LINEAR:
|
||||
default:
|
||||
return (Texture::Flags)(Texture::Flags::FLAG_FILTER | Texture::Flags::FLAG_MIPMAPS);
|
||||
}
|
||||
}
|
||||
|
||||
void set_filter_mode(uint32_t flags) {
|
||||
const bool filter = (flags & Texture::Flags::FLAG_FILTER);
|
||||
const bool mipmaps = (flags & Texture::Flags::FLAG_MIPMAPS);
|
||||
|
||||
if (filter && mipmaps) {
|
||||
min_filter = FilterMode::LINEAR_MIPMAP_LINEAR;
|
||||
mag_filter = FilterMode::LINEAR;
|
||||
} else if (filter) {
|
||||
min_filter = FilterMode::LINEAR;
|
||||
mag_filter = FilterMode::LINEAR;
|
||||
} else if (mipmaps) {
|
||||
min_filter = FilterMode::NEAREST_MIPMAP_LINEAR;
|
||||
mag_filter = FilterMode::NEAREST;
|
||||
} else {
|
||||
min_filter = FilterMode::NEAREST;
|
||||
mag_filter = FilterMode::NEAREST;
|
||||
}
|
||||
}
|
||||
|
||||
Texture::Flags get_wrap_mode() const {
|
||||
if ((wrap_s == WrapMode::MIRRORED_REPEAT) && (wrap_t == WrapMode::MIRRORED_REPEAT)) {
|
||||
return Texture::Flags::FLAG_MIRRORED_REPEAT;
|
||||
} else if ((wrap_s == WrapMode::REPEAT) && (wrap_t == WrapMode::REPEAT)) {
|
||||
return Texture::Flags::FLAG_REPEAT;
|
||||
} else {
|
||||
return (Texture::Flags)0;
|
||||
}
|
||||
}
|
||||
|
||||
void set_wrap_mode(uint32_t flags) {
|
||||
if (flags & Texture::Flags::FLAG_MIRRORED_REPEAT) {
|
||||
wrap_s = WrapMode::MIRRORED_REPEAT;
|
||||
wrap_t = WrapMode::MIRRORED_REPEAT;
|
||||
} else if (flags & Texture::Flags::FLAG_REPEAT) {
|
||||
wrap_s = WrapMode::REPEAT;
|
||||
wrap_t = WrapMode::REPEAT;
|
||||
} else {
|
||||
wrap_s = WrapMode::CLAMP_TO_EDGE;
|
||||
wrap_t = WrapMode::CLAMP_TO_EDGE;
|
||||
}
|
||||
}
|
||||
|
||||
Texture::Flags get_texture_flags() const {
|
||||
return (Texture::Flags)(get_filter_mode() | get_wrap_mode());
|
||||
}
|
||||
|
||||
void set_texture_flags(uint32_t flags) {
|
||||
set_filter_mode(flags);
|
||||
set_wrap_mode(flags);
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#endif // GLTF_TEXTURE_SAMPLER_H
|
|
@ -78,6 +78,7 @@ void register_gltf_types() {
|
|||
ClassDB::register_class<GLTFBufferView>();
|
||||
ClassDB::register_class<GLTFAccessor>();
|
||||
ClassDB::register_class<GLTFTexture>();
|
||||
ClassDB::register_class<GLTFTextureSampler>();
|
||||
ClassDB::register_class<GLTFSkeleton>();
|
||||
ClassDB::register_class<GLTFSkin>();
|
||||
ClassDB::register_class<GLTFCamera>();
|
||||
|
|
Loading…
Reference in a new issue