Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/intern/draw_manager.c
| Show All 28 Lines | |||||
| #include "BLI_string.h" | #include "BLI_string.h" | ||||
| #include "BLI_threads.h" | #include "BLI_threads.h" | ||||
| #include "BLF_api.h" | #include "BLF_api.h" | ||||
| #include "BKE_anim.h" | #include "BKE_anim.h" | ||||
| #include "BKE_colortools.h" | #include "BKE_colortools.h" | ||||
| #include "BKE_curve.h" | #include "BKE_curve.h" | ||||
| #include "BKE_editmesh.h" | |||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_gpencil.h" | #include "BKE_gpencil.h" | ||||
| #include "BKE_lattice.h" | #include "BKE_lattice.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_mball.h" | #include "BKE_mball.h" | ||||
| #include "BKE_mesh.h" | #include "BKE_mesh.h" | ||||
| #include "BKE_object.h" | #include "BKE_object.h" | ||||
| #include "BKE_particle.h" | #include "BKE_particle.h" | ||||
| ▲ Show 20 Lines • Show All 2,565 Lines • ▼ Show 20 Lines | #ifdef DEBUG | ||||
| /* Avoid accidental reuse. */ | /* Avoid accidental reuse. */ | ||||
| drw_state_ensure_not_reused(&DST); | drw_state_ensure_not_reused(&DST); | ||||
| #endif | #endif | ||||
| /* Changin context */ | /* Changin context */ | ||||
| DRW_opengl_context_disable(); | 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]) | |||||
| { | |||||
| GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]); | |||||
| } | |||||
| /** | /** | ||||
| * Clears the Depth Buffer and draws only the specified object. | * Clears the Depth Buffer and draws only the specified object. | ||||
| */ | */ | ||||
| void DRW_draw_depth_object(ARegion *ar, GPUViewport *viewport, Object *object) | void DRW_draw_depth_object(ARegion *ar, GPUViewport *viewport, Object *object) | ||||
| { | { | ||||
| RegionView3D *rv3d = ar->regiondata; | RegionView3D *rv3d = ar->regiondata; | ||||
| DRW_opengl_context_enable(); | DRW_opengl_context_enable(); | ||||
| Show All 27 Lines | case OB_MESH: { | ||||
| } | } | ||||
| DRW_mesh_batch_cache_create_requested(object, me, NULL, false, true); | DRW_mesh_batch_cache_create_requested(object, me, NULL, false, true); | ||||
| const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : | const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : | ||||
| GPU_SHADER_CFG_DEFAULT; | GPU_SHADER_CFG_DEFAULT; | ||||
| GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_DEPTH_ONLY, sh_cfg); | GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_DEPTH_ONLY, sh_cfg); | ||||
| if (world_clip_planes != NULL) { | if (world_clip_planes != NULL) { | ||||
| GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]); | draw_world_clip_planes_from_rv3d(batch, world_clip_planes); | ||||
| } | } | ||||
| GPU_batch_draw(batch); | GPU_batch_draw(batch); | ||||
| } break; | } break; | ||||
| case OB_CURVE: | case OB_CURVE: | ||||
| case OB_SURF: | case OB_SURF: | ||||
| break; | break; | ||||
| } | } | ||||
| if (rv3d->rflag & RV3D_CLIPPING) { | if (rv3d->rflag & RV3D_CLIPPING) { | ||||
| ED_view3d_clipping_disable(); | ED_view3d_clipping_disable(); | ||||
| } | } | ||||
| GPU_matrix_set(rv3d->viewmat); | GPU_matrix_set(rv3d->viewmat); | ||||
| GPU_depth_test(false); | GPU_depth_test(false); | ||||
| GPU_framebuffer_restore(); | GPU_framebuffer_restore(); | ||||
| DRW_opengl_context_disable(); | DRW_opengl_context_disable(); | ||||
| } | } | ||||
| static void draw_mesh_verts(GPUBatch *batch, int 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, int 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, | |||||
| int 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, int 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_solidoffs, | |||||
| uint *r_wireoffs, | |||||
| uint *r_vertoffs) | |||||
| { | |||||
| ToolSettings *ts = scene->toolsettings; | |||||
| if (select_mode == -1) { | |||||
| select_mode = ts->selectmode; | |||||
| } | |||||
| GPU_matrix_mul(ob->obmat); | |||||
| GPU_depth_test(true); | |||||
| 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; | |||||
| } | |||||
| initial_offset += 1; | |||||
| 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 (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_solidoffs = initial_offset + em->bm->totface; | |||||
| } | |||||
| else { | |||||
| *r_solidoffs = initial_offset; | |||||
| } | |||||
| ED_view3d_polygon_offset(rv3d, 1.0); | |||||
| /* we draw edges if edge select mode */ | |||||
| if (select_mode & SCE_SELECT_EDGE) { | |||||
| draw_mesh_edges(geom_edges, *r_solidoffs, world_clip_planes); | |||||
| *r_wireoffs = *r_solidoffs + em->bm->totedge; | |||||
| } | |||||
| else { | |||||
| /* `bm_vertoffs` is calculated from `bm_wireoffs`. (otherwise see T53512) */ | |||||
| *r_wireoffs = *r_solidoffs; | |||||
| } | |||||
| ED_view3d_polygon_offset(rv3d, 1.1); | |||||
| /* we draw verts if vert select mode. */ | |||||
| if (select_mode & SCE_SELECT_VERTEX) { | |||||
| draw_mesh_verts(geom_verts, *r_wireoffs, world_clip_planes); | |||||
| *r_vertoffs = *r_wireoffs + em->bm->totvert; | |||||
| } | |||||
| else { | |||||
| *r_vertoffs = *r_wireoffs; | |||||
| } | |||||
| 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_vertoffs = 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_solidoffs = initial_offset + me_eval->totface; | |||||
| } | |||||
| } | |||||
| 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. */ | /* 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) | void DRW_framebuffer_select_id_setup(ARegion *ar, const bool clear) | ||||
| { | { | ||||
| RegionView3D *rv3d = ar->regiondata; | RegionView3D *rv3d = ar->regiondata; | ||||
| DRW_opengl_context_enable(); | DRW_opengl_context_enable(); | ||||
| /* Setup framebuffer */ | /* Setup framebuffer */ | ||||
| ▲ Show 20 Lines • Show All 405 Lines • Show Last 20 Lines | |||||