[Bf-blender-cvs] [981c49ff4c2] greasepencil-refactor: GPencil: Refactor: Add outline overlay
Clément Foucault
noreply at git.blender.org
Tue Jan 7 15:31:33 CET 2020
Commit: 981c49ff4c250625ca688a1b5fff788b2143e0db
Author: Clément Foucault
Date: Mon Jan 6 18:33:30 2020 +0100
Branches: greasepencil-refactor
https://developer.blender.org/rB981c49ff4c250625ca688a1b5fff788b2143e0db
GPencil: Refactor: Add outline overlay
This does not work correctly on square & dot strokes.
Also another issue is the depth blending. We need to fix the depth of
the outline geometry to match the 2D projection we do in the gpencil engine.
===================================================================
M source/blender/draw/engines/overlay/overlay_engine.c
M source/blender/draw/engines/overlay/overlay_outline.c
M source/blender/draw/engines/overlay/overlay_private.h
M source/blender/draw/engines/overlay/overlay_shader.c
M source/blender/draw/engines/overlay/shaders/outline_prepass_frag.glsl
M source/blender/draw/engines/overlay/shaders/outline_prepass_vert.glsl
===================================================================
diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c
index 38ab3d348ea..dab307dc6ee 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.c
+++ b/source/blender/draw/engines/overlay/overlay_engine.c
@@ -25,6 +25,8 @@
#include "DRW_engine.h"
#include "DRW_render.h"
+#include "DEG_depsgraph_query.h"
+
#include "ED_view3d.h"
#include "BKE_object.h"
@@ -78,6 +80,7 @@ static void OVERLAY_engine_init(void *vedata)
pd->xray_enabled = XRAY_ACTIVE(v3d);
pd->xray_enabled_and_not_wire = pd->xray_enabled && v3d->shading.type > OB_WIRE;
pd->clear_in_front = (v3d->shading.type != OB_SOLID);
+ pd->cfra = DEG_get_ctime(draw_ctx->depsgraph);
OVERLAY_antialiasing_init(vedata);
@@ -184,6 +187,7 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
OVERLAY_PrivateData *pd = data->stl->pd;
const DRWContextState *draw_ctx = DRW_context_state_get();
const bool is_select = DRW_state_is_select();
+ const bool is_gpencil = ob->type == OB_GPENCIL;
const bool renderable = DRW_object_is_renderable(ob);
const bool in_pose_mode = ob->type == OB_ARMATURE && OVERLAY_armature_is_pose_mode(ob, draw_ctx);
const bool in_edit_mode = BKE_object_is_in_editmode(ob);
@@ -197,8 +201,8 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
const bool draw_bones = (pd->overlay.flag & V3D_OVERLAY_HIDE_BONES) == 0;
const bool draw_wires = draw_surface && has_surface &&
(pd->wireframe_mode || !pd->hide_overlays);
- const bool draw_outlines = !in_edit_mode && !in_paint_mode && renderable && has_surface &&
- (pd->v3d_flag & V3D_SELECT_OUTLINE) &&
+ const bool draw_outlines = !in_edit_mode && !in_paint_mode && renderable &&
+ (has_surface || is_gpencil) && (pd->v3d_flag & V3D_SELECT_OUTLINE) &&
(ob->base_flag & BASE_SELECTED);
const bool draw_bone_selection = (ob->type == OB_MESH) && pd->armature.do_pose_fade_geom &&
!is_select;
diff --git a/source/blender/draw/engines/overlay/overlay_outline.c b/source/blender/draw/engines/overlay/overlay_outline.c
index 63738b3c214..12ba0fbb4b9 100644
--- a/source/blender/draw/engines/overlay/overlay_outline.c
+++ b/source/blender/draw/engines/overlay/overlay_outline.c
@@ -23,8 +23,10 @@
#include "DRW_render.h"
#include "BKE_global.h"
+#include "BKE_gpencil.h"
-#include "DNA_lightprobe_types.h"
+// #include "DNA_lightprobe_types.h"
+#include "DNA_gpencil_types.h"
#include "UI_resources.h"
@@ -79,6 +81,11 @@ void OVERLAY_outline_cache_init(OVERLAY_Data *vedata)
pd->outlines_grp = grp = DRW_shgroup_create(sh_geom, psl->outlines_prepass_ps);
DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
+
+ GPUShader *sh_gpencil = OVERLAY_shader_outline_prepass_gpencil();
+
+ pd->outlines_gpencil_grp = grp = DRW_shgroup_create(sh_gpencil, psl->outlines_prepass_ps);
+ DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
}
/* outlines_prepass_ps is still needed for selection of probes. */
@@ -107,6 +114,85 @@ void OVERLAY_outline_cache_init(OVERLAY_Data *vedata)
}
}
+typedef struct iterData {
+ Object *ob;
+ DRWShadingGroup *stroke_grp;
+ DRWShadingGroup *fill_grp;
+ int cfra;
+} iterData;
+
+static void gp_layer_cache_populate(bGPDlayer *gpl,
+ bGPDframe *UNUSED(gpf),
+ bGPDstroke *UNUSED(gps),
+ void *thunk)
+{
+ iterData *iter = (iterData *)thunk;
+ bGPdata *gpd = (bGPdata *)iter->ob->data;
+
+ const bool is_screenspace = (gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS) != 0;
+
+ float object_scale = mat4_to_scale(iter->ob->obmat);
+ /* Negate thickness sign to tag that strokes are in screen space.
+ * Convert to world units (by default, 1 meter = 2000 px). */
+ float thickness_scale = (is_screenspace) ? -1.0f : (gpd->pixfactor / 2000.0f);
+
+ DRWShadingGroup *grp = iter->stroke_grp = DRW_shgroup_create_sub(iter->stroke_grp);
+ DRW_shgroup_uniform_bool_copy(grp, "strokeOrder3d", true);
+ DRW_shgroup_uniform_vec2_copy(grp, "sizeViewportInv", DRW_viewport_invert_size_get());
+ DRW_shgroup_uniform_vec2_copy(grp, "sizeViewport", DRW_viewport_size_get());
+ DRW_shgroup_uniform_float_copy(grp, "thicknessScale", object_scale);
+ DRW_shgroup_uniform_float_copy(grp, "thicknessOffset", (float)gpl->line_change);
+ DRW_shgroup_uniform_float_copy(grp, "thicknessWorldScale", thickness_scale);
+}
+
+static void gp_stroke_cache_populate(bGPDlayer *UNUSED(gpl),
+ bGPDframe *UNUSED(gpf),
+ bGPDstroke *gps,
+ void *thunk)
+{
+ iterData *iter = (iterData *)thunk;
+
+ MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(iter->ob, gps->mat_nr + 1);
+
+ bool hide_material = (gp_style->flag & GP_STYLE_COLOR_HIDE) != 0;
+ bool show_stroke = (gp_style->flag & GP_STYLE_STROKE_SHOW) != 0;
+ // TODO: What about simplify Fill?
+ bool show_fill = (gps->tot_triangles > 0) && (gp_style->flag & GP_STYLE_FILL_SHOW) != 0;
+
+ if (hide_material) {
+ return;
+ }
+
+ if (show_fill) {
+ struct GPUBatch *geom = DRW_cache_gpencil_fills_get(iter->ob, iter->cfra);
+ int vfirst = gps->runtime.fill_start * 3;
+ int vcount = gps->tot_triangles * 3;
+ DRW_shgroup_call_range(iter->fill_grp, iter->ob, geom, vfirst, vcount);
+ }
+
+ if (show_stroke) {
+ struct GPUBatch *geom = DRW_cache_gpencil_strokes_get(iter->ob, iter->cfra);
+ /* Start one vert before to have gl_InstanceID > 0 (see shader). */
+ int vfirst = gps->runtime.stroke_start - 1;
+ /* Include "potential" cyclic vertex and start adj vertex (see shader). */
+ int vcount = gps->totpoints + 1 + 1;
+ DRW_shgroup_call_instance_range(iter->stroke_grp, iter->ob, geom, vfirst, vcount);
+ }
+}
+
+static void OVERLAY_outline_gpencil(OVERLAY_PrivateData *pd, Object *ob)
+{
+ iterData iter = {
+ .ob = ob,
+ .stroke_grp = pd->outlines_gpencil_grp,
+ .fill_grp = DRW_shgroup_create_sub(pd->outlines_gpencil_grp),
+ .cfra = pd->cfra,
+ };
+
+ BKE_gpencil_visible_stroke_iter(
+ ob, gp_layer_cache_populate, gp_stroke_cache_populate, &iter, false, pd->cfra);
+}
+
void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
Object *ob,
OVERLAY_DupliData *dupli,
@@ -123,6 +209,11 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
return;
}
+ if (ob->type == OB_GPENCIL) {
+ OVERLAY_outline_gpencil(pd, ob);
+ return;
+ }
+
if (dupli && !init_dupli) {
geom = dupli->outline_geom;
shgroup = dupli->outline_shgrp;
diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h
index 996ee845799..4bda0cc8ed2 100644
--- a/source/blender/draw/engines/overlay/overlay_private.h
+++ b/source/blender/draw/engines/overlay/overlay_private.h
@@ -229,6 +229,7 @@ typedef struct OVERLAY_PrivateData {
DRWShadingGroup *motion_path_lines_grp;
DRWShadingGroup *motion_path_points_grp;
DRWShadingGroup *outlines_grp;
+ DRWShadingGroup *outlines_gpencil_grp;
DRWShadingGroup *paint_surf_grp;
DRWShadingGroup *paint_wire_grp;
DRWShadingGroup *paint_wire_selected_grp;
@@ -267,6 +268,7 @@ typedef struct OVERLAY_PrivateData {
bool xray_enabled_and_not_wire;
short v3d_flag; /* TODO move to View3DOverlay */
short v3d_gridflag; /* TODO move to View3DOverlay */
+ int cfra;
DRWState clipping_state;
OVERLAY_ShadingData shdata;
@@ -552,6 +554,7 @@ GPUShader *OVERLAY_shader_motion_path_line(void);
GPUShader *OVERLAY_shader_motion_path_vert(void);
GPUShader *OVERLAY_shader_uniform_color(void);
GPUShader *OVERLAY_shader_outline_prepass(bool use_wire);
+GPUShader *OVERLAY_shader_outline_prepass_gpencil(void);
GPUShader *OVERLAY_shader_extra_grid(void);
GPUShader *OVERLAY_shader_outline_detect(void);
GPUShader *OVERLAY_shader_paint_face(void);
diff --git a/source/blender/draw/engines/overlay/overlay_shader.c b/source/blender/draw/engines/overlay/overlay_shader.c
index 7bd3cf4a067..4b63eda9444 100644
--- a/source/blender/draw/engines/overlay/overlay_shader.c
+++ b/source/blender/draw/engines/overlay/overlay_shader.c
@@ -110,6 +110,8 @@ extern char datatoc_gpu_shader_flat_color_frag_glsl[];
extern char datatoc_gpu_shader_point_varying_color_varying_outline_aa_frag_glsl[];
extern char datatoc_gpu_shader_common_obinfos_lib_glsl[];
+extern char datatoc_gpencil_common_lib_glsl[];
+
extern char datatoc_common_colormanagement_lib_glsl[];
extern char datatoc_common_fullscreen_vert_glsl[];
extern char datatoc_common_fxaa_lib_glsl[];
@@ -159,6 +161,7 @@ typedef struct OVERLAY_Shaders {
GPUShader *motion_path_line;
GPUShader *motion_path_vert;
GPUShader *outline_prepass;
+ GPUShader *outline_prepass_gpencil;
GPUShader *outline_prepass_wire;
GPUShader *outline_detect;
GPUShader *paint_face;
@@ -967,6 +970,31 @@ GPUShader *OVERLAY_shader_outline_prepass(bool use_wire)
return use_wire ? sh_data->outline_prepass_wire : sh_data->outline_prepass;
}
+GPUShader *OVERLAY_shader_outline_prepass_gpencil(void)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const GPUShaderConfigData *sh_cfg = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
+ OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
+ if (!sh_data->outline_prepass_gpencil) {
+ sh_data->outline_prepass_gpencil = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){sh_cfg->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_gpencil_common_lib_glsl,
+ datatoc_gpu_shader_common_obinfos_lib_glsl,
+ datatoc_outline_prepass_vert_glsl,
+ NULL},
+ .frag = (const char *[]){datatoc_gpencil_common_lib_glsl,
+ data
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list