Merge remote-tracking branch 'origin/blender-v3.1-release'
This commit is contained in:
@@ -819,6 +819,7 @@ static void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache *cache,
|
||||
EXTRACT_ADD_REQUESTED(vbo, edituv_data);
|
||||
/* Make sure UVs are computed before edituv stuffs. */
|
||||
EXTRACT_ADD_REQUESTED(vbo, uv);
|
||||
EXTRACT_ADD_REQUESTED(vbo, tan);
|
||||
EXTRACT_ADD_REQUESTED(vbo, edituv_stretch_area);
|
||||
EXTRACT_ADD_REQUESTED(vbo, edituv_stretch_angle);
|
||||
EXTRACT_ADD_REQUESTED(ibo, lines_adjacency);
|
||||
@@ -832,6 +833,7 @@ static void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache *cache,
|
||||
return;
|
||||
}
|
||||
|
||||
mesh_render_data_update_looptris(mr, MR_ITER_LOOPTRI, MR_DATA_LOOPTRI);
|
||||
mesh_render_data_update_loose_geom(mr, mbc, MR_ITER_LEDGE | MR_ITER_LVERT, MR_DATA_LOOSE_GEOM);
|
||||
|
||||
void *data_stack = MEM_mallocN(extractors.data_size_total(), __func__);
|
||||
|
||||
@@ -1302,7 +1302,8 @@ void draw_subdiv_interp_custom_data(const DRWSubdivCache *cache,
|
||||
GPUVertBuf *src_data,
|
||||
GPUVertBuf *dst_data,
|
||||
int dimensions,
|
||||
int dst_offset)
|
||||
int dst_offset,
|
||||
bool compress_to_u16)
|
||||
{
|
||||
GPUShader *shader = nullptr;
|
||||
|
||||
@@ -1322,10 +1323,17 @@ void draw_subdiv_interp_custom_data(const DRWSubdivCache *cache,
|
||||
"#define DIMENSIONS 3\n");
|
||||
}
|
||||
else if (dimensions == 4) {
|
||||
shader = get_subdiv_shader(SHADER_COMP_CUSTOM_DATA_INTERP_4D,
|
||||
"#define SUBDIV_POLYGON_OFFSET\n"
|
||||
"#define DIMENSIONS 4\n"
|
||||
"#define GPU_FETCH_U16_TO_FLOAT\n");
|
||||
if (compress_to_u16) {
|
||||
shader = get_subdiv_shader(SHADER_COMP_CUSTOM_DATA_INTERP_4D,
|
||||
"#define SUBDIV_POLYGON_OFFSET\n"
|
||||
"#define DIMENSIONS 4\n"
|
||||
"#define GPU_FETCH_U16_TO_FLOAT\n");
|
||||
}
|
||||
else {
|
||||
shader = get_subdiv_shader(SHADER_COMP_CUSTOM_DATA_INTERP_4D,
|
||||
"#define SUBDIV_POLYGON_OFFSET\n"
|
||||
"#define DIMENSIONS 4\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Crash if dimensions are not supported. */
|
||||
|
||||
@@ -182,7 +182,8 @@ void draw_subdiv_interp_custom_data(const DRWSubdivCache *cache,
|
||||
struct GPUVertBuf *src_data,
|
||||
struct GPUVertBuf *dst_data,
|
||||
int dimensions,
|
||||
int dst_offset);
|
||||
int dst_offset,
|
||||
bool compress_to_u16);
|
||||
|
||||
void draw_subdiv_extract_uvs(const DRWSubdivCache *cache,
|
||||
struct GPUVertBuf *uvs,
|
||||
|
||||
@@ -402,7 +402,7 @@ static void extract_attr_init_subdiv(const DRWSubdivCache *subdiv_cache,
|
||||
/* Ensure data is uploaded properly. */
|
||||
GPU_vertbuf_tag_dirty(src_data);
|
||||
draw_subdiv_interp_custom_data(
|
||||
subdiv_cache, src_data, dst_buffer, static_cast<int>(dimensions), 0);
|
||||
subdiv_cache, src_data, dst_buffer, static_cast<int>(dimensions), 0, false);
|
||||
|
||||
GPU_vertbuf_discard(src_data);
|
||||
}
|
||||
|
||||
@@ -241,7 +241,8 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache,
|
||||
GPU_vertbuf_init_build_on_device(
|
||||
dst_custom_normals, get_custom_normals_format(), subdiv_cache->num_subdiv_loops);
|
||||
|
||||
draw_subdiv_interp_custom_data(subdiv_cache, src_custom_normals, dst_custom_normals, 3, 0);
|
||||
draw_subdiv_interp_custom_data(
|
||||
subdiv_cache, src_custom_normals, dst_custom_normals, 3, 0, false);
|
||||
|
||||
draw_subdiv_finalize_custom_normals(subdiv_cache, dst_custom_normals, vbo);
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ static void extract_sculpt_data_init_subdiv(const DRWSubdivCache *subdiv_cache,
|
||||
GPU_vertbuf_init_build_on_device(
|
||||
subdiv_mask_vbo, &mask_format, subdiv_cache->num_subdiv_loops);
|
||||
|
||||
draw_subdiv_interp_custom_data(subdiv_cache, mask_vbo, subdiv_mask_vbo, 1, 0);
|
||||
draw_subdiv_interp_custom_data(subdiv_cache, mask_vbo, subdiv_mask_vbo, 1, 0, false);
|
||||
}
|
||||
|
||||
/* Then, gather face sets. */
|
||||
|
||||
@@ -16,22 +16,26 @@
|
||||
|
||||
#include "extract_mesh.h"
|
||||
|
||||
#include "draw_subdivision.h"
|
||||
|
||||
namespace blender::draw {
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/** \name Extract Tangent layers
|
||||
* \{ */
|
||||
|
||||
static void extract_tan_ex_init(const MeshRenderData *mr,
|
||||
struct MeshBatchCache *cache,
|
||||
GPUVertBuf *vbo,
|
||||
const bool do_hq)
|
||||
static void extract_tan_init_common(const MeshRenderData *mr,
|
||||
struct MeshBatchCache *cache,
|
||||
GPUVertFormat *format,
|
||||
GPUVertCompType comp_type,
|
||||
GPUVertFetchMode fetch_mode,
|
||||
CustomData *r_loop_data,
|
||||
int *r_v_len,
|
||||
int *r_tan_len,
|
||||
char r_tangent_names[MAX_MTFACE][MAX_CUSTOMDATA_LAYER_NAME],
|
||||
bool *r_use_orco_tan)
|
||||
{
|
||||
GPUVertCompType comp_type = do_hq ? GPU_COMP_I16 : GPU_COMP_I10;
|
||||
GPUVertFetchMode fetch_mode = GPU_FETCH_INT_TO_FLOAT_UNIT;
|
||||
|
||||
GPUVertFormat format = {0};
|
||||
GPU_vertformat_deinterleave(&format);
|
||||
GPU_vertformat_deinterleave(format);
|
||||
|
||||
CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata;
|
||||
CustomData *cd_vdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->vdata : &mr->me->vdata;
|
||||
@@ -41,7 +45,6 @@ static void extract_tan_ex_init(const MeshRenderData *mr,
|
||||
bool use_orco_tan = cache->cd_used.tan_orco != 0;
|
||||
|
||||
int tan_len = 0;
|
||||
char tangent_names[MAX_MTFACE][MAX_CUSTOMDATA_LAYER_NAME];
|
||||
|
||||
/* FIXME(T91838): This is to avoid a crash when orco tangent was requested but there are valid
|
||||
* uv layers. It would be better to fix the root cause. */
|
||||
@@ -57,17 +60,17 @@ static void extract_tan_ex_init(const MeshRenderData *mr,
|
||||
GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
|
||||
/* Tangent layer name. */
|
||||
BLI_snprintf(attr_name, sizeof(attr_name), "t%s", attr_safe_name);
|
||||
GPU_vertformat_attr_add(&format, attr_name, comp_type, 4, fetch_mode);
|
||||
GPU_vertformat_attr_add(format, attr_name, comp_type, 4, fetch_mode);
|
||||
/* Active render layer name. */
|
||||
if (i == CustomData_get_render_layer(cd_ldata, CD_MLOOPUV)) {
|
||||
GPU_vertformat_alias_add(&format, "t");
|
||||
GPU_vertformat_alias_add(format, "t");
|
||||
}
|
||||
/* Active display layer name. */
|
||||
if (i == CustomData_get_active_layer(cd_ldata, CD_MLOOPUV)) {
|
||||
GPU_vertformat_alias_add(&format, "at");
|
||||
GPU_vertformat_alias_add(format, "at");
|
||||
}
|
||||
|
||||
BLI_strncpy(tangent_names[tan_len++], layer_name, MAX_CUSTOMDATA_LAYER_NAME);
|
||||
BLI_strncpy(r_tangent_names[tan_len++], layer_name, MAX_CUSTOMDATA_LAYER_NAME);
|
||||
}
|
||||
}
|
||||
if (use_orco_tan && orco == nullptr) {
|
||||
@@ -94,20 +97,19 @@ static void extract_tan_ex_init(const MeshRenderData *mr,
|
||||
}
|
||||
|
||||
/* Start Fresh */
|
||||
CustomData loop_data;
|
||||
CustomData_reset(&loop_data);
|
||||
CustomData_reset(r_loop_data);
|
||||
if (tan_len != 0 || use_orco_tan) {
|
||||
short tangent_mask = 0;
|
||||
bool calc_active_tangent = false;
|
||||
if (mr->extract_type == MR_EXTRACT_BMESH) {
|
||||
BKE_editmesh_loop_tangent_calc(mr->edit_bmesh,
|
||||
calc_active_tangent,
|
||||
tangent_names,
|
||||
r_tangent_names,
|
||||
tan_len,
|
||||
mr->poly_normals,
|
||||
mr->loop_normals,
|
||||
orco,
|
||||
&loop_data,
|
||||
r_loop_data,
|
||||
mr->loop_len,
|
||||
&tangent_mask);
|
||||
}
|
||||
@@ -120,13 +122,13 @@ static void extract_tan_ex_init(const MeshRenderData *mr,
|
||||
mr->tri_len,
|
||||
cd_ldata,
|
||||
calc_active_tangent,
|
||||
tangent_names,
|
||||
r_tangent_names,
|
||||
tan_len,
|
||||
mr->vert_normals,
|
||||
mr->poly_normals,
|
||||
mr->loop_normals,
|
||||
orco,
|
||||
&loop_data,
|
||||
r_loop_data,
|
||||
mr->loop_len,
|
||||
&tangent_mask);
|
||||
}
|
||||
@@ -134,12 +136,12 @@ static void extract_tan_ex_init(const MeshRenderData *mr,
|
||||
|
||||
if (use_orco_tan) {
|
||||
char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
|
||||
const char *layer_name = CustomData_get_layer_name(&loop_data, CD_TANGENT, 0);
|
||||
const char *layer_name = CustomData_get_layer_name(r_loop_data, CD_TANGENT, 0);
|
||||
GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
|
||||
BLI_snprintf(attr_name, sizeof(*attr_name), "t%s", attr_safe_name);
|
||||
GPU_vertformat_attr_add(&format, attr_name, comp_type, 4, fetch_mode);
|
||||
GPU_vertformat_alias_add(&format, "t");
|
||||
GPU_vertformat_alias_add(&format, "at");
|
||||
GPU_vertformat_attr_add(format, attr_name, comp_type, 4, fetch_mode);
|
||||
GPU_vertformat_alias_add(format, "t");
|
||||
GPU_vertformat_alias_add(format, "at");
|
||||
}
|
||||
|
||||
if (orco_allocated) {
|
||||
@@ -147,12 +149,42 @@ static void extract_tan_ex_init(const MeshRenderData *mr,
|
||||
}
|
||||
|
||||
int v_len = mr->loop_len;
|
||||
if (format.attr_len == 0) {
|
||||
GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
if (format->attr_len == 0) {
|
||||
GPU_vertformat_attr_add(format, "dummy", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
/* VBO will not be used, only allocate minimum of memory. */
|
||||
v_len = 1;
|
||||
}
|
||||
|
||||
*r_use_orco_tan = use_orco_tan;
|
||||
*r_v_len = v_len;
|
||||
*r_tan_len = tan_len;
|
||||
}
|
||||
|
||||
static void extract_tan_ex_init(const MeshRenderData *mr,
|
||||
struct MeshBatchCache *cache,
|
||||
GPUVertBuf *vbo,
|
||||
const bool do_hq)
|
||||
{
|
||||
GPUVertCompType comp_type = do_hq ? GPU_COMP_I16 : GPU_COMP_I10;
|
||||
GPUVertFetchMode fetch_mode = GPU_FETCH_INT_TO_FLOAT_UNIT;
|
||||
|
||||
GPUVertFormat format = {0};
|
||||
CustomData loop_data;
|
||||
int v_len = 0;
|
||||
int tan_len = 0;
|
||||
bool use_orco_tan;
|
||||
char tangent_names[MAX_MTFACE][MAX_CUSTOMDATA_LAYER_NAME];
|
||||
extract_tan_init_common(mr,
|
||||
cache,
|
||||
&format,
|
||||
comp_type,
|
||||
fetch_mode,
|
||||
&loop_data,
|
||||
&v_len,
|
||||
&tan_len,
|
||||
tangent_names,
|
||||
&use_orco_tan);
|
||||
|
||||
GPU_vertbuf_init_with_format(vbo, &format);
|
||||
GPU_vertbuf_data_alloc(vbo, v_len);
|
||||
|
||||
@@ -211,10 +243,92 @@ static void extract_tan_init(const MeshRenderData *mr,
|
||||
extract_tan_ex_init(mr, cache, vbo, false);
|
||||
}
|
||||
|
||||
static GPUVertFormat *get_coarse_tan_format()
|
||||
{
|
||||
static GPUVertFormat format = {0};
|
||||
if (format.attr_len == 0) {
|
||||
GPU_vertformat_attr_add(&format, "tan", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
||||
}
|
||||
return &format;
|
||||
}
|
||||
|
||||
static void extract_tan_init_subdiv(const DRWSubdivCache *subdiv_cache,
|
||||
const MeshRenderData *mr,
|
||||
struct MeshBatchCache *cache,
|
||||
void *buffer,
|
||||
void *UNUSED(data))
|
||||
{
|
||||
GPUVertCompType comp_type = GPU_COMP_F32;
|
||||
GPUVertFetchMode fetch_mode = GPU_FETCH_FLOAT;
|
||||
GPUVertFormat format = {0};
|
||||
CustomData loop_data;
|
||||
int coarse_len = 0;
|
||||
int tan_len = 0;
|
||||
bool use_orco_tan;
|
||||
char tangent_names[MAX_MTFACE][MAX_CUSTOMDATA_LAYER_NAME];
|
||||
extract_tan_init_common(mr,
|
||||
cache,
|
||||
&format,
|
||||
comp_type,
|
||||
fetch_mode,
|
||||
&loop_data,
|
||||
&coarse_len,
|
||||
&tan_len,
|
||||
tangent_names,
|
||||
&use_orco_tan);
|
||||
|
||||
GPUVertBuf *dst_buffer = static_cast<GPUVertBuf *>(buffer);
|
||||
GPU_vertbuf_init_build_on_device(dst_buffer, &format, subdiv_cache->num_subdiv_loops);
|
||||
|
||||
GPUVertBuf *coarse_vbo = GPU_vertbuf_calloc();
|
||||
/* Dynamic as we upload and interpolate layers one at a time. */
|
||||
GPU_vertbuf_init_with_format_ex(coarse_vbo, get_coarse_tan_format(), GPU_USAGE_DYNAMIC);
|
||||
GPU_vertbuf_data_alloc(coarse_vbo, coarse_len);
|
||||
|
||||
/* Index of the tangent layer in the compact buffer. Used layers are stored in a single buffer.
|
||||
*/
|
||||
int pack_layer_index = 0;
|
||||
for (int i = 0; i < tan_len; i++) {
|
||||
float(*tan_data)[4] = (float(*)[4])GPU_vertbuf_get_data(coarse_vbo);
|
||||
const char *name = tangent_names[i];
|
||||
float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_named(&loop_data, CD_TANGENT, name);
|
||||
for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) {
|
||||
copy_v3_v3(*tan_data, layer_data[ml_index]);
|
||||
(*tan_data)[3] = (layer_data[ml_index][3] > 0.0f) ? 1.0f : -1.0f;
|
||||
tan_data++;
|
||||
}
|
||||
|
||||
/* Ensure data is uploaded properly. */
|
||||
GPU_vertbuf_tag_dirty(coarse_vbo);
|
||||
/* Include stride in offset. */
|
||||
const int dst_offset = (int)subdiv_cache->num_subdiv_loops * 4 * pack_layer_index++;
|
||||
draw_subdiv_interp_custom_data(subdiv_cache, coarse_vbo, dst_buffer, 4, dst_offset, false);
|
||||
}
|
||||
if (use_orco_tan) {
|
||||
float(*tan_data)[4] = (float(*)[4])GPU_vertbuf_get_data(coarse_vbo);
|
||||
float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_n(&loop_data, CD_TANGENT, 0);
|
||||
for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) {
|
||||
copy_v3_v3(*tan_data, layer_data[ml_index]);
|
||||
(*tan_data)[3] = (layer_data[ml_index][3] > 0.0f) ? 1.0f : -1.0f;
|
||||
tan_data++;
|
||||
}
|
||||
|
||||
/* Ensure data is uploaded properly. */
|
||||
GPU_vertbuf_tag_dirty(coarse_vbo);
|
||||
/* Include stride in offset. */
|
||||
const int dst_offset = (int)subdiv_cache->num_subdiv_loops * 4 * pack_layer_index++;
|
||||
draw_subdiv_interp_custom_data(subdiv_cache, coarse_vbo, dst_buffer, 4, dst_offset, true);
|
||||
}
|
||||
|
||||
CustomData_free(&loop_data, mr->loop_len);
|
||||
GPU_vertbuf_discard(coarse_vbo);
|
||||
}
|
||||
|
||||
constexpr MeshExtract create_extractor_tan()
|
||||
{
|
||||
MeshExtract extractor = {nullptr};
|
||||
extractor.init = extract_tan_init;
|
||||
extractor.init_subdiv = extract_tan_init_subdiv;
|
||||
extractor.data_type = MR_DATA_POLY_NOR | MR_DATA_TAN_LOOP_NOR | MR_DATA_LOOPTRI;
|
||||
extractor.data_size = 0;
|
||||
extractor.use_threading = false;
|
||||
|
||||
@@ -164,7 +164,7 @@ static void extract_vcol_init_subdiv(const DRWSubdivCache *subdiv_cache,
|
||||
|
||||
/* Ensure data is uploaded properly. */
|
||||
GPU_vertbuf_tag_dirty(src_data);
|
||||
draw_subdiv_interp_custom_data(subdiv_cache, src_data, dst_buffer, 4, dst_offset);
|
||||
draw_subdiv_interp_custom_data(subdiv_cache, src_data, dst_buffer, 4, dst_offset, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ static void extract_weights_init_subdiv(const DRWSubdivCache *subdiv_cache,
|
||||
}
|
||||
}
|
||||
|
||||
draw_subdiv_interp_custom_data(subdiv_cache, coarse_weights, vbo, 1, 0);
|
||||
draw_subdiv_interp_custom_data(subdiv_cache, coarse_weights, vbo, 1, 0, false);
|
||||
|
||||
GPU_vertbuf_discard(coarse_weights);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user