|
@@ -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 "";
|
|
|
}
|