From 651d8bfd98db11eb58018412cc030cfe2705c519 Mon Sep 17 00:00:00 2001 From: mano-wii Date: Tue, 30 Jul 2019 06:46:59 -0300 Subject: 3D View: Move selection API to a Selection engine. This commit moves the API of selecting faces, vertices and edges to a DRW manager engine. Reviewers: campbellbarton, fclem Subscribers: jbakker, brecht Differential Revision: https://developer.blender.org/D5090 --- source/blender/draw/CMakeLists.txt | 5 + source/blender/draw/DRW_engine.h | 36 +- source/blender/draw/engines/select/select_engine.c | 647 +++++++++++++++++++++ source/blender/draw/engines/select/select_engine.h | 29 + .../select/shaders/selection_id_3D_vert.glsl | 26 + .../engines/select/shaders/selection_id_frag.glsl | 14 + source/blender/draw/intern/draw_manager.c | 392 +++---------- source/blender/editors/include/ED_view3d.h | 20 - source/blender/editors/mesh/CMakeLists.txt | 1 + source/blender/editors/mesh/editmesh_select.c | 31 +- .../editors/space_view3d/view3d_draw_legacy.c | 28 +- .../blender/editors/space_view3d/view3d_select.c | 238 +------- source/blender/gpu/CMakeLists.txt | 3 - source/blender/gpu/GPU_shader.h | 5 +- source/blender/gpu/intern/gpu_shader.c | 19 +- .../shaders/gpu_shader_3D_selection_id_vert.glsl | 26 - .../gpu/shaders/gpu_shader_selection_id_frag.glsl | 13 - 17 files changed, 863 insertions(+), 670 deletions(-) create mode 100644 source/blender/draw/engines/select/select_engine.c create mode 100644 source/blender/draw/engines/select/select_engine.h create mode 100644 source/blender/draw/engines/select/shaders/selection_id_3D_vert.glsl create mode 100644 source/blender/draw/engines/select/shaders/selection_id_frag.glsl delete mode 100644 source/blender/gpu/shaders/gpu_shader_3D_selection_id_vert.glsl delete mode 100644 source/blender/gpu/shaders/gpu_shader_selection_id_frag.glsl (limited to 'source') diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 8631a9f556b..664484d9a57 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -126,6 +126,7 @@ set(SRC engines/gpencil/gpencil_engine.h engines/gpencil/gpencil_render.c engines/gpencil/gpencil_shader_fx.c + engines/select/select_engine.c DRW_engine.h intern/DRW_render.h @@ -150,6 +151,7 @@ set(SRC engines/external/external_engine.h engines/workbench/workbench_engine.h engines/workbench/workbench_private.h + engines/select/select_engine.h ) set(LIB @@ -363,6 +365,9 @@ data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_shadow_resolve_frag.glsl data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl SRC) data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl SRC) +data_to_c_simple(engines/select/shaders/selection_id_3D_vert.glsl SRC) +data_to_c_simple(engines/select/shaders/selection_id_frag.glsl SRC) + list(APPEND INC ) diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index 5919e100ddd..64a02f3931b 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -26,6 +26,7 @@ #include "BLI_sys_types.h" /* for bool */ struct ARegion; +struct Base; struct DRWInstanceDataList; struct DRWPass; struct Depsgraph; @@ -136,19 +137,12 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph, void DRW_draw_depth_object(struct ARegion *ar, struct GPUViewport *viewport, struct Object *object); -void DRW_draw_select_id_object(struct Scene *scene, - struct RegionView3D *rv3d, - struct Object *ob, - short select_mode, - bool draw_facedot, - uint initial_offset, - uint *r_vert_offset, - uint *r_edge_offset, - uint *r_face_offset); - -void DRW_framebuffer_select_id_setup(struct ARegion *ar, const bool clear); -void DRW_framebuffer_select_id_release(struct ARegion *ar); -void DRW_framebuffer_select_id_read(const struct rcti *rect, uint *r_buf); +void DRW_draw_select_id(struct Depsgraph *depsgraph, + struct ARegion *ar, + struct View3D *v3d, + struct Base **bases, + const uint bases_len, + short select_mode); /* grease pencil render */ bool DRW_render_check_grease_pencil(struct Depsgraph *depsgraph); @@ -181,4 +175,20 @@ void DRW_deferred_shader_remove(struct GPUMaterial *mat); struct DrawDataList *DRW_drawdatalist_from_id(struct ID *id); void DRW_drawdata_free(struct ID *id); +/* select_engine.c */ +void DRW_select_context_create(struct Depsgraph *depsgraph, + struct Base **bases, + const uint bases_len, + short select_mode); +bool DRW_select_elem_get(const uint sel_id, uint *r_elem, uint *r_base_index, char *r_elem_type); +uint DRW_select_context_offset_for_object_elem(const uint base_index, char elem_type); +uint DRW_select_context_elem_len(void); +void DRW_framebuffer_select_id_read(const struct rcti *rect, uint *r_buf); +void DRW_draw_select_id_object(struct Depsgraph *depsgraph, + struct ViewLayer *view_layer, + struct ARegion *ar, + struct View3D *v3d, + struct Object *ob, + short select_mode); + #endif /* __DRW_ENGINE_H__ */ diff --git a/source/blender/draw/engines/select/select_engine.c b/source/blender/draw/engines/select/select_engine.c new file mode 100644 index 00000000000..f1fc9cbc0d6 --- /dev/null +++ b/source/blender/draw/engines/select/select_engine.c @@ -0,0 +1,647 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2019, Blender Foundation. + */ + +/** \file + * \ingroup draw_engine + * + * Engine for drawing a selection map where the pixels indicate the selection indices. + */ + +#include "BLI_rect.h" + +#include "BKE_editmesh.h" + +#include "DNA_mesh_types.h" +#include "DNA_screen_types.h" + +#include "ED_view3d.h" + +#include "GPU_shader.h" +#include "GPU_select.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "UI_resources.h" + +#include "DRW_engine.h" +#include "DRW_render.h" + +#include "draw_cache_impl.h" + +#include "select_engine.h" +/* Shaders */ + +#define SELECT_ENGINE "SELECT_ENGINE" + +/* *********** LISTS *********** */ + +/* GPUViewport.storage + * Is freed everytime the viewport engine changes */ +typedef struct SELECTID_StorageList { + struct SELECTID_PrivateData *g_data; +} SELECTID_StorageList; + +typedef struct SELECTID_PassList { + struct DRWPass *select_id_face_pass; + struct DRWPass *select_id_edge_pass; + struct DRWPass *select_id_vert_pass; +} SELECTID_PassList; + +typedef struct SELECTID_Data { + void *engine_type; + DRWViewportEmptyList *fbl; + DRWViewportEmptyList *txl; + SELECTID_PassList *psl; + SELECTID_StorageList *stl; +} SELECTID_Data; + +typedef struct SELECTID_Shaders { + /* Depth Pre Pass */ + struct GPUShader *select_id_flat; + struct GPUShader *select_id_uniform; +} SELECTID_Shaders; + +/* *********** STATIC *********** */ + +static struct { + SELECTID_Shaders sh_data[GPU_SHADER_CFG_LEN]; + + struct GPUFrameBuffer *framebuffer_select_id; + struct GPUTexture *texture_u32; + + struct { + struct BaseOffset *base_array_index_offsets; + uint bases_len; + uint last_base_drawn; + /** Total number of items `base_array_index_offsets[bases_len - 1].vert`. */ + uint last_index_drawn; + + struct Depsgraph *depsgraph; + short select_mode; + } context; +} e_data = {{{NULL}}}; /* Engine data */ + +typedef struct SELECTID_PrivateData { + DRWShadingGroup *shgrp_face_unif; + DRWShadingGroup *shgrp_face_flat; + DRWShadingGroup *shgrp_edge; + DRWShadingGroup *shgrp_vert; + + DRWView *view_faces; + DRWView *view_edges; + DRWView *view_verts; +} SELECTID_PrivateData; /* Transient data */ + +struct BaseOffset { + /* For convenience only. */ + union { + uint offset; + uint face_start; + }; + union { + uint face; + uint edge_start; + }; + union { + uint edge; + uint vert_start; + }; + uint vert; +}; + +/* Shaders */ +extern char datatoc_common_view_lib_glsl[]; +extern char datatoc_selection_id_3D_vert_glsl[]; +extern char datatoc_selection_id_frag_glsl[]; + +/* -------------------------------------------------------------------- */ +/** \name Selection Utilities + * \{ */ + +static void draw_select_framebuffer_select_id_setup(void) +{ + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + int size[2]; + size[0] = GPU_texture_width(dtxl->depth); + size[1] = GPU_texture_height(dtxl->depth); + + if (e_data.framebuffer_select_id == NULL) { + e_data.framebuffer_select_id = GPU_framebuffer_create(); + } + + if ((e_data.texture_u32 != NULL) && ((GPU_texture_width(e_data.texture_u32) != size[0]) || + (GPU_texture_height(e_data.texture_u32) != size[1]))) { + + GPU_texture_free(e_data.texture_u32); + e_data.texture_u32 = NULL; + } + + if (e_data.texture_u32 == NULL) { + e_data.texture_u32 = GPU_texture_create_2d(size[0], size[1], GPU_R32UI, NULL, NULL); + + GPU_framebuffer_texture_attach(e_data.framebuffer_select_id, dtxl->depth, 0, 0); + GPU_framebuffer_texture_attach(e_data.framebuffer_select_id, e_data.texture_u32, 0, 0); + GPU_framebuffer_check_valid(e_data.framebuffer_select_id, NULL); + } +} + +static void draw_select_id_object(void *vedata, + Object *ob, + short select_mode, + bool draw_facedot, + uint initial_offset, + uint *r_vert_offset, + uint *r_edge_offset, + uint *r_face_offset) +{ + SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl; + + BLI_assert(initial_offset > 0); + + switch (ob->type) { + case OB_MESH: + if (ob->mode & OB_MODE_EDIT) { + Mesh *me = ob->data; + BMEditMesh *em = me->edit_mesh; + const bool use_faceselect = (select_mode & SCE_SELECT_FACE) != 0; + + DRW_mesh_batch_cache_validate(me); + + BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE); + + struct GPUBatch *geom_faces, *geom_edges, *geom_verts, *geom_facedots; + geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me); + if (select_mode & SCE_SELECT_EDGE) { + geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me); + } + if (select_mode & SCE_SELECT_VERTEX) { + geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me); + } + if (use_faceselect && draw_facedot) { + geom_facedots = DRW_mesh_batch_cache_get_facedots_with_select_id(me); + } + DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true); + + DRWShadingGroup *face_shgrp; + if (use_faceselect) { + face_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_face_flat); + DRW_shgroup_uniform_int_copy(face_shgrp, "offset", *(int *)&initial_offset); + + if (draw_facedot) { + DRW_shgroup_call(face_shgrp, geom_facedots, ob); + } + *r_face_offset = initial_offset + em->bm->totface; + } + else { + face_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_face_unif); + DRW_shgroup_uniform_int_copy(face_shgrp, "id", 0); + + *r_face_offset = initial_offset; + } + DRW_shgroup_call(face_shgrp, geom_faces, ob); + + /* Unlike faces, only draw edges if edge select mode. */ + if (select_mode & SCE_SELECT_EDGE) { + DRWShadingGroup *edge_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_edge); + DRW_shgroup_uniform_int_copy(edge_shgrp, "offset", *(int *)r_face_offset); + DRW_shgroup_call(edge_shgrp, geom_edges, ob); + *r_edge_offset = *r_face_offset + em->bm->totedge; + } + else { + /* Note that `r_vert_offset` is calculated from `r_edge_offset`. + * Otherwise the first vertex is never selected, see: T53512. */ + *r_edge_offset = *r_face_offset; + } + + /* Unlike faces, only verts if vert select mode. */ + if (select_mode & SCE_SELECT_VERTEX) { + DRWShadingGroup *vert_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_vert); + DRW_shgroup_uniform_int_copy(vert_shgrp, "offset", *(int *)r_edge_offset); + DRW_shgroup_call(vert_shgrp, geom_verts, ob); + *r_vert_offset = *r_edge_offset + em->bm->totvert; + } + else { + *r_vert_offset = *r_edge_offset; + } + } + else { + Mesh *me_orig = DEG_get_original_object(ob)->data; + Mesh *me_eval = ob->data; + + DRW_mesh_batch_cache_validate(me_eval); + struct GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me_eval); + if ((me_orig->editflag & ME_EDIT_PAINT_VERT_SEL) && + /* Currently vertex select supports weight paint and vertex paint. */ + ((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT))) { + + struct GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me_eval); + DRW_mesh_batch_cache_create_requested(ob, me_eval, NULL, false, true); + + /* Only draw faces to mask out verts, we don't want their selection ID's. */ + DRWShadingGroup *face_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_face_unif); + DRW_shgroup_uniform_int_copy(face_shgrp, "id", 0); + DRW_shgroup_call(face_shgrp, geom_faces, ob); + + DRWShadingGroup *vert_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_vert); + DRW_shgroup_uniform_int_copy(vert_shgrp, "offset", 1); + DRW_shgroup_call(vert_shgrp, geom_verts, ob); + + *r_face_offset = *r_edge_offset = initial_offset; + *r_vert_offset = me_eval->totvert + 1; + } + else { + const bool use_hide = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL); + DRW_mesh_batch_cache_create_requested(ob, me_eval, NULL, false, use_hide); + + DRWShadingGroup *face_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_face_flat); + DRW_shgroup_uniform_int_copy(face_shgrp, "offset", *(int *)&initial_offset); + DRW_shgroup_call(face_shgrp, geom_faces, ob); + + *r_face_offset = initial_offset + me_eval->totpoly; + *r_edge_offset = *r_vert_offset = *r_face_offset; + } + } + break; + case OB_CURVE: + case OB_SURF: + break; + } +} + +static bool check_ob_drawface_dot(short select_mode, const View3D *v3d, char dt) +{ + if (select_mode & SCE_SELECT_FACE) { + if ((dt < OB_SOLID) || XRAY_FLAG_ENABLED(v3d)) { + return true; + } + if (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_DOT) { + return true; + } + if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_EDGES) == 0) { + /* Since we can't deduce face selection when edges aren't visible - show dots. */ + return true; + } + } + return false; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Engine Functions + * \{ */ + +static void select_engine_init(void *vedata) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + eGPUShaderConfig sh_cfg = draw_ctx->sh_cfg; + + SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl; + SELECTID_Shaders *sh_data = &e_data.sh_data[sh_cfg]; + + /* Prepass */ + if (!sh_data->select_id_flat) { + const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg]; + sh_data->select_id_flat = GPU_shader_create_from_arrays({ + .vert = (const char *[]){sh_cfg_data->lib, + datatoc_common_view_lib_glsl, + datatoc_selection_id_3D_vert_glsl, + NULL}, + .frag = (const char *[]){datatoc_selection_id_frag_glsl, NULL}, + .defs = (const char *[]){sh_cfg_data->def, NULL}, + }); + } + if (!sh_data->select_id_uniform) { + const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg]; + sh_data->select_id_uniform = GPU_shader_create_from_arrays({ + .vert = (const char *[]){sh_cfg_data->lib, + datatoc_common_view_lib_glsl, + datatoc_selection_id_3D_vert_glsl, + NULL}, + .frag = (const char *[]){datatoc_selection_id_frag_glsl, NULL}, + .defs = (const char *[]){sh_cfg_data->def, "#define UNIFORM_ID\n", NULL}, + }); + } + + if (!stl->g_data) { + /* Alloc transient pointers */ + stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__); + } + + { + /* Create view with depth offset */ + stl->g_data->view_faces = (DRWView *)DRW_view_default_get(); + stl->g_data->view_edges = DRW_view_create_with_zoffset(draw_ctx->rv3d, 1.0f); + stl->g_data->view_verts = DRW_view_create_with_zoffset(draw_ctx->rv3d, 1.1f); + } +} + +static void select_cache_init(void *vedata) +{ + SELECTID_PassList *psl = ((SELECTID_Data *)vedata)->psl; + SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl; + + const DRWContextState *draw_ctx = DRW_context_state_get(); + SELECTID_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; + { + psl->select_id_face_pass = DRW_pass_create("Face Pass", DRW_STATE_DEFAULT); + stl->g_data->shgrp_face_unif = DRW_shgroup_create(sh_data->select_id_uniform, + psl->select_id_face_pass); + + stl->g_data->shgrp_face_flat = DRW_shgroup_create(sh_data->select_id_flat, + psl->select_id_face_pass); + + psl->select_id_edge_pass = DRW_pass_create( + "Edge Pass", DRW_STATE_DEFAULT | DRW_STATE_FIRST_VERTEX_CONVENTION); + + stl->g_data->shgrp_edge = DRW_shgroup_create(sh_data->select_id_flat, + psl->select_id_edge_pass); + + psl->select_id_vert_pass = DRW_pass_create("Vert Pass", DRW_STATE_DEFAULT); + stl->g_data->shgrp_vert = DRW_shgroup_create(sh_data->select_id_flat, + psl->select_id_vert_pass); + + DRW_shgroup_uniform_float_copy(stl->g_data->shgrp_vert, "sizeVertex", G_draw.block.sizeVertex); + + if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) { + DRW_shgroup_state_enable(stl->g_data->shgrp_face_unif, DRW_STATE_CLIP_PLANES); + DRW_shgroup_state_enable(stl->g_data->shgrp_face_flat, DRW_STATE_CLIP_PLANES); + DRW_shgroup_state_enable(stl->g_data->shgrp_edge, DRW_STATE_CLIP_PLANES); + DRW_shgroup_state_enable(stl->g_data->shgrp_vert, DRW_STATE_CLIP_PLANES); + } + } + + e_data.context.last_base_drawn = 0; + e_data.context.last_index_drawn = 1; +} + +static void select_cache_populate(void *vedata, Object *ob) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + short select_mode = e_data.context.select_mode; + + if (select_mode == -1) { + ToolSettings *ts = draw_ctx->scene->toolsettings; + select_mode = ts->selectmode; + } + + bool draw_facedot = check_ob_drawface_dot(select_mode, draw_ctx->v3d, ob->dt); + + struct BaseOffset *base_ofs = + &e_data.context.base_array_index_offsets[e_data.context.last_base_drawn++]; + + uint offset = e_data.context.last_index_drawn; + + draw_select_id_object(vedata, + ob, + select_mode, + draw_facedot, + offset, + &base_ofs->vert, + &base_ofs->edge, + &base_ofs->face); + + base_ofs->offset = offset; + e_data.context.last_index_drawn = base_ofs->vert; +} + +static void select_draw_scene(void *vedata) +{ + SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl; + SELECTID_PassList *psl = ((SELECTID_Data *)vedata)->psl; + + /* Setup framebuffer */ + draw_select_framebuffer_select_id_setup(); + GPU_framebuffer_bind(e_data.framebuffer_select_id); + + /* dithering and AA break color coding, so disable */ + glDisable(GL_DITHER); + + GPU_framebuffer_clear_color_depth(e_data.framebuffer_select_id, (const float[4]){0.0f}, 1.0f); + + DRW_view_set_active(stl->g_data->view_faces); + DRW_draw_pass(psl->select_id_face_pass); + + DRW_view_set_active(stl->g_data->view_edges); + DRW_draw_pass(psl->select_id_edge_pass); + + DRW_view_set_active(stl->g_data->view_verts); + DRW_draw_pass(psl->select_id_vert_pass); +} + +static void select_engine_free(void) +{ + for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) { + SELECTID_Shaders *sh_data = &e_data.sh_data[sh_data_index]; + DRW_SHADER_FREE_SAFE(sh_data->select_id_flat); + DRW_SHADER_FREE_SAFE(sh_data->select_id_uniform); + } + + DRW_TEXTURE_FREE_SAFE(e_data.texture_u32); + GPU_FRAMEBUFFER_FREE_SAFE(e_data.framebuffer_select_id); + MEM_SAFE_FREE(e_data.context.base_array_index_offsets); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Exposed `DRW_engine.h` functions + * \{ */ + +bool DRW_select_elem_get(const uint sel_id, uint *r_elem, uint *r_base_index, char *r_elem_type) +{ + char elem_type = 0; + uint elem_id; + uint base_index = 0; + + for (; base_index < e_data.context.bases_len; base_index++) { + struct BaseOffset *base_ofs = &e_data.context.base_array_index_offsets[base_index]; + + if (base_ofs->face > sel_id) { + elem_id = sel_id - base_ofs->face_start; + elem_type = SCE_SELECT_FACE; + break; + } + if (base_ofs->edge > sel_id) { + elem_id = sel_id - base_ofs->edge_start; + elem_type = SCE_SELECT_EDGE; + break; + } + if (base_ofs->vert > sel_id) { + elem_id = sel_id - base_ofs->vert_start; + elem_type = SCE_SELECT_VERTEX; + break; + } + } + + if (base_index == e_data.context.bases_len) { + return false; + } + + *r_elem = elem_id; + + if (r_base_index) { + *r_base_index = base_index; + } + + if (r_elem_type) { + *r_elem_type = elem_type; + } + + return true; +} + +uint DRW_select_context_offset_for_object_elem(const uint base_index, char elem_type) +{ + struct BaseOffset *base_ofs = &e_data.context.base_array_index_offsets[base_index]; + + if (elem_type == SCE_SELECT_VERTEX) { + return base_ofs->vert_start - 1; + } + if (elem_type == SCE_SELECT_EDGE) { + return base_ofs->edge_start - 1; + } + if (elem_type == SCE_SELECT_FACE) { + return base_ofs->face_start - 1; + } + BLI_assert(0); + return 0; +} + +uint DRW_select_context_elem_len(void) +{ + return e_data.context.last_index_drawn; +} + +/* Read a block of pixels from the select frame buffer. */ +void DRW_framebuffer_select_id_read(const rcti *rect, uint *r_buf) +{ + /* clamp rect by texture */ + rcti r = { + .xmin = 0, + .xmax = GPU_texture_width(e_data.texture_u32), + .ymin = 0, + .ymax = GPU_texture_height(e_data.texture_u32), + }; + + rcti rect_clamp = *rect; + if (BLI_rcti_isect(&r, &rect_clamp, &rect_clamp)) { + DRW_opengl_context_enable(); + GPU_framebuffer_bind(e_data.framebuffer_select_id); + glReadBuffer(GL_COLOR_ATTACHMENT0); + glReadPixels(rect_clamp.xmin, + rect_clamp.ymin, + BLI_rcti_size_x(&rect_clamp), + BLI_rcti_size_y(&rect_clamp), + GL_RED_INTEGER, + GL_UNSIGNED_INT, + r_buf); + + GPU_framebuffer_restore(); + DRW_opengl_context_disable(); + + if (!BLI_rcti_compare(rect, &rect_clamp)) { + GPU_select_buffer_stride_realign(rect, &rect_clamp, r_buf); + } + } + else { + size_t buf_size = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect) * sizeof(*r_buf); + + memset(r_buf, 0, buf_size); + } +} + +void DRW_select_context_create(Depsgraph *depsgraph, + Base **UNUSED(bases), + const uint bases_len, + short select_mode) +{ + e_data.context.depsgraph = depsgraph; + e_data.context.select_mode = select_mode; + e_data.context.bases_len = bases_len; + + MEM_SAFE_FREE(e_data.context.base_array_index_offsets); + e_data.context.base_array_index_offsets = MEM_mallocN( + sizeof(*e_data.context.base_array_index_offsets) * bases_len, __func__); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Legacy + * \{ */ + +void DRW_draw_select_id_object(Depsgraph *depsgraph, + ViewLayer *view_layer, + ARegion *ar, + View3D *v3d, + Object *ob, + short select_mode) +{ + Base *base = BKE_view_layer_base_find(view_layer, ob); + DRW_draw_select_id(depsgraph, ar, v3d, &base, 1, select_mode); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Engine Type + * \{ */ + +static const DrawEngineDataSize select_data_size = DRW_VIEWPORT_DATA_SIZE(SELECTID_Data); + +DrawEngineType draw_engine_select_type = { + NULL, + NULL, + N_("Select ID"), + &select_data_size, + &select_engine_init, + &select_engine_free, + &select_cache_init, + &select_cache_populate, + NULL, + NULL, + &select_draw_scene, + NULL, + NULL, + NULL, +}; + +/* Note: currently unused, we may want to register so we can see this when debugging the view. */ + +RenderEngineType DRW_engine_viewport_select_type = { + NULL, + NULL, + SELECT_ENGINE, + N_("Select ID"), + RE_INTERNAL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &draw_engine_select_type, + {NULL, NULL, NULL}, +}; + +/** \} */ + +#undef SELECT_ENGINE diff --git a/source/blender/draw/engines/select/select_engine.h b/source/blender/draw/engines/select/select_engine.h new file mode 100644 index 00000000000..5b900ccaf27 --- /dev/null +++ b/source/blender/draw/engines/select/select_engine.h @@ -0,0 +1,29 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2019, Blender Foundation. + */ + +/** \file + * \ingroup draw_engine + */ + +#ifndef __SELECT_ENGINE_H__ +#define __SELECT_ENGINE_H__ + +extern DrawEngineType draw_engine_select_type; +extern RenderEngineType DRW_engine_viewport_select_type; + +#endif /* __SELECT_ID_ENGINE_H__ */ diff --git a/source/blender/draw/engines/select/shaders/selection_id_3D_vert.glsl b/source/blender/draw/engines/select/shaders/selection_id_3D_vert.glsl new file mode 100644 index 00000000000..9b0107cffdb --- /dev/null +++ b/source/blender/draw/engines/select/shaders/selection_id_3D_vert.glsl @@ -0,0 +1,26 @@ + +uniform float sizeVertex; + +in vec3 pos; + +#ifndef UNIFORM_ID +uniform int offset; +in uint color; + +flat out uint id; +#endif + +void main() +{ +#ifndef UNIFORM_ID + id = floatBitsToUint(intBitsToFloat(offset)) + color; +#endif + + vec3 world_pos = point_object_to_world(pos); + gl_Position = point_world_to_ndc(world_pos); + gl_PointSize = sizeVertex; + +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_calc_clip_distance(world_pos); +#endif +} diff --git a/source/blender/draw/engines/select/shaders/selection_id_frag.glsl b/source/blender/draw/engines/select/shaders/selection_id_frag.glsl new file mode 100644 index 00000000000..ea86ddc7301 --- /dev/null +++ b/source/blender/draw/engines/select/shaders/selection_id_frag.glsl @@ -0,0 +1,14 @@ + +#ifdef UNIFORM_ID +uniform int id; +# define id floatBitsToUint(intBitsToFloat(id)) +#else +flat in uint id; +#endif + +out uint fragColor; + +void main() +{ + fragColor = id; +} diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 2841e017ef6..320a6f6aaaa 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -89,6 +89,7 @@ #include "engines/workbench/workbench_engine.h" #include "engines/external/external_engine.h" #include "engines/gpencil/gpencil_engine.h" +#include "engines/select/select_engine.h" #include "GPU_context.h" @@ -2136,16 +2137,13 @@ void DRW_custom_pipeline(DrawEngineType *draw_engine_type, static struct DRWSelectBuffer { struct GPUFrameBuffer *framebuffer_depth_only; - struct GPUFrameBuffer *framebuffer_select_id; struct GPUTexture *texture_depth; - struct GPUTexture *texture_u32; } g_select_buffer = {NULL}; static void draw_select_framebuffer_depth_only_setup(const int size[2]) { if (g_select_buffer.framebuffer_depth_only == NULL) { g_select_buffer.framebuffer_depth_only = GPU_framebuffer_create(); - g_select_buffer.framebuffer_select_id = GPU_framebuffer_create(); } if ((g_select_buffer.texture_depth != NULL) && @@ -2162,32 +2160,7 @@ static void draw_select_framebuffer_depth_only_setup(const int size[2]) GPU_framebuffer_texture_attach( g_select_buffer.framebuffer_depth_only, g_select_buffer.texture_depth, 0, 0); - GPU_framebuffer_texture_attach( - g_select_buffer.framebuffer_select_id, g_select_buffer.texture_depth, 0, 0); - GPU_framebuffer_check_valid(g_select_buffer.framebuffer_depth_only, NULL); - GPU_framebuffer_check_valid(g_select_buffer.framebuffer_select_id, NULL); - } -} - -static void draw_select_framebuffer_select_id_setup(const int size[2]) -{ - draw_select_framebuffer_depth_only_setup(size); - - if ((g_select_buffer.texture_u32 != NULL) && - ((GPU_texture_width(g_select_buffer.texture_u32) != size[0]) || - (GPU_texture_height(g_select_buffer.texture_u32) != size[1]))) { - GPU_texture_free(g_select_buffer.texture_u32); - g_select_buffer.texture_u32 = NULL; - } - - if (g_select_buffer.texture_u32 == NULL) { - g_select_buffer.texture_u32 = GPU_texture_create_2d(size[0], size[1], GPU_R32UI, NULL, NULL); - - GPU_framebuffer_texture_attach( - g_select_buffer.framebuffer_select_id, g_select_buffer.texture_u32, 0, 0); - - GPU_framebuffer_check_valid(g_select_buffer.framebuffer_select_id, NULL); } } @@ -2575,6 +2548,78 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph, DRW_opengl_context_disable(); } +void DRW_draw_select_id(Depsgraph *depsgraph, + ARegion *ar, + View3D *v3d, + Base **bases, + const uint bases_len, + short select_mode) +{ + Scene *scene = DEG_get_evaluated_scene(depsgraph); + ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); + + DRW_select_context_create(depsgraph, bases, bases_len, select_mode); + + DRW_opengl_context_enable(); + + /* Reset before using it. */ + drw_state_prepare_clean_for_draw(&DST); + DST.buffer_finish_called = true; + + /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */ + DST.draw_ctx = (DRWContextState){ + .ar = ar, + .rv3d = ar->regiondata, + .v3d = v3d, + .scene = scene, + .view_layer = view_layer, + .obact = OBACT(view_layer), + .depsgraph = depsgraph, + }; + + use_drw_engine(&draw_engine_select_type); + drw_context_state_init(); + + /* Setup viewport */ + DST.viewport = WM_draw_region_get_viewport(ar, 0); + drw_viewport_var_init(); + + /* Update ubos */ + DRW_globals_update(); + + /* Init engines */ + drw_engines_init(); + + { + drw_engines_cache_init(); + + /* Keep `base_index` in sync with `e_data.context.last_base_drawn`. + * So don't skip objects. */ + for (uint base_index = 0; base_index < bases_len; base_index++) { + Object *obj_eval = DEG_get_evaluated_object(depsgraph, bases[base_index]->object); + drw_engines_cache_populate(obj_eval); + } + + drw_engines_cache_finish(); + } + + /* Start Drawing */ + DRW_state_reset(); + drw_engines_draw_scene(); + DRW_state_reset(); + + drw_engines_disable(); + +#ifdef DEBUG + /* Avoid accidental reuse. */ + drw_state_ensure_not_reused(&DST); +#endif + + /* Changin context */ + GPU_framebuffer_restore(); + DRW_opengl_context_disable(); +} + /** See #DRW_shgroup_world_clip_planes_from_rv3d. */ static void draw_world_clip_planes_from_rv3d(GPUBatch *batch, const float world_clip_planes[6][4]) { @@ -2646,294 +2691,6 @@ void DRW_draw_depth_object(ARegion *ar, GPUViewport *viewport, Object *object) DRW_opengl_context_disable(); } -static void draw_mesh_verts(GPUBatch *batch, uint offset, const float world_clip_planes[6][4]) -{ - GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE)); - - const eGPUShaderConfig sh_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, sh_cfg); - GPU_batch_uniform_1ui(batch, "offset", offset); - if (world_clip_planes != NULL) { - draw_world_clip_planes_from_rv3d(batch, world_clip_planes); - } - GPU_batch_draw(batch); -} - -static void draw_mesh_edges(GPUBatch *batch, uint offset, const float world_clip_planes[6][4]) -{ - GPU_line_width(1.0f); - glProvokingVertex(GL_FIRST_VERTEX_CONVENTION); - - const eGPUShaderConfig sh_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, sh_cfg); - GPU_batch_uniform_1ui(batch, "offset", offset); - if (world_clip_planes != NULL) { - draw_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 draw_mesh_face(GPUBatch *batch, - uint offset, - const bool use_select, - const float world_clip_planes[6][4]) -{ - if (use_select) { - const eGPUShaderConfig sh_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, sh_cfg); - GPU_batch_uniform_1ui(batch, "offset", offset); - if (world_clip_planes != NULL) { - draw_world_clip_planes_from_rv3d(batch, world_clip_planes); - } - GPU_batch_draw(batch); - } - else { - const eGPUShaderConfig sh_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, sh_cfg); - GPU_batch_uniform_1ui(batch, "id", 0); - if (world_clip_planes != NULL) { - draw_world_clip_planes_from_rv3d(batch, world_clip_planes); - } - GPU_batch_draw(batch); - } -} - -static void draw_mesh_face_dot(GPUBatch *batch, uint offset, const float world_clip_planes[6][4]) -{ - const eGPUShaderConfig sh_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, sh_cfg); - GPU_batch_uniform_1ui(batch, "offset", offset); - if (world_clip_planes != NULL) { - draw_world_clip_planes_from_rv3d(batch, world_clip_planes); - } - GPU_batch_draw(batch); -} - -void DRW_draw_select_id_object(Scene *scene, - RegionView3D *rv3d, - Object *ob, - short select_mode, - bool draw_facedot, - uint initial_offset, - uint *r_vert_offset, - uint *r_edge_offset, - uint *r_face_offset) -{ - ToolSettings *ts = scene->toolsettings; - if (select_mode == -1) { - select_mode = ts->selectmode; - } - - /* Init the scene of the draw context. When using face dot selection on - * when the subsurf modifier is active on the cage, the scene needs to be - * valid. It is read from the context in the - * `DRW_mesh_batch_cache_create_requested` and used in the `isDisabled` - * method of the SubSurfModifier. */ - DRWContextState *draw_ctx = &DST.draw_ctx; - draw_ctx->scene = scene; - - GPU_matrix_mul(ob->obmat); - - const float(*world_clip_planes)[4] = NULL; - if (rv3d->rflag & RV3D_CLIPPING) { - ED_view3d_clipping_local(rv3d, ob->obmat); - world_clip_planes = rv3d->clip_local; - } - - BLI_assert(initial_offset > 0); - - switch (ob->type) { - case OB_MESH: - if (ob->mode & OB_MODE_EDIT) { - Mesh *me = ob->data; - BMEditMesh *em = me->edit_mesh; - const bool use_faceselect = (select_mode & SCE_SELECT_FACE) != 0; - - DRW_mesh_batch_cache_validate(me); - - BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE); - - GPUBatch *geom_faces, *geom_edges, *geom_verts, *geom_facedots; - geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me); - if (select_mode & SCE_SELECT_EDGE) { - geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me); - } - if (select_mode & SCE_SELECT_VERTEX) { - geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me); - } - if (use_faceselect && draw_facedot) { - geom_facedots = DRW_mesh_batch_cache_get_facedots_with_select_id(me); - } - DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true); - - draw_mesh_face(geom_faces, initial_offset, use_faceselect, world_clip_planes); - - if (use_faceselect && draw_facedot) { - draw_mesh_face_dot(geom_facedots, initial_offset, world_clip_planes); - } - - if (select_mode & SCE_SELECT_FACE) { - *r_face_offset = initial_offset + em->bm->totface; - } - else { - *r_face_offset = initial_offset; - } - - ED_view3d_polygon_offset(rv3d, 1.0); - - /* Unlike faces, only draw edges if edge select mode. */ - if (select_mode & SCE_SELECT_EDGE) { - draw_mesh_edges(geom_edges, *r_face_offset, world_clip_planes); - *r_edge_offset = *r_face_offset + em->bm->totedge; - } - else { - /* Note that `r_vert_offset` is calculated from `r_edge_offset`. - * Otherwise the first vertex is never selected, see: T53512. */ - *r_edge_offset = *r_face_offset; - } - - ED_view3d_polygon_offset(rv3d, 1.1); - - /* Unlike faces, only verts if vert select mode. */ - if (select_mode & SCE_SELECT_VERTEX) { - draw_mesh_verts(geom_verts, *r_edge_offset, world_clip_planes); - *r_vert_offset = *r_edge_offset + em->bm->totvert; - } - else { - *r_vert_offset = *r_edge_offset; - } - - ED_view3d_polygon_offset(rv3d, 0.0); - } - else { - Mesh *me_orig = DEG_get_original_object(ob)->data; - Mesh *me_eval = ob->data; - - DRW_mesh_batch_cache_validate(me_eval); - GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me_eval); - if ((me_orig->editflag & ME_EDIT_PAINT_VERT_SEL) && - /* Currently vertex select supports weight paint and vertex paint. */ - ((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT))) { - - GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me_eval); - DRW_mesh_batch_cache_create_requested(ob, me_eval, NULL, false, true); - - /* Only draw faces to mask out verts, we don't want their selection ID's. */ - draw_mesh_face(geom_faces, 0, false, world_clip_planes); - draw_mesh_verts(geom_verts, 1, world_clip_planes); - - *r_face_offset = *r_edge_offset = initial_offset; - *r_vert_offset = me_eval->totvert + 1; - } - else { - const bool use_hide = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL); - DRW_mesh_batch_cache_create_requested(ob, me_eval, NULL, false, use_hide); - - draw_mesh_face(geom_faces, initial_offset, true, world_clip_planes); - - *r_face_offset = initial_offset + me_eval->totpoly; - *r_edge_offset = *r_vert_offset = *r_face_offset; - } - } - break; - case OB_CURVE: - case OB_SURF: - break; - } - - GPU_matrix_set(rv3d->viewmat); -} - -/* Set an opengl context to be used with shaders that draw on U32 colors. */ -void DRW_framebuffer_select_id_setup(ARegion *ar, const bool clear) -{ - RegionView3D *rv3d = ar->regiondata; - - DRW_opengl_context_enable(); - - /* Setup framebuffer */ - int viewport_size[2] = {ar->winx, ar->winy}; - draw_select_framebuffer_select_id_setup(viewport_size); - GPU_framebuffer_bind(g_select_buffer.framebuffer_select_id); - - /* dithering and AA break color coding, so disable */ - glDisable(GL_DITHER); - - GPU_depth_test(true); - GPU_program_point_size(false); - - if (clear) { - GPU_framebuffer_clear_color_depth( - g_select_buffer.framebuffer_select_id, (const float[4]){0.0f}, 1.0f); - } - - if (rv3d->rflag & RV3D_CLIPPING) { - ED_view3d_clipping_set(rv3d); - } -} - -/* Ends the context for selection and restoring the previous one. */ -void DRW_framebuffer_select_id_release(ARegion *ar) -{ - RegionView3D *rv3d = ar->regiondata; - - if (rv3d->rflag & RV3D_CLIPPING) { - ED_view3d_clipping_disable(); - } - - GPU_depth_test(false); - - GPU_framebuffer_restore(); - - DRW_opengl_context_disable(); -} - -/* Read a block of pixels from the select frame buffer. */ -void DRW_framebuffer_select_id_read(const rcti *rect, uint *r_buf) -{ - /* clamp rect by texture */ - rcti r = { - .xmin = 0, - .xmax = GPU_texture_width(g_select_buffer.texture_u32), - .ymin = 0, - .ymax = GPU_texture_height(g_select_buffer.texture_u32), - }; - - rcti rect_clamp = *rect; - if (BLI_rcti_isect(&r, &rect_clamp, &rect_clamp)) { - DRW_opengl_context_enable(); - GPU_framebuffer_bind(g_select_buffer.framebuffer_select_id); - glReadBuffer(GL_COLOR_ATTACHMENT0); - glReadPixels(rect_clamp.xmin, - rect_clamp.ymin, - BLI_rcti_size_x(&rect_clamp), - BLI_rcti_size_y(&rect_clamp), - GL_RED_INTEGER, - GL_UNSIGNED_INT, - r_buf); - - GPU_framebuffer_restore(); - DRW_opengl_context_disable(); - - if (!BLI_rcti_compare(rect, &rect_clamp)) { - GPU_select_buffer_stride_realign(rect, &rect_clamp, r_buf); - } - } - else { - size_t buf_size = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect) * sizeof(*r_buf); - - memset(r_buf, 0, buf_size); - } -} - /** \} */ /* -------------------------------------------------------------------- */ @@ -3089,6 +2846,7 @@ void DRW_engines_register(void) DRW_engine_register(&draw_engine_pose_type); DRW_engine_register(&draw_engine_sculpt_type); DRW_engine_register(&draw_engine_gpencil_type); + DRW_engine_register(&draw_engine_select_type); /* setup callbacks */ { @@ -3123,9 +2881,7 @@ void DRW_engines_free(void) DRW_opengl_context_enable(); - DRW_TEXTURE_FREE_SAFE(g_select_buffer.texture_u32); DRW_TEXTURE_FREE_SAFE(g_select_buffer.texture_depth); - GPU_FRAMEBUFFER_FREE_SAFE(g_select_buffer.framebuffer_select_id); GPU_FRAMEBUFFER_FREE_SAFE(g_select_buffer.framebuffer_depth_only); DRW_hair_free(); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 93268456277..751f71cc53b 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -512,26 +512,6 @@ int view3d_opengl_select(struct ViewContext *vc, eV3DSelectObjectFilter select_filter); /* view3d_select.c */ -struct EDSelectID_Context; -struct EDSelectID_Context *ED_view3d_select_id_context_create(struct ViewContext *vc, - struct Base **bases, - const uint bases_len, - short select_mode); - -void ED_view3d_select_id_context_destroy(struct EDSelectID_Context *sel_id_ctx); -void ED_view3d_select_id_validate_view_matrices(struct EDSelectID_Context *sel_id_ctx, - struct ViewContext *vc); - -uint ED_view3d_select_id_context_offset_for_object_elem( - const struct EDSelectID_Context *sel_id_ctx, int base_index, char elem_type); - -uint ED_view3d_select_id_context_elem_len(const struct EDSelectID_Context *sel_id_ctx); -bool ED_view3d_select_id_elem_get(struct EDSelectID_Context *sel_id_ctx, - const uint sel_id, - uint *r_elem, - uint *r_base_index, - char *r_elem_type); - float ED_view3d_select_dist_px(void); void ED_view3d_viewcontext_init(struct bContext *C, struct ViewContext *vc); void ED_view3d_viewcontext_init_object(struct ViewContext *vc, struct Object *obact); diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt index 57bf67e825e..9a779db4812 100644 --- a/source/blender/editors/mesh/CMakeLists.txt +++ b/source/blender/editors/mesh/CMakeLists.txt @@ -23,6 +23,7 @@ set(INC ../../blentranslation ../../bmesh ../../depsgraph + ../../draw ../../gpu ../../imbuf ../../makesdna diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 7b770f055b4..12b5a36c510 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -68,6 +68,8 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" +#include "DRW_engine.h" + #include "mesh_intern.h" /* own include */ /* use bmesh operator flags for a few operators */ @@ -197,15 +199,11 @@ void EDBM_automerge(Scene *scene, Object *obedit, bool update, const char hflag) /** \name Back-Buffer OpenGL Selection * \{ */ -static BMElem *EDBM_select_id_bm_elem_get(struct EDSelectID_Context *sel_id_ctx, - Base **bases, - const uint sel_id, - uint *r_base_index) +static BMElem *edbm_select_id_bm_elem_get(Base **bases, const uint sel_id, uint *r_base_index) { uint elem_id; char elem_type = 0; - bool success = ED_view3d_select_id_elem_get( - sel_id_ctx, sel_id, &elem_id, r_base_index, &elem_type); + bool success = DRW_select_elem_get(sel_id, &elem_id, r_base_index, &elem_type); if (success) { Object *obedit = bases[*r_base_index]->object; @@ -335,20 +333,17 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc, { FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_VERTEX); - struct EDSelectID_Context *sel_id_ctx = ED_view3d_select_id_context_create( - vc, bases, bases_len, select_mode); + DRW_draw_select_id(vc->depsgraph, vc->ar, vc->v3d, bases, bases_len, select_mode); index = ED_select_buffer_find_nearest_to_point(vc->mval, 1, UINT_MAX, &dist_px); if (index) { - eve = (BMVert *)EDBM_select_id_bm_elem_get(sel_id_ctx, bases, index, &base_index); + eve = (BMVert *)edbm_select_id_bm_elem_get(bases, index, &base_index); } else { eve = NULL; } - ED_view3d_select_id_context_destroy(sel_id_ctx); - FAKE_SELECT_MODE_END(vc, fake_select_mode); } @@ -564,20 +559,17 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc, { FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_EDGE); - struct EDSelectID_Context *sel_id_ctx = ED_view3d_select_id_context_create( - vc, bases, bases_len, select_mode); + DRW_draw_select_id(vc->depsgraph, vc->ar, vc->v3d, bases, bases_len, select_mode); index = ED_select_buffer_find_nearest_to_point(vc->mval, 1, UINT_MAX, &dist_px); if (index) { - eed = (BMEdge *)EDBM_select_id_bm_elem_get(sel_id_ctx, bases, index, &base_index); + eed = (BMEdge *)edbm_select_id_bm_elem_get(bases, index, &base_index); } else { eed = NULL; } - ED_view3d_select_id_context_destroy(sel_id_ctx); - FAKE_SELECT_MODE_END(vc, fake_select_mode); } @@ -777,20 +769,17 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc, { FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_FACE); - struct EDSelectID_Context *sel_id_ctx = ED_view3d_select_id_context_create( - vc, bases, bases_len, select_mode); + DRW_draw_select_id(vc->depsgraph, vc->ar, vc->v3d, bases, bases_len, select_mode); index = ED_select_buffer_sample_point(vc->mval); if (index) { - efa = (BMFace *)EDBM_select_id_bm_elem_get(sel_id_ctx, bases, index, &base_index); + efa = (BMFace *)edbm_select_id_bm_elem_get(bases, index, &base_index); } else { efa = NULL; } - ED_view3d_select_id_context_destroy(sel_id_ctx); - FAKE_SELECT_MODE_END(vc, fake_select_mode); } diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c index 386c3164843..4c03995307a 100644 --- a/source/blender/editors/space_view3d/view3d_draw_legacy.c +++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c @@ -155,11 +155,13 @@ void ED_view3d_clipping_enable(void) /** * \note Only use in object mode. */ -static void validate_object_select_id( - struct Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d, Object *obact) +static void validate_object_select_id(struct Depsgraph *depsgraph, + Scene *scene, + ViewLayer *view_layer, + ARegion *ar, + View3D *v3d, + Object *obact) { - RegionView3D *rv3d = ar->regiondata; - Scene *scene_eval = (Scene *)DEG_get_evaluated_id(depsgraph, &scene->id); Object *obact_eval = DEG_get_evaluated_object(depsgraph, obact); BLI_assert(ar->regiontype == RGN_TYPE_WINDOW); @@ -186,19 +188,8 @@ static void validate_object_select_id( } if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) { - uint dummy_vert_ofs, dummy_edge_ofs, dummy_face_ofs; - DRW_framebuffer_select_id_setup(ar, true); - DRW_draw_select_id_object(scene_eval, - rv3d, - obact_eval, - scene->toolsettings->selectmode, - false, - 1, - &dummy_vert_ofs, - &dummy_edge_ofs, - &dummy_face_ofs); - - DRW_framebuffer_select_id_release(ar); + DRW_draw_select_id_object( + depsgraph, view_layer, ar, v3d, obact, scene->toolsettings->selectmode); } /* TODO: Create a flag in `DRW_manager` because the drawing is no longer @@ -233,7 +224,8 @@ void ED_view3d_select_id_validate(ViewContext *vc) /* TODO: Create a flag in `DRW_manager` because the drawing is no longer * made on the backbuffer in this case. */ if (vc->v3d->flag & V3D_INVALID_BACKBUF) { - validate_object_select_id(vc->depsgraph, vc->scene, vc->ar, vc->v3d, vc->obact); + validate_object_select_id( + vc->depsgraph, vc->scene, vc->view_layer, vc->ar, vc->v3d, vc->obact); } } diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 61de61c8e31..754c8359d28 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -110,192 +110,6 @@ // #include "PIL_time_utildefines.h" -/* -------------------------------------------------------------------- */ -/** \name Selection Utilities - * \{ */ - -struct EDBaseOffset { - /* For convenience only. */ - union { - uint offset; - uint face_start; - }; - union { - uint face; - uint edge_start; - }; - union { - uint edge; - uint vert_start; - }; - uint vert; -}; - -struct EDSelectID_Context { - struct EDBaseOffset *base_array_index_offsets; - /** Borrow from caller (not freed). */ - struct Base **bases; - uint bases_len; - /** Total number of items `base_array_index_offsets[bases_len - 1].vert`. */ - uint base_array_index_len; - /** Used to check for changes. (Use depsgraph instead?). */ - float persmat[4][4]; - short select_mode; -}; - -static bool check_ob_drawface_dot(short select_mode, const View3D *v3d, char dt) -{ - if (select_mode & SCE_SELECT_FACE) { - if ((dt < OB_SOLID) || XRAY_FLAG_ENABLED(v3d)) { - return true; - } - if (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_DOT) { - return true; - } - if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_EDGES) == 0) { - /* Since we can't deduce face selection when edges aren't visible - show dots. */ - return true; - } - } - return false; -} - -static void ed_select_id_draw_bases(struct EDSelectID_Context *sel_id_ctx, - ViewContext *vc, - short select_mode) -{ - Scene *scene_eval = (Scene *)DEG_get_evaluated_id(vc->depsgraph, &vc->scene->id); - DRW_framebuffer_select_id_setup(vc->ar, true); - - uint offset = 1; - for (uint base_index = 0; base_index < sel_id_ctx->bases_len; base_index++) { - Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph, - sel_id_ctx->bases[base_index]->object); - - struct EDBaseOffset *base_ofs = &sel_id_ctx->base_array_index_offsets[base_index]; - bool draw_facedot = check_ob_drawface_dot(select_mode, vc->v3d, ob_eval->dt); - - DRW_draw_select_id_object(scene_eval, - vc->rv3d, - ob_eval, - select_mode, - draw_facedot, - offset, - &base_ofs->vert, - &base_ofs->edge, - &base_ofs->face); - - base_ofs->offset = offset; - offset = base_ofs->vert; - } - - sel_id_ctx->base_array_index_len = offset; - - DRW_framebuffer_select_id_release(vc->ar); -} - -void ED_view3d_select_id_validate_view_matrices(struct EDSelectID_Context *sel_id_ctx, - ViewContext *vc) -{ - if (!compare_m4m4(sel_id_ctx->persmat, vc->rv3d->persmat, FLT_EPSILON)) { - ed_select_id_draw_bases(sel_id_ctx, vc, sel_id_ctx->select_mode); - } -} - -uint ED_view3d_select_id_context_offset_for_object_elem( - const struct EDSelectID_Context *sel_id_ctx, int base_index, char elem_type) -{ - struct EDBaseOffset *base_ofs = &sel_id_ctx->base_array_index_offsets[base_index]; - if (elem_type == SCE_SELECT_VERTEX) { - return base_ofs->vert_start - 1; - } - if (elem_type == SCE_SELECT_EDGE) { - return base_ofs->edge_start - 1; - } - if (elem_type == SCE_SELECT_FACE) { - return base_ofs->face_start - 1; - } - BLI_assert(0); - return 0; -} - -uint ED_view3d_select_id_context_elem_len(const struct EDSelectID_Context *sel_id_ctx) -{ - return sel_id_ctx->base_array_index_len; -} - -struct EDSelectID_Context *ED_view3d_select_id_context_create(ViewContext *vc, - Base **bases, - const uint bases_len, - short select_mode) -{ - struct EDSelectID_Context *sel_id_ctx = MEM_mallocN(sizeof(*sel_id_ctx), __func__); - sel_id_ctx->base_array_index_offsets = MEM_mallocN(sizeof(struct EDBaseOffset) * bases_len, - __func__); - sel_id_ctx->bases = bases; - sel_id_ctx->bases_len = bases_len; - copy_m4_m4(sel_id_ctx->persmat, vc->rv3d->persmat); - sel_id_ctx->select_mode = select_mode; - ed_select_id_draw_bases(sel_id_ctx, vc, select_mode); - - return sel_id_ctx; -} - -void ED_view3d_select_id_context_destroy(struct EDSelectID_Context *sel_id_ctx) -{ - MEM_freeN(sel_id_ctx->base_array_index_offsets); - MEM_freeN(sel_id_ctx); -} - -bool ED_view3d_select_id_elem_get(struct EDSelectID_Context *sel_id_ctx, - const uint sel_id, - uint *r_elem, - uint *r_base_index, - char *r_elem_type) -{ - char elem_type = 0; - uint elem_id; - uint base_index = 0; - - while (true) { - struct EDBaseOffset *base_ofs = &sel_id_ctx->base_array_index_offsets[base_index]; - if (base_ofs->face > sel_id) { - elem_id = sel_id - base_ofs->face_start; - elem_type = SCE_SELECT_FACE; - break; - } - if (base_ofs->edge > sel_id) { - elem_id = sel_id - base_ofs->edge_start; - elem_type = SCE_SELECT_EDGE; - break; - } - if (base_ofs->vert > sel_id) { - elem_id = sel_id - base_ofs->vert_start; - elem_type = SCE_SELECT_VERTEX; - break; - } - - base_index++; - if (base_index >= sel_id_ctx->bases_len) { - return false; - } - } - - *r_elem = elem_id; - - if (r_base_index) { - *r_base_index = base_index; - } - - if (r_elem_type) { - *r_elem_type = elem_type; - } - - return true; -} - -/** \} */ - /* -------------------------------------------------------------------- */ /** \name Public Utilities * \{ */ @@ -385,7 +199,6 @@ static bool object_deselect_all_except(ViewLayer *view_layer, Base *b) struct EditSelectBuf_Cache { Base **bases; uint bases_len; - struct EDSelectID_Context *sel_id_ctx; BLI_bitmap *select_bitmap; }; @@ -407,8 +220,12 @@ static void editselect_buf_cache_init(struct EditSelectBuf_Cache *esel, ViewCont esel->bases_len = 0; } } - esel->sel_id_ctx = ED_view3d_select_id_context_create( - vc, esel->bases, esel->bases_len, vc->scene->toolsettings->selectmode); + DRW_draw_select_id(vc->depsgraph, + vc->ar, + vc->v3d, + esel->bases, + esel->bases_len, + vc->scene->toolsettings->selectmode); for (int i = 0; i < esel->bases_len; i++) { esel->bases[i]->object->runtime.select_id = i; } @@ -416,9 +233,6 @@ static void editselect_buf_cache_init(struct EditSelectBuf_Cache *esel, ViewCont static void editselect_buf_cache_free(struct EditSelectBuf_Cache *esel) { - if (esel->sel_id_ctx) { - ED_view3d_select_id_context_destroy(esel->sel_id_ctx); - } MEM_SAFE_FREE(esel->select_bitmap); MEM_SAFE_FREE(esel->bases); } @@ -455,8 +269,7 @@ static bool edbm_backbuf_check_and_select_verts(struct EditSelectBuf_Cache *esel bool changed = false; const BLI_bitmap *select_bitmap = esel->select_bitmap; - uint index = ED_view3d_select_id_context_offset_for_object_elem( - esel->sel_id_ctx, ob->runtime.select_id, SCE_SELECT_VERTEX); + uint index = DRW_select_context_offset_for_object_elem(ob->runtime.select_id, SCE_SELECT_VERTEX); BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { @@ -483,8 +296,7 @@ static bool edbm_backbuf_check_and_select_edges(struct EditSelectBuf_Cache *esel bool changed = false; const BLI_bitmap *select_bitmap = esel->select_bitmap; - uint index = ED_view3d_select_id_context_offset_for_object_elem( - esel->sel_id_ctx, ob->runtime.select_id, SCE_SELECT_EDGE); + uint index = DRW_select_context_offset_for_object_elem(ob->runtime.select_id, SCE_SELECT_EDGE); BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { @@ -511,8 +323,7 @@ static bool edbm_backbuf_check_and_select_faces(struct EditSelectBuf_Cache *esel bool changed = false; const BLI_bitmap *select_bitmap = esel->select_bitmap; - uint index = ED_view3d_select_id_context_offset_for_object_elem( - esel->sel_id_ctx, ob->runtime.select_id, SCE_SELECT_FACE); + uint index = DRW_select_context_offset_for_object_elem(ob->runtime.select_id, SCE_SELECT_FACE); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { @@ -1017,7 +828,7 @@ static bool do_lasso_select_mesh(ViewContext *vc, if (wm_userdata->data == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc); esel = wm_userdata->data; - const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx); + const uint buffer_len = DRW_select_context_elem_len(); esel->select_bitmap = ED_select_buffer_bitmap_from_poly(buffer_len, mcords, moves, &rect); } } @@ -1036,10 +847,8 @@ static bool do_lasso_select_mesh(ViewContext *vc, struct LassoSelectUserData_ForMeshEdge data_for_edge = { .data = &data, .esel = use_zbuf ? esel : NULL, - .backbuf_offset = use_zbuf ? ED_view3d_select_id_context_offset_for_object_elem( - esel->sel_id_ctx, - vc->obedit->runtime.select_id, - SCE_SELECT_EDGE) : + .backbuf_offset = use_zbuf ? DRW_select_context_offset_for_object_elem( + vc->obedit->runtime.select_id, SCE_SELECT_EDGE) : 0, }; mesh_foreachScreenEdge( @@ -1327,7 +1136,7 @@ static bool do_lasso_select_paintvert(ViewContext *vc, if (wm_userdata->data == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc); esel = wm_userdata->data; - const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx); + const uint buffer_len = DRW_select_context_elem_len(); esel->select_bitmap = ED_select_buffer_bitmap_from_poly(buffer_len, mcords, moves, &rect); } } @@ -1386,7 +1195,7 @@ static bool do_lasso_select_paintface(ViewContext *vc, if (esel == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc); esel = wm_userdata->data; - const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx); + const uint buffer_len = DRW_select_context_elem_len(); esel->select_bitmap = ED_select_buffer_bitmap_from_poly(buffer_len, mcords, moves, &rect); } @@ -2742,7 +2551,7 @@ static bool do_paintvert_box_select(ViewContext *vc, if (wm_userdata->data == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc); esel = wm_userdata->data; - const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx); + const uint buffer_len = DRW_select_context_elem_len(); esel->select_bitmap = ED_select_buffer_bitmap_from_rect(buffer_len, rect); } if (esel->select_bitmap != NULL) { @@ -2797,7 +2606,7 @@ static bool do_paintface_box_select(ViewContext *vc, if (wm_userdata->data == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc); esel = wm_userdata->data; - const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx); + const uint buffer_len = DRW_select_context_elem_len(); esel->select_bitmap = ED_select_buffer_bitmap_from_rect(buffer_len, rect); } if (esel->select_bitmap != NULL) { @@ -2995,7 +2804,7 @@ static bool do_mesh_box_select(ViewContext *vc, if (wm_userdata->data == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc); esel = wm_userdata->data; - const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx); + const uint buffer_len = DRW_select_context_elem_len(); esel->select_bitmap = ED_select_buffer_bitmap_from_rect(buffer_len, rect); } } @@ -3014,10 +2823,8 @@ static bool do_mesh_box_select(ViewContext *vc, struct BoxSelectUserData_ForMeshEdge cb_data = { .data = &data, .esel = use_zbuf ? esel : NULL, - .backbuf_offset = use_zbuf ? ED_view3d_select_id_context_offset_for_object_elem( - esel->sel_id_ctx, - vc->obedit->runtime.select_id, - SCE_SELECT_EDGE) : + .backbuf_offset = use_zbuf ? DRW_select_context_offset_for_object_elem( + vc->obedit->runtime.select_id, SCE_SELECT_EDGE) : 0, }; mesh_foreachScreenEdge( @@ -3582,8 +3389,7 @@ static bool mesh_circle_select(ViewContext *vc, struct EditSelectBuf_Cache *esel = wm_userdata->data; if (use_zbuf) { - ED_view3d_select_id_validate_view_matrices(esel->sel_id_ctx, vc); - const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx); + const uint buffer_len = DRW_select_context_elem_len(); esel->select_bitmap = ED_select_buffer_bitmap_from_circle(buffer_len, mval, (int)(rad + 1.0f)); } @@ -3660,7 +3466,7 @@ static bool paint_facesel_circle_select(ViewContext *vc, { struct EditSelectBuf_Cache *esel = wm_userdata->data; - const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx); + const uint buffer_len = DRW_select_context_elem_len(); esel->select_bitmap = ED_select_buffer_bitmap_from_circle(buffer_len, mval, (int)(rad + 1.0f)); if (esel->select_bitmap != NULL) { changed |= edbm_backbuf_check_and_select_faces_obmode(me, esel, sel_op); @@ -3715,7 +3521,7 @@ static bool paint_vertsel_circle_select(ViewContext *vc, if (use_zbuf) { struct EditSelectBuf_Cache *esel = wm_userdata->data; - const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx); + const uint buffer_len = DRW_select_context_elem_len(); esel->select_bitmap = ED_select_buffer_bitmap_from_circle(buffer_len, mval, (int)(rad + 1.0f)); if (esel->select_bitmap != NULL) { changed |= edbm_backbuf_check_and_select_verts_obmode(me, esel, sel_op); diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index f30eff1484b..c620644a5f8 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -221,9 +221,6 @@ data_to_c_simple(shaders/gpu_shader_2D_edituvs_edges_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_2D_edituvs_faces_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_2D_edituvs_stretch_vert.glsl SRC) -data_to_c_simple(shaders/gpu_shader_3D_selection_id_vert.glsl SRC) -data_to_c_simple(shaders/gpu_shader_selection_id_frag.glsl SRC) - data_to_c_simple(shaders/gpu_shader_text_simple_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_text_simple_geom.glsl SRC) data_to_c_simple(shaders/gpu_shader_text_vert.glsl SRC) diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index cae2392e503..124f1f1ff8a 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -355,11 +355,8 @@ typedef enum eGPUBuiltinShader { GPU_SHADER_2D_UV_FACES, GPU_SHADER_2D_UV_FACES_STRETCH_AREA, GPU_SHADER_2D_UV_FACES_STRETCH_ANGLE, - /* Selection */ - GPU_SHADER_3D_FLAT_SELECT_ID, - GPU_SHADER_3D_UNIFORM_SELECT_ID, } eGPUBuiltinShader; -#define GPU_SHADER_BUILTIN_LEN (GPU_SHADER_3D_UNIFORM_SELECT_ID + 1) +#define GPU_SHADER_BUILTIN_LEN (GPU_SHADER_2D_UV_FACES_STRETCH_ANGLE + 1) /** Support multiple configurations. */ typedef enum eGPUShaderConfig { diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index c142d8ccba2..3e930d19696 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -139,9 +139,6 @@ extern char datatoc_gpu_shader_2D_edituvs_edges_vert_glsl[]; extern char datatoc_gpu_shader_2D_edituvs_faces_vert_glsl[]; extern char datatoc_gpu_shader_2D_edituvs_stretch_vert_glsl[]; -extern char datatoc_gpu_shader_3D_selection_id_vert_glsl[]; -extern char datatoc_gpu_shader_selection_id_frag_glsl[]; - extern char datatoc_gpu_shader_2D_line_dashed_uniform_color_vert_glsl[]; extern char datatoc_gpu_shader_2D_line_dashed_frag_glsl[]; extern char datatoc_gpu_shader_2D_line_dashed_geom_glsl[]; @@ -1312,18 +1309,6 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = { .defs = "#define STRETCH_ANGLE\n", }, - [GPU_SHADER_3D_FLAT_SELECT_ID] = - { - .vert = datatoc_gpu_shader_3D_selection_id_vert_glsl, - .frag = datatoc_gpu_shader_selection_id_frag_glsl, - }, - [GPU_SHADER_3D_UNIFORM_SELECT_ID] = - { - .vert = datatoc_gpu_shader_3D_selection_id_vert_glsl, - .frag = datatoc_gpu_shader_selection_id_frag_glsl, - .defs = "#define UNIFORM_ID\n", - }, - [GPU_SHADER_GPENCIL_STROKE] = { .vert = datatoc_gpu_shader_gpencil_stroke_vert_glsl, @@ -1370,9 +1355,7 @@ GPUShader *GPU_shader_get_builtin_shader_with_config(eGPUBuiltinShader shader, GPU_SHADER_3D_GROUNDLINE, GPU_SHADER_3D_GROUNDPOINT, GPU_SHADER_DISTANCE_LINES, - GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR, - GPU_SHADER_3D_FLAT_SELECT_ID, - GPU_SHADER_3D_UNIFORM_SELECT_ID) || + GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR) || ELEM(shader, GPU_SHADER_3D_FLAT_COLOR, GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR, diff --git a/source/blender/gpu/shaders/gpu_shader_3D_selection_id_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_selection_id_vert.glsl deleted file mode 100644 index 0d58909efd8..00000000000 --- a/source/blender/gpu/shaders/gpu_shader_3D_selection_id_vert.glsl +++ /dev/null @@ -1,26 +0,0 @@ - -uniform mat4 ModelViewProjectionMatrix; - -in vec3 pos; - -#ifndef UNIFORM_ID -uniform uint offset; -in uint color; - -flat out uint id; -#endif - -void main() -{ -#ifndef UNIFORM_ID - id = offset + color; -#endif - - 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 -} diff --git a/source/blender/gpu/shaders/gpu_shader_selection_id_frag.glsl b/source/blender/gpu/shaders/gpu_shader_selection_id_frag.glsl deleted file mode 100644 index 1f22b9cb0b4..00000000000 --- a/source/blender/gpu/shaders/gpu_shader_selection_id_frag.glsl +++ /dev/null @@ -1,13 +0,0 @@ - -#ifdef UNIFORM_ID -uniform uint id; -#else -flat in uint id; -#endif - -out uint fragColor; - -void main() -{ - fragColor = id; -} -- cgit v1.2.3