Refactored Mesh internals and formats.
-Changed how mesh data is organized, hoping to make it more efficient on Vulkan and GLES. -Removed compression, it now always uses the most efficient format. -Added support for custom arrays (up to 8 custom formats) -Added support for 8 weights in skeleton data. -Added a simple optional versioning system for imported assets, to reimport if binary is newer -Fixes #43979 (I needed to test) WARNING: -NOT backwards compatible with previous 4.x-devel, will most likely never be, but it will force reimport scenes due to version change. -NOT backwards compatible with 3.x scenes, this will be eventually re-added. -Skeletons not working any longer, will fix in next PR.
This commit is contained in:
parent
3beab2646f
commit
70f5972905
29 changed files with 1332 additions and 881 deletions
|
|
@ -119,9 +119,9 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
Vector<uint8_t> polygon_buffer;
|
||||
polygon_buffer.resize(buffer_size * sizeof(float));
|
||||
Vector<RD::VertexAttribute> descriptions;
|
||||
descriptions.resize(4);
|
||||
descriptions.resize(5);
|
||||
Vector<RID> buffers;
|
||||
buffers.resize(4);
|
||||
buffers.resize(5);
|
||||
|
||||
{
|
||||
const uint8_t *r = polygon_buffer.ptr();
|
||||
|
|
@ -218,7 +218,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::VertexAttribute vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
|
||||
vd.format = RD::DATA_FORMAT_R16G16B16A16_UINT;
|
||||
vd.offset = base_offset * sizeof(float);
|
||||
vd.location = RS::ARRAY_BONES;
|
||||
vd.stride = stride * sizeof(float);
|
||||
|
|
@ -226,24 +226,17 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
descriptions.write[3] = vd;
|
||||
|
||||
const int *bone_ptr = p_bones.ptr();
|
||||
const float *weight_ptr = p_weights.ptr();
|
||||
|
||||
for (uint32_t i = 0; i < vertex_count; i++) {
|
||||
uint16_t *bone16w = (uint16_t *)&uptr[base_offset + i * stride];
|
||||
uint16_t *weight16w = (uint16_t *)&uptr[base_offset + i * stride + 2];
|
||||
|
||||
bone16w[0] = bone_ptr[i * 4 + 0];
|
||||
bone16w[1] = bone_ptr[i * 4 + 1];
|
||||
bone16w[2] = bone_ptr[i * 4 + 2];
|
||||
bone16w[3] = bone_ptr[i * 4 + 3];
|
||||
|
||||
weight16w[0] = CLAMP(weight_ptr[i * 4 + 0] * 65535, 0, 65535);
|
||||
weight16w[1] = CLAMP(weight_ptr[i * 4 + 1] * 65535, 0, 65535);
|
||||
weight16w[2] = CLAMP(weight_ptr[i * 4 + 2] * 65535, 0, 65535);
|
||||
weight16w[3] = CLAMP(weight_ptr[i * 4 + 3] * 65535, 0, 65535);
|
||||
}
|
||||
|
||||
base_offset += 4;
|
||||
base_offset += 2;
|
||||
} else {
|
||||
RD::VertexAttribute vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
|
||||
|
|
@ -255,6 +248,39 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
buffers.write[3] = storage->mesh_get_default_rd_buffer(RasterizerStorageRD::DEFAULT_RD_BUFFER_BONES);
|
||||
}
|
||||
|
||||
//weights
|
||||
if ((uint32_t)p_weights.size() == vertex_count * 4) {
|
||||
RD::VertexAttribute vd;
|
||||
vd.format = RD::DATA_FORMAT_R16G16B16A16_UNORM;
|
||||
vd.offset = base_offset * sizeof(float);
|
||||
vd.location = RS::ARRAY_WEIGHTS;
|
||||
vd.stride = stride * sizeof(float);
|
||||
|
||||
descriptions.write[4] = vd;
|
||||
|
||||
const float *weight_ptr = p_weights.ptr();
|
||||
|
||||
for (uint32_t i = 0; i < vertex_count; i++) {
|
||||
uint16_t *weight16w = (uint16_t *)&uptr[base_offset + i * stride];
|
||||
|
||||
weight16w[0] = CLAMP(weight_ptr[i * 4 + 0] * 65535, 0, 65535);
|
||||
weight16w[1] = CLAMP(weight_ptr[i * 4 + 1] * 65535, 0, 65535);
|
||||
weight16w[2] = CLAMP(weight_ptr[i * 4 + 2] * 65535, 0, 65535);
|
||||
weight16w[3] = CLAMP(weight_ptr[i * 4 + 3] * 65535, 0, 65535);
|
||||
}
|
||||
|
||||
base_offset += 2;
|
||||
} else {
|
||||
RD::VertexAttribute vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
|
||||
vd.offset = 0;
|
||||
vd.location = RS::ARRAY_WEIGHTS;
|
||||
vd.stride = 0;
|
||||
|
||||
descriptions.write[4] = vd;
|
||||
buffers.write[4] = storage->mesh_get_default_rd_buffer(RasterizerStorageRD::DEFAULT_RD_BUFFER_BONES);
|
||||
}
|
||||
|
||||
//check that everything is as it should be
|
||||
ERR_FAIL_COND_V(base_offset != stride, 0); //bug
|
||||
}
|
||||
|
|
@ -1796,22 +1822,25 @@ void RasterizerCanvasRD::occluder_polygon_set_shape(RID p_occluder, const Vector
|
|||
ERR_FAIL_COND(!oc);
|
||||
|
||||
Vector<Vector2> lines;
|
||||
int lc = p_points.size() * 2;
|
||||
|
||||
lines.resize(lc - (p_closed ? 0 : 2));
|
||||
{
|
||||
Vector2 *w = lines.ptrw();
|
||||
const Vector2 *r = p_points.ptr();
|
||||
if (p_points.size()) {
|
||||
int lc = p_points.size() * 2;
|
||||
|
||||
int max = lc / 2;
|
||||
if (!p_closed) {
|
||||
max--;
|
||||
}
|
||||
for (int i = 0; i < max; i++) {
|
||||
Vector2 a = r[i];
|
||||
Vector2 b = r[(i + 1) % (lc / 2)];
|
||||
w[i * 2 + 0] = a;
|
||||
w[i * 2 + 1] = b;
|
||||
lines.resize(lc - (p_closed ? 0 : 2));
|
||||
{
|
||||
Vector2 *w = lines.ptrw();
|
||||
const Vector2 *r = p_points.ptr();
|
||||
|
||||
int max = lc / 2;
|
||||
if (!p_closed) {
|
||||
max--;
|
||||
}
|
||||
for (int i = 0; i < max; i++) {
|
||||
Vector2 a = r[i];
|
||||
Vector2 b = r[(i + 1) % (lc / 2)];
|
||||
w[i * 2 + 0] = a;
|
||||
w[i * 2 + 1] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1832,7 +1861,7 @@ void RasterizerCanvasRD::occluder_polygon_set_shape(RID p_occluder, const Vector
|
|||
if (lines.size()) {
|
||||
Vector<uint8_t> geometry;
|
||||
Vector<uint8_t> indices;
|
||||
lc = lines.size();
|
||||
int lc = lines.size();
|
||||
|
||||
geometry.resize(lc * 6 * sizeof(float));
|
||||
indices.resize(lc * 3 * sizeof(uint16_t));
|
||||
|
|
@ -1902,19 +1931,21 @@ void RasterizerCanvasRD::occluder_polygon_set_shape(RID p_occluder, const Vector
|
|||
|
||||
Vector<int> sdf_indices;
|
||||
|
||||
if (p_closed) {
|
||||
sdf_indices = Geometry2D::triangulate_polygon(p_points);
|
||||
oc->sdf_is_lines = false;
|
||||
} else {
|
||||
int max = p_points.size();
|
||||
sdf_indices.resize(max * 2);
|
||||
if (p_points.size()) {
|
||||
if (p_closed) {
|
||||
sdf_indices = Geometry2D::triangulate_polygon(p_points);
|
||||
oc->sdf_is_lines = false;
|
||||
} else {
|
||||
int max = p_points.size();
|
||||
sdf_indices.resize(max * 2);
|
||||
|
||||
int *iw = sdf_indices.ptrw();
|
||||
for (int i = 0; i < max; i++) {
|
||||
iw[i * 2 + 0] = i;
|
||||
iw[i * 2 + 1] = (i + 1) % max;
|
||||
int *iw = sdf_indices.ptrw();
|
||||
for (int i = 0; i < max; i++) {
|
||||
iw[i * 2 + 0] = i;
|
||||
iw[i * 2 + 1] = (i + 1) % max;
|
||||
}
|
||||
oc->sdf_is_lines = true;
|
||||
}
|
||||
oc->sdf_is_lines = true;
|
||||
}
|
||||
|
||||
if (oc->sdf_index_count != sdf_indices.size() && oc->sdf_point_count != p_points.size() && oc->sdf_vertex_array.is_valid()) {
|
||||
|
|
|
|||
|
|
@ -2795,6 +2795,12 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
|
|||
actions.renames["FOG"] = "custom_fog";
|
||||
actions.renames["RADIANCE"] = "custom_radiance";
|
||||
actions.renames["IRRADIANCE"] = "custom_irradiance";
|
||||
actions.renames["BONE_INDICES"] = "bone_attrib";
|
||||
actions.renames["BONE_WEIGHTS"] = "weight_attrib";
|
||||
actions.renames["CUSTOM0"] = "custom0_attrib";
|
||||
actions.renames["CUSTOM1"] = "custom1_attrib";
|
||||
actions.renames["CUSTOM2"] = "custom2_attrib";
|
||||
actions.renames["CUSTOM3"] = "custom3_attrib";
|
||||
|
||||
//for light
|
||||
actions.renames["VIEW"] = "view";
|
||||
|
|
@ -2817,6 +2823,12 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
|
|||
actions.usage_defines["AO_LIGHT_AFFECT"] = "#define AO_USED\n";
|
||||
actions.usage_defines["UV"] = "#define UV_USED\n";
|
||||
actions.usage_defines["UV2"] = "#define UV2_USED\n";
|
||||
actions.usage_defines["BONE_INDICES"] = "#define BONES_USED\n";
|
||||
actions.usage_defines["BONE_WEIGHTS"] = "#define WEIGHTS_USED\n";
|
||||
actions.usage_defines["CUSTOM0"] = "#define CUSTOM0\n";
|
||||
actions.usage_defines["CUSTOM1"] = "#define CUSTOM1\n";
|
||||
actions.usage_defines["CUSTOM2"] = "#define CUSTOM2\n";
|
||||
actions.usage_defines["CUSTOM3"] = "#define CUSTOM3\n";
|
||||
actions.usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
|
||||
actions.usage_defines["NORMALMAP_DEPTH"] = "@NORMALMAP";
|
||||
actions.usage_defines["COLOR"] = "#define COLOR_USED\n";
|
||||
|
|
|
|||
|
|
@ -5336,18 +5336,19 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
|
|||
tonemap.exposure = env->exposure;
|
||||
}
|
||||
|
||||
tonemap.use_color_correction = false;
|
||||
tonemap.use_1d_color_correction = false;
|
||||
tonemap.color_correction_texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
|
||||
|
||||
if (can_use_effects && env) {
|
||||
tonemap.use_bcs = env->adjustments_enabled;
|
||||
tonemap.brightness = env->adjustments_brightness;
|
||||
tonemap.contrast = env->adjustments_contrast;
|
||||
tonemap.saturation = env->adjustments_saturation;
|
||||
tonemap.use_1d_color_correction = env->use_1d_color_correction;
|
||||
if (env->adjustments_enabled && env->color_correction.is_valid()) {
|
||||
tonemap.use_color_correction = true;
|
||||
tonemap.use_1d_color_correction = env->use_1d_color_correction;
|
||||
tonemap.color_correction_texture = storage->texture_get_rd_texture(env->color_correction);
|
||||
} else {
|
||||
tonemap.use_color_correction = false;
|
||||
tonemap.color_correction_texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2398,13 +2398,15 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
|
|||
ERR_FAIL_COND(!mesh);
|
||||
|
||||
//ensure blend shape consistency
|
||||
ERR_FAIL_COND(mesh->blend_shape_count && p_surface.blend_shapes.size() != (int)mesh->blend_shape_count);
|
||||
ERR_FAIL_COND(mesh->blend_shape_count && p_surface.blend_shape_count != mesh->blend_shape_count);
|
||||
ERR_FAIL_COND(mesh->blend_shape_count && p_surface.bone_aabbs.size() != mesh->bone_aabbs.size());
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
//do a validation, to catch errors first
|
||||
{
|
||||
uint32_t stride = 0;
|
||||
uint32_t attrib_stride = 0;
|
||||
uint32_t skin_stride = 0;
|
||||
|
||||
for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) {
|
||||
if ((p_surface.format & (1 << i))) {
|
||||
|
|
@ -2418,59 +2420,54 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
|
|||
|
||||
} break;
|
||||
case RS::ARRAY_NORMAL: {
|
||||
if (p_surface.format & RS::ARRAY_COMPRESS_NORMAL) {
|
||||
stride += sizeof(int8_t) * 4;
|
||||
} else {
|
||||
stride += sizeof(float) * 4;
|
||||
}
|
||||
stride += sizeof(int32_t);
|
||||
|
||||
} break;
|
||||
case RS::ARRAY_TANGENT: {
|
||||
if (p_surface.format & RS::ARRAY_COMPRESS_TANGENT) {
|
||||
stride += sizeof(int8_t) * 4;
|
||||
} else {
|
||||
stride += sizeof(float) * 4;
|
||||
}
|
||||
stride += sizeof(int32_t);
|
||||
|
||||
} break;
|
||||
case RS::ARRAY_COLOR: {
|
||||
if (p_surface.format & RS::ARRAY_COMPRESS_COLOR) {
|
||||
stride += sizeof(int8_t) * 4;
|
||||
} else {
|
||||
stride += sizeof(float) * 4;
|
||||
}
|
||||
|
||||
attrib_stride += sizeof(int16_t) * 4;
|
||||
} break;
|
||||
case RS::ARRAY_TEX_UV: {
|
||||
if (p_surface.format & RS::ARRAY_COMPRESS_TEX_UV) {
|
||||
stride += sizeof(int16_t) * 2;
|
||||
} else {
|
||||
stride += sizeof(float) * 2;
|
||||
}
|
||||
attrib_stride += sizeof(float) * 2;
|
||||
|
||||
} break;
|
||||
case RS::ARRAY_TEX_UV2: {
|
||||
if (p_surface.format & RS::ARRAY_COMPRESS_TEX_UV2) {
|
||||
stride += sizeof(int16_t) * 2;
|
||||
} else {
|
||||
stride += sizeof(float) * 2;
|
||||
}
|
||||
attrib_stride += sizeof(float) * 2;
|
||||
|
||||
} break;
|
||||
case RS::ARRAY_CUSTOM0:
|
||||
case RS::ARRAY_CUSTOM1:
|
||||
case RS::ARRAY_CUSTOM2:
|
||||
case RS::ARRAY_CUSTOM3: {
|
||||
int idx = i - RS::ARRAY_CUSTOM0;
|
||||
uint32_t fmt_shift[RS::ARRAY_CUSTOM_COUNT] = { RS::ARRAY_FORMAT_CUSTOM0_SHIFT, RS::ARRAY_FORMAT_CUSTOM1_SHIFT, RS::ARRAY_FORMAT_CUSTOM2_SHIFT, RS::ARRAY_FORMAT_CUSTOM3_SHIFT };
|
||||
uint32_t fmt = (p_surface.format >> fmt_shift[idx]) & RS::ARRAY_FORMAT_CUSTOM_MASK;
|
||||
uint32_t fmtsize[RS::ARRAY_CUSTOM_MAX] = { 4, 4, 4, 8, 4, 8, 12, 16 };
|
||||
attrib_stride += fmtsize[fmt];
|
||||
|
||||
} break;
|
||||
case RS::ARRAY_WEIGHTS:
|
||||
case RS::ARRAY_BONES: {
|
||||
//assumed weights too
|
||||
|
||||
//unique format, internally 16 bits, exposed as single array for 32
|
||||
|
||||
stride += sizeof(int32_t) * 4;
|
||||
|
||||
//uses a separate array
|
||||
bool use_8 = p_surface.format & RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS;
|
||||
skin_stride += sizeof(int16_t) * (use_8 ? 8 : 4);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int expected_size = stride * p_surface.vertex_count;
|
||||
ERR_FAIL_COND_MSG(expected_size != p_surface.vertex_data.size(), "Size of data provided (" + itos(p_surface.vertex_data.size()) + ") does not match expected (" + itos(expected_size) + ")");
|
||||
ERR_FAIL_COND_MSG(expected_size != p_surface.vertex_data.size(), "Size of vertex data provided (" + itos(p_surface.vertex_data.size()) + ") does not match expected (" + itos(expected_size) + ")");
|
||||
int expected_attrib_size = attrib_stride * p_surface.vertex_count;
|
||||
ERR_FAIL_COND_MSG(expected_attrib_size != p_surface.attribute_data.size(), "Size of attribute data provided (" + itos(p_surface.attribute_data.size()) + ") does not match expected (" + itos(expected_attrib_size) + ")");
|
||||
|
||||
if ((p_surface.format & RS::ARRAY_FORMAT_WEIGHTS) && (p_surface.format & RS::ARRAY_FORMAT_BONES)) {
|
||||
expected_size = skin_stride * p_surface.vertex_count;
|
||||
ERR_FAIL_COND_MSG(expected_size != p_surface.skin_data.size(), "Size of skin data provided (" + itos(p_surface.skin_data.size()) + ") does not match expected (" + itos(expected_size) + ")");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -2481,6 +2478,12 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
|
|||
s->primitive = p_surface.primitive;
|
||||
|
||||
s->vertex_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.vertex_data.size(), p_surface.vertex_data);
|
||||
if (p_surface.attribute_data.size()) {
|
||||
s->attribute_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.attribute_data.size(), p_surface.attribute_data);
|
||||
}
|
||||
if (p_surface.skin_data.size()) {
|
||||
s->skin_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.skin_data.size(), p_surface.skin_data);
|
||||
}
|
||||
s->vertex_count = p_surface.vertex_count;
|
||||
|
||||
if (p_surface.index_count) {
|
||||
|
|
@ -2504,7 +2507,7 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
|
|||
|
||||
s->aabb = p_surface.aabb;
|
||||
s->bone_aabbs = p_surface.bone_aabbs; //only really useful for returning them.
|
||||
|
||||
#if 0
|
||||
for (int i = 0; i < p_surface.blend_shapes.size(); i++) {
|
||||
if (p_surface.blend_shapes[i].size() != p_surface.vertex_data.size()) {
|
||||
memdelete(s);
|
||||
|
|
@ -2513,8 +2516,8 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
|
|||
RID vertex_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.blend_shapes[i].size(), p_surface.blend_shapes[i]);
|
||||
s->blend_shapes.push_back(vertex_buffer);
|
||||
}
|
||||
|
||||
mesh->blend_shape_count = p_surface.blend_shapes.size();
|
||||
#endif
|
||||
mesh->blend_shape_count = p_surface.blend_shape_count;
|
||||
|
||||
if (mesh->surface_count == 0) {
|
||||
mesh->bone_aabbs = p_surface.bone_aabbs;
|
||||
|
|
@ -2596,6 +2599,12 @@ RS::SurfaceData RasterizerStorageRD::mesh_get_surface(RID p_mesh, int p_surface)
|
|||
RS::SurfaceData sd;
|
||||
sd.format = s.format;
|
||||
sd.vertex_data = RD::get_singleton()->buffer_get_data(s.vertex_buffer);
|
||||
if (s.attribute_buffer.is_valid()) {
|
||||
sd.attribute_data = RD::get_singleton()->buffer_get_data(s.attribute_buffer);
|
||||
}
|
||||
if (s.skin_buffer.is_valid()) {
|
||||
sd.skin_data = RD::get_singleton()->buffer_get_data(s.skin_buffer);
|
||||
}
|
||||
sd.vertex_count = s.vertex_count;
|
||||
sd.index_count = s.index_count;
|
||||
sd.primitive = s.primitive;
|
||||
|
|
@ -2613,9 +2622,8 @@ RS::SurfaceData RasterizerStorageRD::mesh_get_surface(RID p_mesh, int p_surface)
|
|||
|
||||
sd.bone_aabbs = s.bone_aabbs;
|
||||
|
||||
for (int i = 0; i < s.blend_shapes.size(); i++) {
|
||||
Vector<uint8_t> bs = RD::get_singleton()->buffer_get_data(s.blend_shapes[i]);
|
||||
sd.blend_shapes.push_back(bs);
|
||||
if (s.blend_shape_buffer.is_valid()) {
|
||||
sd.blend_shape_data = RD::get_singleton()->buffer_get_data(s.blend_shape_buffer);
|
||||
}
|
||||
|
||||
return sd;
|
||||
|
|
@ -2750,6 +2758,12 @@ void RasterizerStorageRD::mesh_clear(RID p_mesh) {
|
|||
for (uint32_t i = 0; i < mesh->surface_count; i++) {
|
||||
Mesh::Surface &s = *mesh->surfaces[i];
|
||||
RD::get_singleton()->free(s.vertex_buffer); //clears arrays as dependency automatically, including all versions
|
||||
if (s.attribute_buffer.is_valid()) {
|
||||
RD::get_singleton()->free(s.attribute_buffer);
|
||||
}
|
||||
if (s.skin_buffer.is_valid()) {
|
||||
RD::get_singleton()->free(s.skin_buffer);
|
||||
}
|
||||
if (s.versions) {
|
||||
memfree(s.versions); //reallocs, so free with memfree.
|
||||
}
|
||||
|
|
@ -2765,12 +2779,8 @@ void RasterizerStorageRD::mesh_clear(RID p_mesh) {
|
|||
memdelete_arr(s.lods);
|
||||
}
|
||||
|
||||
for (int32_t j = 0; j < s.blend_shapes.size(); j++) {
|
||||
RD::get_singleton()->free(s.blend_shapes[j]);
|
||||
}
|
||||
|
||||
if (s.blend_shape_base_buffer.is_valid()) {
|
||||
RD::get_singleton()->free(s.blend_shape_base_buffer);
|
||||
if (s.blend_shape_buffer.is_valid()) {
|
||||
RD::get_singleton()->free(s.blend_shape_buffer);
|
||||
}
|
||||
|
||||
memdelete(mesh->surfaces[i]);
|
||||
|
|
@ -2796,8 +2806,10 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
|
|||
Vector<RID> buffers;
|
||||
|
||||
uint32_t stride = 0;
|
||||
uint32_t attribute_stride = 0;
|
||||
uint32_t skin_stride = 0;
|
||||
|
||||
for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) {
|
||||
for (int i = 0; i < RS::ARRAY_INDEX; i++) {
|
||||
RD::VertexAttribute vd;
|
||||
RID buffer;
|
||||
vd.location = i;
|
||||
|
|
@ -2805,6 +2817,7 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
|
|||
if (!(s->format & (1 << i))) {
|
||||
// Not supplied by surface, use default value
|
||||
buffer = mesh_default_rd_buffers[i];
|
||||
vd.stride = 0;
|
||||
switch (i) {
|
||||
case RS::ARRAY_VERTEX: {
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
|
||||
|
|
@ -2827,20 +2840,31 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
|
|||
case RS::ARRAY_TEX_UV2: {
|
||||
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
|
||||
} break;
|
||||
case RS::ARRAY_CUSTOM0:
|
||||
case RS::ARRAY_CUSTOM1:
|
||||
case RS::ARRAY_CUSTOM2:
|
||||
case RS::ARRAY_CUSTOM3: {
|
||||
//assumed weights too
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
|
||||
} break;
|
||||
case RS::ARRAY_BONES: {
|
||||
//assumed weights too
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
|
||||
} break;
|
||||
case RS::ARRAY_WEIGHTS: {
|
||||
//assumed weights too
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
|
||||
} break;
|
||||
}
|
||||
} else {
|
||||
//Supplied, use it
|
||||
|
||||
vd.offset = stride;
|
||||
vd.stride = 1; //mark that it needs a stride set
|
||||
buffer = s->vertex_buffer;
|
||||
vd.stride = 1; //mark that it needs a stride set (default uses 0)
|
||||
|
||||
switch (i) {
|
||||
case RS::ARRAY_VERTEX: {
|
||||
vd.offset = stride;
|
||||
|
||||
if (s->format & RS::ARRAY_FLAG_USE_2D_VERTICES) {
|
||||
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
|
||||
stride += sizeof(float) * 2;
|
||||
|
|
@ -2849,71 +2873,80 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
|
|||
stride += sizeof(float) * 3;
|
||||
}
|
||||
|
||||
buffer = s->vertex_buffer;
|
||||
|
||||
} break;
|
||||
case RS::ARRAY_NORMAL: {
|
||||
if (s->format & RS::ARRAY_COMPRESS_NORMAL) {
|
||||
vd.format = RD::DATA_FORMAT_R8G8B8A8_SNORM;
|
||||
stride += sizeof(int8_t) * 4;
|
||||
} else {
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
|
||||
stride += sizeof(float) * 4;
|
||||
}
|
||||
vd.offset = stride;
|
||||
|
||||
vd.format = RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32;
|
||||
|
||||
stride += sizeof(uint32_t);
|
||||
buffer = s->vertex_buffer;
|
||||
} break;
|
||||
case RS::ARRAY_TANGENT: {
|
||||
if (s->format & RS::ARRAY_COMPRESS_TANGENT) {
|
||||
vd.format = RD::DATA_FORMAT_R8G8B8A8_SNORM;
|
||||
stride += sizeof(int8_t) * 4;
|
||||
} else {
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
|
||||
stride += sizeof(float) * 4;
|
||||
}
|
||||
vd.offset = stride;
|
||||
|
||||
vd.format = RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32;
|
||||
stride += sizeof(uint32_t);
|
||||
buffer = s->vertex_buffer;
|
||||
} break;
|
||||
case RS::ARRAY_COLOR: {
|
||||
if (s->format & RS::ARRAY_COMPRESS_COLOR) {
|
||||
vd.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
|
||||
stride += sizeof(int8_t) * 4;
|
||||
} else {
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
|
||||
stride += sizeof(float) * 4;
|
||||
}
|
||||
vd.offset = attribute_stride;
|
||||
|
||||
vd.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
|
||||
attribute_stride += sizeof(int16_t) * 4;
|
||||
buffer = s->attribute_buffer;
|
||||
} break;
|
||||
case RS::ARRAY_TEX_UV: {
|
||||
if (s->format & RS::ARRAY_COMPRESS_TEX_UV) {
|
||||
vd.format = RD::DATA_FORMAT_R16G16_SFLOAT;
|
||||
stride += sizeof(int16_t) * 2;
|
||||
} else {
|
||||
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
|
||||
stride += sizeof(float) * 2;
|
||||
}
|
||||
vd.offset = attribute_stride;
|
||||
|
||||
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
|
||||
attribute_stride += sizeof(float) * 2;
|
||||
buffer = s->attribute_buffer;
|
||||
|
||||
} break;
|
||||
case RS::ARRAY_TEX_UV2: {
|
||||
if (s->format & RS::ARRAY_COMPRESS_TEX_UV2) {
|
||||
vd.format = RD::DATA_FORMAT_R16G16_SFLOAT;
|
||||
stride += sizeof(int16_t) * 2;
|
||||
} else {
|
||||
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
|
||||
stride += sizeof(float) * 2;
|
||||
}
|
||||
vd.offset = attribute_stride;
|
||||
|
||||
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
|
||||
attribute_stride += sizeof(float) * 2;
|
||||
buffer = s->attribute_buffer;
|
||||
} break;
|
||||
case RS::ARRAY_CUSTOM0:
|
||||
case RS::ARRAY_CUSTOM1:
|
||||
case RS::ARRAY_CUSTOM2:
|
||||
case RS::ARRAY_CUSTOM3: {
|
||||
vd.offset = attribute_stride;
|
||||
|
||||
int idx = i - RS::ARRAY_CUSTOM0;
|
||||
uint32_t fmt_shift[RS::ARRAY_CUSTOM_COUNT] = { RS::ARRAY_FORMAT_CUSTOM0_SHIFT, RS::ARRAY_FORMAT_CUSTOM1_SHIFT, RS::ARRAY_FORMAT_CUSTOM2_SHIFT, RS::ARRAY_FORMAT_CUSTOM3_SHIFT };
|
||||
uint32_t fmt = (s->format >> fmt_shift[idx]) & RS::ARRAY_FORMAT_CUSTOM_MASK;
|
||||
uint32_t fmtsize[RS::ARRAY_CUSTOM_MAX] = { 4, 4, 4, 8, 4, 8, 12, 16 };
|
||||
RD::DataFormat fmtrd[RS::ARRAY_CUSTOM_MAX] = { RD::DATA_FORMAT_R8G8B8A8_UNORM, RD::DATA_FORMAT_R8G8B8A8_SNORM, RD::DATA_FORMAT_R16G16_SFLOAT, RD::DATA_FORMAT_R16G16B16A16_SFLOAT, RD::DATA_FORMAT_R32_SFLOAT, RD::DATA_FORMAT_R32G32_SFLOAT, RD::DATA_FORMAT_R32G32B32_SFLOAT, RD::DATA_FORMAT_R32G32B32A32_SFLOAT };
|
||||
vd.format = fmtrd[fmt];
|
||||
attribute_stride += fmtsize[fmt];
|
||||
buffer = s->attribute_buffer;
|
||||
} break;
|
||||
case RS::ARRAY_BONES: {
|
||||
//assumed weights too
|
||||
vd.offset = skin_stride;
|
||||
|
||||
//unique format, internally 16 bits, exposed as single array for 32
|
||||
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
|
||||
stride += sizeof(int32_t) * 4;
|
||||
vd.format = RD::DATA_FORMAT_R16G16B16A16_UINT;
|
||||
skin_stride += sizeof(int16_t) * 4;
|
||||
buffer = s->skin_buffer;
|
||||
} break;
|
||||
case RS::ARRAY_WEIGHTS: {
|
||||
vd.offset = skin_stride;
|
||||
|
||||
vd.format = RD::DATA_FORMAT_R16G16B16A16_UNORM;
|
||||
skin_stride += sizeof(int16_t) * 4;
|
||||
buffer = s->skin_buffer;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(p_input_mask & (1 << i))) {
|
||||
continue; // Shader does not need this, skip it
|
||||
continue; // Shader does not need this, skip it (but computing stride was important anyway)
|
||||
}
|
||||
|
||||
attributes.push_back(vd);
|
||||
|
|
@ -2922,8 +2955,17 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
|
|||
|
||||
//update final stride
|
||||
for (int i = 0; i < attributes.size(); i++) {
|
||||
if (attributes[i].stride == 1) {
|
||||
if (attributes[i].stride == 0) {
|
||||
continue; //default location
|
||||
}
|
||||
int loc = attributes[i].location;
|
||||
|
||||
if (loc < RS::ARRAY_COLOR) {
|
||||
attributes.write[i].stride = stride;
|
||||
} else if (loc < RS::ARRAY_BONES) {
|
||||
attributes.write[i].stride = attribute_stride;
|
||||
} else {
|
||||
attributes.write[i].stride = skin_stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8263,6 +8305,19 @@ RasterizerStorageRD::RasterizerStorageRD() {
|
|||
mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV2] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
|
||||
}
|
||||
|
||||
for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) {
|
||||
buffer.resize(sizeof(float) * 4);
|
||||
{
|
||||
uint8_t *w = buffer.ptrw();
|
||||
float *fptr = (float *)w;
|
||||
fptr[0] = 0.0;
|
||||
fptr[1] = 0.0;
|
||||
fptr[2] = 0.0;
|
||||
fptr[3] = 0.0;
|
||||
}
|
||||
mesh_default_rd_buffers[DEFAULT_RD_BUFFER_CUSTOM0 + i] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
|
||||
}
|
||||
|
||||
{ //bones
|
||||
buffer.resize(sizeof(uint32_t) * 4);
|
||||
{
|
||||
|
|
|
|||
|
|
@ -170,6 +170,10 @@ public:
|
|||
DEFAULT_RD_BUFFER_COLOR,
|
||||
DEFAULT_RD_BUFFER_TEX_UV,
|
||||
DEFAULT_RD_BUFFER_TEX_UV2,
|
||||
DEFAULT_RD_BUFFER_CUSTOM0,
|
||||
DEFAULT_RD_BUFFER_CUSTOM1,
|
||||
DEFAULT_RD_BUFFER_CUSTOM2,
|
||||
DEFAULT_RD_BUFFER_CUSTOM3,
|
||||
DEFAULT_RD_BUFFER_BONES,
|
||||
DEFAULT_RD_BUFFER_WEIGHTS,
|
||||
DEFAULT_RD_BUFFER_MAX,
|
||||
|
|
@ -378,6 +382,8 @@ private:
|
|||
uint32_t format = 0;
|
||||
|
||||
RID vertex_buffer;
|
||||
RID attribute_buffer;
|
||||
RID skin_buffer;
|
||||
uint32_t vertex_count = 0;
|
||||
|
||||
// A different pipeline needs to be allocated
|
||||
|
|
@ -414,8 +420,7 @@ private:
|
|||
|
||||
Vector<AABB> bone_aabbs;
|
||||
|
||||
Vector<RID> blend_shapes;
|
||||
RID blend_shape_base_buffer; //source buffer goes here when using blend shapes, and main one is uncompressed
|
||||
RID blend_shape_buffer;
|
||||
|
||||
RID material;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ layout(location = 0) in vec2 vertex_attrib;
|
|||
layout(location = 3) in vec4 color_attrib;
|
||||
layout(location = 4) in vec2 uv_attrib;
|
||||
|
||||
layout(location = 6) in uvec4 bones_attrib;
|
||||
layout(location = 10) in uvec4 bone_attrib;
|
||||
layout(location = 11) in vec4 weight_attrib;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -61,6 +62,7 @@ void main() {
|
|||
color = vec4(unpackHalf2x16(draw_data.colors[4]), unpackHalf2x16(draw_data.colors[5]));
|
||||
}
|
||||
uvec4 bones = uvec4(0, 0, 0, 0);
|
||||
vec4 bone_weights = vec4(0.0);
|
||||
|
||||
#elif defined(USE_ATTRIBUTES)
|
||||
|
||||
|
|
@ -68,7 +70,8 @@ void main() {
|
|||
vec4 color = color_attrib;
|
||||
vec2 uv = uv_attrib;
|
||||
|
||||
uvec4 bones = bones_attrib;
|
||||
uvec4 bones = bone_attrib;
|
||||
vec4 bone_weights = weight_attrib;
|
||||
#else
|
||||
|
||||
vec2 vertex_base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
|
||||
|
|
|
|||
|
|
@ -24,7 +24,29 @@ layout(location = 4) in vec2 uv_attrib;
|
|||
layout(location = 5) in vec2 uv2_attrib;
|
||||
#endif
|
||||
|
||||
layout(location = 6) in uvec4 bone_attrib; // always bound, even if unused
|
||||
#if defined(CUSTOM0_USED)
|
||||
layout(location = 6) in vec4 custom0_attrib;
|
||||
#endif
|
||||
|
||||
#if defined(CUSTOM1_USED)
|
||||
layout(location = 7) in vec4 custom1_attrib;
|
||||
#endif
|
||||
|
||||
#if defined(CUSTOM2_USED)
|
||||
layout(location = 8) in vec4 custom2_attrib;
|
||||
#endif
|
||||
|
||||
#if defined(CUSTOM3_USED)
|
||||
layout(location = 9) in vec4 custom3_attrib;
|
||||
#endif
|
||||
|
||||
#if defined(BONES_USED)
|
||||
layout(location = 10) in uvec4 bone_attrib;
|
||||
#endif
|
||||
|
||||
#if defined(WEIGHTS_USED)
|
||||
layout(location = 11) in vec4 weight_attrib;
|
||||
#endif
|
||||
|
||||
/* Varyings */
|
||||
|
||||
|
|
@ -116,14 +138,15 @@ void main() {
|
|||
}
|
||||
|
||||
vec3 vertex = vertex_attrib;
|
||||
vec3 normal = normal_attrib;
|
||||
vec3 normal = normal_attrib * 2.0 - 1.0;
|
||||
|
||||
#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
|
||||
vec3 tangent = tangent_attrib.xyz;
|
||||
float binormalf = tangent_attrib.a;
|
||||
vec3 tangent = tangent_attrib.xyz * 2.0 - 1.0;
|
||||
float binormalf = tangent_attrib.a * 2.0 - 1.0;
|
||||
vec3 binormal = normalize(cross(normal, tangent) * binormalf);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_SKELETON)) {
|
||||
//multimesh, instances are for it
|
||||
|
||||
|
|
@ -147,7 +170,7 @@ void main() {
|
|||
binormal = (vec4(binormal, 0.0) * m).xyz;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
uv_interp = uv_attrib;
|
||||
|
||||
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
|
||||
|
|
|
|||
|
|
@ -67,6 +67,12 @@ ShaderTypes::ShaderTypes() {
|
|||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_ID"] = constt(ShaderLanguage::TYPE_INT);
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_CUSTOM"] = constt(ShaderLanguage::TYPE_VEC4);
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["ROUGHNESS"] = ShaderLanguage::TYPE_FLOAT;
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["BONE_INDICES"] = ShaderLanguage::TYPE_UVEC4;
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["BONE_WEIGHTS"] = ShaderLanguage::TYPE_VEC4;
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM0"] = ShaderLanguage::TYPE_VEC4;
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM1"] = ShaderLanguage::TYPE_VEC4;
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM2"] = ShaderLanguage::TYPE_VEC4;
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM3"] = ShaderLanguage::TYPE_VEC4;
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].can_discard = false;
|
||||
|
||||
//builtins
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -52,7 +52,7 @@ class RenderingServer : public Object {
|
|||
|
||||
void _camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far);
|
||||
void _canvas_item_add_style_box(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector<float> &p_margins, const Color &p_modulate = Color(1, 1, 1));
|
||||
Array _get_array_from_surface(uint32_t p_format, Vector<uint8_t> p_vertex_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len) const;
|
||||
Array _get_array_from_surface(uint32_t p_format, Vector<uint8_t> p_vertex_data, Vector<uint8_t> p_attrib_data, Vector<uint8_t> p_skin_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len) const;
|
||||
|
||||
protected:
|
||||
RID _make_test_cube();
|
||||
|
|
@ -61,7 +61,7 @@ protected:
|
|||
RID white_texture;
|
||||
RID test_material;
|
||||
|
||||
Error _surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, Vector<uint8_t> &r_vertex_array, int p_vertex_array_len, Vector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> &r_bone_aabb);
|
||||
Error _surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_vertex_stride, uint32_t p_attrib_stride, uint32_t p_skin_stride, Vector<uint8_t> &r_vertex_array, Vector<uint8_t> &r_attrib_array, Vector<uint8_t> &r_skin_array, int p_vertex_array_len, Vector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> &r_bone_aabb);
|
||||
|
||||
static RenderingServer *(*create_func)();
|
||||
static void _bind_methods();
|
||||
|
|
@ -199,16 +199,36 @@ public:
|
|||
/* MESH API */
|
||||
|
||||
enum ArrayType {
|
||||
ARRAY_VERTEX = 0,
|
||||
ARRAY_NORMAL = 1,
|
||||
ARRAY_TANGENT = 2,
|
||||
ARRAY_COLOR = 3,
|
||||
ARRAY_TEX_UV = 4,
|
||||
ARRAY_TEX_UV2 = 5,
|
||||
ARRAY_BONES = 6,
|
||||
ARRAY_WEIGHTS = 7,
|
||||
ARRAY_INDEX = 8,
|
||||
ARRAY_MAX = 9
|
||||
ARRAY_VERTEX = 0, // RG32F or RGB32F (depending on 2D bit)
|
||||
ARRAY_NORMAL = 1, // A2B10G10R10
|
||||
ARRAY_TANGENT = 2, // A2B10G10R10, A flips sign of binormal
|
||||
ARRAY_COLOR = 3, // RGBA16F
|
||||
ARRAY_TEX_UV = 4, // RG32F
|
||||
ARRAY_TEX_UV2 = 5, // RG32F
|
||||
ARRAY_CUSTOM0 = 6, // depends on ArrayCustomFormat
|
||||
ARRAY_CUSTOM1 = 7,
|
||||
ARRAY_CUSTOM2 = 8,
|
||||
ARRAY_CUSTOM3 = 9,
|
||||
ARRAY_BONES = 10, // RGBA16UI (x2 if 8 weights)
|
||||
ARRAY_WEIGHTS = 11, // RGBA16UNORM (x2 if 8 weights)
|
||||
ARRAY_INDEX = 12, // 16 or 32 bits depending on length > 0xFFFF
|
||||
ARRAY_MAX = 13
|
||||
};
|
||||
|
||||
enum {
|
||||
ARRAY_CUSTOM_COUNT = ARRAY_BONES - ARRAY_CUSTOM0
|
||||
};
|
||||
|
||||
enum ArrayCustomFormat {
|
||||
ARRAY_CUSTOM_RGBA8_UNORM,
|
||||
ARRAY_CUSTOM_RGBA8_SNORM,
|
||||
ARRAY_CUSTOM_RG_HALF,
|
||||
ARRAY_CUSTOM_RGBA_HALF,
|
||||
ARRAY_CUSTOM_R_FLOAT,
|
||||
ARRAY_CUSTOM_RG_FLOAT,
|
||||
ARRAY_CUSTOM_RGB_FLOAT,
|
||||
ARRAY_CUSTOM_RGBA_FLOAT,
|
||||
ARRAY_CUSTOM_MAX
|
||||
};
|
||||
|
||||
enum ArrayFormat {
|
||||
|
|
@ -219,21 +239,29 @@ public:
|
|||
ARRAY_FORMAT_COLOR = 1 << ARRAY_COLOR,
|
||||
ARRAY_FORMAT_TEX_UV = 1 << ARRAY_TEX_UV,
|
||||
ARRAY_FORMAT_TEX_UV2 = 1 << ARRAY_TEX_UV2,
|
||||
ARRAY_FORMAT_CUSTOM0 = 1 << ARRAY_CUSTOM0,
|
||||
ARRAY_FORMAT_CUSTOM1 = 1 << ARRAY_CUSTOM1,
|
||||
ARRAY_FORMAT_CUSTOM2 = 1 << ARRAY_CUSTOM2,
|
||||
ARRAY_FORMAT_CUSTOM3 = 1 << ARRAY_CUSTOM3,
|
||||
ARRAY_FORMAT_BONES = 1 << ARRAY_BONES,
|
||||
ARRAY_FORMAT_WEIGHTS = 1 << ARRAY_WEIGHTS,
|
||||
ARRAY_FORMAT_INDEX = 1 << ARRAY_INDEX,
|
||||
|
||||
ARRAY_COMPRESS_BASE = (ARRAY_INDEX + 1),
|
||||
ARRAY_COMPRESS_NORMAL = 1 << (ARRAY_NORMAL + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_TANGENT = 1 << (ARRAY_TANGENT + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_COLOR = 1 << (ARRAY_COLOR + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_TEX_UV = 1 << (ARRAY_TEX_UV + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_TEX_UV2 = 1 << (ARRAY_TEX_UV2 + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_INDEX = 1 << (ARRAY_INDEX + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2,
|
||||
ARRAY_FORMAT_BLEND_SHAPE_MASK = ~(ARRAY_FORMAT_COLOR | ARRAY_FORMAT_TEX_UV | ARRAY_FORMAT_TEX_UV2 | ARRAY_FORMAT_BONES | ARRAY_FORMAT_WEIGHTS | ARRAY_FORMAT_CUSTOM0 | ARRAY_FORMAT_CUSTOM1 | ARRAY_FORMAT_CUSTOM2 | ARRAY_FORMAT_CUSTOM3 | ARRAY_FORMAT_INDEX),
|
||||
|
||||
ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1,
|
||||
ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3,
|
||||
ARRAY_FORMAT_CUSTOM_BASE = (ARRAY_INDEX + 1),
|
||||
ARRAY_FORMAT_CUSTOM_BITS = 3,
|
||||
ARRAY_FORMAT_CUSTOM0_SHIFT = (ARRAY_FORMAT_CUSTOM_BASE + 0),
|
||||
ARRAY_FORMAT_CUSTOM1_SHIFT = (ARRAY_FORMAT_CUSTOM_BASE + ARRAY_FORMAT_CUSTOM_BITS),
|
||||
ARRAY_FORMAT_CUSTOM2_SHIFT = (ARRAY_FORMAT_CUSTOM_BASE + ARRAY_FORMAT_CUSTOM_BITS * 2),
|
||||
ARRAY_FORMAT_CUSTOM3_SHIFT = (ARRAY_FORMAT_CUSTOM_BASE + ARRAY_FORMAT_CUSTOM_BITS * 3),
|
||||
|
||||
ARRAY_FORMAT_CUSTOM_MASK = 0x7,
|
||||
ARRAY_COMPRESS_FLAGS_BASE = (ARRAY_INDEX + 1 + 12),
|
||||
|
||||
ARRAY_FLAG_USE_2D_VERTICES = 1 << (ARRAY_COMPRESS_FLAGS_BASE + 0),
|
||||
ARRAY_FLAG_USE_DYNAMIC_UPDATE = 1 << (ARRAY_COMPRESS_FLAGS_BASE + 1),
|
||||
ARRAY_FLAG_USE_8_BONE_WEIGHTS = 1 << (ARRAY_COMPRESS_FLAGS_BASE + 2),
|
||||
};
|
||||
|
||||
enum PrimitiveType {
|
||||
|
|
@ -249,11 +277,15 @@ public:
|
|||
PrimitiveType primitive = PRIMITIVE_MAX;
|
||||
|
||||
uint32_t format = 0;
|
||||
Vector<uint8_t> vertex_data;
|
||||
Vector<uint8_t> vertex_data; // vertex, normal, tangent (change with skinning, blendshape)
|
||||
Vector<uint8_t> attribute_data; // color,uv, uv2, custom0-3
|
||||
Vector<uint8_t> skin_data; // bone index, bone weight
|
||||
uint32_t vertex_count = 0;
|
||||
Vector<uint8_t> index_data;
|
||||
uint32_t index_count = 0;
|
||||
|
||||
uint32_t blend_shape_count = 0;
|
||||
|
||||
AABB aabb;
|
||||
struct LOD {
|
||||
float edge_length;
|
||||
|
|
@ -262,7 +294,7 @@ public:
|
|||
Vector<LOD> lods;
|
||||
Vector<AABB> bone_aabbs;
|
||||
|
||||
Vector<Vector<uint8_t>> blend_shapes;
|
||||
Vector<uint8_t> blend_shape_data;
|
||||
|
||||
RID material;
|
||||
};
|
||||
|
|
@ -270,17 +302,20 @@ public:
|
|||
virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces) = 0;
|
||||
virtual RID mesh_create() = 0;
|
||||
|
||||
virtual uint32_t mesh_surface_get_format_offset(uint32_t p_format, int p_vertex_len, int p_index_len, int p_array_index) const;
|
||||
virtual uint32_t mesh_surface_get_format_stride(uint32_t p_format, int p_vertex_len, int p_index_len) const;
|
||||
virtual uint32_t mesh_surface_get_format_offset(uint32_t p_format, int p_vertex_len, int p_array_index) const;
|
||||
virtual uint32_t mesh_surface_get_format_vertex_stride(uint32_t p_format, int p_vertex_len) const;
|
||||
virtual uint32_t mesh_surface_get_format_attribute_stride(uint32_t p_format, int p_vertex_len) const;
|
||||
virtual uint32_t mesh_surface_get_format_skin_stride(uint32_t p_format, int p_vertex_len) const;
|
||||
|
||||
/// Returns stride
|
||||
virtual uint32_t mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets) const;
|
||||
virtual Error mesh_create_surface_data_from_arrays(SurfaceData *r_surface_data, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_compress_format = ARRAY_COMPRESS_DEFAULT);
|
||||
virtual void mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets, uint32_t &r_vertex_element_size, uint32_t &r_attrib_element_size, uint32_t &r_skin_element_size) const;
|
||||
virtual Error mesh_create_surface_data_from_arrays(SurfaceData *r_surface_data, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_compress_format = 0);
|
||||
Array mesh_create_arrays_from_surface_data(const SurfaceData &p_data) const;
|
||||
Array mesh_surface_get_arrays(RID p_mesh, int p_surface) const;
|
||||
Array mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_surface) const;
|
||||
Dictionary mesh_surface_get_lods(RID p_mesh, int p_surface) const;
|
||||
|
||||
virtual void mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_compress_format = ARRAY_COMPRESS_DEFAULT);
|
||||
virtual void mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_compress_format = 0);
|
||||
virtual void mesh_add_surface(RID p_mesh, const SurfaceData &p_surface) = 0;
|
||||
|
||||
virtual int mesh_get_blend_shape_count(RID p_mesh) const = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue