[Bf-blender-cvs] [076eb5c87a7] greasepencil-refactor: GPencil: Refactor: Add support for fill textures

Clément Foucault noreply at git.blender.org
Wed Dec 11 03:07:59 CET 2019


Commit: 076eb5c87a7b1558344e65e85790a1397277a5b9
Author: Clément Foucault
Date:   Wed Dec 11 01:29:38 2019 +0100
Branches: greasepencil-refactor
https://developer.blender.org/rB076eb5c87a7b1558344e65e85790a1397277a5b9

GPencil: Refactor: Add support for fill textures

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

M	source/blender/draw/engines/gpencil/gpencil_cache_utils.c
M	source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
M	source/blender/draw/engines/gpencil/gpencil_draw_data.c
M	source/blender/draw/engines/gpencil/gpencil_engine.c
M	source/blender/draw/engines/gpencil/gpencil_engine.h
M	source/blender/draw/engines/gpencil/gpencil_shader.c
M	source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
M	source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
M	source/blender/draw/engines/gpencil/shaders/gpencil_vert.glsl

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

diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
index 9b753d442f9..d72cf35ce47 100644
--- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -60,7 +60,7 @@ GPENCIL_tLayer *gpencil_layer_cache_add_new(GPENCIL_PrivateData *pd,
   bGPdata *gpd = (bGPdata *)ob->data;
   GPENCIL_tLayer *tgp_layer = BLI_memblock_alloc(pd->gp_layer_pool);
 
-  DRWState state = DRW_STATE_WRITE_COLOR;
+  DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA;
   /* TODO better 3D mode. */
   if (GPENCIL_3D_DRAWMODE(ob, gpd)) {
     state |= DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
index 2f3ece021b4..927b85a4385 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
@@ -71,8 +71,7 @@ typedef struct gpStrokeVert {
   /** Position and thickness packed in the same attribute. */
   float pos[3], thickness;
   // float col[4];
-  // float rad;
-  // float uv[2];
+  float uv[2];
 } gpStrokeVert;
 
 static GPUVertFormat *gpencil_stroke_format(void)
@@ -83,7 +82,7 @@ static GPUVertFormat *gpencil_stroke_format(void)
     GPU_vertformat_attr_add(&format, "ma", GPU_COMP_I32, 1, GPU_FETCH_INT);
     GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
     // GPU_vertformat_attr_add(&format, "col", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
-    // GPU_vertformat_attr_add(&format, "uv", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+    GPU_vertformat_attr_add(&format, "uv", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
     /* IMPORTANT: This means having only 4 attributes to fit into opengl limit of 16 attrib. */
     GPU_vertformat_multiload_enable(&format, 4);
   }
@@ -116,6 +115,7 @@ static void gpencil_buffer_add_point(gpStrokeVert *verts,
 {
   /* TODO other attribs */
   copy_v3_v3(verts->pos, &pt->x);
+  copy_v2_v2(verts->uv, pt->uv_fill);
   verts->thickness = gps->thickness * pt->pressure;
   /* Tag endpoint material to -1 so they get discarded by vertex shader. */
   verts->mat = (is_endpoint) ? -1 : (gps->mat_nr % GPENCIL_MATERIAL_BUFFER_LEN);
@@ -174,20 +174,6 @@ static void gp_object_verts_count_cb(bGPDlayer *UNUSED(gpl),
 {
   gpIterData *iter = (gpIterData *)thunk;
 
-#if 0 /* TODO: Remove as the calc is in evaluated modules (gpencil_modifier.c). */
-  /* Calculate triangles cache for filling area (must be done only after changes) */
-  if ((gps->flag & GP_STROKE_RECALC_GEOMETRY) || (gps->tot_triangles == 0) ||
-      (gps->triangles == NULL)) {
-    if (gps->totpoints >= 3) {
-      /* TODO OPTI only do this if the fill is actually displayed. */
-      BKE_gpencil_triangulate_stroke_fill(iter->gpd, gps);
-    }
-    else {
-      gps->tot_triangles = 0;
-    }
-  }
-#endif
-
   /* Store first index offset */
   gps->runtime.stroke_start = iter->vert_len;
   gps->runtime.fill_start = iter->tri_len;
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_data.c b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
index b297fe57443..89124e6785b 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_data.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
@@ -22,10 +22,14 @@
 
 #include "DRW_render.h"
 
+#include "BKE_image.h"
+
 #include "BLI_memblock.h"
 
 #include "GPU_uniformbuffer.h"
 
+#include "IMB_imbuf_types.h"
+
 #include "gpencil_engine.h"
 
 static GPENCIL_MaterialPool *gpencil_material_pool_add(GPENCIL_PrivateData *pd)
@@ -39,6 +43,47 @@ static GPENCIL_MaterialPool *gpencil_material_pool_add(GPENCIL_PrivateData *pd)
   return matpool;
 }
 
+static struct GPUTexture *gpencil_image_texture_get(Image *image, bool *r_alpha_premult)
+{
+  ImBuf *ibuf;
+  ImageUser iuser = {NULL};
+  struct GPUTexture *gpu_tex = NULL;
+  void *lock;
+
+  iuser.ok = true;
+  ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
+
+  if (ibuf != NULL && ibuf->rect != NULL) {
+    gpu_tex = GPU_texture_from_blender(image, &iuser, GL_TEXTURE_2D);
+    *r_alpha_premult = (image->alpha_mode == IMA_ALPHA_PREMUL);
+  }
+  BKE_image_release_ibuf(image, ibuf, lock);
+
+  return gpu_tex;
+}
+
+static void gpencil_uv_transform_get(const float ofs[2],
+                                     const float scale[2],
+                                     const float rotation,
+                                     float r_uvmat[3][2])
+{
+  /* OPTI this could use 3x2 matrices and reduce the number of operations drastically. */
+  float mat[4][4];
+  float scale_v3[3] = {scale[0], scale[1], 0.0};
+  /* Scale */
+  size_to_mat4(mat, scale_v3);
+  /* Offset to center. */
+  translate_m4(mat, 0.5f + ofs[0], 0.5f + ofs[1], 0.0f);
+  /* Rotation; */
+  rotate_m4(mat, 'Z', -rotation);
+  /* Translate. */
+  translate_m4(mat, -0.5f, -0.5f, 0.0f);
+  /* Convert to 3x2 */
+  copy_v2_v2(r_uvmat[0], mat[0]);
+  copy_v2_v2(r_uvmat[1], mat[1]);
+  copy_v2_v2(r_uvmat[2], mat[3]);
+}
+
 /**
  * Creates a linked list of material pool containing all materials assigned for a given object.
  * We merge the material pools together if object does not contain a huge amount of materials.
@@ -55,14 +100,60 @@ GPENCIL_MaterialPool *gpencil_material_pool_create(GPENCIL_PrivateData *pd, Obje
 
   GPENCIL_MaterialPool *pool = matpool;
   for (int i = 0; i < ob->totcol; i++) {
-    if ((i > 0) && (i % GPENCIL_MATERIAL_BUFFER_LEN) == 0) {
+    int mat_id = (i % GPENCIL_MATERIAL_BUFFER_LEN);
+    if ((i > 0) && (mat_id == 0)) {
       pool->next = gpencil_material_pool_add(pd);
       pool = pool->next;
     }
-    gpMaterial *mat_data = &pool->mat_data[i % GPENCIL_MATERIAL_BUFFER_LEN];
+    gpMaterial *mat_data = &pool->mat_data[mat_id];
     MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, i + 1);
-    copy_v4_v4(mat_data->stroke_color, gp_style->stroke_rgba);
-    copy_v4_v4(mat_data->fill_color, gp_style->fill_rgba);
+
+    mat_data->flag = 0;
+
+    if ((gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (gp_style->sima)) {
+      /* TODO finish. */
+      bool premul;
+      pool->tex_stroke[mat_id] = gpencil_image_texture_get(gp_style->sima, &premul);
+      mat_data->flag |= GP_STROKE_TEXTURE_USE;
+      mat_data->flag |= premul ? GP_STROKE_TEXTURE_PREMUL : 0;
+      copy_v4_v4(mat_data->stroke_color, gp_style->stroke_rgba);
+    }
+    else /* if (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) */ {
+      pool->tex_stroke[mat_id] = NULL;
+      mat_data->flag &= ~GP_STROKE_TEXTURE_USE;
+      copy_v4_v4(mat_data->stroke_color, gp_style->stroke_rgba);
+    }
+
+    if ((gp_style->fill_style == GP_STYLE_FILL_STYLE_TEXTURE) && (gp_style->ima)) {
+      bool use_clip = (gp_style->flag & GP_STYLE_COLOR_TEX_CLAMP) != 0;
+      bool premul;
+      pool->tex_fill[mat_id] = gpencil_image_texture_get(gp_style->ima, &premul);
+      mat_data->flag |= GP_FILL_TEXTURE_USE;
+      mat_data->flag |= premul ? GP_FILL_TEXTURE_PREMUL : 0;
+      mat_data->flag |= use_clip ? GP_FILL_TEXTURE_CLIP : 0;
+      gpencil_uv_transform_get(gp_style->texture_offset,
+                               gp_style->texture_scale,
+                               gp_style->texture_angle,
+                               mat_data->fill_uv_transform);
+      copy_v4_fl4(mat_data->fill_color, 1.0f, 1.0f, 1.0f, gp_style->texture_opacity);
+    }
+    else if (gp_style->fill_style == GP_STYLE_FILL_STYLE_TEXTURE) {
+      /* TODO implement gradient as a texture. */
+      pool->tex_fill[mat_id] = NULL;
+      mat_data->flag &= ~GP_FILL_TEXTURE_USE;
+      copy_v4_v4(mat_data->fill_color, gp_style->fill_rgba);
+    }
+    else if (gp_style->fill_style == GP_STYLE_FILL_STYLE_CHECKER) {
+      /* TODO implement checker as a texture. */
+      pool->tex_fill[mat_id] = NULL;
+      mat_data->flag &= ~GP_FILL_TEXTURE_USE;
+      copy_v4_v4(mat_data->fill_color, gp_style->fill_rgba);
+    }
+    else /* if (gp_style->fill_style == GP_STYLE_FILL_STYLE_SOLID) */ {
+      pool->tex_fill[mat_id] = NULL;
+      mat_data->flag &= ~GP_FILL_TEXTURE_USE;
+      copy_v4_v4(mat_data->fill_color, gp_style->fill_rgba);
+    }
   }
 
   *ofs = 0;
@@ -70,14 +161,25 @@ GPENCIL_MaterialPool *gpencil_material_pool_create(GPENCIL_PrivateData *pd, Obje
   return matpool;
 }
 
-GPUUniformBuffer *gpencil_material_ubo_get(GPENCIL_MaterialPool *first_pool, int mat_id)
+void gpencil_material_resources_get(GPENCIL_MaterialPool *first_pool,
+                                    int mat_id,
+                                    GPUTexture **r_tex_stroke,
+                                    GPUTexture **r_tex_fill,
+                                    GPUUniformBuffer **r_ubo_mat)
 {
   GPENCIL_MaterialPool *matpool = first_pool;
   int pool_id = mat_id / GPENCIL_MATERIAL_BUFFER_LEN;
   for (int i = 0; i < pool_id; i++) {
     matpool = matpool->next;
   }
-  return matpool->ubo;
+  mat_id = mat_id % GPENCIL_MATERIAL_BUFFER_LEN;
+  *r_ubo_mat = matpool->ubo;
+  if (r_tex_fill) {
+    *r_tex_fill = matpool->tex_fill[mat_id];
+  }
+  if (r_tex_stroke) {
+    *r_tex_stroke = matpool->tex_stroke[mat_id];
+  }
 }
 
 void gpencil_material_pool_free(void *storage)
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index e7705bd4b95..6996f0bae00 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -279,12 +279,15 @@ static void GPENCIL_create_shaders(void)
 static void GPENCIL_engine_init_new(void *ved)
 {
   GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
-  GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+  GPENCIL_StorageList *stl = vedata->stl;
+  GPENCIL_TextureList *txl = vedata->txl;
 
   if (!stl->pd) {
     stl->pd = MEM_callocN(sizeof(GPENCIL_PrivateData), "GPENCIL_PrivateData");
   }
 
+  DRW_texture_ensure_2d(&txl->dummy_texture, 1, 1, GPU_R8, 0);
+
   GPENCIL_ViewLayerData *vldata = GPENCIL_view_layer_data_ensure();
 
   /* Resize and reset memblocks. */
@@ -739,8 +742,11 @@ typedef struct 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list