Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc')
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc67
1 files changed, 67 insertions, 0 deletions
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc
index d4c801ab066..ed1a0ccd178 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc
@@ -7,6 +7,8 @@
#include "extract_mesh.h"
+#include "draw_subdivision.h"
+
namespace blender::draw {
/* ---------------------------------------------------------------------- */
@@ -77,12 +79,77 @@ static void extract_orco_iter_poly_mesh(const MeshRenderData *mr,
}
}
+static void extract_orco_init_subdiv(const DRWSubdivCache *subdiv_cache,
+ const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buffer,
+ void *UNUSED(data))
+{
+ static GPUVertFormat format = {0};
+ if (format.attr_len == 0) {
+ /* FIXME(fclem): We use the last component as a way to differentiate from generic vertex
+ * attributes. This is a substantial waste of video-ram and should be done another way.
+ * Unfortunately, at the time of writing, I did not found any other "non disruptive"
+ * alternative. */
+ GPU_vertformat_attr_add(&format, "orco", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ }
+
+ 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, &format, GPU_USAGE_DYNAMIC);
+ GPU_vertbuf_data_alloc(coarse_vbo, mr->loop_len);
+
+ float(*coarse_vbo_data)[4] = static_cast<float(*)[4]>(GPU_vertbuf_get_data(coarse_vbo));
+
+ CustomData *cd_vdata = &mr->me->vdata;
+ float(*orco)[3] = static_cast<float(*)[3]>(CustomData_get_layer(cd_vdata, CD_ORCO));
+
+ if (mr->extract_type == MR_EXTRACT_MESH) {
+ const MLoop *mloop = mr->mloop;
+ const MPoly *mp = mr->mpoly;
+
+ int ml_index = 0;
+ for (int i = 0; i < mr->poly_len; i++, mp++) {
+ const MLoop *ml = &mloop[mp->loopstart];
+
+ for (int j = 0; j < mp->totloop; j++, ml++, ml_index++) {
+ float *loop_orco = coarse_vbo_data[ml_index];
+ copy_v3_v3(loop_orco, orco[ml->v]);
+ loop_orco[3] = 0.0; /* Tag as not a generic attribute. */
+ }
+ }
+ }
+ else {
+ BMIter iter;
+ BMFace *f;
+ BM_ITER_MESH (f, &iter, mr->bm, BM_FACES_OF_MESH) {
+ BMLoop *l_iter;
+ BMLoop *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ const int l_index = BM_elem_index_get(l_iter);
+ float *loop_orco = coarse_vbo_data[l_index];
+ copy_v3_v3(loop_orco, orco[BM_elem_index_get(l_iter->v)]);
+ loop_orco[3] = 0.0; /* Tag as not a generic attribute. */
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
+
+ draw_subdiv_interp_custom_data(subdiv_cache, coarse_vbo, dst_buffer, 4, 0, false);
+
+ GPU_vertbuf_discard(coarse_vbo);
+}
+
constexpr MeshExtract create_extractor_orco()
{
MeshExtract extractor = {nullptr};
extractor.init = extract_orco_init;
extractor.iter_poly_bm = extract_orco_iter_poly_bm;
extractor.iter_poly_mesh = extract_orco_iter_poly_mesh;
+ extractor.init_subdiv = extract_orco_init_subdiv;
extractor.data_type = MR_DATA_NONE;
extractor.data_size = sizeof(MeshExtract_Orco_Data);
extractor.use_threading = true;