Overlays: Support for wireframes and edit mode overlay on xray objects
This commit is contained in:
parent
32e57fe4e7
commit
c761153f64
|
@ -270,6 +270,7 @@ data_to_c_simple(modes/shaders/edit_mesh_overlay_geom_edge.glsl SRC)
|
|||
data_to_c_simple(modes/shaders/edit_mesh_overlay_loosevert_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_facedot_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_facedot_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_ghost_clear_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_mix_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_frag.glsl SRC)
|
||||
|
|
|
@ -923,8 +923,8 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata)
|
|||
if (GHOST_ENABLED(psl)) {
|
||||
/* We need to set the stencil buffer to 0 where Ghost objects
|
||||
* else they will get shadow and even badly shadowed. */
|
||||
DRW_pass_state_set(psl->ghost_prepass_pass, DRW_STATE_WRITE_STENCIL);
|
||||
DRW_pass_state_set(psl->ghost_prepass_hair_pass, DRW_STATE_WRITE_STENCIL);
|
||||
DRW_pass_state_set(psl->ghost_prepass_pass, DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL);
|
||||
DRW_pass_state_set(psl->ghost_prepass_hair_pass, DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL);
|
||||
|
||||
DRW_draw_pass(psl->ghost_prepass_pass);
|
||||
DRW_draw_pass(psl->ghost_prepass_hair_pass);
|
||||
|
@ -940,6 +940,21 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata)
|
|||
DRW_draw_pass(psl->composite_pass);
|
||||
}
|
||||
|
||||
/* TODO(fclem): only enable when needed (when there is overlays). */
|
||||
if (GHOST_ENABLED(psl)) {
|
||||
/* In order to not draw on top of ghost objects, we clear the stencil
|
||||
* to 0xFF and the ghost object to 0x00 and only draw overlays on top if
|
||||
* stencil is not 0. */
|
||||
GPU_framebuffer_bind(dfbl->depth_only_fb);
|
||||
GPU_framebuffer_clear_stencil(dfbl->depth_only_fb, 0xFF);
|
||||
|
||||
DRW_pass_state_set(psl->ghost_prepass_pass, DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL);
|
||||
DRW_pass_state_set(psl->ghost_prepass_hair_pass, DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL);
|
||||
|
||||
DRW_draw_pass(psl->ghost_prepass_pass);
|
||||
DRW_draw_pass(psl->ghost_prepass_hair_pass);
|
||||
}
|
||||
|
||||
if (wpd->volumes_do) {
|
||||
GPU_framebuffer_bind(fbl->volume_fb);
|
||||
DRW_draw_pass(psl->volume_pass);
|
||||
|
|
|
@ -53,7 +53,7 @@ extern char datatoc_edit_mesh_overlay_geom_edge_glsl[];
|
|||
extern char datatoc_edit_mesh_overlay_loosevert_vert_glsl[];
|
||||
extern char datatoc_edit_mesh_overlay_facedot_frag_glsl[];
|
||||
extern char datatoc_edit_mesh_overlay_facedot_vert_glsl[];
|
||||
extern char datatoc_edit_mesh_overlay_mix_vert_glsl[];
|
||||
extern char datatoc_edit_mesh_overlay_ghost_clear_vert_glsl[];
|
||||
extern char datatoc_edit_mesh_overlay_mix_frag_glsl[];
|
||||
extern char datatoc_edit_mesh_overlay_facefill_vert_glsl[];
|
||||
extern char datatoc_edit_mesh_overlay_facefill_frag_glsl[];
|
||||
|
@ -67,6 +67,7 @@ extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
|
|||
typedef struct EDIT_MESH_PassList {
|
||||
struct DRWPass *vcolor_faces;
|
||||
struct DRWPass *depth_hidden_wire;
|
||||
struct DRWPass *ghost_clear_depth;
|
||||
struct DRWPass *edit_face_overlay;
|
||||
struct DRWPass *edit_face_occluded;
|
||||
struct DRWPass *mix_occlude;
|
||||
|
@ -76,6 +77,7 @@ typedef struct EDIT_MESH_PassList {
|
|||
|
||||
typedef struct EDIT_MESH_FramebufferList {
|
||||
struct GPUFrameBuffer *occlude_wire_fb;
|
||||
struct GPUFrameBuffer *ghost_wire_fb;
|
||||
} EDIT_MESH_FramebufferList;
|
||||
|
||||
typedef struct EDIT_MESH_StorageList {
|
||||
|
@ -109,6 +111,7 @@ static struct {
|
|||
GPUShader *normals_loop_sh;
|
||||
GPUShader *normals_sh;
|
||||
GPUShader *depth_sh;
|
||||
GPUShader *ghost_clear_depth_sh;
|
||||
/* temp buffer texture */
|
||||
struct GPUTexture *occlude_wire_depth_tx;
|
||||
struct GPUTexture *occlude_wire_color_tx;
|
||||
|
@ -134,6 +137,8 @@ typedef struct EDIT_MESH_PrivateData {
|
|||
DRWShadingGroup *facedot_occluded_shgrp;
|
||||
DRWShadingGroup *facefill_occluded_shgrp;
|
||||
|
||||
int ghost_ob;
|
||||
int edit_ob;
|
||||
bool do_zbufclip;
|
||||
} EDIT_MESH_PrivateData; /* Transient data */
|
||||
|
||||
|
@ -300,6 +305,10 @@ static void EDIT_MESH_engine_init(void *vedata)
|
|||
if (!e_data.depth_sh) {
|
||||
e_data.depth_sh = DRW_shader_create_3D_depth_only();
|
||||
}
|
||||
if (!e_data.ghost_clear_depth_sh) {
|
||||
e_data.ghost_clear_depth_sh = DRW_shader_create(datatoc_edit_mesh_overlay_ghost_clear_vert_glsl,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static DRWPass *edit_mesh_create_overlay_pass(
|
||||
|
@ -362,7 +371,8 @@ static void EDIT_MESH_cache_init(void *vedata)
|
|||
/* Alloc transient pointers */
|
||||
stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
|
||||
}
|
||||
|
||||
stl->g_data->ghost_ob = 0;
|
||||
stl->g_data->edit_ob = 0;
|
||||
|
||||
const bool xray_enabled = ((draw_ctx->v3d->shading.flag & V3D_SHADING_XRAY) != 0) &&
|
||||
(draw_ctx->v3d->shading.type < OB_MATERIAL);
|
||||
|
@ -391,6 +401,17 @@ static void EDIT_MESH_cache_init(void *vedata)
|
|||
stl->g_data->depth_shgrp_hidden_wire = DRW_shgroup_create(e_data.depth_sh, psl->depth_hidden_wire);
|
||||
}
|
||||
|
||||
{
|
||||
/* Depth clearing for ghosting. */
|
||||
psl->ghost_clear_depth = DRW_pass_create(
|
||||
"Ghost Depth Clear",
|
||||
DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_STENCIL_NEQUAL);
|
||||
|
||||
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.ghost_clear_depth_sh, psl->ghost_clear_depth);
|
||||
DRW_shgroup_stencil_mask(shgrp, 0x00);
|
||||
DRW_shgroup_call_add(shgrp, DRW_cache_fullscreen_quad_get(), NULL);
|
||||
}
|
||||
|
||||
{
|
||||
/* Normals */
|
||||
psl->normals = DRW_pass_create(
|
||||
|
@ -412,7 +433,7 @@ static void EDIT_MESH_cache_init(void *vedata)
|
|||
|
||||
if (!stl->g_data->do_zbufclip) {
|
||||
psl->edit_face_overlay = edit_mesh_create_overlay_pass(
|
||||
&face_mod, DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WRITE_DEPTH | DRW_STATE_BLEND,
|
||||
&face_mod, DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND,
|
||||
&stl->g_data->face_overlay_shgrp, &stl->g_data->ledges_overlay_shgrp,
|
||||
&stl->g_data->lverts_overlay_shgrp, &stl->g_data->facedot_overlay_shgrp);
|
||||
}
|
||||
|
@ -538,6 +559,9 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
|
|||
stl->g_data->lverts_overlay_shgrp, NULL, NULL);
|
||||
}
|
||||
|
||||
stl->g_data->ghost_ob += (ob->dtx & OB_DRAWXRAY) ? 1 : 0;
|
||||
stl->g_data->edit_ob += 1;
|
||||
|
||||
/* 3D text overlay */
|
||||
if (me->drawflag & (ME_DRAWEXTRA_EDGELEN |
|
||||
ME_DRAWEXTRA_FACEAREA |
|
||||
|
@ -560,6 +584,7 @@ static void EDIT_MESH_draw_scene(void *vedata)
|
|||
EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
|
||||
EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
|
||||
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
|
||||
DRW_draw_pass(psl->vcolor_faces);
|
||||
|
||||
|
@ -582,6 +607,30 @@ static void EDIT_MESH_draw_scene(void *vedata)
|
|||
}
|
||||
else {
|
||||
DRW_draw_pass(psl->normals);
|
||||
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
View3D *v3d = draw_ctx->v3d;
|
||||
|
||||
if (v3d->shading.type == OB_SOLID && (v3d->shading.flag & V3D_SHADING_XRAY) == 0) {
|
||||
if (stl->g_data->ghost_ob == 1 && stl->g_data->edit_ob == 1) {
|
||||
/* In the case of single ghost object edit (common case for retopology):
|
||||
* we duplicate the depht+stencil buffer and clear all depth to 1.0f where
|
||||
* the stencil buffer is no 0x00. */
|
||||
const float *viewport_size = DRW_viewport_size_get();
|
||||
const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
|
||||
struct GPUTexture *ghost_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_edit_mesh_type);
|
||||
GPU_framebuffer_ensure_config(&fbl->ghost_wire_fb, {
|
||||
GPU_ATTACHMENT_TEXTURE(ghost_depth_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(dtxl->color),
|
||||
});
|
||||
|
||||
GPU_framebuffer_blit(dfbl->depth_only_fb, 0, fbl->ghost_wire_fb, 0, GPU_DEPTH_BIT | GPU_STENCIL_BIT);
|
||||
GPU_framebuffer_bind(fbl->ghost_wire_fb);
|
||||
|
||||
DRW_draw_pass(psl->ghost_clear_depth);
|
||||
}
|
||||
}
|
||||
|
||||
DRW_draw_pass(psl->edit_face_overlay);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2553,7 +2553,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
|
|||
const bool hide_object_extra = (v3d->overlay.flag & V3D_OVERLAY_HIDE_OBJECT_XTRAS) != 0;
|
||||
|
||||
if (do_outlines) {
|
||||
if ((ob != draw_ctx->object_edit) && !((ob == draw_ctx->obact) && (draw_ctx->object_mode & OB_MODE_ALL_PAINT))) {
|
||||
if (!BKE_object_is_in_editmode(ob) && !((ob == draw_ctx->obact) && (draw_ctx->object_mode & OB_MODE_ALL_PAINT))) {
|
||||
struct GPUBatch *geom;
|
||||
const bool xray_enabled = ((v3d->shading.flag & V3D_SHADING_XRAY) != 0) &&
|
||||
(v3d->shading.type < OB_MATERIAL);
|
||||
|
|
|
@ -56,6 +56,7 @@ typedef struct OVERLAY_PrivateData {
|
|||
DRWShadingGroup *face_orientation_shgrp;
|
||||
View3DOverlay overlay;
|
||||
float wire_step_param[2];
|
||||
bool ghost_stencil_test;
|
||||
} OVERLAY_PrivateData; /* Transient data */
|
||||
|
||||
/* *********** STATIC *********** */
|
||||
|
@ -87,6 +88,7 @@ static void overlay_engine_init(void *vedata)
|
|||
/* Alloc transient pointers */
|
||||
stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
|
||||
}
|
||||
stl->g_data->ghost_stencil_test = false;
|
||||
|
||||
if (!e_data.face_orientation_sh) {
|
||||
/* Face orientation */
|
||||
|
@ -146,20 +148,22 @@ static void overlay_cache_init(void *vedata)
|
|||
: e_data.face_wireframe_pretty_sh;
|
||||
DRWShadingGroup *shgrp = DRW_shgroup_create(stl->g_data->wire_sh, psl->face_wireframe_pass);
|
||||
DRW_shgroup_uniform_vec2(shgrp, "viewportSize", DRW_viewport_size_get(), 1);
|
||||
DRW_shgroup_uniform_vec2(shgrp, "wireStepParam", stl->g_data->wire_step_param, 1);
|
||||
if (stl->g_data->overlay.wireframe_threshold < 1.0f) {
|
||||
/**
|
||||
* The wireframe threshold ranges from 0.0 to 1.0
|
||||
* When 1.0 we show all the edges, when 0.5 we show as many as 2.7.
|
||||
*
|
||||
* If we wanted 0.0 to match 2.7, factor would need to be 0.003f.
|
||||
* The range controls the falloff effect. If range was 0.0f we would get a hard cut (as in 2.7).
|
||||
* That said we are using a different algorithm so the results will always differ.
|
||||
*/
|
||||
const float factor = 0.0045f;
|
||||
const float range = 0.00125f;
|
||||
stl->g_data->wire_step_param[1] = (1.0f - factor) + stl->g_data->overlay.wireframe_threshold * factor;
|
||||
stl->g_data->wire_step_param[0] = stl->g_data->wire_step_param[1] + range;
|
||||
|
||||
/**
|
||||
* The wireframe threshold ranges from 0.0 to 1.0
|
||||
* When 1.0 we show all the edges, when 0.5 we show as many as 2.7.
|
||||
*
|
||||
* If we wanted 0.0 to match 2.7, factor would need to be 0.003f.
|
||||
* The range controls the falloff effect. If range was 0.0f we would get a hard cut (as in 2.7).
|
||||
* That said we are using a different algorithm so the results will always differ.
|
||||
*/
|
||||
const float factor = 0.0045f;
|
||||
const float range = 0.00125f;
|
||||
stl->g_data->wire_step_param[1] = (1.0f - factor) + stl->g_data->overlay.wireframe_threshold * factor;
|
||||
stl->g_data->wire_step_param[0] = stl->g_data->wire_step_param[1] + range;
|
||||
DRW_shgroup_uniform_vec2(shgrp, "wireStepParam", stl->g_data->wire_step_param, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,6 +197,7 @@ static void overlay_cache_populate(void *vedata, Object *ob)
|
|||
rim_col = (ob == draw_ctx->obact) ? ts.colorActive : ts.colorSelect;
|
||||
}
|
||||
DRWShadingGroup *shgrp = DRW_shgroup_create(stl->g_data->wire_sh, psl->face_wireframe_pass);
|
||||
DRW_shgroup_stencil_mask(shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF);
|
||||
DRW_shgroup_uniform_texture(shgrp, "vertData", verts);
|
||||
DRW_shgroup_uniform_texture(shgrp, "faceIds", faceids);
|
||||
DRW_shgroup_uniform_vec3(shgrp, "wireColor", ts.colorWire, 1);
|
||||
|
@ -201,10 +206,26 @@ static void overlay_cache_populate(void *vedata, Object *ob)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ob->dtx & OB_DRAWXRAY) {
|
||||
stl->g_data->ghost_stencil_test = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void overlay_cache_finish(void *UNUSED(vedata))
|
||||
static void overlay_cache_finish(void *vedata)
|
||||
{
|
||||
OVERLAY_Data * data = (OVERLAY_Data *)vedata;
|
||||
OVERLAY_PassList *psl = data->psl;
|
||||
OVERLAY_StorageList *stl = data->stl;
|
||||
|
||||
const DRWContextState *ctx = DRW_context_state_get();
|
||||
View3D *v3d = ctx->v3d;
|
||||
|
||||
/* only in solid mode */
|
||||
if (v3d->shading.type == OB_SOLID && (v3d->shading.flag & V3D_SHADING_XRAY) == 0) {
|
||||
if (stl->g_data->ghost_stencil_test)
|
||||
DRW_pass_state_add(psl->face_wireframe_pass, DRW_STATE_STENCIL_EQUAL);
|
||||
}
|
||||
}
|
||||
|
||||
static void overlay_draw_scene(void *vedata)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
in vec2 pos;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(pos, 1.0, 1.0);
|
||||
}
|
Loading…
Reference in New Issue