From aa1b77dccbda5b57f857d27ed8f7d46544c82503 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 24 Jan 2019 18:27:26 +1100 Subject: DRW: support clipping for object outlines --- source/blender/draw/modes/object_mode.c | 28 +++++++++++++--------- .../modes/shaders/object_outline_prepass_geom.glsl | 16 +++++++++++-- .../modes/shaders/object_outline_prepass_vert.glsl | 5 ++++ 3 files changed, 36 insertions(+), 13 deletions(-) (limited to 'source') diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 1f0bb4738db..bd8a112f710 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -418,12 +418,15 @@ static void OBJECT_engine_init(void *vedata) if (!sh_data->outline_resolve) { /* Outline */ - sh_data->outline_prepass = DRW_shader_create_3D(datatoc_object_outline_prepass_frag_glsl, NULL); - - sh_data->outline_prepass_wire = DRW_shader_create( - datatoc_object_outline_prepass_vert_glsl, - datatoc_object_outline_prepass_geom_glsl, - datatoc_object_outline_prepass_frag_glsl, NULL); + sh_data->outline_prepass = DRW_shader_create_from_arrays({ + .vert = (const char *[]){world_clip_lib_or_empty, datatoc_drw_shader_3D_vert_glsl, NULL}, + .frag = (const char *[]){datatoc_object_outline_prepass_frag_glsl, NULL}, + .defs = (const char *[]){world_clip_def_or_empty, NULL}}); + sh_data->outline_prepass_wire = DRW_shader_create_from_arrays({ + .vert = (const char *[]){world_clip_lib_or_empty, datatoc_object_outline_prepass_vert_glsl, NULL}, + .geom = (const char *[]){world_clip_lib_or_empty, datatoc_object_outline_prepass_geom_glsl, NULL}, + .frag = (const char *[]){datatoc_object_outline_prepass_frag_glsl, NULL}, + .defs = (const char *[]){world_clip_def_or_empty, NULL}}); sh_data->outline_resolve = DRW_shader_create_fullscreen(datatoc_object_outline_resolve_frag_glsl, NULL); @@ -665,11 +668,14 @@ static void OBJECT_engine_free(void) } } -static DRWShadingGroup *shgroup_outline(DRWPass *pass, const int *ofs, GPUShader *sh) +static DRWShadingGroup *shgroup_outline(DRWPass *pass, const int *ofs, GPUShader *sh, eDRW_ShaderSlot shader_slot) { DRWShadingGroup *grp = DRW_shgroup_create(sh, pass); DRW_shgroup_uniform_int(grp, "baseId", ofs, 1); + if (shader_slot == DRW_SHADER_SLOT_CLIPPED) { + DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d); + } return grp; } @@ -1002,10 +1008,10 @@ static void OBJECT_cache_init(void *vedata) sh = sh_data->outline_prepass_wire; } - g_data->outlines_select = shgroup_outline(psl->outlines, &g_data->id_ofs_select, sh); - g_data->outlines_select_dupli = shgroup_outline(psl->outlines, &g_data->id_ofs_select_dupli, sh); - g_data->outlines_transform = shgroup_outline(psl->outlines, &g_data->id_ofs_transform, sh); - g_data->outlines_active = shgroup_outline(psl->outlines, &g_data->id_ofs_active, sh); + g_data->outlines_select = shgroup_outline(psl->outlines, &g_data->id_ofs_select, sh, draw_ctx->shader_slot); + g_data->outlines_select_dupli = shgroup_outline(psl->outlines, &g_data->id_ofs_select_dupli, sh, draw_ctx->shader_slot); + g_data->outlines_transform = shgroup_outline(psl->outlines, &g_data->id_ofs_transform, sh, draw_ctx->shader_slot); + g_data->outlines_active = shgroup_outline(psl->outlines, &g_data->id_ofs_active, sh, draw_ctx->shader_slot); g_data->id_ofs_select = 0; g_data->id_ofs_select_dupli = 0; diff --git a/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl b/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl index 1fa0a9137c0..85da0f25654 100644 --- a/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl +++ b/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl @@ -7,6 +7,14 @@ uniform mat4 ProjectionMatrix; in vec4 pPos[]; in vec3 vPos[]; +void vert_from_gl_in(int v) +{ + gl_Position = pPos[v]; +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_set_clip_distance(gl_in[v].gl_ClipDistance); +#endif +} + void main() { bool is_persp = (ProjectionMatrix[3][3] == 0.0); @@ -34,7 +42,11 @@ void main() // if (dot(n0, v13) > 0.01) // return; - gl_Position = pPos[1]; EmitVertex(); - gl_Position = pPos[2]; EmitVertex(); + vert_from_gl_in(1); + EmitVertex(); + + vert_from_gl_in(2); + EmitVertex(); + EndPrimitive(); } diff --git a/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl b/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl index ba824a7c007..744bf0ff1e3 100644 --- a/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl +++ b/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl @@ -1,6 +1,7 @@ uniform mat4 ModelViewMatrix; uniform mat4 ModelViewProjectionMatrix; +uniform mat4 ModelMatrix; in vec3 pos; @@ -13,4 +14,8 @@ void main() pPos = ModelViewProjectionMatrix * vec4(pos, 1.0); /* Small bias to always be on top of the geom. */ pPos.z -= 1e-3; + +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz); +#endif } -- cgit v1.2.3