[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