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/engines/gpencil/gpencil_engine.c')
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.c124
1 files changed, 113 insertions, 11 deletions
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 7be06d501f1..a80ad133d09 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -64,6 +64,7 @@ extern char datatoc_gpencil_paper_frag_glsl[];
extern char datatoc_gpencil_edit_point_vert_glsl[];
extern char datatoc_gpencil_edit_point_geom_glsl[];
extern char datatoc_gpencil_edit_point_frag_glsl[];
+extern char datatoc_gpencil_blend_frag_glsl[];
/* *********** STATIC *********** */
static GPENCIL_e_data e_data = {NULL}; /* Engine data */
@@ -221,6 +222,11 @@ static void GPENCIL_create_shaders(void)
e_data.gpencil_simple_fullscreen_sh = DRW_shader_create_fullscreen(datatoc_gpencil_simple_mix_frag_glsl, NULL);
}
+ /* blend */
+ if (!e_data.gpencil_blend_fullscreen_sh) {
+ e_data.gpencil_blend_fullscreen_sh = DRW_shader_create_fullscreen(datatoc_gpencil_blend_frag_glsl, NULL);
+ }
+
/* shaders for use when drawing */
if (!e_data.gpencil_background_sh) {
e_data.gpencil_background_sh = DRW_shader_create_fullscreen(datatoc_gpencil_background_frag_glsl, NULL);
@@ -266,6 +272,7 @@ static void GPENCIL_engine_free(void)
DRW_SHADER_FREE_SAFE(e_data.gpencil_edit_point_sh);
DRW_SHADER_FREE_SAFE(e_data.gpencil_fullscreen_sh);
DRW_SHADER_FREE_SAFE(e_data.gpencil_simple_fullscreen_sh);
+ DRW_SHADER_FREE_SAFE(e_data.gpencil_blend_fullscreen_sh);
DRW_SHADER_FREE_SAFE(e_data.gpencil_background_sh);
DRW_SHADER_FREE_SAFE(e_data.gpencil_paper_sh);
@@ -371,6 +378,7 @@ void GPENCIL_cache_init(void *vedata)
stl->storage->simplify_fill = GP_SIMPLIFY_FILL(scene, stl->storage->is_playing);
stl->storage->simplify_modif = GP_SIMPLIFY_MODIF(scene, stl->storage->is_playing);
stl->storage->simplify_fx = GP_SIMPLIFY_FX(scene, stl->storage->is_playing);
+ stl->storage->simplify_blend = GP_SIMPLIFY_BLEND(scene, stl->storage->is_playing);
/* save pixsize */
stl->storage->pixsize = DRW_viewport_pixelsize_get();
@@ -485,6 +493,20 @@ void GPENCIL_cache_init(void *vedata)
stl->g_data->shgrps_grid = DRW_shgroup_create(e_data.gpencil_line_sh, psl->grid_pass);
}
+ /* blend layers pass */
+ psl->blend_pass = DRW_pass_create(
+ "GPencil Blend Layers Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+ DRWShadingGroup *blend_shgrp = DRW_shgroup_create(e_data.gpencil_blend_fullscreen_sh, psl->blend_pass);
+ DRW_shgroup_call_add(blend_shgrp, quad, NULL);
+ DRW_shgroup_uniform_texture_ref(blend_shgrp, "strokeColor", &e_data.temp_color_tx_a);
+ DRW_shgroup_uniform_texture_ref(blend_shgrp, "strokeDepth", &e_data.temp_depth_tx_a);
+ DRW_shgroup_uniform_texture_ref(blend_shgrp, "blendColor", &e_data.temp_color_tx_fx);
+ DRW_shgroup_uniform_texture_ref(blend_shgrp, "blendDepth", &e_data.temp_depth_tx_fx);
+ DRW_shgroup_uniform_int(blend_shgrp, "mode", &stl->storage->blend_mode, 1);
+ DRW_shgroup_uniform_int(blend_shgrp, "clamp_layer", &stl->storage->clamp_layer, 1);
+ DRW_shgroup_uniform_float(blend_shgrp, "blend_opacity", &stl->storage->blend_opacity, 1);
+
/* create effects passes */
if (!stl->storage->simplify_fx) {
GPENCIL_create_fx_passes(psl);
@@ -639,12 +661,40 @@ static void gpencil_free_obj_runtime(GPENCIL_StorageList *stl)
tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i];
bGPdata *gpd = cache_ob->gpd;
gpd->flag &= ~GP_DATA_CACHE_IS_DIRTY;
+
+ /* free shgrp array */
+ cache_ob->tot_layers = 0;
+ MEM_SAFE_FREE(cache_ob->shgrp_array);
}
/* free the cache itself */
MEM_SAFE_FREE(stl->g_data->gp_object_cache);
}
+static void gpencil_draw_pass_range(
+ GPENCIL_FramebufferList *fbl, GPENCIL_StorageList *stl,
+ GPENCIL_PassList *psl, GPENCIL_TextureList *txl,
+ GPUFrameBuffer *fb,
+ DRWShadingGroup *init_shgrp, DRWShadingGroup *end_shgrp, bool multi)
+{
+ if (init_shgrp == NULL) {
+ return;
+ }
+
+ /* previews don't use AA */
+ if ((!stl->storage->is_mat_preview) && (multi)) {
+ MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl);
+ }
+
+ DRW_draw_pass_subset(
+ psl->stroke_pass, init_shgrp, end_shgrp);
+
+ if ((!stl->storage->is_mat_preview) && (multi)) {
+ MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, fb, txl);
+ }
+
+}
+
/* draw scene */
void GPENCIL_draw_scene(void *ved)
{
@@ -657,6 +707,10 @@ void GPENCIL_draw_scene(void *ved)
GPENCIL_TextureList *txl = ((GPENCIL_Data *)vedata)->txl;
tGPencilObjectCache *cache_ob;
+ tGPencilObjectCache_shgrp *array_elm = NULL;
+ DRWShadingGroup *init_shgrp = NULL;
+ DRWShadingGroup *end_shgrp = NULL;
+
const float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -712,7 +766,7 @@ void GPENCIL_draw_scene(void *ved)
for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
cache_ob = &stl->g_data->gp_object_cache[i];
bGPdata *gpd = cache_ob->gpd;
-
+ init_shgrp = NULL;
/* Render stroke in separated framebuffer */
GPU_framebuffer_bind(fbl->temp_fb_a);
GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
@@ -720,19 +774,67 @@ void GPENCIL_draw_scene(void *ved)
/* Stroke Pass:
* draw only a subset that usually starts with a fill and ends with stroke
*/
- if (cache_ob->init_grp) {
- /* previews don't use AA */
- if (!stl->storage->is_mat_preview) {
- MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl);
- }
+ bool use_blend = false;
+ if (cache_ob->tot_layers > 0) {
+ for (int e = 0; e < cache_ob->tot_layers; e++) {
+ bool is_last = e == cache_ob->tot_layers - 1 ? true : false;
+ array_elm = &cache_ob->shgrp_array[e];
+
+ if (((array_elm->mode == eGplBlendMode_Normal) &&
+ (!use_blend) && (!array_elm->clamp_layer)) ||
+ ( e == 0))
+ {
+ if (init_shgrp == NULL) {
+ init_shgrp = array_elm->init_shgrp;
+ }
+ end_shgrp = array_elm->end_shgrp;
+ }
+ else {
+ use_blend = true;
+ /* draw pending groups */
+ gpencil_draw_pass_range(
+ fbl, stl, psl, txl, fbl->temp_fb_a,
+ init_shgrp, end_shgrp, is_last);
+
+ /* draw current group in separated texture */
+ init_shgrp = array_elm->init_shgrp;
+ end_shgrp = array_elm->end_shgrp;
+
+ GPU_framebuffer_bind(fbl->temp_fb_fx);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
+ gpencil_draw_pass_range(
+ fbl, stl, psl, txl, fbl->temp_fb_fx,
+ init_shgrp, end_shgrp,
+ is_last);
+
+ /* Blend A texture and FX texture */
+ GPU_framebuffer_bind(fbl->temp_fb_b);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
+ stl->storage->blend_mode = array_elm->mode;
+ stl->storage->clamp_layer = (int)array_elm->clamp_layer;
+ stl->storage->blend_opacity = array_elm->blend_opacity;
+ DRW_draw_pass(psl->blend_pass);
+
+ /* Copy B texture to A texture to follow loop */
+ e_data.input_depth_tx = e_data.temp_depth_tx_b;
+ e_data.input_color_tx = e_data.temp_color_tx_b;
+
+ GPU_framebuffer_bind(fbl->temp_fb_a);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
+ DRW_draw_pass(psl->mix_pass_noblend);
+
+ /* prepare next group */
+ init_shgrp = NULL;
+ }
- DRW_draw_pass_subset(
- psl->stroke_pass, cache_ob->init_grp, cache_ob->end_grp);
-
- if (!stl->storage->is_mat_preview) {
- MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, fbl->temp_fb_a, txl);
}
+ /* last group */
+ gpencil_draw_pass_range(
+ fbl, stl, psl, txl, fbl->temp_fb_a,
+ init_shgrp, end_shgrp,
+ true);
}
+
/* Current buffer drawing */
if ((!is_render) && (cache_ob->is_dup_ob == false)) {
DRW_draw_pass(psl->drawing_pass);