summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2019-09-14 00:37:42 -0300
committerJuan Linietsky <reduzio@gmail.com>2020-02-11 12:01:22 +0100
commit6deffa62fbd1e91873afa663630b788b9ffabee3 (patch)
treee77c1a67c8b8ddb64429280131502f64c8cd8e8c
parent9d7b7f931b6924399903e4954a0c32d59c15d4c3 (diff)
Several fixes to 3D rendering, and multimesh implementation.
-rw-r--r--core/io/resource_loader.cpp1
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp4
-rw-r--r--editor/doc/doc_data.cpp2
-rw-r--r--editor/import/resource_importer_texture.cpp17
-rw-r--r--editor/plugins/multimesh_editor_plugin.cpp2
-rw-r--r--modules/gridmap/grid_map.cpp2
-rw-r--r--scene/2d/cpu_particles_2d.cpp4
-rw-r--r--scene/3d/cpu_particles.cpp4
-rw-r--r--scene/3d/vehicle_body.cpp3
-rw-r--r--scene/3d/voxel_light_baker.cpp2
-rw-r--r--scene/main/viewport.cpp2
-rw-r--r--scene/resources/environment.cpp14
-rw-r--r--scene/resources/environment.h3
-rw-r--r--scene/resources/mesh.cpp117
-rw-r--r--scene/resources/multimesh.cpp95
-rw-r--r--scene/resources/multimesh.h33
-rw-r--r--scene/resources/texture.cpp76
-rw-r--r--scene/resources/texture.h4
-rw-r--r--servers/visual/rasterizer.h6
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp2
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp90
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h12
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp3
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp655
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_storage_rd.h125
-rw-r--r--servers/visual/rasterizer_rd/shader_compiler_rd.cpp3
-rw-r--r--servers/visual/rasterizer_rd/shaders/scene_forward.glsl58
-rw-r--r--servers/visual/rasterizer_rd/shaders/scene_forward_inc.glsl16
-rw-r--r--servers/visual/rasterizer_rd/shaders/tonemap.glsl4
-rw-r--r--servers/visual/shader_language.cpp18
-rw-r--r--servers/visual/shader_language.h12
-rw-r--r--servers/visual/visual_server_raster.h5
-rw-r--r--servers/visual/visual_server_scene.cpp1
-rw-r--r--servers/visual/visual_server_wrap_mt.h5
-rw-r--r--servers/visual_server.cpp11
-rw-r--r--servers/visual_server.h21
36 files changed, 1211 insertions, 221 deletions
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 0e1ada9475..b6e75dd0e7 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -404,6 +404,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
if (!p_no_cache) {
_remove_from_loading_map(local_path);
}
+ print_verbose("Failed loading resource: " + path);
return RES();
}
if (!p_no_cache)
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 8cc07c59b1..09b0f7113e 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -3969,7 +3969,7 @@ RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Po
ERR_FAIL_COND_V(p_data.size() && (uint32_t)p_data.size() != p_size_bytes, RID());
Buffer buffer;
- Error err = _buffer_allocate(&buffer, p_size_bytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY);
+ Error err = _buffer_allocate(&buffer, p_size_bytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY);
ERR_FAIL_COND_V(err != OK, RID());
if (p_data.size()) {
@@ -4600,6 +4600,8 @@ PoolVector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) {
buffer = index_buffer_owner.getornull(p_buffer);
} else if (texture_buffer_owner.owns(p_buffer)) {
buffer = &texture_buffer_owner.getornull(p_buffer)->buffer;
+ } else if (storage_buffer_owner.owns(p_buffer)) {
+ buffer = storage_buffer_owner.getornull(p_buffer);
} else {
ERR_FAIL_V_MSG(PoolVector<uint8_t>(), "Buffer is either invalid or this type of buffer can't be retrieved. Only Index and Vertex buffers allow retrieving.");
}
diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp
index 0d9e53c71c..c128ca4321 100644
--- a/editor/doc/doc_data.cpp
+++ b/editor/doc/doc_data.cpp
@@ -304,6 +304,8 @@ void DocData::generate(bool p_basic_types) {
}
}
+ //used to track uninitialized values using valgrind
+ //print_line("getting default value for " + String(name) + "." + String(E->get().name));
if (default_value_valid && default_value.get_type() != Variant::OBJECT) {
prop.default_value = default_value.get_construct_string().replace("\n", "");
}
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index 1c373fbcf2..32bf9c6f40 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -115,8 +115,8 @@ void ResourceImporterTexture::update_imports() {
changed = true;
}
- if (E->get().flags & MAKE_3D_FLAG && bool(cf->get_value("params", "detect_3d"))) {
- cf->set_value("params", "detect_3d", false);
+ if (E->get().flags & MAKE_3D_FLAG && bool(cf->get_value("params", "usage/detect_3d"))) {
+ cf->set_value("params", "usage/detect_3d", false);
cf->set_value("params", "compress/mode", 2);
cf->set_value("params", "format/mipmaps", true);
changed = true;
@@ -214,9 +214,10 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options,
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/premult_alpha"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/invert_color"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/HDR_as_SRGB"), false));
- r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "stream"), false));
- r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "size_limit", PROPERTY_HINT_RANGE, "0,4096,1"), 0));
- r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "detect_3d"), p_preset == PRESET_DETECT));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "process/size_limit", PROPERTY_HINT_RANGE, "0,4096,1"), 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "process/mipmap_limit", PROPERTY_HINT_RANGE, "0,999,1"), 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "usage/stream"), false));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "usage/detect_3d"), p_preset == PRESET_DETECT));
r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "svg/scale", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 1.0));
}
@@ -385,8 +386,8 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
bool fix_alpha_border = p_options["process/fix_alpha_border"];
bool premult_alpha = p_options["process/premult_alpha"];
bool invert_color = p_options["process/invert_color"];
- bool stream = p_options["stream"];
- int size_limit = p_options["size_limit"];
+ bool stream = p_options["usage/stream"];
+ int size_limit = p_options["process/size_limit"];
bool hdr_as_srgb = p_options["process/HDR_as_SRGB"];
int normal = p_options["compress/normal_map"];
float scale = p_options["svg/scale"];
@@ -443,7 +444,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
image->unlock();
}
- bool detect_3d = p_options["detect_3d"];
+ bool detect_3d = p_options["usage/detect_3d"];
bool detect_roughness = roughness == 0;
bool detect_normal = normal == 0;
bool force_normal = normal == 1;
diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp
index 5dc222f84c..ddd27b5e97 100644
--- a/editor/plugins/multimesh_editor_plugin.cpp
+++ b/editor/plugins/multimesh_editor_plugin.cpp
@@ -172,7 +172,7 @@ void MultiMeshEditor::_populate() {
int instance_count = populate_amount->get_value();
multimesh->set_transform_format(MultiMesh::TRANSFORM_3D);
- multimesh->set_color_format(MultiMesh::COLOR_NONE);
+ multimesh->set_use_colors(false);
multimesh->set_instance_count(instance_count);
float _tilt_random = populate_tilt_random->get_value();
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index 1e73a715db..7fe58f8ce7 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -514,7 +514,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
Octant::MultimeshInstance mmi;
RID mm = VS::get_singleton()->multimesh_create();
- VS::get_singleton()->multimesh_allocate(mm, E->get().size(), VS::MULTIMESH_TRANSFORM_3D, VS::MULTIMESH_COLOR_NONE);
+ VS::get_singleton()->multimesh_allocate(mm, E->get().size(), VS::MULTIMESH_TRANSFORM_3D);
VS::get_singleton()->multimesh_set_mesh(mm, mesh_library->get_item_mesh(E->key())->get_rid());
int idx = 0;
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 0e5c1b8c02..b4d1052c04 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -59,7 +59,7 @@ void CPUParticles2D::set_amount(int p_amount) {
}
particle_data.resize((8 + 4 + 1) * p_amount);
- VS::get_singleton()->multimesh_allocate(multimesh, p_amount, VS::MULTIMESH_TRANSFORM_2D, VS::MULTIMESH_COLOR_8BIT, VS::MULTIMESH_CUSTOM_DATA_FLOAT);
+ VS::get_singleton()->multimesh_allocate(multimesh, p_amount, VS::MULTIMESH_TRANSFORM_2D, true, true);
particle_order.resize(p_amount);
}
@@ -1077,7 +1077,7 @@ void CPUParticles2D::_update_render_thread() {
update_mutex->lock();
#endif
- VS::get_singleton()->multimesh_set_as_bulk_array(multimesh, particle_data);
+ VS::get_singleton()->multimesh_set_buffer(multimesh, particle_data);
#ifndef NO_THREADS
update_mutex->unlock();
diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp
index aa7a413548..e8760983e9 100644
--- a/scene/3d/cpu_particles.cpp
+++ b/scene/3d/cpu_particles.cpp
@@ -73,7 +73,7 @@ void CPUParticles::set_amount(int p_amount) {
}
particle_data.resize((12 + 4 + 1) * p_amount);
- VS::get_singleton()->multimesh_allocate(multimesh, p_amount, VS::MULTIMESH_TRANSFORM_3D, VS::MULTIMESH_COLOR_8BIT, VS::MULTIMESH_CUSTOM_DATA_FLOAT);
+ VS::get_singleton()->multimesh_allocate(multimesh, p_amount, VS::MULTIMESH_TRANSFORM_3D, true, true);
particle_order.resize(p_amount);
}
@@ -1144,7 +1144,7 @@ void CPUParticles::_update_render_thread() {
update_mutex->lock();
#endif
if (can_update) {
- VS::get_singleton()->multimesh_set_as_bulk_array(multimesh, particle_data);
+ VS::get_singleton()->multimesh_set_buffer(multimesh, particle_data);
can_update = false; //wait for next time
}
diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp
index 92b17d5056..52e50aa84e 100644
--- a/scene/3d/vehicle_body.cpp
+++ b/scene/3d/vehicle_body.cpp
@@ -364,9 +364,8 @@ VehicleWheel::VehicleWheel() {
steers = false;
engine_traction = false;
-
m_steering = real_t(0.);
- //m_engineForce = real_t(0.);
+ m_engineForce = real_t(0.);
m_rotation = real_t(0.);
m_deltaRotation = real_t(0.);
m_brake = real_t(0.);
diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp
index 1b6e328342..db8d7f0851 100644
--- a/scene/3d/voxel_light_baker.cpp
+++ b/scene/3d/voxel_light_baker.cpp
@@ -2339,7 +2339,7 @@ Ref<MultiMesh> VoxelLightBaker::create_debug_multimesh(DebugMode p_mode) {
mm.instance();
mm->set_transform_format(MultiMesh::TRANSFORM_3D);
- mm->set_color_format(MultiMesh::COLOR_8BIT);
+ mm->set_use_colors(true);
mm->set_instance_count(leaf_voxel_count);
Ref<ArrayMesh> mesh;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 976c66ad0c..19edf556fb 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -300,7 +300,7 @@ void Viewport::_notification(int p_what) {
//3D
PhysicsServer::get_singleton()->space_set_debug_contacts(find_world()->get_space(), get_tree()->get_collision_debug_contact_count());
contact_3d_debug_multimesh = VisualServer::get_singleton()->multimesh_create();
- VisualServer::get_singleton()->multimesh_allocate(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), VS::MULTIMESH_TRANSFORM_3D, VS::MULTIMESH_COLOR_8BIT);
+ VisualServer::get_singleton()->multimesh_allocate(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), VS::MULTIMESH_TRANSFORM_3D, true);
VisualServer::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, 0);
VisualServer::get_singleton()->multimesh_set_mesh(contact_3d_debug_multimesh, get_tree()->get_debug_contact_mesh()->get_rid());
contact_3d_debug_instance = VisualServer::get_singleton()->instance_create();
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 5e18e73b5b..4ee8962702 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -937,6 +937,20 @@ float Environment::get_fog_height_curve() const {
return fog_height_curve;
}
+#ifndef DISABLE_DEPRECATED
+bool Environment::_set(const StringName &p_name, const Variant &p_value) {
+ if (p_name == "background_sky") {
+ set_sky(p_value);
+ return true;
+ } else if (p_name == "background_sky_custom_fov") {
+ set_sky_custom_fov(p_value);
+ return true;
+ } else {
+ return false;
+ }
+}
+#endif
+
void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_background", "mode"), &Environment::set_background);
diff --git a/scene/resources/environment.h b/scene/resources/environment.h
index 30f96e97fd..69f18c3424 100644
--- a/scene/resources/environment.h
+++ b/scene/resources/environment.h
@@ -194,6 +194,9 @@ private:
protected:
static void _bind_methods();
virtual void _validate_property(PropertyInfo &property) const;
+#ifndef DISABLE_DEPRECATED
+ bool _set(const StringName &p_name, const Variant &p_value);
+#endif
public:
void set_background(BGMode p_bg);
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 96c609174f..e102d944e8 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -590,6 +590,89 @@ Vector<Ref<Shape> > Mesh::convex_decompose() const {
Mesh::Mesh() {
}
+static PoolVector<uint8_t> _fix_array_compatibility(const PoolVector<uint8_t> &p_src, uint32_t p_format, uint32_t p_elements) {
+
+ bool vertex_16bit = p_format & ((1 << (Mesh::ARRAY_VERTEX + Mesh::ARRAY_COMPRESS_BASE)));
+ bool bone_32_bits = (p_format & Mesh::ARRAY_FORMAT_BONES) && !(p_format & (Mesh::ARRAY_COMPRESS_INDEX << 2));
+
+ print_line("convert vertex16: " + itos(vertex_16bit) + " bone 32 " + itos(bone_32_bits));
+ if (!vertex_16bit && !bone_32_bits) {
+ return p_src;
+ }
+
+ bool vertex_2d = (p_format & (Mesh::ARRAY_COMPRESS_INDEX << 1));
+
+ uint32_t src_stride = p_src.size() / p_elements;
+ uint32_t dst_stride = src_stride + (vertex_16bit ? 4 : 0) - (bone_32_bits ? 16 : 0);
+
+ PoolVector<uint8_t> ret;
+ ret.resize(dst_stride * p_elements);
+ {
+ PoolVector<uint8_t>::Write w = ret.write();
+ PoolVector<uint8_t>::Read r = p_src.read();
+
+ for (uint32_t i = 0; i < p_elements; i++) {
+
+ uint32_t remaining = src_stride;
+ const uint8_t *src = (const uint8_t *)(r.ptr() + src_stride * i);
+ uint8_t *dst = (uint8_t *)(w.ptr() + dst_stride * i);
+
+ if (!vertex_2d) { //3D
+ if (vertex_16bit) {
+ float *dstw = (float *)dst;
+ const uint16_t *srcr = (const uint16_t *)src;
+ dstw[0] = Math::half_to_float(srcr[0]);
+ dstw[1] = Math::half_to_float(srcr[1]);
+ dstw[2] = Math::half_to_float(srcr[2]);
+ remaining -= 8;
+ src += 8;
+ } else {
+ src += 12;
+ remaining -= 12;
+ }
+ dst += 12;
+ } else {
+ if (vertex_16bit) {
+ float *dstw = (float *)dst;
+ const uint16_t *srcr = (const uint16_t *)src;
+ dstw[0] = Math::half_to_float(srcr[0]);
+ dstw[1] = Math::half_to_float(srcr[1]);
+ remaining -= 4;
+ src += 4;
+ } else {
+ src += 8;
+ remaining -= 8;
+ }
+ dst += 8;
+ }
+
+ if (bone_32_bits) {
+
+ const uint32_t *src_bones = (const uint32_t *)&src[remaining - 32];
+ const float *src_weights = (const float *)&src[remaining - 16];
+ uint16_t *dstw = (uint16_t *)&dst[remaining - 32];
+
+ dstw[0] = src_bones[0];
+ dstw[1] = src_bones[1];
+ dstw[2] = src_bones[2];
+ dstw[3] = src_bones[3];
+ dstw[4] = CLAMP(src_weights[0] * 65535, 0, 65535); //16bits unorm
+ dstw[5] = CLAMP(src_weights[1] * 65535, 0, 65535);
+ dstw[6] = CLAMP(src_weights[2] * 65535, 0, 65535);
+ dstw[7] = CLAMP(src_weights[3] * 65535, 0, 65535);
+
+ remaining -= 32;
+ }
+
+ for (uint32_t j = 0; j < remaining; j++) {
+ dst[j] = src[j];
+ }
+ }
+ }
+
+ return ret;
+}
+
bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
String sname = p_name;
@@ -624,11 +707,11 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
return true;
}
-#ifdef ENABLE_DEPRECATED
+#ifndef DISABLE_DEPRECATED
if (!sname.begins_with("surfaces"))
return false;
- WARN_DEPRECATED("Mesh uses old surface format, which is deprecated (and loads slower). Consider re-importing or re-saving the scene.");
+ WARN_DEPRECATED_MSG("Mesh uses old surface format, which is deprecated (and loads slower). Consider re-importing or re-saving the scene.");
int idx = sname.get_slicec('/', 1).to_int();
String what = sname.get_slicec('/', 2);
@@ -640,12 +723,13 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_COND_V(!d.has("primitive"), false);
if (d.has("arrays")) {
- //old format
+ //oldest format (2.x)
ERR_FAIL_COND_V(!d.has("morph_arrays"), false);
add_surface_from_arrays(PrimitiveType(int(d["primitive"])), d["arrays"], d["morph_arrays"]);
} else if (d.has("array_data")) {
-
+ print_line("array data (old style");
+ //older format (3.x)
PoolVector<uint8_t> array_data = d["array_data"];
PoolVector<uint8_t> array_index_data;
if (d.has("array_index_data"))
@@ -655,16 +739,24 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
uint32_t format = d["format"];
uint32_t primitive = d["primitive"];
- if (primitive > PRIMITIVE_LINE_STRIP) {
- primitive--; //line loop was deprecated, so it's not supported and indices go down by one
- }
- if (primitive > PRIMITIVE_TRIANGLE_STRIP) {
- primitive = PRIMITIVE_TRIANGLE_STRIP; //fan is no longer supported
- }
+
+ uint32_t primitive_remap[7] = {
+ PRIMITIVE_POINTS,
+ PRIMITIVE_LINES,
+ PRIMITIVE_LINE_STRIP,
+ PRIMITIVE_LINES,
+ PRIMITIVE_TRIANGLES,
+ PRIMITIVE_TRIANGLE_STRIP,
+ PRIMITIVE_TRIANGLE_STRIP
+ };
+
+ primitive = primitive_remap[primitive]; //compatibility
ERR_FAIL_COND_V(!d.has("vertex_count"), false);
int vertex_count = d["vertex_count"];
+ array_data = _fix_array_compatibility(array_data, format, vertex_count);
+
int index_count = 0;
if (d.has("index_count"))
index_count = d["index_count"];
@@ -675,10 +767,15 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
Array blend_shape_data = d["blend_shape_data"];
for (int i = 0; i < blend_shape_data.size(); i++) {
PoolVector<uint8_t> shape = blend_shape_data[i];
+ shape = _fix_array_compatibility(shape, format, vertex_count);
+
blend_shapes.push_back(shape);
}
}
+ //clear unused flags
+ format &= ~((1 << (ARRAY_VERTEX + ARRAY_COMPRESS_BASE)) | (ARRAY_COMPRESS_INDEX << 2));
+
ERR_FAIL_COND_V(!d.has("aabb"), false);
AABB aabb = d["aabb"];
diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp
index ee831f36f5..946511c766 100644
--- a/scene/resources/multimesh.cpp
+++ b/scene/resources/multimesh.cpp
@@ -31,6 +31,8 @@
#include "multimesh.h"
#include "servers/visual_server.h"
+#ifndef DISABLE_DEPRECATED
+
void MultiMesh::_set_transform_array(const PoolVector<Vector3> &p_array) {
if (transform_format != TRANSFORM_3D)
return;
@@ -146,7 +148,7 @@ void MultiMesh::_set_color_array(const PoolVector<Color> &p_array) {
PoolVector<Color> MultiMesh::_get_color_array() const {
- if (instance_count == 0 || color_format == COLOR_NONE)
+ if (instance_count == 0 || !use_colors)
return PoolVector<Color>();
PoolVector<Color> colors;
@@ -178,7 +180,7 @@ void MultiMesh::_set_custom_data_array(const PoolVector<Color> &p_array) {
PoolVector<Color> MultiMesh::_get_custom_data_array() const {
- if (instance_count == 0 || custom_data_format == CUSTOM_DATA_NONE)
+ if (instance_count == 0 || !use_custom_data)
return PoolVector<Color>();
PoolVector<Color> custom_datas;
@@ -191,6 +193,16 @@ PoolVector<Color> MultiMesh::_get_custom_data_array() const {
return custom_datas;
}
+
+#endif
+void MultiMesh::set_buffer(const PoolVector<float> &p_buffer) {
+ VS::get_singleton()->multimesh_set_buffer(multimesh, p_buffer);
+}
+
+PoolVector<float> MultiMesh::get_buffer() const {
+ return VS::get_singleton()->multimesh_get_buffer(multimesh);
+}
+
void MultiMesh::set_mesh(const Ref<Mesh> &p_mesh) {
mesh = p_mesh;
@@ -207,7 +219,7 @@ Ref<Mesh> MultiMesh::get_mesh() const {
void MultiMesh::set_instance_count(int p_count) {
ERR_FAIL_COND(p_count < 0);
- VisualServer::get_singleton()->multimesh_allocate(multimesh, p_count, VS::MultimeshTransformFormat(transform_format), VS::MultimeshColorFormat(color_format), VS::MultimeshCustomDataFormat(custom_data_format));
+ VisualServer::get_singleton()->multimesh_allocate(multimesh, p_count, VS::MultimeshTransformFormat(transform_format), use_colors, use_custom_data);
instance_count = p_count;
}
int MultiMesh::get_instance_count() const {
@@ -217,6 +229,7 @@ int MultiMesh::get_instance_count() const {
void MultiMesh::set_visible_instance_count(int p_count) {
ERR_FAIL_COND(p_count < -1);
+ ERR_FAIL_COND(p_count > instance_count);
VisualServer::get_singleton()->multimesh_set_visible_instances(multimesh, p_count);
visible_instance_count = p_count;
}
@@ -263,11 +276,6 @@ Color MultiMesh::get_instance_custom_data(int p_instance) const {
return VisualServer::get_singleton()->multimesh_instance_get_custom_data(multimesh, p_instance);
}
-void MultiMesh::set_as_bulk_array(const PoolVector<float> &p_array) {
-
- VisualServer::get_singleton()->multimesh_set_as_bulk_array(multimesh, p_array);
-}
-
AABB MultiMesh::get_aabb() const {
return VisualServer::get_singleton()->multimesh_get_aabb(multimesh);
@@ -278,26 +286,22 @@ RID MultiMesh::get_rid() const {
return multimesh;
}
-void MultiMesh::set_color_format(ColorFormat p_color_format) {
-
+void MultiMesh::set_use_colors(bool p_enable) {
ERR_FAIL_COND(instance_count > 0);
- color_format = p_color_format;
+ use_colors = p_enable;
}
-MultiMesh::ColorFormat MultiMesh::get_color_format() const {
-
- return color_format;
+bool MultiMesh::is_using_colors() const {
+ return use_colors;
}
-void MultiMesh::set_custom_data_format(CustomDataFormat p_custom_data_format) {
-
+void MultiMesh::set_use_custom_data(bool p_enable) {
ERR_FAIL_COND(instance_count > 0);
- custom_data_format = p_custom_data_format;
+ use_custom_data = p_enable;
}
-MultiMesh::CustomDataFormat MultiMesh::get_custom_data_format() const {
-
- return custom_data_format;
+bool MultiMesh::is_using_custom_data() const {
+ return use_custom_data;
}
void MultiMesh::set_transform_format(TransformFormat p_transform_format) {
@@ -314,10 +318,10 @@ void MultiMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &MultiMesh::set_mesh);
ClassDB::bind_method(D_METHOD("get_mesh"), &MultiMesh::get_mesh);
- ClassDB::bind_method(D_METHOD("set_color_format", "format"), &MultiMesh::set_color_format);
- ClassDB::bind_method(D_METHOD("get_color_format"), &MultiMesh::get_color_format);
- ClassDB::bind_method(D_METHOD("set_custom_data_format", "format"), &MultiMesh::set_custom_data_format);
- ClassDB::bind_method(D_METHOD("get_custom_data_format"), &MultiMesh::get_custom_data_format);
+ ClassDB::bind_method(D_METHOD("set_use_colors", "enable"), &MultiMesh::set_use_colors);
+ ClassDB::bind_method(D_METHOD("is_using_colors"), &MultiMesh::is_using_colors);
+ ClassDB::bind_method(D_METHOD("set_use_custom_data", "enable"), &MultiMesh::set_use_custom_data);
+ ClassDB::bind_method(D_METHOD("is_using_custom_data"), &MultiMesh::is_using_custom_data);
ClassDB::bind_method(D_METHOD("set_transform_format", "format"), &MultiMesh::set_transform_format);
ClassDB::bind_method(D_METHOD("get_transform_format"), &MultiMesh::get_transform_format);
@@ -333,9 +337,22 @@ void MultiMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_instance_color", "instance"), &MultiMesh::get_instance_color);
ClassDB::bind_method(D_METHOD("set_instance_custom_data", "instance", "custom_data"), &MultiMesh::set_instance_custom_data);
ClassDB::bind_method(D_METHOD("get_instance_custom_data", "instance"), &MultiMesh::get_instance_custom_data);
- ClassDB::bind_method(D_METHOD("set_as_bulk_array", "array"), &MultiMesh::set_as_bulk_array);
ClassDB::bind_method(D_METHOD("get_aabb"), &MultiMesh::get_aabb);
+ ClassDB::bind_method(D_METHOD("get_buffer"), &MultiMesh::get_buffer);
+ ClassDB::bind_method(D_METHOD("set_buffer", "buffer"), &MultiMesh::set_buffer);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "transform_format", PROPERTY_HINT_ENUM, "2D,3D"), "set_transform_format", "get_transform_format");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_colors"), "set_use_colors", "is_using_colors");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_custom_data"), "set_use_custom_data", "is_using_custom_data");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "instance_count", PROPERTY_HINT_RANGE, "0,16384,1,or_greater"), "set_instance_count", "get_instance_count");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_instance_count", PROPERTY_HINT_RANGE, "-1,16384,1,or_greater"), "set_visible_instance_count", "get_visible_instance_count");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_REAL_ARRAY, "buffer", PROPERTY_HINT_NONE), "set_buffer", "get_buffer");
+
+#ifndef DISABLE_DEPRECATED
+ //kept for compatibility
+
ClassDB::bind_method(D_METHOD("_set_transform_array"), &MultiMesh::_set_transform_array);
ClassDB::bind_method(D_METHOD("_get_transform_array"), &MultiMesh::_get_transform_array);
ClassDB::bind_method(D_METHOD("_set_transform_2d_array"), &MultiMesh::_set_transform_2d_array);
@@ -345,34 +362,20 @@ void MultiMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_custom_data_array"), &MultiMesh::_set_custom_data_array);
ClassDB::bind_method(D_METHOD("_get_custom_data_array"), &MultiMesh::_get_custom_data_array);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "color_format", PROPERTY_HINT_ENUM, "None,Byte,Float"), "set_color_format", "get_color_format");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "transform_format", PROPERTY_HINT_ENUM, "2D,3D"), "set_transform_format", "get_transform_format");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "custom_data_format", PROPERTY_HINT_ENUM, "None,Byte,Float"), "set_custom_data_format", "get_custom_data_format");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "instance_count", PROPERTY_HINT_RANGE, "0,16384,1,or_greater"), "set_instance_count", "get_instance_count");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_instance_count", PROPERTY_HINT_RANGE, "-1,16384,1,or_greater"), "set_visible_instance_count", "get_visible_instance_count");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "transform_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_transform_array", "_get_transform_array");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "transform_2d_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_transform_2d_array", "_get_transform_2d_array");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "color_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_color_array", "_get_color_array");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "custom_data_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_custom_data_array", "_get_custom_data_array");
-
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "transform_array", PROPERTY_HINT_NONE, "", 0), "_set_transform_array", "_get_transform_array");
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "transform_2d_array", PROPERTY_HINT_NONE, "", 0), "_set_transform_2d_array", "_get_transform_2d_array");
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "color_array", PROPERTY_HINT_NONE, "", 0), "_set_color_array", "_get_color_array");
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "custom_data_array", PROPERTY_HINT_NONE, "", 0), "_set_custom_data_array", "_get_custom_data_array");
+#endif
BIND_ENUM_CONSTANT(TRANSFORM_2D);
BIND_ENUM_CONSTANT(TRANSFORM_3D);
-
- BIND_ENUM_CONSTANT(COLOR_NONE);
- BIND_ENUM_CONSTANT(COLOR_8BIT);
- BIND_ENUM_CONSTANT(COLOR_FLOAT);
-
- BIND_ENUM_CONSTANT(CUSTOM_DATA_NONE);
- BIND_ENUM_CONSTANT(CUSTOM_DATA_8BIT);
- BIND_ENUM_CONSTANT(CUSTOM_DATA_FLOAT);
}
MultiMesh::MultiMesh() {
multimesh = VisualServer::get_singleton()->multimesh_create();
- color_format = COLOR_NONE;
- custom_data_format = CUSTOM_DATA_NONE;
+ use_colors = false;
+ use_custom_data = false;
transform_format = TRANSFORM_2D;
visible_instance_count = -1;
instance_count = 0;
diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h
index 9394737799..e7d62d0993 100644
--- a/scene/resources/multimesh.h
+++ b/scene/resources/multimesh.h
@@ -45,30 +45,20 @@ public:
TRANSFORM_3D = VS::MULTIMESH_TRANSFORM_3D
};
- enum ColorFormat {
- COLOR_NONE = VS::MULTIMESH_COLOR_NONE,
- COLOR_8BIT = VS::MULTIMESH_COLOR_8BIT,
- COLOR_FLOAT = VS::MULTIMESH_COLOR_FLOAT,
- };
-
- enum CustomDataFormat {
- CUSTOM_DATA_NONE,
- CUSTOM_DATA_8BIT,
- CUSTOM_DATA_FLOAT,
- };
-
private:
Ref<Mesh> mesh;
RID multimesh;
TransformFormat transform_format;
- ColorFormat color_format;
- CustomDataFormat custom_data_format;
+ bool use_colors;
+ bool use_custom_data;
int instance_count;
int visible_instance_count;
protected:
static void _bind_methods();
+#ifndef DISABLE_DEPRECATED
+
void _set_transform_array(const PoolVector<Vector3> &p_array);
PoolVector<Vector3> _get_transform_array() const;
@@ -80,16 +70,19 @@ protected:
void _set_custom_data_array(const PoolVector<Color> &p_array);
PoolVector<Color> _get_custom_data_array() const;
+#endif
+ void set_buffer(const PoolVector<float> &p_buffer);
+ PoolVector<float> get_buffer() const;
public:
void set_mesh(const Ref<Mesh> &p_mesh);
Ref<Mesh> get_mesh() const;
- void set_color_format(ColorFormat p_color_format);
- ColorFormat get_color_format() const;
+ void set_use_colors(bool p_enable);
+ bool is_using_colors() const;
- void set_custom_data_format(CustomDataFormat p_custom_data_format);
- CustomDataFormat get_custom_data_format() const;
+ void set_use_custom_data(bool p_enable);
+ bool is_using_custom_data() const;
void set_transform_format(TransformFormat p_transform_format);
TransformFormat get_transform_format() const;
@@ -111,8 +104,6 @@ public:
void set_instance_custom_data(int p_instance, const Color &p_custom_data);
Color get_instance_custom_data(int p_instance) const;
- void set_as_bulk_array(const PoolVector<float> &p_array);
-
virtual AABB get_aabb() const;
virtual RID get_rid() const;
@@ -122,7 +113,5 @@ public:
};
VARIANT_ENUM_CAST(MultiMesh::TransformFormat);
-VARIANT_ENUM_CAST(MultiMesh::ColorFormat);
-VARIANT_ENUM_CAST(MultiMesh::CustomDataFormat);
#endif // MULTI_MESH_H
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 7085171043..c0311aca3a 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -394,7 +394,7 @@ Image::Format StreamTexture::get_format() const {
return format;
}
-Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, int p_size_limit) {
+Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int p_size_limit) {
alpha_cache.unref();
@@ -420,29 +420,16 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_
#ifdef TOOLS_ENABLED
- if (request_3d_callback && df & FORMAT_BIT_DETECT_3D) {
- //print_line("request detect 3D at " + p_path);
- VS::get_singleton()->texture_set_detect_3d_callback(texture, _requested_3d, this);
- } else {
- //print_line("not requesting detect 3D at " + p_path);
- VS::get_singleton()->texture_set_detect_3d_callback(texture, NULL, NULL);
- }
+ r_request_3d = request_3d_callback && df & FORMAT_BIT_DETECT_3D;
+ r_request_roughness = request_roughness_callback && df & FORMAT_BIT_DETECT_ROUGNESS;
+ r_request_normal = request_normal_callback && df & FORMAT_BIT_DETECT_NORMAL;
- if (request_roughness_callback && df & FORMAT_BIT_DETECT_ROUGNESS) {
- //print_line("request detect srgb at " + p_path);
- VS::get_singleton()->texture_set_detect_roughness_callback(texture, _requested_roughness, this);
- } else {
- //print_line("not requesting detect srgb at " + p_path);
- VS::get_singleton()->texture_set_detect_roughness_callback(texture, NULL, NULL);
- }
+#else
+
+ r_request_3d = false;
+ r_request_roughness = false;
+ r_request_normal = false;
- if (request_normal_callback && df & FORMAT_BIT_DETECT_NORMAL) {
- //print_line("request detect srgb at " + p_path);
- VS::get_singleton()->texture_set_detect_normal_callback(texture, _requested_normal, this);
- } else {
- //print_line("not requesting detect normal at " + p_path);
- VS::get_singleton()->texture_set_detect_normal_callback(texture, NULL, NULL);
- }
#endif
if (!(df & FORMAT_BIT_STREAM)) {
p_size_limit = 0;
@@ -607,7 +594,7 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_
}
}
- return ERR_BUG; //unreachable
+ ERR_FAIL_V(ERR_BUG); //unreachable
}
Error StreamTexture::load(const String &p_path) {
@@ -615,14 +602,15 @@ Error StreamTexture::load(const String &p_path) {
int lw, lh, lwc, lhc;
Ref<Image> image;
image.instance();
- Error err = _load_data(p_path, lw, lh, lwc, lhc, image);
+
+ bool request_3d;
+ bool request_normal;
+ bool request_roughness;
+
+ Error err = _load_data(p_path, lw, lh, lwc, lhc, image, request_3d, request_normal, request_roughness);
if (err)
return err;
- if (get_path() == String()) {
- //temporarily set path if no path set for resource, helps find errors
- VisualServer::get_singleton()->texture_set_path(texture, p_path);
- }
if (texture.is_valid()) {
RID new_texture = VS::get_singleton()->texture_2d_create(image);
VS::get_singleton()->texture_replace(texture, new_texture);
@@ -638,6 +626,38 @@ Error StreamTexture::load(const String &p_path) {
path_to_file = p_path;
format = image->get_format();
+ if (get_path() == String()) {
+ //temporarily set path if no path set for resource, helps find errors
+ VisualServer::get_singleton()->texture_set_path(texture, p_path);
+ }
+
+#ifdef TOOLS_ENABLED
+
+ if (request_3d) {
+ //print_line("request detect 3D at " + p_path);
+ VS::get_singleton()->texture_set_detect_3d_callback(texture, _requested_3d, this);
+ } else {
+ //print_line("not requesting detect 3D at " + p_path);
+ VS::get_singleton()->texture_set_detect_3d_callback(texture, NULL, NULL);
+ }
+
+ if (request_roughness) {
+ //print_line("request detect srgb at " + p_path);
+ VS::get_singleton()->texture_set_detect_roughness_callback(texture, _requested_roughness, this);
+ } else {
+ //print_line("not requesting detect srgb at " + p_path);
+ VS::get_singleton()->texture_set_detect_roughness_callback(texture, NULL, NULL);
+ }
+
+ if (request_normal) {
+ //print_line("request detect srgb at " + p_path);
+ VS::get_singleton()->texture_set_detect_normal_callback(texture, _requested_normal, this);
+ } else {
+ //print_line("not requesting detect normal at " + p_path);
+ VS::get_singleton()->texture_set_detect_normal_callback(texture, NULL, NULL);
+ }
+
+#endif
_change_notify();
emit_changed();
return OK;
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index c18368fb85..173556da72 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -155,7 +155,7 @@ public:
};
private:
- Error _load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, int p_size_limit = 0);
+ Error _load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int p_size_limit = 0);
String path_to_file;
mutable RID texture;
Image::Format format;
@@ -390,6 +390,7 @@ public:
class Cubemap : public TextureLayered {
GDCLASS(Cubemap, TextureLayered);
+
public:
Cubemap() :
TextureLayered(VS::TEXTURE_LAYERED_CUBEMAP) {}
@@ -398,6 +399,7 @@ public:
class CubemapArray : public TextureLayered {
GDCLASS(CubemapArray, TextureLayered);
+
public:
CubemapArray() :
TextureLayered(VS::TEXTURE_LAYERED_CUBEMAP_ARRAY) {}
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index fe682618a4..f5ce604b04 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -358,7 +358,8 @@ public:
virtual RID multimesh_create() = 0;
- virtual void multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format, VS::MultimeshCustomDataFormat p_data = VS::MULTIMESH_CUSTOM_DATA_NONE) = 0;
+ virtual void multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0;
+
virtual int multimesh_get_instance_count(RID p_multimesh) const = 0;
virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh) = 0;
@@ -374,7 +375,8 @@ public:
virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const = 0;
virtual Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const = 0;
- virtual void multimesh_set_as_bulk_array(RID p_multimesh, const PoolVector<float> &p_array) = 0;
+ virtual void multimesh_set_buffer(RID p_multimesh, const PoolVector<float> &p_buffer) = 0;
+ virtual PoolVector<float> multimesh_get_buffer(RID p_multimesh) const = 0;
virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible) = 0;
virtual int multimesh_get_visible_instances(RID p_multimesh) const = 0;
diff --git a/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp
index 1dc0503027..1a94f11334 100644
--- a/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_canvas_rd.cpp
@@ -2107,7 +2107,7 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V
if (p_textures_dirty && tex_uniform_count) {
- update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw());
+ update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), false);
}
if (shader_data->ubo_size == 0 && !shader_data->uses_material_samplers) {
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp
index be5b8f1845..bf4d7e4fc8 100644
--- a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.cpp
@@ -465,7 +465,7 @@ void RasterizerSceneForwardRD::MaterialData::update_parameters(const Map<StringN
if (p_textures_dirty && tex_uniform_count) {
- update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw());
+ update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
}
if (shader_data->ubo_size == 0 && shader_data->texture_uniforms.size() == 0) {
@@ -607,6 +607,26 @@ void RasterizerSceneForwardRD::_fill_instances(RenderList::Element **p_elements,
id.flags = 0;
id.mask = e->instance->layer_mask;
+ if (e->instance->base_type == VS::INSTANCE_MULTIMESH) {
+ id.flags |= INSTANCE_DATA_FLAG_MULTIMESH;
+ uint32_t stride;
+ if (storage->multimesh_get_transform_format(e->instance->base) == VS::MULTIMESH_TRANSFORM_2D) {
+ id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D;
+ stride = 2;
+ } else {
+ stride = 3;
+ }
+ if (storage->multimesh_uses_colors(e->instance->base)) {
+ id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR;
+ stride += 1;
+ }
+ if (storage->multimesh_uses_custom_data(e->instance->base)) {
+ id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA;
+ stride += 1;
+ }
+
+ id.flags |= (stride << INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT);
+ }
//forward
uint32_t reflection_count = 0;
@@ -632,7 +652,7 @@ void RasterizerSceneForwardRD::_fill_instances(RenderList::Element **p_elements,
}
if (reflection_count < 8) {
- id.omni_light_indices[omni_count] = reflection_probe_instance_get_render_index(rpi_ptrs[j]);
+ id.reflection_probe_indices[reflection_count] = reflection_probe_instance_get_render_index(rpi_ptrs[j]);
reflection_count++;
}
}
@@ -661,7 +681,7 @@ void RasterizerSceneForwardRD::_fill_instances(RenderList::Element **p_elements,
}
} else {
if (spot_count < 8) {
- id.omni_light_indices[spot_count] = light_instance_get_index(light_ptrs[j]);
+ id.spot_light_indices[spot_count] = light_instance_get_index(light_ptrs[j]);
spot_count++;
}
}
@@ -686,6 +706,7 @@ void RasterizerSceneForwardRD::_render_list(RenderingDevice::DrawListID p_draw_l
//global scope bindings
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, render_base_uniform_set, 0);
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, default_vec4_xform_uniform_set, 1);
MaterialData *prev_material = nullptr;
// ShaderData *prev_shader = nullptr;
@@ -693,6 +714,7 @@ void RasterizerSceneForwardRD::_render_list(RenderingDevice::DrawListID p_draw_l
RID prev_vertex_array_rd;
RID prev_index_array_rd;
RID prev_pipeline_rd;
+ RID prev_xforms_uniform_set;
PushConstant push_constant;
zeromem(&push_constant, sizeof(PushConstant));
@@ -703,6 +725,7 @@ void RasterizerSceneForwardRD::_render_list(RenderingDevice::DrawListID p_draw_l
MaterialData *material = e->material;
ShaderData *shader = material->shader_data;
+ RID xforms_uniform_set;
//find cull variant
ShaderData::CullVariant cull_variant;
@@ -725,7 +748,12 @@ void RasterizerSceneForwardRD::_render_list(RenderingDevice::DrawListID p_draw_l
primitive = storage->mesh_surface_get_primitive(e->instance->base, e->surface_index);
} break;
case VS::INSTANCE_MULTIMESH: {
- ERR_CONTINUE(true); //should be a bug
+ RID mesh = storage->multimesh_get_mesh(e->instance->base);
+ ERR_CONTINUE(!mesh.is_valid()); //should be a bug
+ primitive = storage->mesh_surface_get_primitive(mesh, e->surface_index);
+
+ xforms_uniform_set = storage->multimesh_get_3d_uniform_set(e->instance->base, default_shader_rd, 1);
+
} break;
case VS::INSTANCE_IMMEDIATE: {
ERR_CONTINUE(true); //should be a bug
@@ -790,7 +818,9 @@ void RasterizerSceneForwardRD::_render_list(RenderingDevice::DrawListID p_draw_l
storage->mesh_surface_get_arrays_and_format(e->instance->base, e->surface_index, pipeline->get_vertex_input_mask(), vertex_array_rd, index_array_rd, vertex_format);
} break;
case VS::INSTANCE_MULTIMESH: {
- ERR_CONTINUE(true); //should be a bug
+ RID mesh = storage->multimesh_get_mesh(e->instance->base);
+ ERR_CONTINUE(!mesh.is_valid()); //should be a bug
+ storage->mesh_surface_get_arrays_and_format(mesh, e->surface_index, pipeline->get_vertex_input_mask(), vertex_array_rd, index_array_rd, vertex_format);
} break;
case VS::INSTANCE_IMMEDIATE: {
ERR_CONTINUE(true); //should be a bug
@@ -824,6 +854,11 @@ void RasterizerSceneForwardRD::_render_list(RenderingDevice::DrawListID p_draw_l
prev_pipeline_rd = pipeline_rd;
}
+ if (xforms_uniform_set.is_valid() && prev_xforms_uniform_set != xforms_uniform_set) {
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, material->uniform_set, 1);
+ prev_xforms_uniform_set = xforms_uniform_set;
+ }
+
if (material != prev_material) {
//update uniform set
if (material->uniform_set.is_valid()) {
@@ -841,7 +876,8 @@ void RasterizerSceneForwardRD::_render_list(RenderingDevice::DrawListID p_draw_l
RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid());
} break;
case VS::INSTANCE_MULTIMESH: {
-
+ uint32_t instances = storage->multimesh_get_instances_to_draw(e->instance->base);
+ RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instances);
} break;
case VS::INSTANCE_IMMEDIATE: {
@@ -1223,28 +1259,35 @@ void RasterizerSceneForwardRD::_fill_render_list(InstanceBase **p_cull_result, i
//mesh->last_pass=frame;
} break;
-#if 0
+
case VS::INSTANCE_MULTIMESH: {
- RasterizerStorageGLES3::MultiMesh *multi_mesh = storage->multimesh_owner.getornull(inst->base);
- ERR_CONTINUE(!multi_mesh);
+ if (storage->multimesh_get_instances_to_draw(inst->base) == 0) {
+ //not visible, 0 instances
+ continue;
+ }
- if (multi_mesh->size == 0 || multi_mesh->visible_instances == 0)
+ RID mesh = storage->multimesh_get_mesh(inst->base);
+ if (!mesh.is_valid()) {
continue;
+ }
- RasterizerStorageGLES3::Mesh *mesh = storage->mesh_owner.getornull(multi_mesh->mesh);
- if (!mesh)
- continue; //mesh not assigned
+ const RID *materials = NULL;
+ uint32_t surface_count;
- int ssize = mesh->surfaces.size();
+ materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count);
+ if (!materials) {
+ continue; //nothing to do
+ }
- for (int j = 0; j < ssize; j++) {
+ for (uint32_t j = 0; j < surface_count; j++) {
- RasterizerStorageGLES3::Surface *s = mesh->surfaces[j];
- _add_geometry(s, inst, multi_mesh, -1, p_depth_pass, p_shadow_pass);
+ uint32_t surface_index = storage->mesh_surface_get_multimesh_render_pass_index(inst->base, j, render_pass, &geometry_index);
+ _add_geometry(inst, j, materials[j], p_pass_mode, surface_index);
}
} break;
+#if 0
case VS::INSTANCE_IMMEDIATE: {
RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getornull(inst->base);
@@ -2589,7 +2632,7 @@ RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storag
actions.renames["POINT_COORD"] = "gl_PointCoord";
actions.renames["INSTANCE_CUSTOM"] = "instance_custom";
actions.renames["SCREEN_UV"] = "screen_uv";
- actions.renames["SCREEN_TEXTURE"] = "screen_texture";
+ actions.renames["SCREEN_TEXTURE"] = "color_buffer";
actions.renames["DEPTH_TEXTURE"] = "depth_buffer";
actions.renames["NORMAL_TEXTURE"] = "normal_buffer";
actions.renames["DEPTH"] = "gl_FragDepth";
@@ -2698,6 +2741,17 @@ RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storag
}
{
+ default_vec4_xform_buffer = RD::get_singleton()->storage_buffer_create(256);
+ Vector<RD::Uniform> uniforms;
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.ids.push_back(default_vec4_xform_buffer);
+ u.binding = 0;
+ uniforms.push_back(u);
+
+ default_vec4_xform_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, 1);
+ }
+ {
RD::SamplerState sampler;
sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR;
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h
index c8166c3f88..912d62b1d8 100644
--- a/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h
@@ -247,6 +247,15 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
float shadow_matrices[4][16];
};
+ enum {
+ INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12,
+ INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13,
+ INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14,
+ INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA = 1 << 15,
+ INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT = 16,
+ INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_MASK = 0x7,
+ };
+
struct InstanceData {
float transform[16];
float normal_transform[16];
@@ -471,6 +480,9 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
RID default_material;
RID default_shader_rd;
+ RID default_vec4_xform_buffer;
+ RID default_vec4_xform_uniform_set;
+
enum PassMode {
PASS_MODE_COLOR,
PASS_MODE_COLOR_SPECULAR,
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
index 63b65a8a15..7bb615eda9 100644
--- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
@@ -428,6 +428,7 @@ VS::EnvironmentReflectionSource RasterizerSceneRD::environment_get_reflection_so
void RasterizerSceneRD::environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
+ env->exposure = p_exposure;
env->tone_mapper = p_tone_mapper;
env->auto_exposure = p_auto_exposure;
env->white = p_white;
@@ -1414,7 +1415,7 @@ bool RasterizerSceneRD::free(RID p_rid) {
reflection_atlas_owner.free(p_rid);
} else if (reflection_probe_instance_owner.owns(p_rid)) {
//not much to delete, just free it
- ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_rid);
+ //ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_rid);
reflection_probe_release_atlas_index(p_rid);
reflection_probe_instance_owner.free(p_rid);
} else if (sky_owner.owns(p_rid)) {
diff --git a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp
index e80f5f54b9..7cf93a82e0 100644
--- a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp
@@ -199,7 +199,7 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima
case Image::FORMAT_DXT1: {
if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
r_format.format = RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK;
- r_format.format_srgb = RD::DATA_FORMAT_BC1_RGBA_SRGB_BLOCK;
+ r_format.format_srgb = RD::DATA_FORMAT_BC1_RGB_SRGB_BLOCK;
} else {
//not supported, reconvert
r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
@@ -788,16 +788,31 @@ void RasterizerStorageRD::texture_set_size_override(RID p_texture, int p_width,
}
void RasterizerStorageRD::texture_set_path(RID p_texture, const String &p_path) {
+ Texture *tex = texture_owner.getornull(p_texture);
+ ERR_FAIL_COND(!tex);
+ tex->path = p_path;
}
String RasterizerStorageRD::texture_get_path(RID p_texture) const {
return String();
}
void RasterizerStorageRD::texture_set_detect_3d_callback(RID p_texture, VS::TextureDetectCallback p_callback, void *p_userdata) {
+ Texture *tex = texture_owner.getornull(p_texture);
+ ERR_FAIL_COND(!tex);
+ tex->detect_3d_callback_ud = p_userdata;
+ tex->detect_3d_callback = p_callback;
}
void RasterizerStorageRD::texture_set_detect_normal_callback(RID p_texture, VS::TextureDetectCallback p_callback, void *p_userdata) {
+ Texture *tex = texture_owner.getornull(p_texture);
+ ERR_FAIL_COND(!tex);
+ tex->detect_normal_callback_ud = p_userdata;
+ tex->detect_normal_callback = p_callback;
}
void RasterizerStorageRD::texture_set_detect_roughness_callback(RID p_texture, VS::TextureDetectRoughnessCallback p_callback, void *p_userdata) {
+ Texture *tex = texture_owner.getornull(p_texture);
+ ERR_FAIL_COND(!tex);
+ tex->detect_roughness_callback_ud = p_userdata;
+ tex->detect_roughness_callback = p_callback;
}
void RasterizerStorageRD::texture_debug_usage(List<VS::TextureInfo> *r_info) {
}
@@ -1611,9 +1626,14 @@ void RasterizerStorageRD::MaterialData::update_uniform_buffer(const Map<StringNa
}
}
-void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures) {
+void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) {
RasterizerStorageRD *singleton = (RasterizerStorageRD *)RasterizerStorage::base_singleton;
+#ifdef TOOLS_ENABLED
+ Texture *roughness_detect_texture = nullptr;
+ VS::TextureDetectRoughnessChannel roughness_channel;
+ Texture *normal_detect_texture = nullptr;
+#endif
for (int i = 0; i < p_texture_uniforms.size(); i++) {
@@ -1653,8 +1673,31 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va
} break;
}
} else {
- bool srgb = p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_ALBEDO || p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO;
- rd_texture = singleton->texture_get_rd_texture(texture, srgb);
+ bool srgb = p_use_linear_color && p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_ALBEDO || p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO;
+
+ Texture *tex = singleton->texture_owner.getornull(texture);
+
+ if (tex) {
+ rd_texture = (srgb && tex->rd_texture_srgb.is_valid()) ? tex->rd_texture_srgb : tex->rd_texture;
+#ifdef TOOLS_ENABLED
+ if (tex->detect_3d_callback && p_use_linear_color) {
+ tex->detect_3d_callback(tex->detect_3d_callback_ud);
+ }
+ if (tex->detect_normal_callback && (p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL || p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_ROUGHNESS_NORMAL)) {
+ if (p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_ROUGHNESS_NORMAL) {
+ normal_detect_texture = tex;
+ }
+ tex->detect_normal_callback(tex->detect_normal_callback_ud);
+ }
+ if (tex->detect_roughness_callback && (p_texture_uniforms[i].hint >= ShaderLanguage::ShaderNode::Uniform::HINT_ROUGHNESS_R || p_texture_uniforms[i].hint <= ShaderLanguage::ShaderNode::Uniform::HINT_ROUGHNESS_GRAY)) {
+ //find the normal texture
+ roughness_detect_texture = tex;
+ roughness_channel = VS::TextureDetectRoughnessChannel(p_texture_uniforms[i].hint - ShaderLanguage::ShaderNode::Uniform::HINT_ROUGHNESS_R);
+ }
+
+#endif
+ }
+
if (rd_texture.is_null()) {
//wtf
rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE);
@@ -1663,6 +1706,11 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va
p_textures[i] = rd_texture;
}
+#ifdef TOOLS_ENABLED
+ if (roughness_detect_texture && normal_detect_texture && normal_detect_texture->path != String()) {
+ roughness_detect_texture->detect_roughness_callback(roughness_detect_texture->detect_roughness_callback_ud, normal_detect_texture->path, roughness_channel);
+ }
+#endif
}
void RasterizerStorageRD::material_force_update_textures(RID p_material, ShaderType p_shader_type) {
@@ -2087,6 +2135,568 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
v.vertex_array = RD::get_singleton()->vertex_array_create(s->vertex_count, v.vertex_format, buffers);
}
+////////////////// MULTIMESH
+
+RID RasterizerStorageRD::multimesh_create() {
+
+ return multimesh_owner.make_rid(MultiMesh());
+}
+
+void RasterizerStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) {
+
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ ERR_FAIL_COND(!multimesh);
+
+ if (multimesh->instances == p_instances && multimesh->xform_format == p_transform_format && multimesh->uses_colors == p_use_colors && multimesh->uses_custom_data == p_use_custom_data) {
+ return;
+ }
+
+ if (multimesh->buffer.is_valid()) {
+ RD::get_singleton()->free(multimesh->buffer);
+ multimesh->buffer = RID();
+ multimesh->uniform_set_3d = RID(); //cleared by dependency
+ }
+
+ if (multimesh->data_cache_dirty_regions) {
+ memdelete_arr(multimesh->data_cache_dirty_regions);
+ multimesh->data_cache_dirty_regions = nullptr;
+ multimesh->data_cache_used_dirty_regions = 0;
+ }
+
+ multimesh->instances = p_instances;
+ multimesh->xform_format = p_transform_format;
+ multimesh->uses_colors = p_use_colors;
+ multimesh->color_offset_cache = p_transform_format == VS::MULTIMESH_TRANSFORM_2D ? 8 : 12;
+ multimesh->uses_custom_data = p_use_custom_data;
+ multimesh->custom_data_offset_cache = multimesh->color_offset_cache + (p_use_colors ? 4 : 0);
+ multimesh->stride_cache = multimesh->custom_data_offset_cache + (p_use_custom_data ? 4 : 0);
+ multimesh->buffer_set = false;
+
+ print_line("allocate, elements: " + itos(p_instances) + " 2D: " + itos(p_transform_format == VS::MULTIMESH_TRANSFORM_2D) + " colors " + itos(multimesh->uses_colors) + " data " + itos(multimesh->uses_custom_data) + " stride " + itos(multimesh->stride_cache) + " total size " + itos(multimesh->stride_cache * multimesh->instances));
+ multimesh->data_cache = PoolVector<float>();
+ multimesh->aabb = AABB();
+ multimesh->aabb_dirty = false;
+ multimesh->visible_instances = MIN(multimesh->visible_instances, multimesh->instances);
+
+ if (multimesh->instances) {
+
+ multimesh->buffer = RD::get_singleton()->storage_buffer_create(multimesh->instances * multimesh->stride_cache);
+ }
+}
+
+int RasterizerStorageRD::multimesh_get_instance_count(RID p_multimesh) const {
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ ERR_FAIL_COND_V(!multimesh, 0);
+ return multimesh->instances;
+}
+
+void RasterizerStorageRD::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ ERR_FAIL_COND(!multimesh);
+ if (multimesh->mesh == p_mesh) {
+ return;
+ }
+ multimesh->mesh = p_mesh;
+
+ if (multimesh->instances == 0) {
+ return;
+ }
+
+ if (multimesh->data_cache.size()) {
+ //we have a data cache, just mark it dirt
+ _multimesh_mark_all_dirty(multimesh, false, true);
+ } else if (multimesh->instances) {
+ //need to re-create AABB unfortunately, calling this has a penalty
+ {
+ PoolVector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(multimesh->buffer);
+ PoolVector<uint8_t>::Read r = buffer.read();
+ const float *data = (const float *)r.ptr();
+ _multimesh_re_create_aabb(multimesh, data, multimesh->instances);
+ }
+ }
+
+ multimesh->instance_dependency.instance_notify_changed(true, true);
+}
+
+#define MULTIMESH_DIRTY_REGION_SIZE 512
+
+void RasterizerStorageRD::_multimesh_make_local(MultiMesh *multimesh) const {
+ if (multimesh->data_cache.size() > 0) {
+ return; //already local
+ }
+ ERR_FAIL_COND(multimesh->data_cache.size() > 0);
+ // this means that the user wants to load/save individual elements,
+ // for this, the data must reside on CPU, so just copy it there.
+ multimesh->data_cache.resize(multimesh->instances * multimesh->stride_cache);
+ {
+ PoolVector<float>::Write w = multimesh->data_cache.write();
+
+ if (multimesh->buffer_set) {
+ PoolVector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(multimesh->buffer);
+ {
+
+ PoolVector<uint8_t>::Read r = buffer.read();
+ copymem(w.ptr(), r.ptr(), buffer.size());
+ }
+ } else {
+ zeromem(w.ptr(), multimesh->instances * multimesh->stride_cache * sizeof(float));
+ }
+ }
+ uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
+ multimesh->data_cache_dirty_regions = memnew_arr(bool, data_cache_dirty_region_count);
+ for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) {
+ multimesh->data_cache_dirty_regions[i] = 0;
+ }
+ multimesh->data_cache_used_dirty_regions = 0;
+}
+
+void RasterizerStorageRD::_multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb) {
+
+ uint32_t region_index = p_index / MULTIMESH_DIRTY_REGION_SIZE;
+#ifdef DEBUG_ENABLED
+ uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
+ ERR_FAIL_INDEX(region_index, data_cache_dirty_region_count); //bug
+#endif
+ if (!multimesh->data_cache_dirty_regions[region_index]) {
+ multimesh->data_cache_dirty_regions[p_index] = true;
+ multimesh->data_cache_used_dirty_regions++;
+ }
+
+ if (p_aabb) {
+ multimesh->aabb_dirty = true;
+ }
+
+ if (!multimesh->dirty) {
+ multimesh->dirty_list = multimesh_dirty_list;
+ multimesh_dirty_list = multimesh;
+ multimesh->dirty = true;
+ }
+}
+
+void RasterizerStorageRD::_multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, bool p_aabb) {
+ if (p_data) {
+ uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
+
+ for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) {
+ if (!multimesh->data_cache_dirty_regions[i]) {
+ multimesh->data_cache_dirty_regions[i] = true;
+ multimesh->data_cache_used_dirty_regions++;
+ }
+ }
+ }
+
+ if (p_aabb) {
+ multimesh->aabb_dirty = true;
+ }
+
+ if (!multimesh->dirty) {
+ multimesh->dirty_list = multimesh_dirty_list;
+ multimesh_dirty_list = multimesh;
+ multimesh->dirty = true;
+ }
+}
+
+void RasterizerStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances) {
+
+ ERR_FAIL_COND(multimesh->mesh.is_null());
+ AABB aabb;
+ AABB mesh_aabb = mesh_get_aabb(multimesh->mesh);
+ for (int i = 0; i < p_instances; i++) {
+ const float *data = p_data + multimesh->stride_cache * i;
+ Transform t;
+
+ if (multimesh->xform_format == VS::MULTIMESH_TRANSFORM_3D) {
+ t.basis[0].x = data[0];
+ t.basis[0].y = data[1];
+ t.basis[0].z = data[2];
+ t.basis[1].x = data[3];
+ t.basis[1].y = data[4];
+ t.basis[1].z = data[5];
+ t.basis[2].x = data[6];
+ t.basis[2].y = data[7];
+ t.basis[2].z = data[8];
+ t.origin.x = data[9];
+ t.origin.y = data[10];
+ t.origin.z = data[11];
+
+ } else {
+
+ t.basis.elements[0].x = data[0];
+ t.basis.elements[1].x = data[1];
+ t.origin.x = data[3];
+
+ t.basis.elements[0].y = data[4];
+ t.basis.elements[1].y = data[5];
+ t.origin.y = data[7];
+ }
+
+ if (i == 0) {
+ aabb = t.xform(mesh_aabb);
+ } else {
+ aabb.merge_with(t.xform(mesh_aabb));
+ }
+ }
+
+ multimesh->aabb = aabb;
+}
+
+void RasterizerStorageRD::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) {
+
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ ERR_FAIL_COND(!multimesh);
+ ERR_FAIL_INDEX(p_index, multimesh->instances);
+ ERR_FAIL_COND(multimesh->xform_format != VS::MULTIMESH_TRANSFORM_3D);
+
+ _multimesh_make_local(multimesh);
+
+ {
+ PoolVector<float>::Write w = multimesh->data_cache.write();
+
+ float *dataptr = w.ptr() + p_index * multimesh->stride_cache;
+
+ dataptr[0] = p_transform.basis[0].x;
+ dataptr[1] = p_transform.basis[0].y;
+ dataptr[2] = p_transform.basis[0].z;
+ dataptr[3] = p_transform.basis[1].x;
+ dataptr[4] = p_transform.basis[1].y;
+ dataptr[5] = p_transform.basis[1].z;
+ dataptr[6] = p_transform.basis[2].x;
+ dataptr[7] = p_transform.basis[2].y;
+ dataptr[8] = p_transform.basis[2].z;
+ dataptr[9] = p_transform.origin.x;
+ dataptr[10] = p_transform.origin.y;
+ dataptr[11] = p_transform.origin.z;
+ }
+
+ _multimesh_mark_dirty(multimesh, p_index, true);
+}
+
+void RasterizerStorageRD::multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) {
+
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ ERR_FAIL_COND(!multimesh);
+ ERR_FAIL_INDEX(p_index, multimesh->instances);
+ ERR_FAIL_COND(multimesh->xform_format != VS::MULTIMESH_TRANSFORM_2D);
+
+ _multimesh_make_local(multimesh);
+
+ {
+ PoolVector<float>::Write w = multimesh->data_cache.write();
+
+ float *dataptr = w.ptr() + p_index * multimesh->stride_cache;
+
+ dataptr[0] = p_transform.elements[0].x;
+ dataptr[1] = p_transform.elements[1].x;
+ dataptr[2] = 0;
+ dataptr[3] = p_transform.elements[2].x;
+ dataptr[4] = p_transform.elements[0].y;
+ dataptr[5] = p_transform.elements[1].y;
+ dataptr[6] = 0;
+ dataptr[7] = p_transform.elements[2].y;
+ }
+
+ _multimesh_mark_dirty(multimesh, p_index, true);
+}
+void RasterizerStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) {
+
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ ERR_FAIL_COND(!multimesh);
+ ERR_FAIL_INDEX(p_index, multimesh->instances);
+ ERR_FAIL_INDEX(p_index, !multimesh->uses_colors);
+
+ _multimesh_make_local(multimesh);
+
+ {
+ PoolVector<float>::Write w = multimesh->data_cache.write();
+
+ float *dataptr = w.ptr() + p_index * multimesh->stride_cache + multimesh->color_offset_cache;
+
+ dataptr[0] = p_color.r;
+ dataptr[1] = p_color.g;
+ dataptr[2] = p_color.b;
+ dataptr[3] = p_color.a;
+ }
+
+ _multimesh_mark_dirty(multimesh, p_index, false);
+}
+void RasterizerStorageRD::multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) {
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ ERR_FAIL_COND(!multimesh);
+ ERR_FAIL_INDEX(p_index, multimesh->instances);
+ ERR_FAIL_INDEX(p_index, !multimesh->uses_custom_data);
+
+ _multimesh_make_local(multimesh);
+
+ {
+ PoolVector<float>::Write w = multimesh->data_cache.write();
+
+ float *dataptr = w.ptr() + p_index * multimesh->stride_cache + multimesh->custom_data_offset_cache;
+
+ dataptr[0] = p_color.r;
+ dataptr[1] = p_color.g;
+ dataptr[2] = p_color.b;
+ dataptr[3] = p_color.a;
+ }
+
+ _multimesh_mark_dirty(multimesh, p_index, false);
+}
+
+RID RasterizerStorageRD::multimesh_get_mesh(RID p_multimesh) const {
+
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ ERR_FAIL_COND_V(!multimesh, RID());
+
+ return multimesh->mesh;
+}
+
+Transform RasterizerStorageRD::multimesh_instance_get_transform(RID p_multimesh, int p_index) const {
+
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ ERR_FAIL_COND_V(!multimesh, Transform());
+ ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform());
+ ERR_FAIL_COND_V(multimesh->xform_format != VS::MULTIMESH_TRANSFORM_3D, Transform());
+
+ _multimesh_make_local(multimesh);
+
+ Transform t;
+ {
+ PoolVector<float>::Read r = multimesh->data_cache.read();
+
+ const float *dataptr = r.ptr() + p_index * multimesh->stride_cache;
+
+ t.basis[0].x = dataptr[0];
+ t.basis[0].y = dataptr[1];
+ t.basis[0].z = dataptr[2];
+ t.basis[1].x = dataptr[3];
+ t.basis[1].y = dataptr[4];
+ t.basis[1].z = dataptr[5];
+ t.basis[2].x = dataptr[6];
+ t.basis[2].y = dataptr[7];
+ t.basis[2].z = dataptr[8];
+ t.origin.x = dataptr[9];
+ t.origin.y = dataptr[10];
+ t.origin.z = dataptr[11];
+ }
+
+ return t;
+}
+Transform2D RasterizerStorageRD::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const {
+
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ ERR_FAIL_COND_V(!multimesh, Transform2D());
+ ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform2D());
+ ERR_FAIL_COND_V(multimesh->xform_format != VS::MULTIMESH_TRANSFORM_2D, Transform2D());
+
+ _multimesh_make_local(multimesh);
+
+ Transform2D t;
+ {
+ PoolVector<float>::Read r = multimesh->data_cache.read();
+
+ const float *dataptr = r.ptr() + p_index * multimesh->stride_cache;
+
+ t.elements[0].x = dataptr[0];
+ t.elements[1].x = dataptr[1];
+ t.elements[2].x = dataptr[3];
+
+ t.elements[0].y = dataptr[4];
+ t.elements[1].y = dataptr[5];
+ t.elements[2].y = dataptr[7];
+ }
+
+ return t;
+}
+Color RasterizerStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_index) const {
+
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ ERR_FAIL_COND_V(!multimesh, Color());
+ ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color());
+ ERR_FAIL_INDEX_V(p_index, !multimesh->uses_colors, Color());
+
+ _multimesh_make_local(multimesh);
+
+ Color c;
+ {
+ PoolVector<float>::Read r = multimesh->data_cache.read();
+
+ const float *dataptr = r.ptr() + p_index * multimesh->stride_cache + multimesh->color_offset_cache;
+
+ c.r = dataptr[0];
+ c.g = dataptr[1];
+ c.b = dataptr[2];
+ c.a = dataptr[3];
+ }
+
+ return c;
+}
+Color RasterizerStorageRD::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const {
+
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ ERR_FAIL_COND_V(!multimesh, Color());
+ ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color());
+ ERR_FAIL_INDEX_V(p_index, !multimesh->uses_custom_data, Color());
+
+ _multimesh_make_local(multimesh);
+
+ Color c;
+ {
+ PoolVector<float>::Read r = multimesh->data_cache.read();
+
+ const float *dataptr = r.ptr() + p_index * multimesh->stride_cache + multimesh->custom_data_offset_cache;
+
+ c.r = dataptr[0];
+ c.g = dataptr[1];
+ c.b = dataptr[2];
+ c.a = dataptr[3];
+ }
+
+ return c;
+}
+
+void RasterizerStorageRD::multimesh_set_buffer(RID p_multimesh, const PoolVector<float> &p_buffer) {
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ ERR_FAIL_COND(!multimesh);
+ ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)multimesh->stride_cache));
+
+ {
+ PoolVector<float>::Read r = p_buffer.read();
+ RD::get_singleton()->buffer_update(multimesh->buffer, 0, p_buffer.size() * sizeof(float), r.ptr(), false);
+ multimesh->buffer_set = true;
+ }
+
+ if (multimesh->data_cache.size()) {
+ //if we have a data cache, just update it
+ multimesh->data_cache = p_buffer;
+ {
+ //clear dirty since nothing will be dirty anymore
+ uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
+ for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) {
+ multimesh->data_cache_dirty_regions[i] = false;
+ }
+ multimesh->data_cache_used_dirty_regions = 0;
+ }
+
+ _multimesh_mark_all_dirty(multimesh, false, true); //update AABB
+ } else if (multimesh->mesh.is_valid()) {
+ //if we have a mesh set, we need to re-generate the AABB from the new data
+ PoolVector<float>::Read r = p_buffer.read();
+ const float *data = r.ptr();
+ _multimesh_re_create_aabb(multimesh, data, multimesh->instances);
+ multimesh->instance_dependency.instance_notify_changed(true, false);
+ }
+}
+
+PoolVector<float> RasterizerStorageRD::multimesh_get_buffer(RID p_multimesh) const {
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ ERR_FAIL_COND_V(!multimesh, PoolVector<float>());
+ if (multimesh->buffer.is_null()) {
+ return PoolVector<float>();
+ } else if (multimesh->data_cache.size()) {
+ return multimesh->data_cache;
+ } else {
+ //get from memory
+
+ PoolVector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(multimesh->buffer);
+ PoolVector<float> ret;
+ ret.resize(multimesh->instances);
+ {
+ PoolVector<float>::Write w = multimesh->data_cache.write();
+ PoolVector<uint8_t>::Read r = buffer.read();
+ copymem(w.ptr(), r.ptr(), buffer.size());
+ }
+
+ return ret;
+ }
+}
+
+void RasterizerStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p_visible) {
+
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ ERR_FAIL_COND(!multimesh);
+ ERR_FAIL_COND(p_visible < -1 || p_visible > multimesh->instances);
+ if (multimesh->visible_instances == p_visible) {
+ return;
+ }
+
+ if (multimesh->data_cache.size()) {
+ //there is a data cache..
+ _multimesh_mark_all_dirty(multimesh, false, true);
+ }
+
+ multimesh->visible_instances = p_visible;
+}
+int RasterizerStorageRD::multimesh_get_visible_instances(RID p_multimesh) const {
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ ERR_FAIL_COND_V(!multimesh, 0);
+ return multimesh->visible_instances;
+}
+
+AABB RasterizerStorageRD::multimesh_get_aabb(RID p_multimesh) const {
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ ERR_FAIL_COND_V(!multimesh, AABB());
+ if (multimesh->aabb_dirty) {
+ const_cast<RasterizerStorageRD *>(this)->_update_dirty_multimeshes();
+ }
+ return multimesh->aabb;
+}
+
+void RasterizerStorageRD::_update_dirty_multimeshes() {
+
+ while (multimesh_dirty_list) {
+
+ MultiMesh *multimesh = multimesh_dirty_list;
+
+ if (multimesh->data_cache.size()) { //may have been cleared, so only process if it exists
+ PoolVector<float>::Read r = multimesh->data_cache.read();
+ const float *data = r.ptr();
+
+ uint32_t visible_instances = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances;
+
+ if (multimesh->data_cache_used_dirty_regions) {
+
+ uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
+ uint32_t visible_region_count = (visible_instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
+
+ uint32_t region_size = multimesh->stride_cache * MULTIMESH_DIRTY_REGION_SIZE * sizeof(float);
+
+ if (multimesh->data_cache_used_dirty_regions > 32 || multimesh->data_cache_used_dirty_regions > visible_region_count / 2) {
+ //if there too many dirty regions, or represent the majority of regions, just copy all, else transfer cost piles up too much
+ RD::get_singleton()->buffer_update(multimesh->buffer, 0, MIN(visible_region_count * region_size, multimesh->instances * multimesh->stride_cache), data, false);
+ } else {
+ //not that many regions? update them all
+ for (uint32_t i = 0; i < visible_region_count; i++) {
+ if (multimesh->data_cache_dirty_regions[i]) {
+ uint64_t offset = i * region_size;
+ uint64_t size = multimesh->stride_cache * multimesh->instances;
+ RD::get_singleton()->buffer_update(multimesh->buffer, offset, MIN(region_size, size - offset), &data[i * region_size], false);
+ }
+ }
+ }
+
+ for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) {
+ multimesh->data_cache_dirty_regions[i] = false;
+ }
+
+ multimesh->data_cache_used_dirty_regions = 0;
+ }
+
+ if (multimesh->aabb_dirty) {
+ //aabb is dirty..
+ _multimesh_re_create_aabb(multimesh, data, visible_instances);
+ multimesh->aabb_dirty = false;
+ multimesh->instance_dependency.instance_notify_changed(true, false);
+ }
+ }
+
+ multimesh_dirty_list = multimesh->dirty_list;
+
+ multimesh->dirty_list = nullptr;
+ multimesh->dirty = false;
+ }
+
+ multimesh_dirty_list = nullptr;
+}
+
/* LIGHT */
RID RasterizerStorageRD::light_create(VS::LightType p_type) {
@@ -2889,6 +3499,13 @@ void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::In
if (mesh_owner.owns(p_base)) {
Mesh *mesh = mesh_owner.getornull(p_base);
p_instance->update_dependency(&mesh->instance_dependency);
+ } else if (multimesh_owner.owns(p_base)) {
+
+ MultiMesh *multimesh = multimesh_owner.getornull(p_base);
+ p_instance->update_dependency(&multimesh->instance_dependency);
+ if (multimesh->mesh.is_valid()) {
+ base_update_dependency(multimesh->mesh, p_instance);
+ }
} else if (reflection_probe_owner.owns(p_base)) {
ReflectionProbe *rp = reflection_probe_owner.getornull(p_base);
p_instance->update_dependency(&rp->instance_dependency);
@@ -2903,6 +3520,9 @@ VS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const {
if (mesh_owner.owns(p_rid)) {
return VS::INSTANCE_MESH;
}
+ if (multimesh_owner.owns(p_rid)) {
+ return VS::INSTANCE_MULTIMESH;
+ }
if (reflection_probe_owner.owns(p_rid)) {
return VS::INSTANCE_REFLECTION_PROBE;
}
@@ -2914,8 +3534,29 @@ VS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const {
}
void RasterizerStorageRD::update_dirty_resources() {
_update_queued_materials();
+ _update_dirty_multimeshes();
}
+bool RasterizerStorageRD::has_os_feature(const String &p_feature) const {
+
+ if (p_feature == "s3tc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
+ return true;
+ }
+
+ if (p_feature == "bptc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC7_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
+ return true;
+ }
+
+ if ((p_feature == "etc" || p_feature == "etc2") && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
+ return true;
+ }
+
+ if (p_feature == "pvrtc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
+ return true;
+ }
+
+ return false;
+}
bool RasterizerStorageRD::free(RID p_rid) {
if (texture_owner.owns(p_rid)) {
@@ -2972,6 +3613,12 @@ bool RasterizerStorageRD::free(RID p_rid) {
Mesh *mesh = mesh_owner.getornull(p_rid);
mesh->instance_dependency.instance_notify_deleted(p_rid);
mesh_owner.free(p_rid);
+ } else if (multimesh_owner.owns(p_rid)) {
+ _update_dirty_multimeshes();
+ multimesh_allocate(p_rid, 0, VS::MULTIMESH_TRANSFORM_2D);
+ MultiMesh *multimesh = multimesh_owner.getornull(p_rid);
+ multimesh->instance_dependency.instance_notify_deleted(p_rid);
+ multimesh_owner.free(p_rid);
} else if (reflection_probe_owner.owns(p_rid)) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_rid);
reflection_probe->instance_dependency.instance_notify_deleted(p_rid);
diff --git a/servers/visual/rasterizer_rd/rasterizer_storage_rd.h b/servers/visual/rasterizer_rd/rasterizer_storage_rd.h
index 3cfd5601e8..ef22a6689b 100644
--- a/servers/visual/rasterizer_rd/rasterizer_storage_rd.h
+++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.h
@@ -62,7 +62,7 @@ public:
struct MaterialData {
void update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color);
- void update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures);
+ void update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color);
virtual void set_render_priority(int p_priority) = 0;
virtual void set_next_pass(RID p_pass) = 0;
@@ -135,6 +135,15 @@ private:
RID proxy_to;
Vector<RID> proxies;
+
+ VS::TextureDetectCallback detect_3d_callback = nullptr;
+ void *detect_3d_callback_ud = nullptr;
+
+ VS::TextureDetectCallback detect_normal_callback = nullptr;
+ void *detect_normal_callback_ud = nullptr;
+
+ VS::TextureDetectRoughnessCallback detect_roughness_callback = nullptr;
+ void *detect_roughness_callback_ud = nullptr;
};
struct TextureToRDFormat {
@@ -281,6 +290,43 @@ private:
RID mesh_default_rd_buffers[DEFAULT_RD_BUFFER_MAX];
+ /* MultiMesh */
+ struct MultiMesh {
+ RID mesh;
+ int instances = 0;
+ VS::MultimeshTransformFormat xform_format = VS::MULTIMESH_TRANSFORM_3D;
+ bool uses_colors = false;
+ bool uses_custom_data = false;
+ int visible_instances = -1;
+ AABB aabb;
+ bool aabb_dirty = false;
+ bool buffer_set = false;
+ uint32_t stride_cache = 0;
+ uint32_t color_offset_cache = 0;
+ uint32_t custom_data_offset_cache = 0;
+
+ PoolVector<float> data_cache; //used if individual setting is used
+ bool *data_cache_dirty_regions = nullptr;
+ uint32_t data_cache_used_dirty_regions = 0;
+
+ RID buffer; //storage buffer
+ RID uniform_set_3d;
+
+ bool dirty = false;
+ MultiMesh *dirty_list = nullptr;
+
+ RasterizerScene::InstanceDependency instance_dependency;
+ };
+
+ mutable RID_Owner<MultiMesh> multimesh_owner;
+
+ MultiMesh *multimesh_dirty_list = nullptr;
+
+ _FORCE_INLINE_ void _multimesh_make_local(MultiMesh *multimesh) const;
+ _FORCE_INLINE_ void _multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb);
+ _FORCE_INLINE_ void _multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, bool p_aabb);
+ _FORCE_INLINE_ void _multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances);
+ void _update_dirty_multimeshes();
/* LIGHT */
struct Light {
@@ -485,7 +531,7 @@ public:
_FORCE_INLINE_ MaterialData *material_get_data(RID p_material, ShaderType p_shader_type) {
Material *material = material_owner.getornull(p_material);
- if (material->shader_type != p_shader_type) {
+ if (!material || material->shader_type != p_shader_type) {
return NULL;
} else {
return material->data;
@@ -612,30 +658,69 @@ public:
/* MULTIMESH API */
- virtual RID multimesh_create() { return RID(); }
+ RID multimesh_create();
- void multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format, VS::MultimeshCustomDataFormat p_data = VS::MULTIMESH_CUSTOM_DATA_NONE) {}
- int multimesh_get_instance_count(RID p_multimesh) const { return 0; }
+ void multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false);
+ int multimesh_get_instance_count(RID p_multimesh) const;
- void multimesh_set_mesh(RID p_multimesh, RID p_mesh) {}
- void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) {}
- void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) {}
- void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) {}
- void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) {}
+ void multimesh_set_mesh(RID p_multimesh, RID p_mesh);
+ void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform);
+ void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform);
+ void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color);
+ void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color);
- RID multimesh_get_mesh(RID p_multimesh) const { return RID(); }
+ RID multimesh_get_mesh(RID p_multimesh) const;
- Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const { return Transform(); }
- Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const { return Transform2D(); }
- Color multimesh_instance_get_color(RID p_multimesh, int p_index) const { return Color(); }
- Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const { return Color(); }
+ Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const;
+ Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const;
+ Color multimesh_instance_get_color(RID p_multimesh, int p_index) const;
+ Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const;
- void multimesh_set_as_bulk_array(RID p_multimesh, const PoolVector<float> &p_array) {}
+ void multimesh_set_buffer(RID p_multimesh, const PoolVector<float> &p_buffer);
+ PoolVector<float> multimesh_get_buffer(RID p_multimesh) const;
- void multimesh_set_visible_instances(RID p_multimesh, int p_visible) {}
- int multimesh_get_visible_instances(RID p_multimesh) const { return 0; }
+ void multimesh_set_visible_instances(RID p_multimesh, int p_visible);
+ int multimesh_get_visible_instances(RID p_multimesh) const;
- AABB multimesh_get_aabb(RID p_multimesh) const { return AABB(); }
+ AABB multimesh_get_aabb(RID p_multimesh) const;
+
+ _FORCE_INLINE_ VS::MultimeshTransformFormat multimesh_get_transform_format(RID p_multimesh) const {
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ return multimesh->xform_format;
+ }
+
+ _FORCE_INLINE_ bool multimesh_uses_colors(RID p_multimesh) const {
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ return multimesh->uses_colors;
+ }
+
+ _FORCE_INLINE_ bool multimesh_uses_custom_data(RID p_multimesh) const {
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ return multimesh->uses_custom_data;
+ }
+
+ _FORCE_INLINE_ uint32_t multimesh_get_instances_to_draw(RID p_multimesh) const {
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ if (multimesh->visible_instances >= 0) {
+ return multimesh->visible_instances;
+ }
+ return multimesh->instances;
+ }
+
+ _FORCE_INLINE_ RID multimesh_get_3d_uniform_set(RID p_multimesh, RID p_shader, uint32_t p_set) const {
+ MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
+ if (!multimesh->uniform_set_3d.is_valid()) {
+ Vector<RD::Uniform> uniforms;
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 0;
+ u.ids.push_back(multimesh->buffer);
+ uniforms.push_back(u);
+ multimesh->uniform_set_3d = RD::get_singleton()->uniform_set_create(uniforms, p_shader, p_set);
+ }
+
+ return multimesh->uniform_set_3d;
+ }
/* IMMEDIATE API */
@@ -919,7 +1004,7 @@ public:
bool free(RID p_rid);
- bool has_os_feature(const String &p_feature) const { return false; }
+ bool has_os_feature(const String &p_feature) const;
void update_dirty_resources();
diff --git a/servers/visual/rasterizer_rd/shader_compiler_rd.cpp b/servers/visual/rasterizer_rd/shader_compiler_rd.cpp
index 3908fbec3f..1aa48a82fc 100644
--- a/servers/visual/rasterizer_rd/shader_compiler_rd.cpp
+++ b/servers/visual/rasterizer_rd/shader_compiler_rd.cpp
@@ -482,8 +482,10 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
//code for functions
for (int i = 0; i < pnode->functions.size(); i++) {
SL::FunctionNode *fnode = pnode->functions[i].function;
+ function = fnode;
current_func_name = fnode->name;
function_code[fnode->name] = _dump_node_code(fnode->body, p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
+ function = NULL;
}
//place functions in actual code
@@ -763,7 +765,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
sampler_name = actions.custom_samplers[texture_uniform];
} else {
if (shader->uniforms.has(texture_uniform)) {
- print_line("shader from texture uniform " + itos(shader->uniforms[texture_uniform].filter) + ", " + itos(shader->uniforms[texture_uniform].repeat));
sampler_name = _get_sampler_name(shader->uniforms[texture_uniform].filter, shader->uniforms[texture_uniform].repeat);
} else {
bool found = false;
diff --git a/servers/visual/rasterizer_rd/shaders/scene_forward.glsl b/servers/visual/rasterizer_rd/shaders/scene_forward.glsl
index d64276a2bf..1bd11c4288 100644
--- a/servers/visual/rasterizer_rd/shaders/scene_forward.glsl
+++ b/servers/visual/rasterizer_rd/shaders/scene_forward.glsl
@@ -86,16 +86,50 @@ layout(location =8) out float dp_clip;
void main() {
instance_index = draw_call.instance_index;
-
- /*if (draw_call.instance_increment) {
- instance_index += gl_InstanceIndex;
- }*/
-
- vec3 vertex = vertex_attrib;
+ vec4 instance_custom = vec4(0.0);
+#if defined(COLOR_USED)
+ color_interp = color_attrib;
+#endif
mat4 world_matrix = instances.data[instance_index].transform;
mat3 world_normal_matrix= mat3(instances.data[instance_index].normal_transform);
+ if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH)) {
+ //multimesh, instances are for it
+ uint offset = (instances.data[instance_index].flags>>INSTANCE_FLAGS_MULTIMESH_STRIDE_SHIFT)&INSTANCE_FLAGS_MULTIMESH_STRIDE_MASK;
+ offset*=gl_InstanceIndex;
+
+
+ mat4 matrix;
+ if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) {
+ mat4 matrix = mat4(transforms.data[offset+0],transforms.data[offset+1],vec4(0.0,0.0,1.0,0.0),vec4(0.0,0.0,0.0,1.0));
+ offset+=2;
+ } else {
+ mat4 matrix = mat4(transforms.data[offset+0],transforms.data[offset+1],transforms.data[offset+2],vec4(0.0,0.0,0.0,1.0));
+ offset+=3;
+ }
+
+ if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) {
+#ifdef COLOR_USED
+ color_interp *= transforms.data[offset];
+#endif
+ offset+=1;
+ }
+
+ if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) {
+ instance_custom = transforms.data[offset];
+ }
+
+ //transposed, so multiply in opposite order
+ world_matrix = matrix * world_matrix;
+ world_normal_matrix = mat3(matrix) * world_normal_matrix;
+
+ } else {
+ //not a multimesh, instances are for multiple draw calls
+ instance_index += gl_InstanceIndex;
+ }
+
+ vec3 vertex = vertex_attrib;
vec3 normal = normal_attrib;
#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
@@ -103,10 +137,6 @@ void main() {
float binormalf = tangent_attrib.a;
#endif
-#if defined(COLOR_USED)
- color_interp = color_attrib;
-#endif
-
#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
vec3 binormal = normalize(cross(normal, tangent) * binormalf);
@@ -124,7 +154,7 @@ void main() {
vec4 position;
#endif
- vec4 instance_custom = vec4(0.0);
+
mat4 projection_matrix = scene_data.projection_matrix;
@@ -768,7 +798,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 a
transmission,
#endif
#ifdef LIGHT_RIM_USED
- rim * omni_attenuation, rim_tint,
+ rim * spot_attenuation, rim_tint,
#endif
#ifdef LIGHT_CLEARCOAT_USED
clearcoat, clearcoat_gloss,
@@ -932,7 +962,7 @@ void main() {
float normaldepth = 1.0;
#if defined(SCREEN_UV_USED)
- vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size;
+ vec2 screen_uv = gl_FragCoord.xy * scene_data.screen_pixel_size;
#endif
float sss_strength = 0.0;
@@ -1182,7 +1212,7 @@ FRAGMENT_SHADER_CODE
transmission,
#endif
#ifdef LIGHT_RIM_USED
- rim * omni_attenuation, rim_tint,
+ rim, rim_tint,
#endif
#ifdef LIGHT_CLEARCOAT_USED
clearcoat, clearcoat_gloss,
diff --git a/servers/visual/rasterizer_rd/shaders/scene_forward_inc.glsl b/servers/visual/rasterizer_rd/shaders/scene_forward_inc.glsl
index d6b6aa4301..4d1a1c9495 100644
--- a/servers/visual/rasterizer_rd/shaders/scene_forward_inc.glsl
+++ b/servers/visual/rasterizer_rd/shaders/scene_forward_inc.glsl
@@ -118,11 +118,20 @@ layout(set=0,binding=8,std140) uniform SceneData {
#endif
} scene_data;
-#define INSTANCE_FLAGS_FORWARD_MASK 3
+#define INSTANCE_FLAGS_FORWARD_MASK 0x7
#define INSTANCE_FLAGS_FORWARD_OMNI_LIGHT_SHIFT 3
#define INSTANCE_FLAGS_FORWARD_SPOT_LIGHT_SHIFT 6
#define INSTANCE_FLAGS_FORWARD_DECAL_SHIFT 9
+#define INSTANCE_FLAGS_MULTIMESH (1 << 12)
+#define INSTANCE_FLAGS_MULTIMESH_FORMAT_2D (1 << 13)
+#define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14)
+#define INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA (1 << 15)
+#define INSTANCE_FLAGS_MULTIMESH_STRIDE_SHIFT 16
+//3 bits of stride
+#define INSTANCE_FLAGS_MULTIMESH_STRIDE_MASK 0x7
+
+
struct InstanceData {
mat4 transform;
@@ -217,6 +226,11 @@ layout(set=0,binding=15,std430) buffer Skeletons {
//layout(set = 1, binding = 0) uniform textureBuffer multimesh_transforms;
+layout(set=1,binding=0,std430) buffer Transforms {
+ vec4 data[];
+} transforms;
+
+
/* Set 2 Instancing (Multimesh) data */
#if 0
diff --git a/servers/visual/rasterizer_rd/shaders/tonemap.glsl b/servers/visual/rasterizer_rd/shaders/tonemap.glsl
index 6797ff9f77..f54c938e24 100644
--- a/servers/visual/rasterizer_rd/shaders/tonemap.glsl
+++ b/servers/visual/rasterizer_rd/shaders/tonemap.glsl
@@ -145,7 +145,7 @@ vec3 tonemap_filmic(vec3 color, float white) {
vec3 color_tonemapped = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F;
float white_tonemapped = ((white * (A * white + C * B) + D * E) / (white * (A * white + B) + D * F)) - E / F;
- return color_tonemapped / white_tonemapped, vec3(0.0f), vec3(1.0f);
+ return color_tonemapped / white_tonemapped;
}
vec3 tonemap_aces(vec3 color, float white) {
@@ -159,7 +159,7 @@ vec3 tonemap_aces(vec3 color, float white) {
vec3 color_tonemapped = (color * (A * color + B)) / (color * (C * color + D) + E);
float white_tonemapped = (white * (A * white + B)) / (white * (C * white + D) + E);
- return color_tonemapped / white_tonemapped, vec3(0.0f), vec3(1.0f);
+ return color_tonemapped / white_tonemapped;
}
vec3 tonemap_reinhard(vec3 color, float white) {
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index c343e23881..5ef51e3e1a 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -307,6 +307,12 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
{ TK_HINT_WHITE_TEXTURE, "hint_white" },
{ TK_HINT_BLACK_TEXTURE, "hint_black" },
{ TK_HINT_NORMAL_TEXTURE, "hint_normal" },
+ { TK_HINT_ROUGHNESS_NORMAL_TEXTURE, "hint_roughness_normal" },
+ { TK_HINT_ROUGHNESS_R, "hint_roughness_r" },
+ { TK_HINT_ROUGHNESS_G, "hint_roughness_g" },
+ { TK_HINT_ROUGHNESS_B, "hint_roughness_b" },
+ { TK_HINT_ROUGHNESS_A, "hint_roughness_a" },
+ { TK_HINT_ROUGHNESS_GRAY, "hint_roughness_gray" },
{ TK_HINT_ANISO_TEXTURE, "hint_aniso" },
{ TK_HINT_ALBEDO_TEXTURE, "hint_albedo" },
{ TK_HINT_BLACK_ALBEDO_TEXTURE, "hint_black_albedo" },
@@ -5171,6 +5177,18 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
uniform2.hint = ShaderNode::Uniform::HINT_BLACK;
} else if (tk.type == TK_HINT_NORMAL_TEXTURE) {
uniform2.hint = ShaderNode::Uniform::HINT_NORMAL;
+ } else if (tk.type == TK_HINT_ROUGHNESS_NORMAL_TEXTURE) {
+ uniform2.hint = ShaderNode::Uniform::HINT_ROUGHNESS_NORMAL;
+ } else if (tk.type == TK_HINT_ROUGHNESS_R) {
+ uniform2.hint = ShaderNode::Uniform::HINT_ROUGHNESS_R;
+ } else if (tk.type == TK_HINT_ROUGHNESS_G) {
+ uniform2.hint = ShaderNode::Uniform::HINT_ROUGHNESS_G;
+ } else if (tk.type == TK_HINT_ROUGHNESS_B) {
+ uniform2.hint = ShaderNode::Uniform::HINT_ROUGHNESS_B;
+ } else if (tk.type == TK_HINT_ROUGHNESS_A) {
+ uniform2.hint = ShaderNode::Uniform::HINT_ROUGHNESS_A;
+ } else if (tk.type == TK_HINT_ROUGHNESS_GRAY) {
+ uniform2.hint = ShaderNode::Uniform::HINT_ROUGHNESS_GRAY;
} else if (tk.type == TK_HINT_ANISO_TEXTURE) {
uniform2.hint = ShaderNode::Uniform::HINT_ANISO;
} else if (tk.type == TK_HINT_ALBEDO_TEXTURE) {
diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h
index 3a1ded0547..da5b0600ff 100644
--- a/servers/visual/shader_language.h
+++ b/servers/visual/shader_language.h
@@ -150,6 +150,12 @@ public:
TK_HINT_WHITE_TEXTURE,
TK_HINT_BLACK_TEXTURE,
TK_HINT_NORMAL_TEXTURE,
+ TK_HINT_ROUGHNESS_NORMAL_TEXTURE,
+ TK_HINT_ROUGHNESS_R,
+ TK_HINT_ROUGHNESS_G,
+ TK_HINT_ROUGHNESS_B,
+ TK_HINT_ROUGHNESS_A,
+ TK_HINT_ROUGHNESS_GRAY,
TK_HINT_ANISO_TEXTURE,
TK_HINT_ALBEDO_TEXTURE,
TK_HINT_BLACK_ALBEDO_TEXTURE,
@@ -576,6 +582,12 @@ public:
HINT_ALBEDO,
HINT_BLACK_ALBEDO,
HINT_NORMAL,
+ HINT_ROUGHNESS_NORMAL,
+ HINT_ROUGHNESS_R,
+ HINT_ROUGHNESS_G,
+ HINT_ROUGHNESS_B,
+ HINT_ROUGHNESS_A,
+ HINT_ROUGHNESS_GRAY,
HINT_BLACK,
HINT_WHITE,
HINT_ANISO,
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index be19a935e9..8543289083 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -248,7 +248,7 @@ public:
BIND0R(RID, multimesh_create)
- BIND5(multimesh_allocate, RID, int, MultimeshTransformFormat, MultimeshColorFormat, MultimeshCustomDataFormat)
+ BIND5(multimesh_allocate, RID, int, MultimeshTransformFormat, bool, bool)
BIND1RC(int, multimesh_get_instance_count, RID)
BIND2(multimesh_set_mesh, RID, RID)
@@ -265,7 +265,8 @@ public:
BIND2RC(Color, multimesh_instance_get_color, RID, int)
BIND2RC(Color, multimesh_instance_get_custom_data, RID, int)
- BIND2(multimesh_set_as_bulk_array, RID, const PoolVector<float> &)
+ BIND2(multimesh_set_buffer, RID, const PoolVector<float> &)
+ BIND1RC(PoolVector<float>, multimesh_get_buffer, RID)
BIND2(multimesh_set_visible_instances, RID, int)
BIND1RC(int, multimesh_get_visible_instances, RID)
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 3f33ec945c..96831d1cc2 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -1863,7 +1863,6 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
bool keep = false;
if ((camera_layer_mask & ins->layer_mask) == 0) {
-
//failure
} else if (ins->base_type == VS::INSTANCE_LIGHT && ins->visible) {
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index d8cd6771c1..a58d36f279 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -175,7 +175,7 @@ public:
FUNCRID(multimesh)
- FUNC5(multimesh_allocate, RID, int, MultimeshTransformFormat, MultimeshColorFormat, MultimeshCustomDataFormat)
+ FUNC5(multimesh_allocate, RID, int, MultimeshTransformFormat, bool, bool)
FUNC1RC(int, multimesh_get_instance_count, RID)
FUNC2(multimesh_set_mesh, RID, RID)
@@ -192,7 +192,8 @@ public:
FUNC2RC(Color, multimesh_instance_get_color, RID, int)
FUNC2RC(Color, multimesh_instance_get_custom_data, RID, int)
- FUNC2(multimesh_set_as_bulk_array, RID, const PoolVector<float> &)
+ FUNC2(multimesh_set_buffer, RID, const PoolVector<float> &)
+ FUNC1RC(PoolVector<float>, multimesh_get_buffer, RID)
FUNC2(multimesh_set_visible_instances, RID, int)
FUNC1RC(int, multimesh_get_visible_instances, RID)
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 66e0d67938..0c72a09a91 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1638,7 +1638,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("mesh_clear", "mesh"), &VisualServer::mesh_clear);
ClassDB::bind_method(D_METHOD("multimesh_create"), &VisualServer::multimesh_create);
- ClassDB::bind_method(D_METHOD("multimesh_allocate", "multimesh", "instances", "transform_format", "color_format", "custom_data_format"), &VisualServer::multimesh_allocate, DEFVAL(MULTIMESH_CUSTOM_DATA_NONE));
+ ClassDB::bind_method(D_METHOD("multimesh_allocate", "multimesh", "instances", "transform_format", "color_format", "custom_data_format"), &VisualServer::multimesh_allocate, DEFVAL(false), DEFVAL(false));
ClassDB::bind_method(D_METHOD("multimesh_get_instance_count", "multimesh"), &VisualServer::multimesh_get_instance_count);
ClassDB::bind_method(D_METHOD("multimesh_set_mesh", "multimesh", "mesh"), &VisualServer::multimesh_set_mesh);
ClassDB::bind_method(D_METHOD("multimesh_instance_set_transform", "multimesh", "index", "transform"), &VisualServer::multimesh_instance_set_transform);
@@ -1653,7 +1653,8 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("multimesh_instance_get_custom_data", "multimesh", "index"), &VisualServer::multimesh_instance_get_custom_data);
ClassDB::bind_method(D_METHOD("multimesh_set_visible_instances", "multimesh", "visible"), &VisualServer::multimesh_set_visible_instances);
ClassDB::bind_method(D_METHOD("multimesh_get_visible_instances", "multimesh"), &VisualServer::multimesh_get_visible_instances);
- ClassDB::bind_method(D_METHOD("multimesh_set_as_bulk_array", "multimesh", "array"), &VisualServer::multimesh_set_as_bulk_array);
+ ClassDB::bind_method(D_METHOD("multimesh_set_buffer", "multimesh", "buffer"), &VisualServer::multimesh_set_buffer);
+ ClassDB::bind_method(D_METHOD("multimesh_get_buffer", "multimesh"), &VisualServer::multimesh_get_buffer);
#ifndef _3D_DISABLED
ClassDB::bind_method(D_METHOD("immediate_create"), &VisualServer::immediate_create);
ClassDB::bind_method(D_METHOD("immediate_begin", "immediate", "primitive", "texture"), &VisualServer::immediate_begin, DEFVAL(RID()));
@@ -2151,12 +2152,6 @@ void VisualServer::_bind_methods() {
BIND_ENUM_CONSTANT(MULTIMESH_TRANSFORM_2D);
BIND_ENUM_CONSTANT(MULTIMESH_TRANSFORM_3D);
- BIND_ENUM_CONSTANT(MULTIMESH_COLOR_NONE);
- BIND_ENUM_CONSTANT(MULTIMESH_COLOR_8BIT);
- BIND_ENUM_CONSTANT(MULTIMESH_COLOR_FLOAT);
- BIND_ENUM_CONSTANT(MULTIMESH_CUSTOM_DATA_NONE);
- BIND_ENUM_CONSTANT(MULTIMESH_CUSTOM_DATA_8BIT);
- BIND_ENUM_CONSTANT(MULTIMESH_CUSTOM_DATA_FLOAT);
BIND_ENUM_CONSTANT(REFLECTION_PROBE_UPDATE_ONCE);
BIND_ENUM_CONSTANT(REFLECTION_PROBE_UPDATE_ALWAYS);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 2ab521c7c0..06dba99860 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -319,21 +319,7 @@ public:
MULTIMESH_TRANSFORM_3D,
};
- enum MultimeshColorFormat {
- MULTIMESH_COLOR_NONE,
- MULTIMESH_COLOR_8BIT,
- MULTIMESH_COLOR_FLOAT,
- MULTIMESH_COLOR_MAX,
- };
-
- enum MultimeshCustomDataFormat {
- MULTIMESH_CUSTOM_DATA_NONE,
- MULTIMESH_CUSTOM_DATA_8BIT,
- MULTIMESH_CUSTOM_DATA_FLOAT,
- MULTIMESH_CUSTOM_DATA_MAX,
- };
-
- virtual void multimesh_allocate(RID p_multimesh, int p_instances, MultimeshTransformFormat p_transform_format, MultimeshColorFormat p_color_format, MultimeshCustomDataFormat p_data_format = MULTIMESH_CUSTOM_DATA_NONE) = 0;
+ virtual void multimesh_allocate(RID p_multimesh, int p_instances, MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0;
virtual int multimesh_get_instance_count(RID p_multimesh) const = 0;
virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh) = 0;
@@ -350,7 +336,8 @@ public:
virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const = 0;
virtual Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const = 0;
- virtual void multimesh_set_as_bulk_array(RID p_multimesh, const PoolVector<float> &p_array) = 0;
+ virtual void multimesh_set_buffer(RID p_multimesh, const PoolVector<float> &p_buffer) = 0;
+ virtual PoolVector<float> multimesh_get_buffer(RID p_multimesh) const = 0;
virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible) = 0;
virtual int multimesh_get_visible_instances(RID p_multimesh) const = 0;
@@ -1100,8 +1087,6 @@ VARIANT_ENUM_CAST(VisualServer::CanvasOccluderPolygonCullMode);
VARIANT_ENUM_CAST(VisualServer::RenderInfo);
VARIANT_ENUM_CAST(VisualServer::Features);
VARIANT_ENUM_CAST(VisualServer::MultimeshTransformFormat);
-VARIANT_ENUM_CAST(VisualServer::MultimeshColorFormat);
-VARIANT_ENUM_CAST(VisualServer::MultimeshCustomDataFormat);
VARIANT_ENUM_CAST(VisualServer::LightOmniShadowMode);
VARIANT_ENUM_CAST(VisualServer::LightDirectionalShadowMode);
VARIANT_ENUM_CAST(VisualServer::LightDirectionalShadowDepthRangeMode);