Fix T61196: Mesh select ignores clipping
Select clipping now works when x-ray is disabled.
This commit is contained in:
@@ -184,50 +184,77 @@ bool view3d_camera_border_hack_test = false;
|
||||
|
||||
/* ***************** BACKBUF SEL (BBS) ********* */
|
||||
|
||||
static void bbs_mesh_verts(GPUBatch *batch, int offset)
|
||||
/** See #DRW_shgroup_world_clip_planes_from_rv3d, same function for draw manager. */
|
||||
static void bbs_world_clip_planes_from_rv3d(GPUBatch *batch, const float world_clip_planes[6][4])
|
||||
{
|
||||
GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]);
|
||||
}
|
||||
|
||||
static void bbs_mesh_verts(GPUBatch *batch, int offset, const float world_clip_planes[6][4])
|
||||
{
|
||||
GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE));
|
||||
|
||||
GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_SELECT_ID);
|
||||
const eGPUShaderConfig shader_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : GPU_SHADER_CFG_DEFAULT;
|
||||
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, shader_cfg);
|
||||
GPU_batch_uniform_1ui(batch, "offset", offset);
|
||||
if (world_clip_planes != NULL) {
|
||||
bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
|
||||
}
|
||||
GPU_batch_draw(batch);
|
||||
}
|
||||
|
||||
static void bbs_mesh_wire(GPUBatch *batch, int offset)
|
||||
static void bbs_mesh_wire(GPUBatch *batch, int offset, const float world_clip_planes[6][4])
|
||||
{
|
||||
GPU_line_width(1.0f);
|
||||
glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
|
||||
|
||||
GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_SELECT_ID);
|
||||
const eGPUShaderConfig shader_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : GPU_SHADER_CFG_DEFAULT;
|
||||
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, shader_cfg);
|
||||
GPU_batch_uniform_1ui(batch, "offset", offset);
|
||||
if (world_clip_planes != NULL) {
|
||||
bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
|
||||
}
|
||||
GPU_batch_draw(batch);
|
||||
|
||||
glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
|
||||
}
|
||||
|
||||
/* two options, facecolors or black */
|
||||
static void bbs_mesh_face(GPUBatch *batch, const bool use_select)
|
||||
static void bbs_mesh_face(GPUBatch *batch, const bool use_select, const float world_clip_planes[6][4])
|
||||
{
|
||||
if (use_select) {
|
||||
GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_SELECT_ID);
|
||||
const eGPUShaderConfig shader_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : GPU_SHADER_CFG_DEFAULT;
|
||||
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, shader_cfg);
|
||||
GPU_batch_uniform_1ui(batch, "offset", 1);
|
||||
if (world_clip_planes != NULL) {
|
||||
bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
|
||||
}
|
||||
GPU_batch_draw(batch);
|
||||
}
|
||||
else {
|
||||
GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_SELECT_ID);
|
||||
const eGPUShaderConfig shader_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : GPU_SHADER_CFG_DEFAULT;
|
||||
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_UNIFORM_SELECT_ID, shader_cfg);
|
||||
GPU_batch_uniform_1ui(batch, "id", 0);
|
||||
if (world_clip_planes != NULL) {
|
||||
bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
|
||||
}
|
||||
GPU_batch_draw(batch);
|
||||
}
|
||||
}
|
||||
|
||||
static void bbs_mesh_face_dot(GPUBatch *batch)
|
||||
static void bbs_mesh_face_dot(GPUBatch *batch, const float world_clip_planes[6][4])
|
||||
{
|
||||
GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_SELECT_ID);
|
||||
const eGPUShaderConfig shader_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : GPU_SHADER_CFG_DEFAULT;
|
||||
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, shader_cfg);
|
||||
GPU_batch_uniform_1ui(batch, "offset", 1);
|
||||
if (world_clip_planes != NULL) {
|
||||
bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
|
||||
}
|
||||
GPU_batch_draw(batch);
|
||||
}
|
||||
|
||||
static void bbs_mesh_solid_verts(Depsgraph *UNUSED(depsgraph), Scene *UNUSED(scene), Object *ob)
|
||||
static void bbs_mesh_solid_verts(
|
||||
Depsgraph *UNUSED(depsgraph), Scene *UNUSED(scene), Object *ob, const float world_clip_planes[6][4])
|
||||
{
|
||||
Mesh *me = ob->data;
|
||||
|
||||
@@ -236,13 +263,13 @@ static void bbs_mesh_solid_verts(Depsgraph *UNUSED(depsgraph), Scene *UNUSED(sce
|
||||
DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
|
||||
|
||||
/* Only draw faces to mask out verts, we don't want their selection ID's. */
|
||||
bbs_mesh_face(geom_faces, false);
|
||||
bbs_mesh_verts(geom_verts, 1);
|
||||
bbs_mesh_face(geom_faces, false, world_clip_planes);
|
||||
bbs_mesh_verts(geom_verts, 1, world_clip_planes);
|
||||
|
||||
bm_vertoffs = me->totvert + 1;
|
||||
}
|
||||
|
||||
static void bbs_mesh_solid_faces(Scene *UNUSED(scene), Object *ob)
|
||||
static void bbs_mesh_solid_faces(Scene *UNUSED(scene), Object *ob, const float world_clip_planes[6][4])
|
||||
{
|
||||
Mesh *me = ob->data;
|
||||
Mesh *me_orig = DEG_get_original_object(ob)->data;
|
||||
@@ -251,7 +278,7 @@ static void bbs_mesh_solid_faces(Scene *UNUSED(scene), Object *ob)
|
||||
GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me);
|
||||
DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, use_hide);
|
||||
|
||||
bbs_mesh_face(geom_faces, true);
|
||||
bbs_mesh_face(geom_faces, true, world_clip_planes);
|
||||
}
|
||||
|
||||
void draw_object_backbufsel(
|
||||
@@ -266,6 +293,11 @@ void draw_object_backbufsel(
|
||||
GPU_matrix_mul(ob->obmat);
|
||||
GPU_depth_test(true);
|
||||
|
||||
const float (*world_clip_planes)[4] = NULL;
|
||||
if (rv3d->rflag & RV3D_CLIPPING) {
|
||||
world_clip_planes = rv3d->clip;
|
||||
}
|
||||
|
||||
switch (ob->type) {
|
||||
case OB_MESH:
|
||||
if (ob->mode & OB_MODE_EDIT) {
|
||||
@@ -289,10 +321,10 @@ void draw_object_backbufsel(
|
||||
}
|
||||
DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
|
||||
|
||||
bbs_mesh_face(geom_faces, use_faceselect);
|
||||
bbs_mesh_face(geom_faces, use_faceselect, world_clip_planes);
|
||||
|
||||
if (use_faceselect && draw_facedot) {
|
||||
bbs_mesh_face_dot(geom_facedots);
|
||||
bbs_mesh_face_dot(geom_facedots, world_clip_planes);
|
||||
}
|
||||
|
||||
if (select_mode & SCE_SELECT_FACE)
|
||||
@@ -305,7 +337,7 @@ void draw_object_backbufsel(
|
||||
|
||||
/* we draw edges if edge select mode */
|
||||
if (select_mode & SCE_SELECT_EDGE) {
|
||||
bbs_mesh_wire(geom_edges, bm_solidoffs);
|
||||
bbs_mesh_wire(geom_edges, bm_solidoffs, world_clip_planes);
|
||||
bm_wireoffs = bm_solidoffs + em->bm->totedge;
|
||||
}
|
||||
else {
|
||||
@@ -317,7 +349,7 @@ void draw_object_backbufsel(
|
||||
|
||||
/* we draw verts if vert select mode. */
|
||||
if (select_mode & SCE_SELECT_VERTEX) {
|
||||
bbs_mesh_verts(geom_verts, bm_wireoffs);
|
||||
bbs_mesh_verts(geom_verts, bm_wireoffs, world_clip_planes);
|
||||
bm_vertoffs = bm_wireoffs + em->bm->totvert;
|
||||
}
|
||||
else {
|
||||
@@ -332,10 +364,10 @@ void draw_object_backbufsel(
|
||||
/* currently vertex select supports weight paint and vertex paint*/
|
||||
((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT)))
|
||||
{
|
||||
bbs_mesh_solid_verts(depsgraph, scene, ob);
|
||||
bbs_mesh_solid_verts(depsgraph, scene, ob, world_clip_planes);
|
||||
}
|
||||
else {
|
||||
bbs_mesh_solid_faces(scene, ob);
|
||||
bbs_mesh_solid_faces(scene, ob, world_clip_planes);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -104,8 +104,13 @@
|
||||
|
||||
/* ********* custom clipping *********** */
|
||||
|
||||
/* Legacy 2.7x, now use shaders that use clip distance instead.
|
||||
* Remove once clipping is working properly. */
|
||||
#define USE_CLIP_PLANES
|
||||
|
||||
void ED_view3d_clipping_set(RegionView3D *rv3d)
|
||||
{
|
||||
#ifdef USE_CLIP_PLANES
|
||||
double plane[4];
|
||||
const unsigned int tot = (rv3d->viewlock & RV3D_BOXCLIP) ? 4 : 6;
|
||||
|
||||
@@ -113,20 +118,32 @@ void ED_view3d_clipping_set(RegionView3D *rv3d)
|
||||
copy_v4db_v4fl(plane, rv3d->clip[a]);
|
||||
glClipPlane(GL_CLIP_PLANE0 + a, plane);
|
||||
glEnable(GL_CLIP_PLANE0 + a);
|
||||
glEnable(GL_CLIP_DISTANCE0 + a);
|
||||
}
|
||||
#else
|
||||
for (unsigned a = 0; a < 6; a++) {
|
||||
glEnable(GL_CLIP_DISTANCE0 + a);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* use these to temp disable/enable clipping when 'rv3d->rflag & RV3D_CLIPPING' is set */
|
||||
void ED_view3d_clipping_disable(void)
|
||||
{
|
||||
for (unsigned a = 0; a < 6; a++) {
|
||||
#ifdef USE_CLIP_PLANES
|
||||
glDisable(GL_CLIP_PLANE0 + a);
|
||||
#endif
|
||||
glDisable(GL_CLIP_DISTANCE0 + a);
|
||||
}
|
||||
}
|
||||
void ED_view3d_clipping_enable(void)
|
||||
{
|
||||
for (unsigned a = 0; a < 6; a++) {
|
||||
#ifdef USE_CLIP_PLANES
|
||||
glEnable(GL_CLIP_PLANE0 + a);
|
||||
#endif
|
||||
glEnable(GL_CLIP_DISTANCE0 + a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -122,7 +122,11 @@ int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo);
|
||||
|
||||
void GPU_batch_program_set_no_use(GPUBatch *, uint32_t program, const GPUShaderInterface *);
|
||||
void GPU_batch_program_set(GPUBatch *, uint32_t program, const GPUShaderInterface *);
|
||||
void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id);
|
||||
void GPU_batch_program_set_shader(GPUBatch *, GPUShader *shader);
|
||||
void GPU_batch_program_set_builtin(
|
||||
GPUBatch *batch, eGPUBuiltinShader shader_id);
|
||||
void GPU_batch_program_set_builtin_with_config(
|
||||
GPUBatch *batch, eGPUBuiltinShader shader_id, eGPUShaderConfig shader_cfg);
|
||||
/* Entire batch draws with one shader program, but can be redrawn later with another program. */
|
||||
/* Vertex shader's inputs must be compatible with the batch's vertex format. */
|
||||
|
||||
|
||||
@@ -664,10 +664,21 @@ void GPU_draw_primitive(GPUPrimType prim_type, int v_count)
|
||||
/** \name Utilities
|
||||
* \{ */
|
||||
|
||||
void GPU_batch_program_set_shader(GPUBatch *batch, GPUShader *shader)
|
||||
{
|
||||
GPU_batch_program_set(batch, shader->program, shader->interface);
|
||||
}
|
||||
|
||||
void GPU_batch_program_set_builtin_with_config(
|
||||
GPUBatch *batch, eGPUBuiltinShader shader_id, eGPUShaderConfig shader_cfg)
|
||||
{
|
||||
GPUShader *shader = GPU_shader_get_builtin_shader_with_config(shader_id, shader_cfg);
|
||||
GPU_batch_program_set(batch, shader->program, shader->interface);
|
||||
}
|
||||
|
||||
void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id)
|
||||
{
|
||||
GPUShader *shader = GPU_shader_get_builtin_shader(shader_id);
|
||||
GPU_batch_program_set(batch, shader->program, shader->interface);
|
||||
GPU_batch_program_set_builtin_with_config(batch, shader_id, GPU_SHADER_CFG_DEFAULT);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -1219,7 +1219,9 @@ GPUShader *GPU_shader_get_builtin_shader_with_config(
|
||||
GPU_SHADER_3D_GROUNDLINE,
|
||||
GPU_SHADER_3D_GROUNDPOINT,
|
||||
GPU_SHADER_DISTANCE_LINES,
|
||||
GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR));
|
||||
GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR,
|
||||
GPU_SHADER_3D_FLAT_SELECT_ID,
|
||||
GPU_SHADER_3D_UNIFORM_SELECT_ID));
|
||||
const char *world_clip_lib = datatoc_gpu_shader_cfg_world_clip_lib_glsl;
|
||||
const char *world_clip_def = "#define USE_WORLD_CLIP_PLANES\n";
|
||||
/* In rare cases geometry shaders calculate clipping themselves. */
|
||||
|
||||
@@ -20,5 +20,11 @@ void main()
|
||||
(((color + offset) >> 24) ) * (1.0f / 255.0f));
|
||||
#endif
|
||||
|
||||
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
|
||||
vec4 pos_4d = vec4(pos, 1.0);
|
||||
gl_Position = ModelViewProjectionMatrix * pos_4d;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
/* Warning: ModelMatrix is typically used but select drawing is different. */
|
||||
world_clip_planes_calc_clip_distance(pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user