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.c199
1 files changed, 108 insertions, 91 deletions
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 9554e9c0275..aed6789fe26 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -62,6 +62,7 @@ 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[];
+extern char datatoc_gpencil_merge_depth_frag_glsl[];
extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
@@ -124,35 +125,35 @@ static void GPENCIL_create_framebuffers(void *vedata)
/* Framebufers for basic object drawing */
if (stl->storage->framebuffer_flag & GP_FRAMEBUFFER_BASIC) {
/* temp textures for ping-pong buffers */
- stl->g_data->temp_depth_tx_a = DRW_texture_pool_query_2d(
+ stl->g_data->temp_depth_a_tx = DRW_texture_pool_query_2d(
size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_gpencil_type);
- stl->g_data->temp_color_tx_a = DRW_texture_pool_query_2d(
+ stl->g_data->temp_color_a_tx = DRW_texture_pool_query_2d(
size[0], size[1], fb_format, &draw_engine_gpencil_type);
- GPU_framebuffer_ensure_config(&fbl->temp_fb_a,
+ GPU_framebuffer_ensure_config(&fbl->temp_a_fb,
{
- GPU_ATTACHMENT_TEXTURE(stl->g_data->temp_depth_tx_a),
- GPU_ATTACHMENT_TEXTURE(stl->g_data->temp_color_tx_a),
+ GPU_ATTACHMENT_TEXTURE(stl->g_data->temp_depth_a_tx),
+ GPU_ATTACHMENT_TEXTURE(stl->g_data->temp_color_a_tx),
});
- stl->g_data->temp_depth_tx_b = DRW_texture_pool_query_2d(
+ stl->g_data->temp_depth_b_tx = DRW_texture_pool_query_2d(
size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_gpencil_type);
- stl->g_data->temp_color_tx_b = DRW_texture_pool_query_2d(
+ stl->g_data->temp_color_b_tx = DRW_texture_pool_query_2d(
size[0], size[1], fb_format, &draw_engine_gpencil_type);
- GPU_framebuffer_ensure_config(&fbl->temp_fb_b,
+ GPU_framebuffer_ensure_config(&fbl->temp_b_fb,
{
- GPU_ATTACHMENT_TEXTURE(stl->g_data->temp_depth_tx_b),
- GPU_ATTACHMENT_TEXTURE(stl->g_data->temp_color_tx_b),
+ GPU_ATTACHMENT_TEXTURE(stl->g_data->temp_depth_b_tx),
+ GPU_ATTACHMENT_TEXTURE(stl->g_data->temp_color_b_tx),
});
/* used for FX effects and Layer blending */
- stl->g_data->temp_depth_tx_fx = DRW_texture_pool_query_2d(
+ stl->g_data->temp_depth_fx_tx = DRW_texture_pool_query_2d(
size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_gpencil_type);
- stl->g_data->temp_color_tx_fx = DRW_texture_pool_query_2d(
+ stl->g_data->temp_color_fx_tx = DRW_texture_pool_query_2d(
size[0], size[1], fb_format, &draw_engine_gpencil_type);
- GPU_framebuffer_ensure_config(&fbl->temp_fb_fx,
+ GPU_framebuffer_ensure_config(&fbl->temp_fx_fb,
{
- GPU_ATTACHMENT_TEXTURE(stl->g_data->temp_depth_tx_fx),
- GPU_ATTACHMENT_TEXTURE(stl->g_data->temp_color_tx_fx),
+ GPU_ATTACHMENT_TEXTURE(stl->g_data->temp_depth_fx_tx),
+ GPU_ATTACHMENT_TEXTURE(stl->g_data->temp_color_fx_tx),
});
}
@@ -258,6 +259,9 @@ static void GPENCIL_create_shaders(void)
if (!e_data.gpencil_blend_fullscreen_sh) {
e_data.gpencil_blend_fullscreen_sh = DRW_shader_create_fullscreen(
datatoc_gpencil_blend_frag_glsl, NULL);
+
+ e_data.gpencil_merge_depth_sh = DRW_shader_create_fullscreen(
+ datatoc_gpencil_merge_depth_frag_glsl, NULL);
}
/* shaders for use when drawing */
@@ -298,6 +302,7 @@ static void GPENCIL_engine_free(void)
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_merge_depth_sh);
DRW_SHADER_FREE_SAFE(e_data.gpencil_background_sh);
DRW_SHADER_FREE_SAFE(e_data.gpencil_paper_sh);
@@ -524,10 +529,11 @@ void GPENCIL_cache_init(void *vedata)
/* full screen pass to combine the result with default framebuffer */
struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
- psl->mix_pass = DRW_pass_create("GPencil Mix Pass",
- DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA |
- DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
- DRWShadingGroup *mix_shgrp = DRW_shgroup_create(e_data.gpencil_fullscreen_sh, psl->mix_pass);
+ psl->mix_screen_pass = DRW_pass_create("GPencil Mix Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA |
+ DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+ DRWShadingGroup *mix_shgrp = DRW_shgroup_create(e_data.gpencil_fullscreen_sh,
+ psl->mix_screen_pass);
DRW_shgroup_call(mix_shgrp, quad, NULL);
DRW_shgroup_uniform_texture_ref(mix_shgrp, "strokeColor", &stl->g_data->input_color_tx);
DRW_shgroup_uniform_texture_ref(mix_shgrp, "strokeDepth", &stl->g_data->input_depth_tx);
@@ -541,11 +547,11 @@ void GPENCIL_cache_init(void *vedata)
* This pass is used too to take the snapshot used for background_pass. This image
* will be used as the background while the user is drawing.
*/
- psl->mix_pass_noblend = DRW_pass_create("GPencil Mix Pass no blend",
- DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
- DRW_STATE_DEPTH_LESS);
+ psl->mix_screen_noblend_pass = DRW_pass_create("GPencil Mix Pass no blend",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
+ DRW_STATE_DEPTH_LESS);
DRWShadingGroup *mix_shgrp_noblend = DRW_shgroup_create(e_data.gpencil_fullscreen_sh,
- psl->mix_pass_noblend);
+ psl->mix_screen_noblend_pass);
DRW_shgroup_call(mix_shgrp_noblend, quad, NULL);
DRW_shgroup_uniform_texture_ref(
mix_shgrp_noblend, "strokeColor", &stl->g_data->input_color_tx);
@@ -624,19 +630,20 @@ void GPENCIL_cache_init(void *vedata)
}
/* blend layers pass */
- psl->blend_pass = DRW_pass_create("GPencil Blend Layers Pass",
- DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA |
- DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+ psl->blend_layers_pass = DRW_pass_create("GPencil Blend Layers Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM);
DRWShadingGroup *blend_shgrp = DRW_shgroup_create(e_data.gpencil_blend_fullscreen_sh,
- psl->blend_pass);
- DRW_shgroup_call(blend_shgrp, quad, NULL);
- DRW_shgroup_uniform_texture_ref(blend_shgrp, "strokeColor", &stl->g_data->temp_color_tx_a);
- DRW_shgroup_uniform_texture_ref(blend_shgrp, "strokeDepth", &stl->g_data->temp_depth_tx_a);
- DRW_shgroup_uniform_texture_ref(blend_shgrp, "blendColor", &stl->g_data->temp_color_tx_fx);
- DRW_shgroup_uniform_texture_ref(blend_shgrp, "blendDepth", &stl->g_data->temp_depth_tx_fx);
+ psl->blend_layers_pass);
+ DRW_shgroup_uniform_texture_ref(blend_shgrp, "strokeColor", &stl->g_data->temp_color_fx_tx);
DRW_shgroup_uniform_int(blend_shgrp, "mode", &stl->storage->blend_mode, 1);
- DRW_shgroup_uniform_int(blend_shgrp, "mask_layer", &stl->storage->mask_layer, 1);
- DRW_shgroup_uniform_int(mix_shgrp, "tonemapping", &stl->storage->tonemapping, 1);
+ DRW_shgroup_call(blend_shgrp, quad, NULL);
+
+ psl->blend_layers_depth_pass = DRW_pass_create("GPencil Merge Depth Pass",
+ DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+ DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.gpencil_merge_depth_sh,
+ psl->blend_layers_depth_pass);
+ DRW_shgroup_uniform_texture_ref(shgrp, "strokeDepth", &stl->g_data->temp_depth_fx_tx);
+ DRW_shgroup_call(shgrp, quad, NULL);
/* create effects passes */
if (!stl->storage->simplify_fx) {
@@ -652,6 +659,7 @@ static void gpencil_add_draw_data(void *vedata, Object *ob)
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
const DRWContextState *draw_ctx = DRW_context_state_get();
const View3D *v3d = draw_ctx->v3d;
+ tGPencilObjectCache_shgrp *array_elm = NULL;
int i = stl->g_data->gp_cache_used - 1;
tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i];
@@ -666,6 +674,16 @@ static void gpencil_add_draw_data(void *vedata, Object *ob)
}
}
+ /* Verify if the object has layer blending */
+ cache_ob->has_layer_blend = false;
+ for (int e = 0; e < cache_ob->tot_layers; e++) {
+ array_elm = &cache_ob->shgrp_array[e];
+ if ((array_elm->mode != eGplBlendMode_Regular) || (array_elm->mask_layer)) {
+ cache_ob->has_layer_blend = true;
+ break;
+ }
+ }
+
/* FX passses */
cache_ob->has_fx = false;
if ((!stl->storage->simplify_fx) &&
@@ -870,16 +888,13 @@ void DRW_gpencil_free_runtime_data(void *ved)
MEM_SAFE_FREE(stl->g_data->gp_object_cache);
}
-static void gpencil_draw_pass_range(GPENCIL_FramebufferList *fbl,
- GPENCIL_StorageList *stl,
+static void gpencil_draw_pass_range(GPENCIL_StorageList *stl,
GPENCIL_PassList *psl,
- GPENCIL_TextureList *txl,
GPUFrameBuffer *fb,
Object *ob,
bGPdata *gpd,
DRWShadingGroup *init_shgrp,
- DRWShadingGroup *end_shgrp,
- bool multi)
+ DRWShadingGroup *end_shgrp)
{
if (init_shgrp == NULL) {
return;
@@ -1020,73 +1035,75 @@ void GPENCIL_draw_scene(void *ved)
sizeof(tGPencilObjectCache),
gpencil_object_cache_compare_zdepth);
+ GPUFrameBuffer *blend_fb = fbl->temp_fx_fb;
+ const bool do_antialiasing = ((!stl->storage->is_mat_preview) &&
+ (stl->storage->multisamples > 0));
+ GPUFrameBuffer *final_fb = (do_antialiasing) ? fbl->multisample_fb : fbl->temp_a_fb;
+
for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
+ GPU_framebuffer_bind(fbl->temp_a_fb);
+ GPU_framebuffer_clear_color_depth_stencil(fbl->temp_a_fb, clearcol, 1.0f, 0x0);
+
cache_ob = &stl->g_data->gp_object_cache[i];
Object *ob = cache_ob->ob;
+ /* TODO: To check if the object has Blend, verify the value of
+ * cache_ob->has_layer_blend
+ * Actually this variable is set to true if any layer has any blend mode
+ * different of Regular mode or the layer has the Masking enabled.
+ */
+
+ /* TODO: To check if the object has VFX, verify the value of
+ * cache_ob->has_fx
+ */
+
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_stencil(fbl->temp_fb_a, clearcol, 1.0f, 0x0);
/* Stroke Pass:
* draw only a subset that usually starts with a fill and ends with stroke
*/
- 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];
+ init_shgrp = array_elm->init_shgrp;
+ end_shgrp = array_elm->end_shgrp;
- if (((array_elm->mode == eGplBlendMode_Regular) && (!use_blend) &&
- (!array_elm->mask_layer)) ||
- (e == 0)) {
- if (init_shgrp == NULL) {
- init_shgrp = array_elm->init_shgrp;
- }
- end_shgrp = array_elm->end_shgrp;
+ if (stl->storage->multisamples > 0) {
+ GPU_framebuffer_bind(fbl->multisample_fb);
}
else {
- use_blend = true;
- /* draw pending groups */
- gpencil_draw_pass_range(
- fbl, stl, psl, txl, fbl->temp_fb_a, ob, gpd, init_shgrp, end_shgrp, is_last);
-
- /* Draw current group in separated texture to blend later */
- init_shgrp = array_elm->init_shgrp;
- end_shgrp = array_elm->end_shgrp;
+ GPU_framebuffer_bind(fbl->temp_a_fb);
+ }
- GPU_framebuffer_bind(fbl->temp_fb_fx);
- GPU_framebuffer_clear_color_depth_stencil(fbl->temp_fb_fx, clearcol, 1.0f, 0x0);
- gpencil_draw_pass_range(
- fbl, stl, psl, txl, fbl->temp_fb_fx, ob, gpd, init_shgrp, end_shgrp, is_last);
+ if (array_elm->mode == eGplBlendMode_Regular) {
+ /* Draw current group in MSAA texture or final texture. */
+ gpencil_draw_pass_range(stl, psl, final_fb, ob, gpd, init_shgrp, end_shgrp);
+ }
+ else {
+ /* Draw current group in separated texture to blend later. */
+ GPU_framebuffer_bind(blend_fb);
+ GPU_framebuffer_clear_color_depth_stencil(blend_fb, clearcol, 1.0f, 0x0);
+ gpencil_draw_pass_range(stl, psl, fbl->temp_fx_fb, ob, gpd, init_shgrp, end_shgrp);
- /* Blend A texture and FX texture */
- GPU_framebuffer_bind(fbl->temp_fb_b);
- GPU_framebuffer_clear_color_depth_stencil(fbl->temp_fb_b, clearcol, 1.0f, 0x0);
+ /* Draw Blended texture over MSAA texture */
+ GPU_framebuffer_bind(final_fb);
stl->storage->blend_mode = array_elm->mode;
- stl->storage->mask_layer = (int)array_elm->mask_layer;
- stl->storage->tonemapping = DRW_state_do_color_management() ? 0 : 1;
- DRW_draw_pass(psl->blend_pass);
- stl->storage->tonemapping = 0;
-
- /* Copy B texture to A texture to follow loop */
- stl->g_data->input_depth_tx = stl->g_data->temp_depth_tx_b;
- stl->g_data->input_color_tx = stl->g_data->temp_color_tx_b;
-
- GPU_framebuffer_bind(fbl->temp_fb_a);
- GPU_framebuffer_clear_color_depth_stencil(fbl->temp_fb_a, clearcol, 1.0f, 0x0);
- DRW_draw_pass(psl->mix_pass_noblend);
-
- /* prepare next group */
- init_shgrp = NULL;
+ DRW_draw_pass(psl->blend_layers_pass);
+ DRW_draw_pass(psl->blend_layers_depth_pass);
}
}
- /* last group */
- gpencil_draw_pass_range(
- fbl, stl, psl, txl, fbl->temp_fb_a, ob, gpd, init_shgrp, end_shgrp, true);
+
+ /* Resolve MSAA texture to A texture to follow with VFX */
+ MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, fbl->temp_a_fb, txl);
+ }
+
+ /* Clear multisample framebuffer to avoid garbage in the screen */
+ if (stl->storage->multisamples > 0) {
+ GPU_framebuffer_bind(fbl->multisample_fb);
+ GPU_framebuffer_clear_color_depth_stencil(
+ fbl->multisample_fb, (const float[4]){0.0f}, 1.0f, 0x0);
}
/* Current buffer drawing */
+ GPU_framebuffer_bind(fbl->temp_a_fb);
if ((!is_render) && (cache_ob->is_dup_ob == false)) {
DRW_draw_pass(psl->drawing_pass);
}
@@ -1096,15 +1113,15 @@ void GPENCIL_draw_scene(void *ved)
gpencil_fx_draw(&e_data, vedata, cache_ob);
}
- stl->g_data->input_depth_tx = stl->g_data->temp_depth_tx_a;
- stl->g_data->input_color_tx = stl->g_data->temp_color_tx_a;
+ stl->g_data->input_depth_tx = stl->g_data->temp_depth_a_tx;
+ stl->g_data->input_color_tx = stl->g_data->temp_color_a_tx;
/* Combine with scene buffer */
- if ((!is_render) || (fbl->main == NULL)) {
+ if ((!is_render) || (fbl->main_fb == NULL)) {
GPU_framebuffer_bind(dfbl->default_fb);
}
else {
- GPU_framebuffer_bind(fbl->main);
+ GPU_framebuffer_bind(fbl->main_fb);
}
/* tonemapping */
stl->storage->tonemapping = DRW_state_do_color_management() ? 0 : 1;
@@ -1125,7 +1142,7 @@ void GPENCIL_draw_scene(void *ved)
}
/* draw mix pass */
- DRW_draw_pass(psl->mix_pass);
+ DRW_draw_pass(psl->mix_screen_pass);
/* disable select flag */
stl->storage->do_select_outline = 0;
@@ -1133,7 +1150,7 @@ void GPENCIL_draw_scene(void *ved)
/* prepare for fast drawing */
if (!is_render) {
if (!playing) {
- gpencil_prepare_fast_drawing(stl, dfbl, fbl, psl->mix_pass_noblend, clearcol);
+ gpencil_prepare_fast_drawing(stl, dfbl, fbl, psl->mix_screen_noblend_pass, clearcol);
}
}
else {