Added proper import support for 3D and Array textures
This commit is contained in:
parent
80a8636aa3
commit
edde52c8de
@ -987,8 +987,10 @@ int Image::_get_dst_image_size(int p_width, int p_height, Format p_format, int &
|
||||
int pixsize = get_format_pixel_size(p_format);
|
||||
int pixshift = get_format_pixel_rshift(p_format);
|
||||
int block = get_format_block_size(p_format);
|
||||
int minw, minh;
|
||||
get_format_min_pixel_size(p_format, minw, minh);
|
||||
//technically, you can still compress up to 1 px no matter the format, so commenting this
|
||||
//int minw, minh;
|
||||
//get_format_min_pixel_size(p_format, minw, minh);
|
||||
int minw = 1, minh = 1;
|
||||
|
||||
while (true) {
|
||||
|
||||
@ -1304,7 +1306,7 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_forma
|
||||
int size = _get_dst_image_size(p_width, p_height, p_format, mm, p_use_mipmaps ? -1 : 0);
|
||||
|
||||
if (size != p_data.size()) {
|
||||
ERR_EXPLAIN("Expected data size of " + itos(size) + " in Image::create()");
|
||||
ERR_EXPLAIN("Expected data size of " + itos(size) + " bytes in Image::create(), got instead " + itos(p_data.size()) + " bytes.");
|
||||
ERR_FAIL_COND(p_data.size() != size);
|
||||
}
|
||||
|
||||
@ -1592,10 +1594,10 @@ Error Image::save_png(const String &p_path) const {
|
||||
return save_png_func(p_path, Ref<Image>((Image *)this));
|
||||
}
|
||||
|
||||
int Image::get_image_data_size(int p_width, int p_height, Format p_format, int p_mipmaps) {
|
||||
int Image::get_image_data_size(int p_width, int p_height, Format p_format, bool p_mipmaps) {
|
||||
|
||||
int mm;
|
||||
return _get_dst_image_size(p_width, p_height, p_format, mm, p_mipmaps);
|
||||
return _get_dst_image_size(p_width, p_height, p_format, mm, p_mipmaps ? -1 : 0);
|
||||
}
|
||||
|
||||
int Image::get_image_required_mipmaps(int p_width, int p_height, Format p_format) {
|
||||
@ -2376,6 +2378,17 @@ Image::DetectChannels Image::get_detected_channels() {
|
||||
return DETECTED_RGBA;
|
||||
}
|
||||
|
||||
void Image::optimize_channels() {
|
||||
switch (get_detected_channels()) {
|
||||
case DETECTED_L: convert(FORMAT_L8); break;
|
||||
case DETECTED_LA: convert(FORMAT_LA8); break;
|
||||
case DETECTED_R: convert(FORMAT_R8); break;
|
||||
case DETECTED_RG: convert(FORMAT_RG8); break;
|
||||
case DETECTED_RGB: convert(FORMAT_RGB8); break;
|
||||
case DETECTED_RGBA: convert(FORMAT_RGBA8); break;
|
||||
}
|
||||
}
|
||||
|
||||
void Image::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_width"), &Image::get_width);
|
||||
|
@ -116,7 +116,8 @@ public:
|
||||
enum CompressSource {
|
||||
COMPRESS_SOURCE_GENERIC,
|
||||
COMPRESS_SOURCE_SRGB,
|
||||
COMPRESS_SOURCE_NORMAL
|
||||
COMPRESS_SOURCE_NORMAL,
|
||||
COMPRESS_SOURCE_LAYERED,
|
||||
};
|
||||
|
||||
//some functions provided by something else
|
||||
@ -272,7 +273,7 @@ public:
|
||||
static int get_format_block_size(Format p_format);
|
||||
static void get_format_min_pixel_size(Format p_format, int &r_w, int &r_h);
|
||||
|
||||
static int get_image_data_size(int p_width, int p_height, Format p_format, int p_mipmaps = 0);
|
||||
static int get_image_data_size(int p_width, int p_height, Format p_format, bool p_mipmaps = false);
|
||||
static int get_image_required_mipmaps(int p_width, int p_height, Format p_format);
|
||||
|
||||
enum CompressMode {
|
||||
@ -329,6 +330,7 @@ public:
|
||||
};
|
||||
|
||||
DetectChannels get_detected_channels();
|
||||
void optimize_channels();
|
||||
|
||||
Color get_pixelv(const Point2 &p_src) const;
|
||||
Color get_pixel(int p_x, int p_y) const;
|
||||
|
@ -370,13 +370,17 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_
|
||||
switch (p_type) {
|
||||
case VS::TEXTURE_TYPE_2D: {
|
||||
texture->target = GL_TEXTURE_2D;
|
||||
texture->images.resize(1);
|
||||
} break;
|
||||
case VS::TEXTURE_TYPE_CUBEMAP: {
|
||||
texture->target = GL_TEXTURE_CUBE_MAP;
|
||||
texture->images.resize(6);
|
||||
} break;
|
||||
case VS::TEXTURE_TYPE_2D_ARRAY: {
|
||||
texture->images.resize(p_depth_3d);
|
||||
} break;
|
||||
case VS::TEXTURE_TYPE_3D: {
|
||||
texture->images.resize(p_depth_3d);
|
||||
} break;
|
||||
}
|
||||
|
||||
@ -419,7 +423,7 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p
|
||||
bool compressed = false;
|
||||
|
||||
if (config.keep_original_textures && !(texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING)) {
|
||||
texture->images[p_layer] = p_image;
|
||||
texture->images.write[p_layer] = p_image;
|
||||
}
|
||||
|
||||
Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), texture->flags, format, internal_format, type, compressed);
|
||||
|
@ -258,7 +258,7 @@ public:
|
||||
|
||||
RenderTarget *render_target;
|
||||
|
||||
Ref<Image> images[6];
|
||||
Vector<Ref<Image> > images;
|
||||
|
||||
bool redraw_if_visible;
|
||||
|
||||
|
@ -622,15 +622,19 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_
|
||||
switch (p_type) {
|
||||
case VS::TEXTURE_TYPE_2D: {
|
||||
texture->target = GL_TEXTURE_2D;
|
||||
texture->images.resize(1);
|
||||
} break;
|
||||
case VS::TEXTURE_TYPE_CUBEMAP: {
|
||||
texture->target = GL_TEXTURE_CUBE_MAP;
|
||||
texture->images.resize(6);
|
||||
} break;
|
||||
case VS::TEXTURE_TYPE_2D_ARRAY: {
|
||||
texture->target = GL_TEXTURE_2D_ARRAY;
|
||||
texture->images.resize(p_depth_3d);
|
||||
} break;
|
||||
case VS::TEXTURE_TYPE_3D: {
|
||||
texture->target = GL_TEXTURE_3D;
|
||||
texture->images.resize(p_depth_3d);
|
||||
} break;
|
||||
}
|
||||
|
||||
@ -703,7 +707,7 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
|
||||
bool srgb;
|
||||
|
||||
if (config.keep_original_textures && !(texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING)) {
|
||||
texture->images[p_layer] = p_image;
|
||||
texture->images.write[p_layer] = p_image;
|
||||
}
|
||||
|
||||
Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), texture->flags, format, internal_format, type, compressed, srgb);
|
||||
|
@ -277,7 +277,7 @@ public:
|
||||
|
||||
RenderTarget *render_target;
|
||||
|
||||
Ref<Image> images[6];
|
||||
Vector<Ref<Image> > images;
|
||||
|
||||
VisualServer::TextureDetectCallback detect_3d;
|
||||
void *detect_3d_ud;
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include "editor/import/resource_importer_bitmask.h"
|
||||
#include "editor/import/resource_importer_csv_translation.h"
|
||||
#include "editor/import/resource_importer_image.h"
|
||||
#include "editor/import/resource_importer_layered_texture.h"
|
||||
#include "editor/import/resource_importer_obj.h"
|
||||
#include "editor/import/resource_importer_scene.h"
|
||||
#include "editor/import/resource_importer_texture.h"
|
||||
@ -4666,6 +4667,16 @@ EditorNode::EditorNode() {
|
||||
import_texture.instance();
|
||||
ResourceFormatImporter::get_singleton()->add_importer(import_texture);
|
||||
|
||||
Ref<ResourceImporterLayeredTexture> import_3d;
|
||||
import_3d.instance();
|
||||
import_3d->set_3d(true);
|
||||
ResourceFormatImporter::get_singleton()->add_importer(import_3d);
|
||||
|
||||
Ref<ResourceImporterLayeredTexture> import_array;
|
||||
import_array.instance();
|
||||
import_array->set_3d(false);
|
||||
ResourceFormatImporter::get_singleton()->add_importer(import_array);
|
||||
|
||||
Ref<ResourceImporterImage> import_image;
|
||||
import_image.instance();
|
||||
ResourceFormatImporter::get_singleton()->add_importer(import_image);
|
||||
|
75
editor/icons/icon_texture_3_d.svg
Normal file
75
editor/icons/icon_texture_3_d.svg
Normal file
@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
version="1.1"
|
||||
viewBox="0 0 16 16"
|
||||
id="svg6"
|
||||
sodipodi:docname="icon_texture_3_d.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1853"
|
||||
inkscape:window-height="1016"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
inkscape:zoom="29.5"
|
||||
inkscape:cx="15.226978"
|
||||
inkscape:cy="9.4909723"
|
||||
inkscape:window-x="67"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg6" />
|
||||
<g
|
||||
id="g830"
|
||||
transform="translate(0.35954582,-0.28763666)">
|
||||
<path
|
||||
d="M 2,1 C 1.4477153,1 1,1.4477153 1,2 v 12 c 0,0.552285 0.4477153,1 1,1 h 12 c 0.552285,0 1,-0.447715 1,-1 V 2 C 15,1.4477153 14.552285,1 14,1 Z m 1,2 h 10 v 8 H 3 Z"
|
||||
id="path2"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#e0e0e0;fill-opacity:0.99607999"
|
||||
sodipodi:nodetypes="sssssssssccccc" />
|
||||
</g>
|
||||
<g
|
||||
aria-label="3D"
|
||||
transform="scale(0.9167105,1.0908569)"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.12847996px;line-height:1.25;font-family:Ubuntu;-inkscape-font-specification:'Ubuntu Bold';letter-spacing:0px;word-spacing:0px;fill:#e0e0e0;fill-opacity:0.99607843;stroke:none;stroke-width:0.20321201"
|
||||
id="text834">
|
||||
<path
|
||||
d="m 5.8175194,8.9717502 q -0.2194689,0 -0.4633233,-0.032514 Q 5.1103417,8.9148508 4.8827442,8.86608 4.6551468,8.8173091 4.4681918,8.7604097 4.2812367,8.7035104 4.1755665,8.6547395 L 4.4112924,7.646808 q 0.2113405,0.089413 0.5364797,0.1950835 0.3332677,0.097542 0.8209765,0.097542 0.5608651,0 0.8209764,-0.2113404 0.2601114,-0.2113405 0.2601114,-0.5689936 0,-0.219469 -0.097542,-0.3657816 Q 6.6628814,6.6388764 6.5003118,6.5494632 6.3377422,6.4519214 6.1101447,6.4194075 5.8906758,6.3787651 5.6386929,6.3787651 H 5.167241 V 5.4033475 h 0.5364797 q 0.1788266,0 0.3413962,-0.032514 0.1706981,-0.032514 0.3007537,-0.1056703 0.1300557,-0.081285 0.203212,-0.2113404 0.081285,-0.1381842 0.081285,-0.3413962 0,-0.1544411 -0.065028,-0.2682398 Q 6.5003118,4.3303881 6.3946415,4.2572318 6.2970998,4.1840755 6.1589156,4.1515616 6.0288599,4.1109192 5.8906758,4.1109192 q -0.3495247,0 -0.6502784,0.1056702 Q 4.9477721,4.3222597 4.7039177,4.4767008 L 4.2731082,3.5906965 Q 4.4031639,3.5094117 4.573862,3.4199984 4.7526886,3.3305851 4.964029,3.2574288 5.1753695,3.1842725 5.4110954,3.1355016 q 0.2438544,-0.048771 0.5120943,-0.048771 0.4958373,0 0.8534904,0.1219272 0.3657816,0.1137987 0.6015075,0.3332677 0.2357259,0.2113405 0.3495246,0.5039657 0.1137987,0.2844968 0.1137987,0.625893 0,0.3332677 -0.186955,0.6502784 -0.186955,0.3088822 -0.5039657,0.4714518 0.4389379,0.1788266 0.6746638,0.5364797 0.2438544,0.3495246 0.2438544,0.8453619 0,0.3901671 -0.1300557,0.7234347 Q 7.808997,8.22393 7.5326287,8.4677844 7.2562604,8.7035104 6.825451,8.8416945 6.40277,8.9717502 5.8175194,8.9717502 Z"
|
||||
style="fill:#e0e0e0;fill-opacity:0.99607843;stroke-width:0.20321201"
|
||||
id="path836" />
|
||||
<path
|
||||
d="m 10.502445,7.817506 q 0.08941,0.00813 0.203212,0.016257 0.121927,0 0.284497,0 0.951032,0 1.406227,-0.4795803 0.463323,-0.4795803 0.463323,-1.3249422 0,-0.8860044 -0.438938,-1.3411992 -0.438938,-0.4551949 -1.38997,-0.4551949 -0.130055,0 -0.26824,0.00813 -0.138184,0 -0.260111,0.016257 z M 14.16839,6.0292405 q 0,0.7315631 -0.227598,1.2761713 -0.227597,0.5446082 -0.650278,0.9022613 -0.414553,0.3576531 -1.01606,0.5364797 -0.601508,0.1788265 -1.349328,0.1788265 -0.341396,0 -0.796591,-0.032514 Q 9.6733402,8.86608 9.2344022,8.7766667 v -5.486724 q 0.438938,-0.081285 0.9103898,-0.1056702 0.47958,-0.032514 0.820976,-0.032514 0.723435,0 1.308686,0.1625696 0.593379,0.1625696 1.01606,0.5120943 0.422681,0.3495246 0.650278,0.8941328 0.227598,0.5446081 0.227598,1.3086853 z"
|
||||
style="fill:#e0e0e0;fill-opacity:0.99607843;stroke-width:0.20321201"
|
||||
id="path838" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.8 KiB |
77
editor/icons/icon_texture_array.svg
Normal file
77
editor/icons/icon_texture_array.svg
Normal file
@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
version="1.1"
|
||||
viewBox="0 0 16 16"
|
||||
id="svg6"
|
||||
sodipodi:docname="icon_texture_array.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1526"
|
||||
inkscape:window-height="766"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
inkscape:zoom="29.5"
|
||||
inkscape:cx="8.3117238"
|
||||
inkscape:cy="9.4909723"
|
||||
inkscape:window-x="67"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg6" />
|
||||
<g
|
||||
id="g830"
|
||||
transform="translate(0.35954582,-0.28763666)">
|
||||
<path
|
||||
d="M 2,1 C 1.4477153,1 1,1.4477153 1,2 v 12 c 0,0.552285 0.4477153,1 1,1 h 12 c 0.552285,0 1,-0.447715 1,-1 V 2 C 15,1.4477153 14.552285,1 14,1 Z m 1,2 h 10 v 8 H 3 Z"
|
||||
id="path2"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#e0e0e0;fill-opacity:0.99607999"
|
||||
sodipodi:nodetypes="sssssssssccccc" />
|
||||
</g>
|
||||
<g
|
||||
aria-label="[]"
|
||||
transform="matrix(1.6197742,0,0,0.750929,-3.7231532,1.8329569)"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.29580784px;line-height:1.25;font-family:Ubuntu;-inkscape-font-specification:'Ubuntu Bold';letter-spacing:0px;word-spacing:0px;fill:#e0e0e0;fill-opacity:0.99607843;stroke:none;stroke-width:0.2073952"
|
||||
id="text834">
|
||||
<path
|
||||
d="M 4.7302951,2.4553483 H 6.978459 V 3.4425495 H 5.9082998 V 9.4984892 H 6.978459 V 10.48569 H 4.7302951 Z"
|
||||
style="fill:#e0e0e0;fill-opacity:0.99607843;stroke-width:0.2073952"
|
||||
id="path862"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 10.138643,10.48569 H 7.8904794 V 9.4984892 H 8.9606386 V 3.4425495 H 7.8904794 V 2.4553483 h 2.2481636 z"
|
||||
style="fill:#e0e0e0;fill-opacity:0.99607843;stroke-width:0.2073952"
|
||||
id="path864"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
274
editor/import/resource_importer_layered_texture.cpp
Normal file
274
editor/import/resource_importer_layered_texture.cpp
Normal file
@ -0,0 +1,274 @@
|
||||
#include "resource_importer_layered_texture.h"
|
||||
|
||||
#include "resource_importer_texture.h"
|
||||
|
||||
#include "editor/editor_file_system.h"
|
||||
#include "editor/editor_node.h"
|
||||
#include "io/config_file.h"
|
||||
#include "io/image_loader.h"
|
||||
#include "scene/resources/texture.h"
|
||||
|
||||
String ResourceImporterLayeredTexture::get_importer_name() const {
|
||||
|
||||
return is_3d ? "texture_3d" : "texture_array";
|
||||
}
|
||||
|
||||
String ResourceImporterLayeredTexture::get_visible_name() const {
|
||||
|
||||
return is_3d ? "Texture3D" : "TextureArray";
|
||||
}
|
||||
void ResourceImporterLayeredTexture::get_recognized_extensions(List<String> *p_extensions) const {
|
||||
|
||||
ImageLoader::get_recognized_extensions(p_extensions);
|
||||
}
|
||||
String ResourceImporterLayeredTexture::get_save_extension() const {
|
||||
return is_3d ? "tex3d" : "texarr";
|
||||
}
|
||||
|
||||
String ResourceImporterLayeredTexture::get_resource_type() const {
|
||||
|
||||
return is_3d ? "Texture3D" : "TextureArray";
|
||||
}
|
||||
|
||||
bool ResourceImporterLayeredTexture::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int ResourceImporterLayeredTexture::get_preset_count() const {
|
||||
return 3;
|
||||
}
|
||||
String ResourceImporterLayeredTexture::get_preset_name(int p_idx) const {
|
||||
|
||||
static const char *preset_names[] = {
|
||||
"3D",
|
||||
"2D",
|
||||
"ColorCorrect"
|
||||
};
|
||||
|
||||
return preset_names[p_idx];
|
||||
}
|
||||
|
||||
void ResourceImporterLayeredTexture::get_import_options(List<ImportOption> *r_options, int p_preset) const {
|
||||
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Video RAM,Uncompressed", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), p_preset == PRESET_3D ? 1 : 0));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "flags/repeat", PROPERTY_HINT_ENUM, "Disabled,Enabled,Mirrored"), 0));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/filter"), true));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/mipmaps"), p_preset == PRESET_COLOR_CORRECT ? 0 : 1));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "flags/srgb", PROPERTY_HINT_ENUM, "Disable,Enable"), p_preset == PRESET_3D ? 1 : 0));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/horizontal", PROPERTY_HINT_RANGE, "1,256,1"), p_preset == PRESET_COLOR_CORRECT ? 16 : 8));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/vertical", PROPERTY_HINT_RANGE, "1,256,1"), p_preset == PRESET_COLOR_CORRECT ? 1 : 8));
|
||||
}
|
||||
|
||||
void ResourceImporterLayeredTexture::_save_tex(const Vector<Ref<Image> > &p_images, const String &p_to_path, int p_compress_mode, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags) {
|
||||
|
||||
FileAccess *f = FileAccess::open(p_to_path, FileAccess::WRITE);
|
||||
f->store_8('G');
|
||||
f->store_8('D');
|
||||
if (is_3d) {
|
||||
f->store_8('3');
|
||||
} else {
|
||||
f->store_8('A');
|
||||
}
|
||||
f->store_8('T'); //godot streamable texture
|
||||
|
||||
f->store_32(p_images[0]->get_width());
|
||||
f->store_32(p_images[0]->get_height());
|
||||
f->store_32(p_images.size()); //depth
|
||||
f->store_32(p_texture_flags);
|
||||
if (p_compress_mode != COMPRESS_VIDEO_RAM) {
|
||||
//vram needs to do a first compression to tell what the format is, for the rest its ok
|
||||
f->store_32(p_images[0]->get_format());
|
||||
f->store_32(p_compress_mode); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed
|
||||
}
|
||||
|
||||
if ((p_compress_mode == COMPRESS_LOSSLESS) && p_images[0]->get_format() > Image::FORMAT_RGBA8) {
|
||||
p_compress_mode = COMPRESS_UNCOMPRESSED; //these can't go as lossy
|
||||
}
|
||||
|
||||
for (int i = 0; i < p_images.size(); i++) {
|
||||
|
||||
switch (p_compress_mode) {
|
||||
case COMPRESS_LOSSLESS: {
|
||||
|
||||
Ref<Image> image = p_images[i]->duplicate();
|
||||
if (p_mipmaps) {
|
||||
image->generate_mipmaps();
|
||||
} else {
|
||||
image->clear_mipmaps();
|
||||
}
|
||||
|
||||
int mmc = image->get_mipmap_count() + 1;
|
||||
f->store_32(mmc);
|
||||
|
||||
for (int i = 0; i < mmc; i++) {
|
||||
|
||||
if (i > 0) {
|
||||
image->shrink_x2();
|
||||
}
|
||||
|
||||
PoolVector<uint8_t> data = Image::lossless_packer(image);
|
||||
int data_len = data.size();
|
||||
f->store_32(data_len);
|
||||
|
||||
PoolVector<uint8_t>::Read r = data.read();
|
||||
f->store_buffer(r.ptr(), data_len);
|
||||
}
|
||||
|
||||
} break;
|
||||
case COMPRESS_VIDEO_RAM: {
|
||||
|
||||
Ref<Image> image = p_images[i]->duplicate();
|
||||
image->generate_mipmaps(false);
|
||||
|
||||
Image::CompressSource csource = Image::COMPRESS_SOURCE_LAYERED;
|
||||
image->compress(p_vram_compression, csource, 0.7);
|
||||
|
||||
if (i == 0) {
|
||||
//hack so we can properly tell the format
|
||||
f->store_32(image->get_format());
|
||||
f->store_32(p_compress_mode); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed
|
||||
}
|
||||
|
||||
PoolVector<uint8_t> data = image->get_data();
|
||||
int dl = data.size();
|
||||
|
||||
PoolVector<uint8_t>::Read r = data.read();
|
||||
f->store_buffer(r.ptr(), dl);
|
||||
} break;
|
||||
case COMPRESS_UNCOMPRESSED: {
|
||||
|
||||
Ref<Image> image = p_images[i]->duplicate();
|
||||
|
||||
if (p_mipmaps) {
|
||||
image->generate_mipmaps();
|
||||
} else {
|
||||
image->clear_mipmaps();
|
||||
}
|
||||
|
||||
PoolVector<uint8_t> data = image->get_data();
|
||||
int dl = data.size();
|
||||
|
||||
PoolVector<uint8_t>::Read r = data.read();
|
||||
|
||||
f->store_buffer(r.ptr(), dl);
|
||||
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
memdelete(f);
|
||||
}
|
||||
|
||||
Error ResourceImporterLayeredTexture::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) {
|
||||
|
||||
int compress_mode = p_options["compress/mode"];
|
||||
int repeat = p_options["flags/repeat"];
|
||||
bool filter = p_options["flags/filter"];
|
||||
bool mipmaps = p_options["flags/mipmaps"];
|
||||
int srgb = p_options["flags/srgb"];
|
||||
int hslices = p_options["slices/horizontal"];
|
||||
int vslices = p_options["slices/vertical"];
|
||||
|
||||
Ref<Image> image;
|
||||
image.instance();
|
||||
Error err = ImageLoader::load_image(p_source_file, image, NULL, false, 1.0);
|
||||
if (err != OK)
|
||||
return err;
|
||||
|
||||
int tex_flags = 0;
|
||||
if (repeat > 0)
|
||||
tex_flags |= Texture::FLAG_REPEAT;
|
||||
if (repeat == 2)
|
||||
tex_flags |= Texture::FLAG_MIRRORED_REPEAT;
|
||||
if (filter)
|
||||
tex_flags |= Texture::FLAG_FILTER;
|
||||
if (mipmaps || compress_mode == COMPRESS_VIDEO_RAM)
|
||||
tex_flags |= Texture::FLAG_MIPMAPS;
|
||||
if (srgb == 1)
|
||||
tex_flags |= Texture::FLAG_CONVERT_TO_LINEAR;
|
||||
|
||||
Vector<Ref<Image> > slices;
|
||||
|
||||
int slice_w = image->get_width() / hslices;
|
||||
int slice_h = image->get_height() / vslices;
|
||||
|
||||
//optimize
|
||||
if (compress_mode == COMPRESS_VIDEO_RAM) {
|
||||
//if using video ram, optimize
|
||||
if (srgb) {
|
||||
//remove alpha if not needed, so compression is more efficient
|
||||
if (image->get_format() == Image::FORMAT_RGBA8 && !image->detect_alpha()) {
|
||||
image->convert(Image::FORMAT_RGB8);
|
||||
}
|
||||
} else {
|
||||
image->optimize_channels();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < vslices; i++) {
|
||||
for (int j = 0; j < hslices; j++) {
|
||||
int x = slice_w * j;
|
||||
int y = slice_h * i;
|
||||
Ref<Image> slice = image->get_rect(Rect2(x, y, slice_w, slice_h));
|
||||
ERR_CONTINUE(slice.is_null() || slice->empty());
|
||||
if (slice->get_width() != slice_w || slice->get_height() != slice_h) {
|
||||
slice->resize(slice_w, slice_h);
|
||||
}
|
||||
slices.push_back(slice);
|
||||
}
|
||||
}
|
||||
|
||||
String extension = get_save_extension();
|
||||
|
||||
if (compress_mode == COMPRESS_VIDEO_RAM) {
|
||||
//must import in all formats, in order of priority (so platform choses the best supported one. IE, etc2 over etc).
|
||||
//Android, GLES 2.x
|
||||
|
||||
bool ok_on_pc = false;
|
||||
|
||||
if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc")) {
|
||||
|
||||
_save_tex(slices, p_save_path + ".s3tc." + extension, compress_mode, Image::COMPRESS_S3TC, mipmaps, tex_flags);
|
||||
r_platform_variants->push_back("s3tc");
|
||||
ok_on_pc = true;
|
||||
}
|
||||
|
||||
if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) {
|
||||
|
||||
_save_tex(slices, p_save_path + ".etc2." + extension, compress_mode, Image::COMPRESS_ETC2, mipmaps, tex_flags);
|
||||
r_platform_variants->push_back("etc2");
|
||||
}
|
||||
|
||||
if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) {
|
||||
_save_tex(slices, p_save_path + ".etc." + extension, compress_mode, Image::COMPRESS_ETC, mipmaps, tex_flags);
|
||||
r_platform_variants->push_back("etc");
|
||||
}
|
||||
|
||||
if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) {
|
||||
|
||||
_save_tex(slices, p_save_path + ".pvrtc." + extension, compress_mode, Image::COMPRESS_PVRTC4, mipmaps, tex_flags);
|
||||
r_platform_variants->push_back("pvrtc");
|
||||
}
|
||||
|
||||
if (!ok_on_pc) {
|
||||
EditorNode::add_io_error("Warning, no suitable PC VRAM compression enabled in Project Settings. This texture will not display correcly on PC.");
|
||||
}
|
||||
} else {
|
||||
//import normally
|
||||
_save_tex(slices, p_save_path + "." + extension, compress_mode, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, tex_flags);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
ResourceImporterLayeredTexture *ResourceImporterLayeredTexture::singleton = NULL;
|
||||
|
||||
ResourceImporterLayeredTexture::ResourceImporterLayeredTexture() {
|
||||
|
||||
singleton = this;
|
||||
is_3d = true;
|
||||
}
|
||||
|
||||
ResourceImporterLayeredTexture::~ResourceImporterLayeredTexture() {
|
||||
}
|
57
editor/import/resource_importer_layered_texture.h
Normal file
57
editor/import/resource_importer_layered_texture.h
Normal file
@ -0,0 +1,57 @@
|
||||
#ifndef RESOURCE_IMPORTER_LAYERED_TEXTURE_H
|
||||
#define RESOURCE_IMPORTER_LAYERED_TEXTURE_H
|
||||
|
||||
#include "image.h"
|
||||
#include "io/resource_import.h"
|
||||
|
||||
class StreamTexture;
|
||||
|
||||
class ResourceImporterLayeredTexture : public ResourceImporter {
|
||||
GDCLASS(ResourceImporterLayeredTexture, ResourceImporter)
|
||||
|
||||
bool is_3d;
|
||||
|
||||
protected:
|
||||
static void _texture_reimport_srgb(const Ref<StreamTexture> &p_tex);
|
||||
static void _texture_reimport_3d(const Ref<StreamTexture> &p_tex);
|
||||
static void _texture_reimport_normal(const Ref<StreamTexture> &p_tex);
|
||||
|
||||
static ResourceImporterLayeredTexture *singleton;
|
||||
|
||||
public:
|
||||
static ResourceImporterLayeredTexture *get_singleton() { return singleton; }
|
||||
virtual String get_importer_name() const;
|
||||
virtual String get_visible_name() const;
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual String get_save_extension() const;
|
||||
virtual String get_resource_type() const;
|
||||
|
||||
enum Preset {
|
||||
PRESET_3D,
|
||||
PRESET_2D,
|
||||
PRESET_COLOR_CORRECT,
|
||||
};
|
||||
|
||||
enum CompressMode {
|
||||
COMPRESS_LOSSLESS,
|
||||
COMPRESS_VIDEO_RAM,
|
||||
COMPRESS_UNCOMPRESSED
|
||||
};
|
||||
|
||||
virtual int get_preset_count() const;
|
||||
virtual String get_preset_name(int p_idx) const;
|
||||
|
||||
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
|
||||
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
|
||||
|
||||
void _save_tex(const Vector<Ref<Image> > &p_images, const String &p_to_path, int p_compress_mode, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags);
|
||||
|
||||
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL);
|
||||
|
||||
void update_imports();
|
||||
|
||||
void set_3d(bool p_3d) { is_3d = p_3d; }
|
||||
ResourceImporterLayeredTexture();
|
||||
~ResourceImporterLayeredTexture();
|
||||
};
|
||||
#endif // RESOURCE_IMPORTER_LAYERED_TEXTURE_H
|
@ -98,6 +98,33 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f
|
||||
Image::Format img_format = p_img->get_format();
|
||||
Image::DetectChannels detected_channels = p_img->get_detected_channels();
|
||||
|
||||
if (p_source == Image::COMPRESS_SOURCE_LAYERED) {
|
||||
//keep what comes in
|
||||
switch (p_img->get_format()) {
|
||||
case Image::FORMAT_L8: {
|
||||
detected_channels = Image::DETECTED_L;
|
||||
} break;
|
||||
case Image::FORMAT_LA8: {
|
||||
detected_channels = Image::DETECTED_LA;
|
||||
} break;
|
||||
case Image::FORMAT_R8: {
|
||||
detected_channels = Image::DETECTED_R;
|
||||
} break;
|
||||
case Image::FORMAT_RG8: {
|
||||
detected_channels = Image::DETECTED_RG;
|
||||
} break;
|
||||
case Image::FORMAT_RGB8: {
|
||||
detected_channels = Image::DETECTED_RGB;
|
||||
} break;
|
||||
case Image::FORMAT_RGBA8:
|
||||
case Image::FORMAT_RGBA4444:
|
||||
case Image::FORMAT_RGBA5551: {
|
||||
detected_channels = Image::DETECTED_RGBA;
|
||||
} break;
|
||||
default: {}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_source == Image::COMPRESS_SOURCE_SRGB && (detected_channels == Image::DETECTED_R || detected_channels == Image::DETECTED_RG)) {
|
||||
//R and RG do not support SRGB
|
||||
detected_channels = Image::DETECTED_RGB;
|
||||
@ -147,7 +174,7 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f
|
||||
|
||||
PoolVector<uint8_t>::Read r = img->get_data().read();
|
||||
|
||||
int target_size = Image::get_image_data_size(imgw, imgh, etc_format, p_img->has_mipmaps() ? -1 : 0);
|
||||
int target_size = Image::get_image_data_size(imgw, imgh, etc_format, p_img->has_mipmaps());
|
||||
int mmc = 1 + (p_img->has_mipmaps() ? Image::get_image_required_mipmaps(imgw, imgh, etc_format) : 0);
|
||||
|
||||
PoolVector<uint8_t> dst_data;
|
||||
|
@ -46,7 +46,7 @@ void image_decompress_squish(Image *p_image) {
|
||||
|
||||
Image::Format target_format = Image::FORMAT_RGBA8;
|
||||
PoolVector<uint8_t> data;
|
||||
int target_size = Image::get_image_data_size(w, h, target_format, p_image->has_mipmaps() ? -1 : 0);
|
||||
int target_size = Image::get_image_data_size(w, h, target_format, p_image->has_mipmaps());
|
||||
int mm_count = p_image->get_mipmap_count();
|
||||
data.resize(target_size);
|
||||
|
||||
@ -96,6 +96,33 @@ void image_compress_squish(Image *p_image, Image::CompressSource p_source) {
|
||||
|
||||
Image::DetectChannels dc = p_image->get_detected_channels();
|
||||
|
||||
if (p_source == Image::COMPRESS_SOURCE_LAYERED) {
|
||||
//keep what comes in
|
||||
switch (p_image->get_format()) {
|
||||
case Image::FORMAT_L8: {
|
||||
dc = Image::DETECTED_L;
|
||||
} break;
|
||||
case Image::FORMAT_LA8: {
|
||||
dc = Image::DETECTED_LA;
|
||||
} break;
|
||||
case Image::FORMAT_R8: {
|
||||
dc = Image::DETECTED_R;
|
||||
} break;
|
||||
case Image::FORMAT_RG8: {
|
||||
dc = Image::DETECTED_RG;
|
||||
} break;
|
||||
case Image::FORMAT_RGB8: {
|
||||
dc = Image::DETECTED_RGB;
|
||||
} break;
|
||||
case Image::FORMAT_RGBA8:
|
||||
case Image::FORMAT_RGBA4444:
|
||||
case Image::FORMAT_RGBA5551: {
|
||||
dc = Image::DETECTED_RGBA;
|
||||
} break;
|
||||
default: {}
|
||||
}
|
||||
}
|
||||
|
||||
p_image->convert(Image::FORMAT_RGBA8); //still uses RGBA to convert
|
||||
|
||||
if (p_source == Image::COMPRESS_SOURCE_SRGB && (dc == Image::DETECTED_R || dc == Image::DETECTED_RG)) {
|
||||
@ -148,7 +175,7 @@ void image_compress_squish(Image *p_image, Image::CompressSource p_source) {
|
||||
}
|
||||
|
||||
PoolVector<uint8_t> data;
|
||||
int target_size = Image::get_image_data_size(w, h, target_format, p_image->has_mipmaps() ? -1 : 0);
|
||||
int target_size = Image::get_image_data_size(w, h, target_format, p_image->has_mipmaps());
|
||||
int mm_count = p_image->has_mipmaps() ? Image::get_image_required_mipmaps(w, h, target_format) : 0;
|
||||
data.resize(target_size);
|
||||
int shift = Image::get_format_pixel_rshift(target_format);
|
||||
|
@ -217,6 +217,7 @@ static ResourceFormatLoaderText *resource_loader_text = NULL;
|
||||
static ResourceFormatLoaderDynamicFont *resource_loader_dynamic_font = NULL;
|
||||
|
||||
static ResourceFormatLoaderStreamTexture *resource_loader_stream_texture = NULL;
|
||||
static ResourceFormatLoaderTextureLayered *resource_loader_texture_layered = NULL;
|
||||
|
||||
static ResourceFormatLoaderBMFont *resource_loader_bmfont = NULL;
|
||||
|
||||
@ -237,6 +238,9 @@ void register_scene_types() {
|
||||
resource_loader_stream_texture = memnew(ResourceFormatLoaderStreamTexture);
|
||||
ResourceLoader::add_resource_format_loader(resource_loader_stream_texture);
|
||||
|
||||
resource_loader_texture_layered = memnew(ResourceFormatLoaderTextureLayered);
|
||||
ResourceLoader::add_resource_format_loader(resource_loader_texture_layered);
|
||||
|
||||
resource_loader_theme = memnew(ResourceFormatLoaderTheme);
|
||||
ResourceLoader::add_resource_format_loader(resource_loader_theme);
|
||||
|
||||
@ -615,7 +619,9 @@ void register_scene_types() {
|
||||
ClassDB::register_class<ProxyTexture>();
|
||||
ClassDB::register_class<AnimatedTexture>();
|
||||
ClassDB::register_class<CubeMap>();
|
||||
ClassDB::register_virtual_class<TextureLayered>();
|
||||
ClassDB::register_class<Texture3D>();
|
||||
ClassDB::register_class<TextureArray>();
|
||||
ClassDB::register_class<Animation>();
|
||||
ClassDB::register_virtual_class<Font>();
|
||||
ClassDB::register_class<BitmapFont>();
|
||||
@ -729,6 +735,7 @@ void unregister_scene_types() {
|
||||
|
||||
memdelete(resource_loader_dynamic_font);
|
||||
memdelete(resource_loader_stream_texture);
|
||||
memdelete(resource_loader_texture_layered);
|
||||
memdelete(resource_loader_theme);
|
||||
|
||||
DynamicFont::finish_dynamic_fonts();
|
||||
|
@ -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,112 +1860,9 @@ AnimatedTexture::AnimatedTexture() {
|
||||
AnimatedTexture::~AnimatedTexture() {
|
||||
VS::get_singleton()->free(proxy);
|
||||
}
|
||||
///////////////////////////////
|
||||
|
||||
bool Texture3D::get_split_single_image_enabled() const {
|
||||
return split_single_image_enabled;
|
||||
}
|
||||
|
||||
void Texture3D::set_split_single_image_enabled(bool p_split_enabled) {
|
||||
split_single_image_enabled = p_split_enabled;
|
||||
|
||||
_change_notify();
|
||||
}
|
||||
|
||||
uint32_t Texture3D::get_split_single_image_h_split() const {
|
||||
return split_single_image_h_split;
|
||||
}
|
||||
|
||||
void Texture3D::set_split_single_image_h_split(uint32_t p_h_split) {
|
||||
split_single_image_h_split = p_h_split;
|
||||
|
||||
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 Texture3D::get_split_single_image_v_split() const {
|
||||
return split_single_image_v_split;
|
||||
}
|
||||
|
||||
void Texture3D::set_split_single_image_v_split(uint32_t p_v_split) {
|
||||
split_single_image_v_split = p_v_split;
|
||||
|
||||
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 Texture3D::get_split_single_image_num_layers() const {
|
||||
return split_single_image_num_layers;
|
||||
}
|
||||
|
||||
void Texture3D::set_split_single_image_num_layers(uint32_t p_num_layers) {
|
||||
split_single_image_num_layers = p_num_layers;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Ref<Image> Texture3D::get_split_single_image_image() const {
|
||||
return split_single_image_image;
|
||||
}
|
||||
|
||||
void Texture3D::set_split_single_image_image(const Ref<Image> &p_image) {
|
||||
split_single_image_image = p_image;
|
||||
|
||||
create_from_image(split_single_image_image, split_single_image_h_split, split_single_image_v_split, split_single_image_num_layers, flags);
|
||||
}
|
||||
|
||||
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 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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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("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("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("set_data_partial", "image", "x_offset", "y_offset", "layer", "mipmap"), &Texture3D::set_data_partial, DEFVAL(0));
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter"), "set_flags", "get_flags");
|
||||
|
||||
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) {
|
||||
void TextureLayered::set_flags(uint32_t p_flags) {
|
||||
flags = p_flags;
|
||||
|
||||
if (texture.is_valid()) {
|
||||
@ -1989,28 +1870,71 @@ void Texture3D::set_flags(uint32_t p_flags) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t Texture3D::get_flags() const {
|
||||
uint32_t TextureLayered::get_flags() const {
|
||||
return flags;
|
||||
}
|
||||
|
||||
Image::Format Texture3D::get_format() const {
|
||||
Image::Format TextureLayered::get_format() const {
|
||||
return format;
|
||||
}
|
||||
|
||||
uint32_t Texture3D::get_width() const {
|
||||
uint32_t TextureLayered::get_width() const {
|
||||
return width;
|
||||
}
|
||||
|
||||
uint32_t Texture3D::get_height() const {
|
||||
uint32_t TextureLayered::get_height() const {
|
||||
return height;
|
||||
}
|
||||
|
||||
uint32_t Texture3D::get_depth() const {
|
||||
uint32_t TextureLayered::get_depth() const {
|
||||
return depth;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary TextureLayered::_get_data() const {
|
||||
Dictionary d;
|
||||
d["width"] = width;
|
||||
d["height"] = height;
|
||||
d["depth"] = depth;
|
||||
d["flags"] = flags;
|
||||
d["format"] = format;
|
||||
|
||||
Array layers;
|
||||
for (int i = 0; i < depth; i++) {
|
||||
layers.push_back(get_layer_data(i));
|
||||
}
|
||||
d["layers"] = layers;
|
||||
return d;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
width = p_width;
|
||||
height = p_height;
|
||||
@ -2019,40 +1943,27 @@ void Texture3D::create(uint32_t p_width, uint32_t p_height, uint32_t p_depth, Im
|
||||
flags = p_flags;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
ERR_FAIL_COND(p_image.is_null());
|
||||
ERR_FAIL_COND((p_h_split + 1) * (p_v_split + 1) < p_num_layer);
|
||||
|
||||
uint32_t total_width = p_image->get_width();
|
||||
uint32_t total_height = p_image->get_height();
|
||||
|
||||
uint32_t width = total_width / (p_h_split + 1);
|
||||
uint32_t height = total_height / (p_v_split + 1);
|
||||
|
||||
create(width, height, p_num_layer, p_image->get_format(), flags);
|
||||
|
||||
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);
|
||||
|
||||
uint32_t x_offset = col * width;
|
||||
uint32_t y_offset = row * height;
|
||||
|
||||
VS::get_singleton()->texture_set_data_partial(texture, p_image, x_offset, y_offset, width, height, 0, 0, 0, i);
|
||||
}
|
||||
}
|
||||
|
||||
void Texture3D::set_data_partial(const Ref<Image> &p_image, int p_x_ofs, int p_y_ofs, int p_layer, int p_mipmap) {
|
||||
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_partial(texture, p_image, 0, 0, p_image->get_width(), p_image->get_height(), p_x_ofs, p_y_ofs, p_mipmap, p_layer);
|
||||
VS::get_singleton()->texture_set_data(texture, p_image, p_layer);
|
||||
}
|
||||
|
||||
RID Texture3D::get_rid() const {
|
||||
Ref<Image> TextureLayered::get_layer_data(int p_layer) const {
|
||||
|
||||
ERR_FAIL_COND_V(!texture.is_valid(), Ref<Image>());
|
||||
return VS::get_singleton()->texture_get_data(texture, p_layer);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
RID TextureLayered::get_rid() const {
|
||||
return texture;
|
||||
}
|
||||
|
||||
void Texture3D::set_path(const String &p_path, bool p_take_over) {
|
||||
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);
|
||||
}
|
||||
@ -2060,7 +1971,35 @@ void Texture3D::set_path(const String &p_path, bool p_take_over) {
|
||||
Resource::set_path(p_path, p_take_over);
|
||||
}
|
||||
|
||||
Texture3D::Texture3D() {
|
||||
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("get_format"), &TextureLayered::get_format);
|
||||
|
||||
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"), &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", "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);
|
||||
}
|
||||
|
||||
TextureLayered::TextureLayered(bool p_3d) {
|
||||
is_3d = p_3d;
|
||||
format = Image::FORMAT_MAX;
|
||||
flags = FLAGS_DEFAULT;
|
||||
|
||||
@ -2068,17 +2007,180 @@ Texture3D::Texture3D() {
|
||||
height = 0;
|
||||
depth = 0;
|
||||
|
||||
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>();
|
||||
|
||||
texture = VS::get_singleton()->texture_create();
|
||||
}
|
||||
|
||||
Texture3D::~Texture3D() {
|
||||
TextureLayered::~TextureLayered() {
|
||||
if (texture.is_valid()) {
|
||||
VS::get_singleton()->free(texture);
|
||||
}
|
||||
}
|
||||
|
||||
RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error) {
|
||||
|
||||
if (r_error) {
|
||||
*r_error = ERR_CANT_OPEN;
|
||||
}
|
||||
|
||||
Ref<TextureLayered> lt;
|
||||
Ref<Texture3D> tex3d;
|
||||
Ref<TextureArray> texarr;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
|
||||
ERR_FAIL_COND_V(!f, RES());
|
||||
|
||||
uint8_t header[5] = { 0, 0, 0, 0, 0 };
|
||||
f->get_buffer(header, 4);
|
||||
|
||||
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 {
|
||||
|
||||
ERR_EXPLAIN("Unrecognized layered texture file format: " + String((const char *)header));
|
||||
ERR_FAIL_V(RES());
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
lt->create(tw, th, td, format, flags);
|
||||
|
||||
for (int layer = 0; layer < td; layer++) {
|
||||
|
||||
Ref<Image> image;
|
||||
image.instance();
|
||||
|
||||
if (compression == COMPRESSION_LOSSLESS) {
|
||||
//look for a PNG file inside
|
||||
|
||||
int mipmaps = f->get_32();
|
||||
Vector<Ref<Image> > mipmap_images;
|
||||
|
||||
for (int i = 0; i < mipmaps; i++) {
|
||||
uint32_t size = f->get_32();
|
||||
|
||||
PoolVector<uint8_t> pv;
|
||||
pv.resize(size);
|
||||
{
|
||||
PoolVector<uint8_t>::Write w = pv.write();
|
||||
f->get_buffer(w.ptr(), size);
|
||||
}
|
||||
|
||||
Ref<Image> img = Image::lossless_unpacker(pv);
|
||||
|
||||
if (img.is_null() || img->empty() || format != img->get_format()) {
|
||||
if (r_error) {
|
||||
*r_error = ERR_FILE_CORRUPT;
|
||||
}
|
||||
memdelete(f);
|
||||
ERR_FAIL_V(RES());
|
||||
}
|
||||
|
||||
mipmap_images.push_back(img);
|
||||
}
|
||||
|
||||
if (mipmap_images.size() == 1) {
|
||||
|
||||
image = mipmap_images[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;
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
//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 "";
|
||||
}
|
||||
|
@ -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;
|
||||
int width;
|
||||
int height;
|
||||
int depth;
|
||||
|
||||
// for setting an image as a property
|
||||
bool split_single_image_enabled;
|
||||
|
||||
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;
|
||||
|
||||
bool get_split_single_image_enabled() const;
|
||||
void set_split_single_image_enabled(bool p_split_enabled);
|
||||
|
||||
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);
|
||||
|
||||
uint32_t get_split_single_image_num_layers() const;
|
||||
void set_split_single_image_num_layers(uint32_t p_num_layers);
|
||||
|
||||
Ref<Image> get_split_single_image_image() const;
|
||||
void set_split_single_image_image(const Ref<Image> &p_image);
|
||||
|
||||
virtual void set_path(const String &p_path, bool p_take_over = false);
|
||||
|
||||
Texture3D();
|
||||
~Texture3D();
|
||||
TextureLayered(bool p_3d = false);
|
||||
~TextureLayered();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(TextureLayered::Flags)
|
||||
|
||||
class Texture3D : public TextureLayered {
|
||||
|
||||
GDCLASS(Texture3D, TextureLayered)
|
||||
public:
|
||||
Texture3D() :
|
||||
TextureLayered(true) {}
|
||||
};
|
||||
|
||||
class TextureArray : public TextureLayered {
|
||||
|
||||
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 {
|
||||
|
Loading…
Reference in New Issue
Block a user