[Bf-blender-cvs] [461c1deb63f] temp-pbvh-vbos: temp-pbvh-vbos: Add support for solid-shaded multires

Joseph Eagar noreply at git.blender.org
Sun Aug 21 00:44:44 CEST 2022


Commit: 461c1deb63f842933c474144000452994a2bec58
Author: Joseph Eagar
Date:   Sat Aug 20 15:43:05 2022 -0700
Branches: temp-pbvh-vbos
https://developer.blender.org/rB461c1deb63f842933c474144000452994a2bec58

temp-pbvh-vbos: Add support for solid-shaded multires

===================================================================

M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/draw/DRW_engine.h
M	source/blender/draw/intern/draw_pbvh.cc
M	source/blender/gpu/intern/gpu_buffers.cc

===================================================================

diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 28832dc3f49..60dd0ecbf1b 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -545,12 +545,14 @@ static void pbvh_draw_args(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node)
 {
   memset((void *)args, 0, sizeof(*args));
 
+  args->pbvh_type = pbvh->header.type;
   args->mesh_verts_num = pbvh->totvert;
   args->mesh_grids_num = pbvh->totgrid;
   args->node = node;
 
   BKE_pbvh_node_num_verts(pbvh, node, NULL, &args->node_verts_num);
 
+  args->grid_hidden = pbvh->grid_hidden;
   args->face_sets_color_default = pbvh->face_sets_color_default;
   args->face_sets_color_seed = pbvh->face_sets_color_seed;
   args->mvert = pbvh->verts;
@@ -571,12 +573,16 @@ static void pbvh_draw_args(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node)
       args->prim_indicies = node->prim_indices;
       break;
     case PBVH_GRIDS:
-      args->mesh_faces_num = pbvh->mesh->totpoly;
       args->vdata = pbvh->vdata;
       args->ldata = pbvh->ldata;
       args->pdata = pbvh->pdata;
       args->ccg_key = pbvh->gridkey;
       args->me = pbvh->mesh;
+      args->totprim = node->totprim;
+      args->grid_indices = node->prim_indices;
+      args->subdiv_ccg = pbvh->subdiv_ccg;
+      args->face_sets = pbvh->face_sets;
+
       args->mesh_grids_num = pbvh->totgrid;
       args->grids = pbvh->grids;
       args->gridfaces = pbvh->gridfaces;
@@ -584,8 +590,6 @@ static void pbvh_draw_args(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node)
       args->vert_normals = pbvh->vert_normals;
       break;
     case PBVH_BMESH:
-      args->mesh_faces_num = pbvh->header.bm->totface;
-
       args->bm = pbvh->header.bm;
       args->vdata = &args->bm->vdata;
       args->ldata = &args->bm->ldata;
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index fb40aa56c1a..2dbf2112ed0 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -8,6 +8,7 @@
 #pragma once
 
 #include "BLI_assert.h"
+#include "BLI_bitmap.h"
 #include "BLI_sys_types.h" /* for bool */
 #include "BLI_utildefines.h"
 
@@ -256,12 +257,15 @@ typedef struct PBVH_GPU_Args {
   const float (*vert_normals)[3];
 
   int face_sets_color_seed, face_sets_color_default;
+  int *face_sets; /* for PBVH_FACES and PBVH_GRIDS */
 
+  struct SubdivCCG *subdiv_ccg;
   const struct DMFlagMat *grid_flag_mats;
   const int *grid_indices;
   struct CCGKey ccg_key;
   CCGElem **grids;
   void **gridfaces;
+  BLI_bitmap **grid_hidden;
 
   int *prim_indicies;
   int totprim;
diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc
index 68da54d15ed..75518b188c0 100644
--- a/source/blender/draw/intern/draw_pbvh.cc
+++ b/source/blender/draw/intern/draw_pbvh.cc
@@ -66,6 +66,7 @@ using ushort4 = blender::vec_base<uint16_t, 4>;
 using short3 = blender::vec_base<int16_t, 3>;
 using uchar3 = blender::vec_base<uint8_t, 3>;
 using char3 = blender::vec_base<int8_t, 3>;
+using uchar4 = blender::vec_base<uint8_t, 4>;
 
 struct PBVHVbo {
   uint64_t type;
@@ -148,6 +149,7 @@ struct PBVHBatches {
   GPUIndexBuf *tri_index = nullptr;
   GPUIndexBuf *lines_index = nullptr;
   int tris_count = 0, lines_count = 0;
+  bool smooth = false;  // XXX
 
   int material_index = 0;
 
@@ -232,8 +234,173 @@ struct PBVHBatches {
     return batches.lookup(build_key(attrs, attrs_num));
   }
 
+  void fill_vbo_normal_faces(
+      PBVHVbo &vbo,
+      PBVH_GPU_Args *args,
+      std::function<void(std::function<void(int, int, int, const MLoopTri *)> callback)> foreach,
+      GPUVertBufRaw *access)
+  {
+    float fno[3];
+    short no[3];
+    int last_poly = -1;
+    bool smooth = false;
+
+    foreach ([&](int buffer_i, int tri_i, int vertex_i, const MLoopTri *tri) {
+      const MPoly *mp = args->mpoly + tri->poly;
+
+      if (tri->poly != last_poly) {
+        last_poly = tri->poly;
+
+        if (mp->flag & ME_SMOOTH) {
+          smooth = true;
+          BKE_mesh_calc_poly_normal(mp, args->mloop + mp->loopstart, args->mvert, fno);
+          normal_float_to_short_v3(no, fno);
+        }
+        else {
+          smooth = false;
+        }
+      }
+
+      if (!smooth) {
+        normal_float_to_short_v3(no, args->vert_normals[vertex_i]);
+      }
+
+#if 0
+        no[0] = no[1] = no[2] = 0;
+        no[last_poly % 3] = (1 << 15) - 1;
+#endif
+
+      *static_cast<short3 *>(GPU_vertbuf_raw_step(access)) = no;
+    })
+      ;
+  }
+
+  ATTR_NO_OPT void fill_vbo_grids_smooth(PBVHVbo &vbo, PBVH_GPU_Args *args)
+  {
+  }
+
+  ATTR_NO_OPT void fill_vbo_grids_solid(PBVHVbo &vbo, PBVH_GPU_Args *args)
+  {
+    int gridsize = args->ccg_key.grid_size;
+
+    uint totgrid = args->totprim;
+    uint vert_per_grid = square_i(args->ccg_key.grid_size - 1) * 4;
+    uint vert_count = totgrid * vert_per_grid;
+
+    auto foreach =
+        [&](std::function<void(int x, int y, int grid_index, CCGElem *elems[4], int i)> func) {
+          for (int i = 0; i < totgrid; i++) {
+            const int grid_index = args->grid_indices[i];
+            CCGElem *grid = args->grids[grid_index];
+
+            for (int y = 0; y < gridsize - 1; y++) {
+              for (int x = 0; x < gridsize - 1; x++) {
+                CCGElem *elems[4] = {
+                    CCG_grid_elem(&args->ccg_key, grid, x, y),
+                    CCG_grid_elem(&args->ccg_key, grid, x + 1, y),
+                    CCG_grid_elem(&args->ccg_key, grid, x + 1, y + 1),
+                    CCG_grid_elem(&args->ccg_key, grid, x, y + 1),
+                };
+
+                func(x, y, grid_index, elems, 0);
+                func(x + 1, y, grid_index, elems, 1);
+                func(x + 1, y + 1, grid_index, elems, 2);
+                func(x, y + 1, grid_index, elems, 3);
+              }
+            }
+          }
+        };
+
+    int existing_num = GPU_vertbuf_get_vertex_len(vbo.vert_buf);
+    void *existing_data = GPU_vertbuf_get_data(vbo.vert_buf);
+
+    printf("%p:%p: vbo.vert_buf: %p\n", args->node, this, vbo.vert_buf);
+
+    if (existing_data == NULL || existing_num != vert_count) {
+      /* Allocate buffer if not allocated yet or size changed. */
+      GPU_vertbuf_data_alloc(vbo.vert_buf, vert_count);
+    }
+
+    void *gpu_data = GPU_vertbuf_get_data(vbo.vert_buf);
+    GPUVertBufRaw access;
+    GPU_vertbuf_attr_get_raw_data(vbo.vert_buf, 0, &access);
+
+    if (!gpu_data || !args->totprim) {
+      printf("%s: eek!\n", __func__);
+    }
+
+    //        [&](std::function<void(int x, int y, CCGElem *grid, CCGElem *elems[4], int i)> func)
+    //        {
+    if (vbo.type == CD_PBVH_CO_TYPE) {
+      foreach ([&](int x, int y, int grid_index, CCGElem *elems[4], int i) {
+        float *co = CCG_elem_co(&args->ccg_key, elems[i]);
+
+        *static_cast<float3 *>(GPU_vertbuf_raw_step(&access)) = co;
+      })
+        ;
+    }
+
+    if (vbo.type == CD_PBVH_NO_TYPE) {
+      foreach ([&](int x, int y, int grid_index, CCGElem *elems[4], int i) {
+        float3 no(0.0f, 0.0f, 0.0f);
+
+        for (int j = 0; j < 4; j++) {
+          no += CCG_elem_no(&args->ccg_key, elems[j]);
+        }
+
+        normalize_v3(no);
+        short sno[3];
+
+        normal_float_to_short_v3(sno, no);
+
+        *static_cast<short3 *>(GPU_vertbuf_raw_step(&access)) = sno;
+      })
+        ;
+    }
+
+    if (vbo.type == CD_PBVH_MASK_TYPE) {
+      foreach ([&](int x, int y, int grid_index, CCGElem *elems[4], int i) {
+        float *mask = CCG_elem_mask(&args->ccg_key, elems[i]);
+
+        *static_cast<uchar *>(GPU_vertbuf_raw_step(&access)) = mask ? (uchar)(*mask * 255.0f) :
+                                                                      255;
+      })
+        ;
+    }
+
+    if (vbo.type == CD_PBVH_FSET_TYPE) {
+      int *sculpt_face_sets = args->face_sets;
+
+      foreach ([&](int x, int y, int grid_index, CCGElem *elems[4], int i) {
+        uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
+        const int face_index = BKE_subdiv_ccg_grid_to_face_index(args->subdiv_ccg, grid_index);
+        const int fset = abs(sculpt_face_sets[face_index]);
+
+        /* Skip for the default color Face Set to render it white. */
+        if (fset != args->face_sets_color_default) {
+          BKE_paint_face_set_overlay_color_get(fset, args->face_sets_color_seed, face_set_color);
+        }
+
+        *static_cast<uchar4 *>(GPU_vertbuf_raw_step(&access)) = face_set_color;
+      })
+        ;
+    }
+  }
+
+  ATTR_NO_OPT void fill_vbo_grids(PBVHVbo &vbo, PBVH_GPU_Args *args)
+  {
+    if (smooth) {
+      fill_vbo_grids_smooth(vbo, args);
+    }
+    else {
+      fill_vbo_grids_solid(vbo, args);
+    }
+  }
+
   ATTR_NO_OPT void fill_vbo_faces(PBVHVbo &vbo, PBVH_GPU_Args *args)
   {
+    int totvert = args->totprim * 3;
+
     auto foreach =
         [&](std::function<void(int buffer_i, int tri_i, int vertex_i, const MLoopTri *tri)> func) {
           int buffer_i = 0;
@@ -254,9 +421,9 @@ struct PBVHBatches {
 
     printf("%p:%p: vbo.vert_buf: %p\n", args->node, this, vbo.vert_buf);
 
-    if (existing_data == NULL || existing_num != args->totprim * 3) {
+    if (existing_data == NULL || existing_num != totvert) {
       /* Allocate buffer if not allocated yet or size changed. */
-      GPU_vertbuf_data_alloc(vbo.vert_buf, args->totprim * 3);
+      GPU_vertbuf_data_alloc(vbo.vert_buf, totvert);
     }
 
     void *gpu_data = GPU_vertbuf_get_data(vbo.vert_buf);
@@ -274,39 +441,11 @@ struct PBVHBatches {
         ;
     }
     else if (vbo.type == CD_PBVH_NO_TYPE) {
-      float fno[3];
-      short no[3];
-      int last_poly = -1;
-      bool smooth = false;
-
-      foreach ([&](int buffer_i, int tri_i, int vertex_i, const MLoopTri *tri) {
-        const MPoly *mp = args->mpoly + tri->poly;
-
-        if (tri->poly != last_poly) {
-          last_poly = tri->poly;
-
-          if (mp->flag & ME_SMOOTH) {
-            smooth = true;
-            BKE_mesh_calc_poly_normal(mp, args->mloop + mp->loopstart, args->mvert, fno);
-            normal_float_to_short_v3(no, fno);
-          }
-          else {
-            smooth = false;
-          }


@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list