diff options
author | Juan Linietsky <reduzio@gmail.com> | 2018-08-06 14:56:06 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2018-08-06 14:56:06 -0300 |
commit | edde52c8dea0193111239b6b2f002adcc24ac0c9 (patch) | |
tree | 8aa3f65b49956fa3f7c3ab765509f2f07b7b6c6c /scene/resources | |
parent | 80a8636aa3739822b1ebbbad39f932a176ec158d (diff) |
Added proper import support for 3D and Array textures
Diffstat (limited to 'scene/resources')
-rw-r--r-- | scene/resources/texture.cpp | 400 | ||||
-rw-r--r-- | scene/resources/texture.h | 75 |
2 files changed, 294 insertions, 181 deletions
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index a5b5375130..536c653a0c 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -151,13 +151,6 @@ bool ImageTexture::_get(const StringName &p_name, Variant &r_ret) const { void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const { - PropertyHint img_hint = PROPERTY_HINT_NONE; - if (storage == STORAGE_COMPRESS_LOSSY) { - img_hint = PROPERTY_HINT_IMAGE_COMPRESS_LOSSY; - } else if (storage == STORAGE_COMPRESS_LOSSLESS) { - img_hint = PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS; - } - p_list->push_back(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic,sRGB,Mirrored Repeat")); p_list->push_back(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image")); p_list->push_back(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, "")); @@ -592,7 +585,7 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla int sh = th; int mipmaps = Image::get_image_required_mipmaps(tw, th, format); - int total_size = Image::get_image_data_size(tw, th, format, mipmaps); + int total_size = Image::get_image_data_size(tw, th, format, true); int idx = 0; int ofs = 0; @@ -1155,7 +1148,6 @@ void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile Size2 scale = p_rect.size / size; - RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); for (int i = 0; i < pieces.size(); i++) { // TODO @@ -1170,7 +1162,6 @@ void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons Size2 scale = p_rect.size / p_src_rect.size; - RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); for (int i = 0; i < pieces.size(); i++) { // TODO @@ -1322,13 +1313,6 @@ bool CubeMap::_get(const StringName &p_name, Variant &r_ret) const { void CubeMap::_get_property_list(List<PropertyInfo> *p_list) const { - PropertyHint img_hint = PROPERTY_HINT_NONE; - if (storage == STORAGE_COMPRESS_LOSSY) { - img_hint = PROPERTY_HINT_IMAGE_COMPRESS_LOSSY; - } else if (storage == STORAGE_COMPRESS_LOSSLESS) { - img_hint = PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS; - } - p_list->push_back(PropertyInfo(Variant::OBJECT, "side/left", PROPERTY_HINT_RESOURCE_TYPE, "Image")); p_list->push_back(PropertyInfo(Variant::OBJECT, "side/right", PROPERTY_HINT_RESOURCE_TYPE, "Image")); p_list->push_back(PropertyInfo(Variant::OBJECT, "side/bottom", PROPERTY_HINT_RESOURCE_TYPE, "Image")); @@ -1876,209 +1860,327 @@ AnimatedTexture::AnimatedTexture() { AnimatedTexture::~AnimatedTexture() { VS::get_singleton()->free(proxy); } +/////////////////////////////// + +void TextureLayered::set_flags(uint32_t p_flags) { + flags = p_flags; -bool Texture3D::get_split_single_image_enabled() const { - return split_single_image_enabled; + if (texture.is_valid()) { + VS::get_singleton()->texture_set_flags(texture, flags); + } } -void Texture3D::set_split_single_image_enabled(bool p_split_enabled) { - split_single_image_enabled = p_split_enabled; +uint32_t TextureLayered::get_flags() const { + return flags; +} - _change_notify(); +Image::Format TextureLayered::get_format() const { + return format; } -uint32_t Texture3D::get_split_single_image_h_split() const { - return split_single_image_h_split; +uint32_t TextureLayered::get_width() const { + return width; } -void Texture3D::set_split_single_image_h_split(uint32_t p_h_split) { - split_single_image_h_split = p_h_split; +uint32_t TextureLayered::get_height() const { + return height; +} - if (split_single_image_image.is_valid()) - create_from_image(split_single_image_image, split_single_image_h_split, split_single_image_v_split, split_single_image_num_layers, flags); +uint32_t TextureLayered::get_depth() const { + return depth; } -uint32_t Texture3D::get_split_single_image_v_split() const { - return split_single_image_v_split; +void TextureLayered::_set_data(const Dictionary &p_data) { + ERR_FAIL_COND(!p_data.has("width")); + ERR_FAIL_COND(!p_data.has("height")); + ERR_FAIL_COND(!p_data.has("depth")); + ERR_FAIL_COND(!p_data.has("format")); + ERR_FAIL_COND(!p_data.has("flags")); + ERR_FAIL_COND(!p_data.has("layers")); + int w = p_data["width"]; + int h = p_data["height"]; + int d = p_data["depth"]; + Image::Format format = Image::Format(int(p_data["format"])); + int flags = p_data["flags"]; + Array layers = p_data["layers"]; + ERR_FAIL_COND(layers.size() != d); + + create(w, h, d, format, flags); + + for (int i = 0; i < layers.size(); i++) { + Ref<Image> img = layers[i]; + ERR_CONTINUE(!img.is_valid()); + ERR_CONTINUE(img->get_format() != format); + ERR_CONTINUE(img->get_width() != w); + ERR_CONTINUE(img->get_height() != h); + set_layer_data(img, i); + } } -void Texture3D::set_split_single_image_v_split(uint32_t p_v_split) { - split_single_image_v_split = p_v_split; +Dictionary TextureLayered::_get_data() const { + Dictionary d; + d["width"] = width; + d["height"] = height; + d["depth"] = depth; + d["flags"] = flags; + d["format"] = format; - if (split_single_image_image.is_valid()) - create_from_image(split_single_image_image, split_single_image_h_split, split_single_image_v_split, split_single_image_num_layers, flags); + Array layers; + for (int i = 0; i < depth; i++) { + layers.push_back(get_layer_data(i)); + } + d["layers"] = layers; + return d; } -uint32_t Texture3D::get_split_single_image_num_layers() const { - return split_single_image_num_layers; -} +void TextureLayered::create(uint32_t p_width, uint32_t p_height, uint32_t p_depth, Image::Format p_format, uint32_t p_flags) { + VS::get_singleton()->texture_allocate(texture, p_width, p_height, p_depth, p_format, is_3d ? VS::TEXTURE_TYPE_3D : VS::TEXTURE_TYPE_2D_ARRAY, p_flags); -void Texture3D::set_split_single_image_num_layers(uint32_t p_num_layers) { - split_single_image_num_layers = p_num_layers; + width = p_width; + height = p_height; + depth = p_depth; - if (split_single_image_image.is_valid()) - create_from_image(split_single_image_image, split_single_image_h_split, split_single_image_v_split, split_single_image_num_layers, flags); + flags = p_flags; } -Ref<Image> Texture3D::get_split_single_image_image() const { - return split_single_image_image; +void TextureLayered::set_layer_data(const Ref<Image> &p_image, int p_layer) { + ERR_FAIL_COND(!texture.is_valid()); + VS::get_singleton()->texture_set_data(texture, p_image, p_layer); } -void Texture3D::set_split_single_image_image(const Ref<Image> &p_image) { - split_single_image_image = p_image; +Ref<Image> TextureLayered::get_layer_data(int p_layer) const { - create_from_image(split_single_image_image, split_single_image_h_split, split_single_image_v_split, split_single_image_num_layers, flags); + ERR_FAIL_COND_V(!texture.is_valid(), Ref<Image>()); + return VS::get_singleton()->texture_get_data(texture, p_layer); } -void Texture3D::_validate_property(PropertyInfo &property) const { - if (property.name.begins_with("split_single_image_") && property.name != "split_single_image_enabled" && !split_single_image_enabled) { - property.usage = 0; - } +void TextureLayered::set_data_partial(const Ref<Image> &p_image, int p_x_ofs, int p_y_ofs, int p_z, int p_mipmap) { + ERR_FAIL_COND(!texture.is_valid()); + VS::get_singleton()->texture_set_data_partial(texture, p_image, 0, 0, p_image->get_width(), p_image->get_height(), p_x_ofs, p_y_ofs, p_mipmap, p_z); } -void Texture3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_flags", "flags"), &Texture3D::set_flags); - ClassDB::bind_method(D_METHOD("get_flags"), &Texture3D::get_flags); - - ClassDB::bind_method(D_METHOD("get_format"), &Texture3D::get_format); - - ClassDB::bind_method(D_METHOD("get_width"), &Texture3D::get_width); - ClassDB::bind_method(D_METHOD("get_height"), &Texture3D::get_height); - ClassDB::bind_method(D_METHOD("get_depth"), &Texture3D::get_depth); +RID TextureLayered::get_rid() const { + return texture; +} - ClassDB::bind_method(D_METHOD("set_split_single_image_enabled", "split_enabled"), &Texture3D::set_split_single_image_enabled); - ClassDB::bind_method(D_METHOD("get_split_single_image_enabled"), &Texture3D::get_split_single_image_enabled); +void TextureLayered::set_path(const String &p_path, bool p_take_over) { + if (texture.is_valid()) { + VS::get_singleton()->texture_set_path(texture, p_path); + } - ClassDB::bind_method(D_METHOD("set_split_single_image_h_split", "h_split"), &Texture3D::set_split_single_image_h_split); - ClassDB::bind_method(D_METHOD("get_split_single_image_h_split"), &Texture3D::get_split_single_image_h_split); + Resource::set_path(p_path, p_take_over); +} - ClassDB::bind_method(D_METHOD("set_split_single_image_v_split", "v_split"), &Texture3D::set_split_single_image_v_split); - ClassDB::bind_method(D_METHOD("get_split_single_image_v_split"), &Texture3D::get_split_single_image_v_split); +void TextureLayered::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_flags", "flags"), &TextureLayered::set_flags); + ClassDB::bind_method(D_METHOD("get_flags"), &TextureLayered::get_flags); - ClassDB::bind_method(D_METHOD("set_split_single_image_num_layers", "num_layers"), &Texture3D::set_split_single_image_num_layers); - ClassDB::bind_method(D_METHOD("get_split_single_image_num_layers"), &Texture3D::get_split_single_image_num_layers); + ClassDB::bind_method(D_METHOD("get_format"), &TextureLayered::get_format); - ClassDB::bind_method(D_METHOD("set_split_single_image_image", "image"), &Texture3D::set_split_single_image_image); - ClassDB::bind_method(D_METHOD("get_split_single_image_image"), &Texture3D::get_split_single_image_image); + ClassDB::bind_method(D_METHOD("get_width"), &TextureLayered::get_width); + ClassDB::bind_method(D_METHOD("get_height"), &TextureLayered::get_height); + ClassDB::bind_method(D_METHOD("get_depth"), &TextureLayered::get_depth); - ClassDB::bind_method(D_METHOD("create", "width", "height", "depth", "format", "flags"), &Texture3D::create, DEFVAL(FLAGS_DEFAULT)); - ClassDB::bind_method(D_METHOD("create_from_image", "image", "h_split", "v_split", "num_layer", "flags"), &Texture3D::create_from_image, DEFVAL(FLAGS_DEFAULT)); + ClassDB::bind_method(D_METHOD("create", "width", "height", "depth", "format", "flags"), &TextureLayered::create, DEFVAL(FLAGS_DEFAULT)); + ClassDB::bind_method(D_METHOD("set_layer_data", "image", "layer"), &TextureLayered::set_layer_data); + ClassDB::bind_method(D_METHOD("get_layer_data", "layer"), &TextureLayered::set_layer_data); + ClassDB::bind_method(D_METHOD("set_data_partial", "image", "x_offset", "y_offset", "layer", "mipmap"), &TextureLayered::set_data_partial, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("set_data_partial", "image", "x_offset", "y_offset", "layer", "mipmap"), &Texture3D::set_data_partial, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("_set_data", "data"), &TextureLayered::_set_data); + ClassDB::bind_method(D_METHOD("_get_data"), &TextureLayered::_get_data); ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter"), "set_flags", "get_flags"); + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_data", "_get_data"); BIND_ENUM_CONSTANT(FLAG_MIPMAPS); BIND_ENUM_CONSTANT(FLAG_REPEAT); BIND_ENUM_CONSTANT(FLAG_FILTER); BIND_ENUM_CONSTANT(FLAGS_DEFAULT); - - ADD_GROUP("Split single image", "split_single_image_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "split_single_image_enabled"), "set_split_single_image_enabled", "get_split_single_image_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "split_single_image_h_split", PROPERTY_HINT_RANGE, "0,1000"), "set_split_single_image_h_split", "get_split_single_image_h_split"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "split_single_image_v_split", PROPERTY_HINT_RANGE, "0,1000"), "set_split_single_image_v_split", "get_split_single_image_v_split"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "split_single_image_num_layers"), "set_split_single_image_num_layers", "get_split_single_image_num_layers"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "split_single_image_image", PROPERTY_HINT_RESOURCE_TYPE, "Image"), "set_split_single_image_image", "get_split_single_image_image"); } -void Texture3D::set_flags(uint32_t p_flags) { - flags = p_flags; +TextureLayered::TextureLayered(bool p_3d) { + is_3d = p_3d; + format = Image::FORMAT_MAX; + flags = FLAGS_DEFAULT; + + width = 0; + height = 0; + depth = 0; + + texture = VS::get_singleton()->texture_create(); +} +TextureLayered::~TextureLayered() { if (texture.is_valid()) { - VS::get_singleton()->texture_set_flags(texture, flags); + VS::get_singleton()->free(texture); } } -uint32_t Texture3D::get_flags() const { - return flags; -} +RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error) { -Image::Format Texture3D::get_format() const { - return format; -} + if (r_error) { + *r_error = ERR_CANT_OPEN; + } -uint32_t Texture3D::get_width() const { - return width; -} + Ref<TextureLayered> lt; + Ref<Texture3D> tex3d; + Ref<TextureArray> texarr; -uint32_t Texture3D::get_height() const { - return height; -} + if (p_path.ends_with("tex3d")) { + tex3d.instance(); + lt = tex3d; + } else if (p_path.ends_with("texarr")) { + texarr.instance(); + lt = texarr; + } else { + ERR_EXPLAIN("Unrecognized layered texture extension"); + ERR_FAIL_V(RES()); + } -uint32_t Texture3D::get_depth() const { - return depth; -} + FileAccess *f = FileAccess::open(p_path, FileAccess::READ); + ERR_FAIL_COND_V(!f, RES()); -void Texture3D::create(uint32_t p_width, uint32_t p_height, uint32_t p_depth, Image::Format p_format, uint32_t p_flags) { - VS::get_singleton()->texture_allocate(texture, p_width, p_height, p_depth, p_format, VS::TEXTURE_TYPE_3D, p_flags); + uint8_t header[5] = { 0, 0, 0, 0, 0 }; + f->get_buffer(header, 4); - width = p_width; - height = p_height; - depth = p_depth; + if (header[0] == 'G' && header[1] == 'D' && header[2] == '3' && header[3] == 'T') { + if (tex3d.is_null()) { + memdelete(f); + ERR_FAIL_COND_V(tex3d.is_null(), RES()) + } + } else if (header[0] == 'G' && header[1] == 'D' && header[2] == 'A' && header[3] == 'T') { + if (texarr.is_null()) { + memdelete(f); + ERR_FAIL_COND_V(texarr.is_null(), RES()) + } + } else { - flags = p_flags; -} + ERR_EXPLAIN("Unrecognized layered texture file format: " + String((const char *)header)); + ERR_FAIL_V(RES()); + } -void Texture3D::create_from_image(const Ref<Image> &p_image, uint32_t p_h_split, uint32_t p_v_split, uint32_t p_num_layer, uint32_t flags) { + int tw = f->get_32(); + int th = f->get_32(); + int td = f->get_32(); + int flags = f->get_32(); //texture flags! + Image::Format format = Image::Format(f->get_32()); + uint32_t compression = f->get_32(); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed - ERR_FAIL_COND(p_image.is_null()); - ERR_FAIL_COND((p_h_split + 1) * (p_v_split + 1) < p_num_layer); + lt->create(tw, th, td, format, flags); - uint32_t total_width = p_image->get_width(); - uint32_t total_height = p_image->get_height(); + for (int layer = 0; layer < td; layer++) { - uint32_t width = total_width / (p_h_split + 1); - uint32_t height = total_height / (p_v_split + 1); + Ref<Image> image; + image.instance(); - create(width, height, p_num_layer, p_image->get_format(), flags); + if (compression == COMPRESSION_LOSSLESS) { + //look for a PNG file inside - for (uint32_t i = 0; i < p_num_layer; i++) { - uint32_t row = i / (p_v_split + 1); - uint32_t col = i % (p_v_split + 1); + int mipmaps = f->get_32(); + Vector<Ref<Image> > mipmap_images; - uint32_t x_offset = col * width; - uint32_t y_offset = row * height; + for (int i = 0; i < mipmaps; i++) { + uint32_t size = f->get_32(); - VS::get_singleton()->texture_set_data_partial(texture, p_image, x_offset, y_offset, width, height, 0, 0, 0, i); - } -} + PoolVector<uint8_t> pv; + pv.resize(size); + { + PoolVector<uint8_t>::Write w = pv.write(); + f->get_buffer(w.ptr(), size); + } -void Texture3D::set_data_partial(const Ref<Image> &p_image, int p_x_ofs, int p_y_ofs, int p_layer, int p_mipmap) { - ERR_FAIL_COND(!texture.is_valid()); - VS::get_singleton()->texture_set_data_partial(texture, p_image, 0, 0, p_image->get_width(), p_image->get_height(), p_x_ofs, p_y_ofs, p_mipmap, p_layer); -} + Ref<Image> img = Image::lossless_unpacker(pv); -RID Texture3D::get_rid() const { - return texture; -} + if (img.is_null() || img->empty() || format != img->get_format()) { + if (r_error) { + *r_error = ERR_FILE_CORRUPT; + } + memdelete(f); + ERR_FAIL_V(RES()); + } -void Texture3D::set_path(const String &p_path, bool p_take_over) { - if (texture.is_valid()) { - VS::get_singleton()->texture_set_path(texture, p_path); - } + mipmap_images.push_back(img); + } - Resource::set_path(p_path, p_take_over); -} + if (mipmap_images.size() == 1) { -Texture3D::Texture3D() { - format = Image::FORMAT_MAX; - flags = FLAGS_DEFAULT; + image = mipmap_images[0]; - width = 0; - height = 0; - depth = 0; + } else { + int total_size = Image::get_image_data_size(tw, th, format, true); + PoolVector<uint8_t> img_data; + img_data.resize(total_size); + + { + PoolVector<uint8_t>::Write w = img_data.write(); + + int ofs = 0; + for (int i = 0; i < mipmap_images.size(); i++) { + + PoolVector<uint8_t> id = mipmap_images[i]->get_data(); + int len = id.size(); + PoolVector<uint8_t>::Read r = id.read(); + copymem(&w[ofs], r.ptr(), len); + ofs += len; + } + } - split_single_image_enabled = false; - split_single_image_h_split = 0; - split_single_image_v_split = 0; - split_single_image_num_layers = 0; - split_single_image_image = Ref<Image>(); + image->create(tw, th, true, format, img_data); + if (image->empty()) { + if (r_error) { + *r_error = ERR_FILE_CORRUPT; + } + memdelete(f); + ERR_FAIL_V(RES()); + } + } - texture = VS::get_singleton()->texture_create(); -} + } else { -Texture3D::~Texture3D() { - if (texture.is_valid()) { - VS::get_singleton()->free(texture); + //look for regular format + bool mipmaps = (flags & Texture::FLAG_MIPMAPS); + int total_size = Image::get_image_data_size(tw, th, format, mipmaps); + + PoolVector<uint8_t> img_data; + img_data.resize(total_size); + + { + PoolVector<uint8_t>::Write w = img_data.write(); + int bytes = f->get_buffer(w.ptr(), total_size); + if (bytes != total_size) { + if (r_error) { + *r_error = ERR_FILE_CORRUPT; + memdelete(f); + } + ERR_FAIL_V(RES()); + } + } + + image->create(tw, th, mipmaps, format, img_data); + } + + lt->set_layer_data(image, layer); } + + if (r_error) + *r_error = OK; + + return lt; +} + +void ResourceFormatLoaderTextureLayered::get_recognized_extensions(List<String> *p_extensions) const { + + p_extensions->push_back("tex3d"); + p_extensions->push_back("texarr"); +} +bool ResourceFormatLoaderTextureLayered::handles_type(const String &p_type) const { + return p_type == "Texture3D" || p_type == "TextureArray"; +} +String ResourceFormatLoaderTextureLayered::get_resource_type(const String &p_path) const { + + if (p_path.get_extension().to_lower() == "tex3d") + return "Texture3D"; + if (p_path.get_extension().to_lower() == "texarr") + return "TextureArray"; + return ""; } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index ebb40ab0cb..1c18189b2c 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -401,39 +401,33 @@ VARIANT_ENUM_CAST(CubeMap::Flags) VARIANT_ENUM_CAST(CubeMap::Side) VARIANT_ENUM_CAST(CubeMap::Storage) -class Texture3D : public Resource { +class TextureLayered : public Resource { - GDCLASS(Texture3D, Resource) - RES_BASE_EXTENSION("tex3d") + GDCLASS(TextureLayered, Resource) public: enum Flags { FLAG_MIPMAPS = VisualServer::TEXTURE_FLAG_MIPMAPS, FLAG_REPEAT = VisualServer::TEXTURE_FLAG_REPEAT, FLAG_FILTER = VisualServer::TEXTURE_FLAG_FILTER, - FLAGS_DEFAULT = FLAG_REPEAT | FLAG_FILTER, + FLAG_CONVERT_TO_LINEAR = VisualServer::TEXTURE_FLAG_CONVERT_TO_LINEAR, + FLAGS_DEFAULT = FLAG_FILTER, }; private: + bool is_3d; RID texture; Image::Format format; uint32_t flags; - uint32_t width; - uint32_t height; - uint32_t depth; - - // for setting an image as a property - bool split_single_image_enabled; + int width; + int height; + int depth; - uint32_t split_single_image_h_split; - uint32_t split_single_image_v_split; - uint32_t split_single_image_num_layers; - Ref<Image> split_single_image_image; + void _set_data(const Dictionary &p_data); + Dictionary _get_data() const; protected: - void _validate_property(PropertyInfo &property) const; - static void _bind_methods(); public: @@ -446,30 +440,47 @@ public: uint32_t get_depth() const; void create(uint32_t p_width, uint32_t p_height, uint32_t p_depth, Image::Format p_format, uint32_t p_flags = FLAGS_DEFAULT); - void create_from_image(const Ref<Image> &p_image, uint32_t p_h_split, uint32_t p_v_split, uint32_t p_num_layer, uint32_t flags = FLAGS_DEFAULT); - - void set_data_partial(const Ref<Image> &p_image, int p_x_ofs, int p_y_ofs, int p_layer, int p_mipmap = 0); + void set_layer_data(const Ref<Image> &p_image, int p_layer); + Ref<Image> get_layer_data(int p_layer) const; + void set_data_partial(const Ref<Image> &p_image, int p_x_ofs, int p_y_ofs, int p_z, int p_mipmap = 0); virtual RID get_rid() const; + virtual void set_path(const String &p_path, bool p_take_over = false); - bool get_split_single_image_enabled() const; - void set_split_single_image_enabled(bool p_split_enabled); + TextureLayered(bool p_3d = false); + ~TextureLayered(); +}; - uint32_t get_split_single_image_h_split() const; - void set_split_single_image_h_split(uint32_t p_h_split); - uint32_t get_split_single_image_v_split() const; - void set_split_single_image_v_split(uint32_t p_v_split); +VARIANT_ENUM_CAST(TextureLayered::Flags) - uint32_t get_split_single_image_num_layers() const; - void set_split_single_image_num_layers(uint32_t p_num_layers); +class Texture3D : public TextureLayered { - Ref<Image> get_split_single_image_image() const; - void set_split_single_image_image(const Ref<Image> &p_image); + GDCLASS(Texture3D, TextureLayered) +public: + Texture3D() : + TextureLayered(true) {} +}; - virtual void set_path(const String &p_path, bool p_take_over = false); +class TextureArray : public TextureLayered { - Texture3D(); - ~Texture3D(); + GDCLASS(TextureArray, TextureLayered) +public: + TextureArray() : + TextureLayered(false) {} +}; + +class ResourceFormatLoaderTextureLayered : public ResourceFormatLoader { +public: + enum Compression { + COMPRESSION_LOSSLESS, + COMPRESSION_VRAM, + COMPRESSION_UNCOMPRESSED + }; + + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); + virtual void get_recognized_extensions(List<String> *p_extensions) const; + virtual bool handles_type(const String &p_type) const; + virtual String get_resource_type(const String &p_path) const; }; class CurveTexture : public Texture { |