Merge pull request #38083 from reduz/use-typed-arrays
Add proper type to most public API uses of Array
This commit is contained in:
commit
cb1ae08c14
|
@ -121,12 +121,37 @@ void Array::_assign(const Array &p_array) {
|
|||
} else if (_p->typed.type == Variant::NIL) { //from typed to untyped, must copy, but this is cheap anyway
|
||||
_p->array = p_array._p->array;
|
||||
} else if (p_array._p->typed.type == Variant::NIL) { //from untyped to typed, must try to check if they are all valid
|
||||
for (int i = 0; i < p_array._p->array.size(); i++) {
|
||||
if (!_p->typed.validate(p_array._p->array[i], "assign")) {
|
||||
return;
|
||||
if (_p->typed.type == Variant::OBJECT) {
|
||||
//for objects, it needs full validation, either can be converted or fail
|
||||
for (int i = 0; i < p_array._p->array.size(); i++) {
|
||||
if (!_p->typed.validate(p_array._p->array[i], "assign")) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
_p->array = p_array._p->array; //then just copy, which is cheap anyway
|
||||
|
||||
} else {
|
||||
//for non objects, we need to check if there is a valid conversion, which needs to happen one by one, so this is the worst case.
|
||||
Vector<Variant> new_array;
|
||||
new_array.resize(p_array._p->array.size());
|
||||
for (int i = 0; i < p_array._p->array.size(); i++) {
|
||||
Variant src_val = p_array._p->array[i];
|
||||
if (src_val.get_type() == _p->typed.type) {
|
||||
new_array.write[i] = src_val;
|
||||
} else if (Variant::can_convert_strict(src_val.get_type(), _p->typed.type)) {
|
||||
Variant *ptr = &src_val;
|
||||
Callable::CallError ce;
|
||||
new_array.write[i] = Variant::construct(_p->typed.type, (const Variant **)&ptr, 1, ce, true);
|
||||
if (ce.error != Callable::CallError::CALL_OK) {
|
||||
ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'.");
|
||||
}
|
||||
} else {
|
||||
ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
_p->array = new_array;
|
||||
}
|
||||
_p->array = p_array._p->array; //then just copy, which is cheap anyway
|
||||
} else if (_p->typed.can_reference(p_array._p->typed)) { //same type or compatible
|
||||
_ref(p_array);
|
||||
} else {
|
||||
|
|
|
@ -17,6 +17,9 @@ public:
|
|||
_FORCE_INLINE_ void operator=(const Array &p_array) {
|
||||
_assign(p_array);
|
||||
}
|
||||
_FORCE_INLINE_ TypedArray(const Variant &p_variant) :
|
||||
Array(Array(p_variant), Variant::OBJECT, T::get_class_static(), Variant()) {
|
||||
}
|
||||
_FORCE_INLINE_ TypedArray(const Array &p_array) :
|
||||
Array(p_array, Variant::OBJECT, T::get_class_static(), Variant()) {
|
||||
}
|
||||
|
@ -27,19 +30,22 @@ public:
|
|||
|
||||
//specialization for the rest of variant types
|
||||
|
||||
#define MAKE_TYPED_ARRAY(m_type, m_variant_type) \
|
||||
template <> \
|
||||
class TypedArray<m_type> : public Array { \
|
||||
public: \
|
||||
_FORCE_INLINE_ void operator=(const Array &p_array) { \
|
||||
_assign(p_array); \
|
||||
} \
|
||||
_FORCE_INLINE_ TypedArray(const Array &p_array) : \
|
||||
Array(p_array, m_variant_type, StringName(), Variant()) { \
|
||||
} \
|
||||
_FORCE_INLINE_ TypedArray() { \
|
||||
set_typed(m_variant_type, StringName(), Variant()); \
|
||||
} \
|
||||
#define MAKE_TYPED_ARRAY(m_type, m_variant_type) \
|
||||
template <> \
|
||||
class TypedArray<m_type> : public Array { \
|
||||
public: \
|
||||
_FORCE_INLINE_ void operator=(const Array &p_array) { \
|
||||
_assign(p_array); \
|
||||
} \
|
||||
_FORCE_INLINE_ TypedArray(const Variant &p_variant) : \
|
||||
Array(Array(p_variant), m_variant_type, StringName(), Variant()) { \
|
||||
} \
|
||||
_FORCE_INLINE_ TypedArray(const Array &p_array) : \
|
||||
Array(p_array, m_variant_type, StringName(), Variant()) { \
|
||||
} \
|
||||
_FORCE_INLINE_ TypedArray() { \
|
||||
set_typed(m_variant_type, StringName(), Variant()); \
|
||||
} \
|
||||
};
|
||||
|
||||
MAKE_TYPED_ARRAY(bool, Variant::BOOL)
|
||||
|
|
|
@ -3327,7 +3327,7 @@ RID RenderingDeviceVulkan::vertex_buffer_create(uint32_t p_size_bytes, const Vec
|
|||
}
|
||||
|
||||
// Internally reference counted, this ID is warranted to be unique for the same description, but needs to be freed as many times as it was allocated
|
||||
RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(const Vector<VertexDescription> &p_vertex_formats) {
|
||||
RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
@ -3402,7 +3402,7 @@ RID RenderingDeviceVulkan::vertex_array_create(uint32_t p_vertex_count, VertexFo
|
|||
|
||||
//validate with buffer
|
||||
{
|
||||
const VertexDescription &atf = vd.vertex_formats[i];
|
||||
const VertexAttribute &atf = vd.vertex_formats[i];
|
||||
|
||||
uint32_t element_size = get_format_vertex_size(atf.format);
|
||||
ERR_FAIL_COND_V(element_size == 0, RID()); //should never happens since this was prevalidated
|
||||
|
|
|
@ -332,7 +332,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||
RID_Owner<Buffer, true> vertex_buffer_owner;
|
||||
|
||||
struct VertexDescriptionKey {
|
||||
Vector<VertexDescription> vertex_formats;
|
||||
Vector<VertexAttribute> vertex_formats;
|
||||
bool operator==(const VertexDescriptionKey &p_key) const {
|
||||
int vdc = vertex_formats.size();
|
||||
int vdck = p_key.vertex_formats.size();
|
||||
|
@ -340,11 +340,11 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||
if (vdc != vdck) {
|
||||
return false;
|
||||
} else {
|
||||
const VertexDescription *a_ptr = vertex_formats.ptr();
|
||||
const VertexDescription *b_ptr = p_key.vertex_formats.ptr();
|
||||
const VertexAttribute *a_ptr = vertex_formats.ptr();
|
||||
const VertexAttribute *b_ptr = p_key.vertex_formats.ptr();
|
||||
for (int i = 0; i < vdc; i++) {
|
||||
const VertexDescription &a = a_ptr[i];
|
||||
const VertexDescription &b = b_ptr[i];
|
||||
const VertexAttribute &a = a_ptr[i];
|
||||
const VertexAttribute &b = b_ptr[i];
|
||||
|
||||
if (a.location != b.location) {
|
||||
return false;
|
||||
|
@ -369,9 +369,9 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||
uint32_t hash() const {
|
||||
int vdc = vertex_formats.size();
|
||||
uint32_t h = hash_djb2_one_32(vdc);
|
||||
const VertexDescription *ptr = vertex_formats.ptr();
|
||||
const VertexAttribute *ptr = vertex_formats.ptr();
|
||||
for (int i = 0; i < vdc; i++) {
|
||||
const VertexDescription &vd = ptr[i];
|
||||
const VertexAttribute &vd = ptr[i];
|
||||
h = hash_djb2_one_32(vd.location, h);
|
||||
h = hash_djb2_one_32(vd.offset, h);
|
||||
h = hash_djb2_one_32(vd.format, h);
|
||||
|
@ -393,7 +393,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||
HashMap<VertexDescriptionKey, VertexFormatID, VertexDescriptionHash> vertex_format_cache;
|
||||
|
||||
struct VertexDescriptionCache {
|
||||
Vector<VertexDescription> vertex_formats;
|
||||
Vector<VertexAttribute> vertex_formats;
|
||||
VkVertexInputBindingDescription *bindings;
|
||||
VkVertexInputAttributeDescription *attributes;
|
||||
VkPipelineVertexInputStateCreateInfo create_info;
|
||||
|
@ -1016,7 +1016,7 @@ public:
|
|||
virtual RID vertex_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>());
|
||||
|
||||
// Internally reference counted, this ID is warranted to be unique for the same description, but needs to be freed as many times as it was allocated
|
||||
virtual VertexFormatID vertex_format_create(const Vector<VertexDescription> &p_vertex_formats);
|
||||
virtual VertexFormatID vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats);
|
||||
virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers);
|
||||
|
||||
virtual RID index_buffer_create(uint32_t p_size_indices, IndexBufferFormat p_format, const Vector<uint8_t> &p_data = Vector<uint8_t>(), bool p_use_restart_indices = false);
|
||||
|
|
|
@ -1066,9 +1066,9 @@ Array EditorSelection::_get_transformable_selected_nodes() {
|
|||
return ret;
|
||||
}
|
||||
|
||||
Array EditorSelection::get_selected_nodes() {
|
||||
TypedArray<Node> EditorSelection::get_selected_nodes() {
|
||||
|
||||
Array ret;
|
||||
TypedArray<Node> ret;
|
||||
|
||||
for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
|
||||
|
||||
|
|
|
@ -257,7 +257,7 @@ protected:
|
|||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
Array get_selected_nodes();
|
||||
TypedArray<Node> get_selected_nodes();
|
||||
void add_node(Node *p_node);
|
||||
void remove_node(Node *p_node);
|
||||
bool is_selected(Node *) const;
|
||||
|
|
|
@ -435,10 +435,10 @@ bool Area2D::is_monitorable() const {
|
|||
return monitorable;
|
||||
}
|
||||
|
||||
Array Area2D::get_overlapping_bodies() const {
|
||||
TypedArray<Node2D> Area2D::get_overlapping_bodies() const {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off.");
|
||||
Array ret;
|
||||
TypedArray<Node2D> ret;
|
||||
ret.resize(body_map.size());
|
||||
int idx = 0;
|
||||
for (const Map<ObjectID, BodyState>::Element *E = body_map.front(); E; E = E->next()) {
|
||||
|
@ -453,10 +453,10 @@ Array Area2D::get_overlapping_bodies() const {
|
|||
return ret;
|
||||
}
|
||||
|
||||
Array Area2D::get_overlapping_areas() const {
|
||||
TypedArray<Area2D> Area2D::get_overlapping_areas() const {
|
||||
|
||||
ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off.");
|
||||
Array ret;
|
||||
TypedArray<Area2D> ret;
|
||||
ret.resize(area_map.size());
|
||||
int idx = 0;
|
||||
for (const Map<ObjectID, AreaState>::Element *E = area_map.front(); E; E = E->next()) {
|
||||
|
|
|
@ -178,8 +178,8 @@ public:
|
|||
void set_collision_layer_bit(int p_bit, bool p_value);
|
||||
bool get_collision_layer_bit(int p_bit) const;
|
||||
|
||||
Array get_overlapping_bodies() const; //function for script
|
||||
Array get_overlapping_areas() const; //function for script
|
||||
TypedArray<Node2D> get_overlapping_bodies() const; //function for script
|
||||
TypedArray<Area2D> get_overlapping_areas() const; //function for script
|
||||
|
||||
bool overlaps_area(Node *p_area) const;
|
||||
bool overlaps_body(Node *p_body) const;
|
||||
|
|
|
@ -95,7 +95,7 @@ Vector<Vector2> NavigationPolygon::get_vertices() const {
|
|||
return vertices;
|
||||
}
|
||||
|
||||
void NavigationPolygon::_set_polygons(const Array &p_array) {
|
||||
void NavigationPolygon::_set_polygons(const TypedArray<Vector<int32_t>> &p_array) {
|
||||
|
||||
{
|
||||
MutexLock lock(navmesh_generation);
|
||||
|
@ -118,7 +118,7 @@ Array NavigationPolygon::_get_polygons() const {
|
|||
return ret;
|
||||
}
|
||||
|
||||
void NavigationPolygon::_set_outlines(const Array &p_array) {
|
||||
void NavigationPolygon::_set_outlines(const TypedArray<Vector<int32_t>> &p_array) {
|
||||
|
||||
outlines.resize(p_array.size());
|
||||
for (int i = 0; i < p_array.size(); i++) {
|
||||
|
|
|
@ -55,10 +55,10 @@ class NavigationPolygon : public Resource {
|
|||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
void _set_polygons(const Array &p_array);
|
||||
void _set_polygons(const TypedArray<Vector<int32_t>> &p_array);
|
||||
Array _get_polygons() const;
|
||||
|
||||
void _set_outlines(const Array &p_array);
|
||||
void _set_outlines(const TypedArray<Vector<int32_t>> &p_array);
|
||||
Array _get_outlines() const;
|
||||
|
||||
public:
|
||||
|
|
|
@ -139,7 +139,7 @@ PhysicsBody2D::PhysicsBody2D(PhysicsServer2D::BodyMode p_mode) :
|
|||
set_pickable(false);
|
||||
}
|
||||
|
||||
Array PhysicsBody2D::get_collision_exceptions() {
|
||||
TypedArray<PhysicsBody2D> PhysicsBody2D::get_collision_exceptions() {
|
||||
List<RID> exceptions;
|
||||
PhysicsServer2D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions);
|
||||
Array ret;
|
||||
|
@ -739,11 +739,11 @@ RigidBody2D::CCDMode RigidBody2D::get_continuous_collision_detection_mode() cons
|
|||
return ccd_mode;
|
||||
}
|
||||
|
||||
Array RigidBody2D::get_colliding_bodies() const {
|
||||
TypedArray<Node2D> RigidBody2D::get_colliding_bodies() const {
|
||||
|
||||
ERR_FAIL_COND_V(!contact_monitor, Array());
|
||||
|
||||
Array ret;
|
||||
TypedArray<Node2D> ret;
|
||||
ret.resize(contact_monitor->body_map.size());
|
||||
int idx = 0;
|
||||
for (const Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
void set_collision_layer_bit(int p_bit, bool p_value);
|
||||
bool get_collision_layer_bit(int p_bit) const;
|
||||
|
||||
Array get_collision_exceptions();
|
||||
TypedArray<PhysicsBody2D> get_collision_exceptions();
|
||||
void add_collision_exception_with(Node *p_node); //must be physicsbody
|
||||
void remove_collision_exception_with(Node *p_node);
|
||||
|
||||
|
@ -256,7 +256,7 @@ public:
|
|||
void add_force(const Vector2 &p_offset, const Vector2 &p_force);
|
||||
void add_torque(float p_torque);
|
||||
|
||||
Array get_colliding_bodies() const; //function for script
|
||||
TypedArray<Node2D> get_colliding_bodies() const; //function for script
|
||||
|
||||
virtual String get_configuration_warning() const;
|
||||
|
||||
|
|
|
@ -1705,13 +1705,13 @@ TypedArray<Vector2i> TileMap::get_used_cells() const {
|
|||
return a;
|
||||
}
|
||||
|
||||
Array TileMap::get_used_cells_by_id(int p_id) const {
|
||||
TypedArray<Vector2i> TileMap::get_used_cells_by_id(int p_id) const {
|
||||
|
||||
Array a;
|
||||
TypedArray<Vector2i> a;
|
||||
for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
|
||||
|
||||
if (E->value().id == p_id) {
|
||||
Vector2 p(E->key().x, E->key().y);
|
||||
Vector2i p(E->key().x, E->key().y);
|
||||
a.push_back(p);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -329,7 +329,7 @@ public:
|
|||
bool is_centered_textures_enabled() const;
|
||||
|
||||
TypedArray<Vector2i> get_used_cells() const;
|
||||
Array get_used_cells_by_id(int p_id) const;
|
||||
TypedArray<Vector2i> get_used_cells_by_id(int p_id) const;
|
||||
Rect2 get_used_rect(); // Not const because of cache
|
||||
|
||||
void set_occluder_light_mask(int p_mask);
|
||||
|
|
|
@ -416,7 +416,7 @@ bool Area3D::is_monitoring() const {
|
|||
return monitoring;
|
||||
}
|
||||
|
||||
Array Area3D::get_overlapping_bodies() const {
|
||||
TypedArray<Node3D> Area3D::get_overlapping_bodies() const {
|
||||
|
||||
ERR_FAIL_COND_V(!monitoring, Array());
|
||||
Array ret;
|
||||
|
@ -451,7 +451,7 @@ bool Area3D::is_monitorable() const {
|
|||
return monitorable;
|
||||
}
|
||||
|
||||
Array Area3D::get_overlapping_areas() const {
|
||||
TypedArray<Area3D> Area3D::get_overlapping_areas() const {
|
||||
|
||||
ERR_FAIL_COND_V(!monitoring, Array());
|
||||
Array ret;
|
||||
|
|
|
@ -184,8 +184,8 @@ public:
|
|||
void set_collision_layer_bit(int p_bit, bool p_value);
|
||||
bool get_collision_layer_bit(int p_bit) const;
|
||||
|
||||
Array get_overlapping_bodies() const;
|
||||
Array get_overlapping_areas() const; //function for script
|
||||
TypedArray<Node3D> get_overlapping_bodies() const;
|
||||
TypedArray<Area3D> get_overlapping_areas() const; //function for script
|
||||
|
||||
bool overlaps_area(Node *p_area) const;
|
||||
bool overlaps_body(Node *p_body) const;
|
||||
|
|
|
@ -110,7 +110,7 @@ bool PhysicsBody3D::get_collision_layer_bit(int p_bit) const {
|
|||
return get_collision_layer() & (1 << p_bit);
|
||||
}
|
||||
|
||||
Array PhysicsBody3D::get_collision_exceptions() {
|
||||
TypedArray<PhysicsBody3D> PhysicsBody3D::get_collision_exceptions() {
|
||||
List<RID> exceptions;
|
||||
PhysicsServer3D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions);
|
||||
Array ret;
|
||||
|
|
|
@ -68,7 +68,7 @@ public:
|
|||
void set_collision_mask_bit(int p_bit, bool p_value);
|
||||
bool get_collision_mask_bit(int p_bit) const;
|
||||
|
||||
Array get_collision_exceptions();
|
||||
TypedArray<PhysicsBody3D> get_collision_exceptions();
|
||||
void add_collision_exception_with(Node *p_node); //must be physicsbody
|
||||
void remove_collision_exception_with(Node *p_node);
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "core/engine.h"
|
||||
#include "core/message_queue.h"
|
||||
#include "core/project_settings.h"
|
||||
#include "core/type_info.h"
|
||||
#include "scene/3d/physics_body_3d.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
|
||||
|
@ -770,7 +771,7 @@ void _pb_start_simulation(const Skeleton3D *p_skeleton, Node *p_node, const Vect
|
|||
}
|
||||
}
|
||||
|
||||
void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) {
|
||||
void Skeleton3D::physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones) {
|
||||
set_physics_process_internal(false);
|
||||
|
||||
Vector<int> sim_bones;
|
||||
|
@ -780,12 +781,9 @@ void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) {
|
|||
sim_bones.resize(p_bones.size());
|
||||
int c = 0;
|
||||
for (int i = sim_bones.size() - 1; 0 <= i; --i) {
|
||||
Variant::Type type = p_bones.get(i).get_type();
|
||||
if (Variant::STRING == type || Variant::STRING_NAME == type) {
|
||||
int bone_id = find_bone(p_bones.get(i));
|
||||
if (bone_id != -1)
|
||||
sim_bones.write[c++] = bone_id;
|
||||
}
|
||||
int bone_id = find_bone(p_bones[i]);
|
||||
if (bone_id != -1)
|
||||
sim_bones.write[c++] = bone_id;
|
||||
}
|
||||
sim_bones.resize(c);
|
||||
}
|
||||
|
|
|
@ -222,7 +222,7 @@ private:
|
|||
|
||||
public:
|
||||
void physical_bones_stop_simulation();
|
||||
void physical_bones_start_simulation_on(const Array &p_bones);
|
||||
void physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones);
|
||||
void physical_bones_add_collision_exception(RID p_exception);
|
||||
void physical_bones_remove_collision_exception(RID p_exception);
|
||||
#endif // _3D_DISABLED
|
||||
|
|
|
@ -170,7 +170,7 @@ void register_server_types() {
|
|||
ClassDB::register_class<RDTextureView>();
|
||||
ClassDB::register_class<RDAttachmentFormat>();
|
||||
ClassDB::register_class<RDSamplerState>();
|
||||
ClassDB::register_class<RDVertexDescription>();
|
||||
ClassDB::register_class<RDVertexAttribute>();
|
||||
ClassDB::register_class<RDUniform>();
|
||||
ClassDB::register_class<RDPipelineRasterizationState>();
|
||||
ClassDB::register_class<RDPipelineMultisampleState>();
|
||||
|
|
|
@ -273,7 +273,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
|
||||
Vector<uint8_t> polygon_buffer;
|
||||
polygon_buffer.resize(buffer_size * sizeof(float));
|
||||
Vector<RD::VertexDescription> descriptions;
|
||||
Vector<RD::VertexAttribute> descriptions;
|
||||
descriptions.resize(4);
|
||||
Vector<RID> buffers;
|
||||
buffers.resize(4);
|
||||
|
@ -284,7 +284,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
uint32_t *uptr = (uint32_t *)r;
|
||||
uint32_t base_offset = 0;
|
||||
{ //vertices
|
||||
RD::VertexDescription vd;
|
||||
RD::VertexAttribute vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
|
||||
vd.offset = base_offset * sizeof(float);
|
||||
vd.location = RS::ARRAY_VERTEX;
|
||||
|
@ -304,7 +304,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
|
||||
//colors
|
||||
if ((uint32_t)p_colors.size() == vertex_count || p_colors.size() == 1) {
|
||||
RD::VertexDescription vd;
|
||||
RD::VertexAttribute vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
|
||||
vd.offset = base_offset * sizeof(float);
|
||||
vd.location = RS::ARRAY_COLOR;
|
||||
|
@ -332,7 +332,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
}
|
||||
base_offset += 4;
|
||||
} else {
|
||||
RD::VertexDescription vd;
|
||||
RD::VertexAttribute vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
|
||||
vd.offset = 0;
|
||||
vd.location = RS::ARRAY_COLOR;
|
||||
|
@ -344,7 +344,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
|
||||
//uvs
|
||||
if ((uint32_t)p_uvs.size() == vertex_count) {
|
||||
RD::VertexDescription vd;
|
||||
RD::VertexAttribute vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
|
||||
vd.offset = base_offset * sizeof(float);
|
||||
vd.location = RS::ARRAY_TEX_UV;
|
||||
|
@ -360,7 +360,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
}
|
||||
base_offset += 2;
|
||||
} else {
|
||||
RD::VertexDescription vd;
|
||||
RD::VertexAttribute vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
|
||||
vd.offset = 0;
|
||||
vd.location = RS::ARRAY_TEX_UV;
|
||||
|
@ -372,7 +372,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
|
||||
//bones
|
||||
if ((uint32_t)p_indices.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) {
|
||||
RD::VertexDescription vd;
|
||||
RD::VertexAttribute vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
|
||||
vd.offset = base_offset * sizeof(float);
|
||||
vd.location = RS::ARRAY_BONES;
|
||||
|
@ -401,7 +401,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
|
||||
base_offset += 4;
|
||||
} else {
|
||||
RD::VertexDescription vd;
|
||||
RD::VertexAttribute vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
|
||||
vd.offset = 0;
|
||||
vd.location = RS::ARRAY_BONES;
|
||||
|
@ -2423,8 +2423,8 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
|
|||
}
|
||||
|
||||
//pipelines
|
||||
Vector<RD::VertexDescription> vf;
|
||||
RD::VertexDescription vd;
|
||||
Vector<RD::VertexAttribute> vf;
|
||||
RD::VertexAttribute vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
|
||||
vd.location = 0;
|
||||
vd.offset = 0;
|
||||
|
|
|
@ -2341,14 +2341,14 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
|
|||
|
||||
Mesh::Surface::Version &v = s->versions[version];
|
||||
|
||||
Vector<RD::VertexDescription> attributes;
|
||||
Vector<RD::VertexAttribute> attributes;
|
||||
Vector<RID> buffers;
|
||||
|
||||
uint32_t stride = 0;
|
||||
|
||||
for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) {
|
||||
|
||||
RD::VertexDescription vd;
|
||||
RD::VertexAttribute vd;
|
||||
RID buffer;
|
||||
vd.location = i;
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ Vector<uint8_t> RenderingDevice::shader_compile_from_source(ShaderStage p_stage,
|
|||
return compile_function(p_stage, p_source_code, p_language, r_error);
|
||||
}
|
||||
|
||||
RID RenderingDevice::_texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const Array &p_data) {
|
||||
RID RenderingDevice::_texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data) {
|
||||
|
||||
ERR_FAIL_COND_V(p_format.is_null(), RID());
|
||||
ERR_FAIL_COND_V(p_view.is_null(), RID());
|
||||
|
@ -86,7 +86,7 @@ RID RenderingDevice::_texture_create_shared_from_slice(const Ref<RDTextureView>
|
|||
return texture_create_shared_from_slice(p_view->base, p_with_texture, p_layer, p_mipmap, p_slice_type);
|
||||
}
|
||||
|
||||
RenderingDevice::FramebufferFormatID RenderingDevice::_framebuffer_format_create(const Array &p_attachments) {
|
||||
RenderingDevice::FramebufferFormatID RenderingDevice::_framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments) {
|
||||
|
||||
Vector<AttachmentFormat> attachments;
|
||||
attachments.resize(p_attachments.size());
|
||||
|
@ -111,20 +111,20 @@ RID RenderingDevice::_sampler_create(const Ref<RDSamplerState> &p_state) {
|
|||
return sampler_create(p_state->base);
|
||||
}
|
||||
|
||||
RenderingDevice::VertexFormatID RenderingDevice::_vertex_format_create(const Array &p_vertex_formats) {
|
||||
RenderingDevice::VertexFormatID RenderingDevice::_vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats) {
|
||||
|
||||
Vector<VertexDescription> descriptions;
|
||||
Vector<VertexAttribute> descriptions;
|
||||
descriptions.resize(p_vertex_formats.size());
|
||||
|
||||
for (int i = 0; i < p_vertex_formats.size(); i++) {
|
||||
Ref<RDVertexDescription> af = p_vertex_formats[i];
|
||||
Ref<RDVertexAttribute> af = p_vertex_formats[i];
|
||||
ERR_FAIL_COND_V(af.is_null(), INVALID_FORMAT_ID);
|
||||
descriptions.write[i] = af->base;
|
||||
}
|
||||
return vertex_format_create(descriptions);
|
||||
}
|
||||
|
||||
RID RenderingDevice::_vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Array &p_src_buffers) {
|
||||
RID RenderingDevice::_vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers) {
|
||||
|
||||
Vector<RID> buffers = Variant(p_src_buffers);
|
||||
|
||||
|
@ -194,6 +194,10 @@ RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p
|
|||
PipelineMultisampleState multisample_state;
|
||||
if (p_multisample_state.is_valid()) {
|
||||
multisample_state = p_multisample_state->base;
|
||||
for (int i = 0; i < p_multisample_state->sample_masks.size(); i++) {
|
||||
int64_t mask = p_multisample_state->sample_masks[i];
|
||||
multisample_state.sample_mask.push_back(mask);
|
||||
}
|
||||
}
|
||||
|
||||
PipelineDepthStencilState depth_stencil_state;
|
||||
|
@ -204,6 +208,12 @@ RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p
|
|||
PipelineColorBlendState color_blend_state;
|
||||
if (p_blend_state.is_valid()) {
|
||||
color_blend_state = p_blend_state->base;
|
||||
for (int i = 0; i < p_blend_state->attachments.size(); i++) {
|
||||
Ref<RDPipelineColorBlendStateAttachment> attachment = p_blend_state->attachments[i];
|
||||
if (attachment.is_valid()) {
|
||||
color_blend_state.attachments.push_back(attachment->base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return render_pipeline_create(p_shader, p_framebuffer_format, p_vertex_format, p_render_primitive, rasterization_state, multisample_state, depth_stencil_state, color_blend_state, p_dynamic_state_flags);
|
||||
|
|
|
@ -32,13 +32,14 @@
|
|||
#define RENDERING_DEVICE_H
|
||||
|
||||
#include "core/object.h"
|
||||
#include "core/typed_array.h"
|
||||
#include "servers/display_server.h"
|
||||
|
||||
class RDTextureFormat;
|
||||
class RDTextureView;
|
||||
class RDAttachments;
|
||||
class RDAttachmentFormat;
|
||||
class RDSamplerState;
|
||||
class RDVertexDescriptions;
|
||||
class RDVertexAttribute;
|
||||
class RDShaderSource;
|
||||
class RDShaderBytecode;
|
||||
class RDUniforms;
|
||||
|
@ -547,13 +548,13 @@ public:
|
|||
VERTEX_FREQUENCY_INSTANCE,
|
||||
};
|
||||
|
||||
struct VertexDescription {
|
||||
struct VertexAttribute {
|
||||
uint32_t location; //shader location
|
||||
uint32_t offset;
|
||||
DataFormat format;
|
||||
uint32_t stride;
|
||||
VertexFrequency frequency;
|
||||
VertexDescription() {
|
||||
VertexAttribute() {
|
||||
location = 0;
|
||||
offset = 0;
|
||||
stride = 0;
|
||||
|
@ -566,7 +567,7 @@ public:
|
|||
typedef int64_t VertexFormatID;
|
||||
|
||||
// This ID is warranted to be unique for the same formats, does not need to be freed
|
||||
virtual VertexFormatID vertex_format_create(const Vector<VertexDescription> &p_vertex_formats) = 0;
|
||||
virtual VertexFormatID vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats) = 0;
|
||||
virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers) = 0;
|
||||
|
||||
enum IndexBufferFormat {
|
||||
|
@ -1051,15 +1052,15 @@ public:
|
|||
|
||||
protected:
|
||||
//binders to script API
|
||||
RID _texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const Array &p_data = Array());
|
||||
RID _texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data = Array());
|
||||
RID _texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture);
|
||||
RID _texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D);
|
||||
|
||||
FramebufferFormatID _framebuffer_format_create(const Array &p_attachments);
|
||||
FramebufferFormatID _framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments);
|
||||
RID _framebuffer_create(const Array &p_textures, FramebufferFormatID p_format_check = INVALID_ID);
|
||||
RID _sampler_create(const Ref<RDSamplerState> &p_state);
|
||||
VertexFormatID _vertex_format_create(const Array &p_vertex_formats);
|
||||
RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Array &p_src_buffers);
|
||||
VertexFormatID _vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats);
|
||||
RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers);
|
||||
|
||||
Ref<RDShaderBytecode> _shader_compile_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache = true);
|
||||
RID _shader_create(const Ref<RDShaderBytecode> &p_bytecode);
|
||||
|
|
|
@ -142,10 +142,10 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
class RDVertexDescription : public Reference {
|
||||
GDCLASS(RDVertexDescription, Reference)
|
||||
class RDVertexAttribute : public Reference {
|
||||
GDCLASS(RDVertexAttribute, Reference)
|
||||
friend class RenderingDevice;
|
||||
RD::VertexDescription base;
|
||||
RD::VertexAttribute base;
|
||||
|
||||
public:
|
||||
RD_SETGET(uint32_t, location)
|
||||
|
@ -156,11 +156,11 @@ public:
|
|||
|
||||
protected:
|
||||
static void _bind_methods() {
|
||||
RD_BIND(Variant::INT, RDVertexDescription, location);
|
||||
RD_BIND(Variant::INT, RDVertexDescription, offset);
|
||||
RD_BIND(Variant::INT, RDVertexDescription, format);
|
||||
RD_BIND(Variant::INT, RDVertexDescription, stride);
|
||||
RD_BIND(Variant::INT, RDVertexDescription, frequency);
|
||||
RD_BIND(Variant::INT, RDVertexAttribute, location);
|
||||
RD_BIND(Variant::INT, RDVertexAttribute, offset);
|
||||
RD_BIND(Variant::INT, RDVertexAttribute, format);
|
||||
RD_BIND(Variant::INT, RDVertexAttribute, stride);
|
||||
RD_BIND(Variant::INT, RDVertexAttribute, frequency);
|
||||
}
|
||||
};
|
||||
class RDShaderSource : public Reference {
|
||||
|
@ -412,6 +412,7 @@ class RDPipelineMultisampleState : public Reference {
|
|||
friend class RenderingDevice;
|
||||
|
||||
RD::PipelineMultisampleState base;
|
||||
TypedArray<int64_t> sample_masks;
|
||||
|
||||
public:
|
||||
RD_SETGET(RD::TextureSamples, sample_count)
|
||||
|
@ -420,24 +421,10 @@ public:
|
|||
RD_SETGET(bool, enable_alpha_to_coverage)
|
||||
RD_SETGET(bool, enable_alpha_to_one)
|
||||
|
||||
void add_sample_mask(uint32_t p_sample_mask) { base.sample_mask.push_back(p_sample_mask); }
|
||||
void clear_sample_masks() { base.sample_mask.clear(); }
|
||||
Vector<int64_t> get_sample_masks() const {
|
||||
Vector<int64_t> sample_masks;
|
||||
for (int i = 0; i < base.sample_mask.size(); i++) {
|
||||
sample_masks.push_back(base.sample_mask[i]);
|
||||
}
|
||||
return sample_masks;
|
||||
}
|
||||
void set_sample_masks(const TypedArray<int64_t> &p_masks) { sample_masks = p_masks; }
|
||||
TypedArray<int64_t> get_sample_masks() const { return sample_masks; }
|
||||
|
||||
protected:
|
||||
void _set_sample_masks(const Vector<int64_t> &p_masks) {
|
||||
base.sample_mask.clear();
|
||||
for (int i = 0; i < p_masks.size(); i++) {
|
||||
int64_t mask = p_masks[i];
|
||||
base.sample_mask.push_back(mask);
|
||||
}
|
||||
}
|
||||
static void _bind_methods() {
|
||||
RD_BIND(Variant::INT, RDPipelineMultisampleState, sample_count);
|
||||
RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_sample_shading);
|
||||
|
@ -445,11 +432,9 @@ protected:
|
|||
RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_coverage);
|
||||
RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_one);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_sample_mask", "mask"), &RDPipelineMultisampleState::add_sample_mask);
|
||||
ClassDB::bind_method(D_METHOD("clear_sample_masks"), &RDPipelineMultisampleState::clear_sample_masks);
|
||||
ClassDB::bind_method(D_METHOD("_set_sample_masks", "sample_masks"), &RDPipelineMultisampleState::_set_sample_masks);
|
||||
ClassDB::bind_method(D_METHOD("set_sample_masks", "masks"), &RDPipelineMultisampleState::set_sample_masks);
|
||||
ClassDB::bind_method(D_METHOD("get_sample_masks"), &RDPipelineMultisampleState::get_sample_masks);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT64_ARRAY, "_sample_masks", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_sample_masks", "get_sample_masks");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "sample_masks", PROPERTY_HINT_ARRAY_TYPE, "int"), "set_sample_masks", "get_sample_masks");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -514,6 +499,7 @@ protected:
|
|||
|
||||
class RDPipelineColorBlendStateAttachment : public Reference {
|
||||
GDCLASS(RDPipelineColorBlendStateAttachment, Reference)
|
||||
friend class RenderingDevice;
|
||||
RD::PipelineColorBlendState::Attachment base;
|
||||
|
||||
public:
|
||||
|
@ -529,10 +515,6 @@ public:
|
|||
RD_SETGET(bool, write_b)
|
||||
RD_SETGET(bool, write_a)
|
||||
|
||||
void set_as_disabled() {
|
||||
base = RD::PipelineColorBlendState::Attachment();
|
||||
}
|
||||
|
||||
void set_as_mix() {
|
||||
|
||||
base = RD::PipelineColorBlendState::Attachment();
|
||||
|
@ -545,6 +527,9 @@ public:
|
|||
|
||||
protected:
|
||||
static void _bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_as_mix"), &RDPipelineColorBlendStateAttachment::set_as_mix);
|
||||
|
||||
RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, enable_blend);
|
||||
RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, src_color_blend_factor);
|
||||
RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, dst_color_blend_factor);
|
||||
|
@ -564,49 +549,19 @@ class RDPipelineColorBlendState : public Reference {
|
|||
friend class RenderingDevice;
|
||||
RD::PipelineColorBlendState base;
|
||||
|
||||
Vector<Ref<RDPipelineColorBlendStateAttachment>> attachments;
|
||||
TypedArray<RDPipelineColorBlendStateAttachment> attachments;
|
||||
|
||||
public:
|
||||
RD_SETGET(bool, enable_logic_op)
|
||||
RD_SETGET(RD::LogicOperation, logic_op)
|
||||
RD_SETGET(Color, blend_constant)
|
||||
|
||||
void add_attachment(const Ref<RDPipelineColorBlendStateAttachment> &p_attachment) {
|
||||
attachments.push_back(p_attachment);
|
||||
void set_attachments(const TypedArray<RDPipelineColorBlendStateAttachment> &p_attachments) {
|
||||
attachments.push_back(p_attachments);
|
||||
}
|
||||
|
||||
void add_no_blend_attachment() {
|
||||
Ref<RDPipelineColorBlendStateAttachment> attachment;
|
||||
attachment.instance();
|
||||
attachment->set_as_disabled();
|
||||
add_attachment(attachment);
|
||||
}
|
||||
|
||||
void add_blend_mix_attachment() {
|
||||
Ref<RDPipelineColorBlendStateAttachment> attachment;
|
||||
attachment.instance();
|
||||
attachment->set_as_mix();
|
||||
add_attachment(attachment);
|
||||
}
|
||||
|
||||
void clear_attachments() {
|
||||
attachments.clear();
|
||||
}
|
||||
|
||||
Array get_attachments() const {
|
||||
Array ret;
|
||||
for (int i = 0; i < attachments.size(); i++) {
|
||||
ret.push_back(attachments[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void _set_attachments(const Array &p_attachments) {
|
||||
attachments.clear();
|
||||
for (int i = 0; i < p_attachments.size(); i++) {
|
||||
Ref<RDPipelineColorBlendStateAttachment> attachment = p_attachments[i];
|
||||
ERR_FAIL_COND(!attachment.is_valid());
|
||||
attachments.push_back(attachment);
|
||||
}
|
||||
TypedArray<RDPipelineColorBlendStateAttachment> get_attachments() const {
|
||||
return attachments;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -615,13 +570,9 @@ protected:
|
|||
RD_BIND(Variant::INT, RDPipelineColorBlendState, logic_op);
|
||||
RD_BIND(Variant::COLOR, RDPipelineColorBlendState, blend_constant);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_attachment", "atachment"), &RDPipelineColorBlendState::add_attachment);
|
||||
ClassDB::bind_method(D_METHOD("add_no_blend_attachment"), &RDPipelineColorBlendState::add_no_blend_attachment);
|
||||
ClassDB::bind_method(D_METHOD("add_blend_mix_attachment"), &RDPipelineColorBlendState::add_blend_mix_attachment);
|
||||
ClassDB::bind_method(D_METHOD("clear_attachments"), &RDPipelineColorBlendState::clear_attachments);
|
||||
ClassDB::bind_method(D_METHOD("_set_attachments", "attachments"), &RDPipelineColorBlendState::_set_attachments);
|
||||
ClassDB::bind_method(D_METHOD("set_attachments", "atachments"), &RDPipelineColorBlendState::set_attachments);
|
||||
ClassDB::bind_method(D_METHOD("get_attachments"), &RDPipelineColorBlendState::get_attachments);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_attachments", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_attachments", "get_attachments");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "attachments", PROPERTY_HINT_ARRAY_TYPE, "RDPipelineColorBlendStateAttachment"), "set_attachments", "get_attachments");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue