diff options
Diffstat (limited to 'source/blender/editors/space_view3d/drawobject.c')
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 192 |
1 files changed, 99 insertions, 93 deletions
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 409f0300530..e6e0438164c 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1,6 +1,4 @@ /* - * ***** BEGIN GPL LICENSE BLOCK ***** - * * 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 @@ -17,14 +15,10 @@ * * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. - * - * Contributor(s): Blender Foundation, full recode and added functions - * - * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/editors/space_view3d/drawobject.c - * \ingroup spview3d +/** \file + * \ingroup spview3d */ #include "DNA_mesh_types.h" @@ -70,7 +64,7 @@ static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt) if ((sce->toolsettings->selectmode & SCE_SELECT_FACE) == 0) return false; - if (G.f & G_BACKBUFSEL) + if (G.f & G_FLAG_BACKBUFSEL) return false; /* if its drawing textures with zbuf sel, then don't draw dots */ @@ -80,7 +74,7 @@ static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt) return true; } -/* ----------------- OpenGL Circle Drawing - Tables for Optimized Drawing Speed ------------------ */ +/* OpenGL Circle Drawing - Tables for Optimized Drawing Speed */ /* 32 values of sin function (still same result!) */ #define CIRCLE_RESOL 32 @@ -116,7 +110,7 @@ static const float sinval[CIRCLE_RESOL] = { -0.57126821, -0.39435585, -0.20129852, - 0.00000000 + 0.00000000, }; /* 32 values of cos function (still same result!) */ @@ -152,7 +146,7 @@ static const float cosval[CIRCLE_RESOL] = { 0.82076344, 0.91895781, 0.97952994, - 1.00000000 + 1.00000000, }; static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, const float tmat[4][4]) @@ -163,7 +157,7 @@ static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3 mul_v3_v3fl(vx, tmat[0], rad); mul_v3_v3fl(vy, tmat[1], rad); - for (unsigned int a = 0; a < CIRCLE_RESOL; a++, viter += 3) { + for (uint a = 0; a < CIRCLE_RESOL; a++, viter += 3) { viter[0] = cent[0] + sinval[a] * vx[0] + cosval[a] * vy[0]; viter[1] = cent[1] + sinval[a] * vx[1] + cosval[a] * vy[1]; viter[2] = cent[2] + sinval[a] * vx[2] + cosval[a] * vy[2]; @@ -184,121 +178,107 @@ void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], un } #ifdef VIEW3D_CAMERA_BORDER_HACK -unsigned char view3d_camera_border_hack_col[3]; +uchar view3d_camera_border_hack_col[3]; bool view3d_camera_border_hack_test = false; #endif /* ***************** BACKBUF SEL (BBS) ********* */ -static void bbs_obmode_mesh_verts(Object *ob, 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]) { - Mesh *me = ob->data; - GPUBatch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset); - GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); - GPU_batch_draw(batch); + GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]); } -static void bbs_mesh_verts(BMEditMesh *em, int offset) +static void bbs_mesh_verts(GPUBatch *batch, int offset, const float world_clip_planes[6][4]) { GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE)); - Mesh *me = em->ob->data; - GPUBatch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset); - GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); + 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) { + bbs_world_clip_planes_from_rv3d(batch, world_clip_planes); + } GPU_batch_draw(batch); } -static void bbs_mesh_wire(BMEditMesh *em, 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); - Mesh *me = em->ob->data; - GPUBatch *batch = DRW_mesh_batch_cache_get_edges_with_select_id(me, offset); - GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); + 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) { + bbs_world_clip_planes_from_rv3d(batch, world_clip_planes); + } GPU_batch_draw(batch); + + glProvokingVertex(GL_LAST_VERTEX_CONVENTION); } -static void bbs_mesh_face(BMEditMesh *em, const bool use_select) +/* two options, facecolors or black */ +static void bbs_mesh_face(GPUBatch *batch, const bool use_select, const float world_clip_planes[6][4]) { - Mesh *me = em->ob->data; - GPUBatch *batch; - if (use_select) { - batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1); - GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); + 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", 1); + if (world_clip_planes != NULL) { + bbs_world_clip_planes_from_rv3d(batch, world_clip_planes); + } GPU_batch_draw(batch); } else { - int selcol; - GPU_select_index_get(0, &selcol); - batch = DRW_mesh_batch_cache_get_triangles_with_select_mask(me, true); - GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32); - GPU_batch_uniform_1ui(batch, "color", selcol); + 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) { + bbs_world_clip_planes_from_rv3d(batch, world_clip_planes); + } GPU_batch_draw(batch); } } -static void bbs_mesh_face_dot(BMEditMesh *em) -{ - Mesh *me = em->ob->data; - GPUBatch *batch = DRW_mesh_batch_cache_get_facedots_with_select_id(me, 1); - GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); - GPU_batch_draw(batch); -} - -/* two options, facecolors or black */ -static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d, - Object *ob, bool use_faceselect) +static void bbs_mesh_face_dot(GPUBatch *batch, const float world_clip_planes[6][4]) { - if (use_faceselect) { - bbs_mesh_face(em, true); - - if (check_ob_drawface_dot(scene, v3d, ob->dt)) { - bbs_mesh_face_dot(em); - } - } - else { - bbs_mesh_face(em, false); + 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", 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; - /* Only draw faces to mask out verts, we don't want their selection ID's. */ - const int G_f_orig = G.f; - G.f &= ~G_BACKBUFSEL; - - { - int selcol; - GPUBatch *batch; - GPU_select_index_get(0, &selcol); - batch = DRW_mesh_batch_cache_get_triangles_with_select_mask(me, true); - GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32); - GPU_batch_uniform_1ui(batch, "color", selcol); - GPU_batch_draw(batch); - } + GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me); + GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me); + DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true); - G.f |= (G_f_orig & G_BACKBUFSEL); + /* Only draw faces to mask out verts, we don't want their selection ID's. */ + bbs_mesh_face(geom_faces, false, world_clip_planes); + bbs_mesh_verts(geom_verts, 1, world_clip_planes); - bbs_obmode_mesh_verts(ob, 1); 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; - GPUBatch *batch; - if ((me_orig->editflag & ME_EDIT_PAINT_FACE_SEL)) { - batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1); - } - else { - batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, false, 1); - } - GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); - GPU_batch_draw(batch); + + const bool use_hide = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL); + 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, world_clip_planes); } void draw_object_backbufsel( @@ -311,19 +291,43 @@ void draw_object_backbufsel( } GPU_matrix_mul(ob->obmat); - - glClearDepth(1.0); GPU_clear(GPU_DEPTH_BIT); 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; + } + switch (ob->type) { case OB_MESH: if (ob->mode & OB_MODE_EDIT) { Mesh *me = ob->data; - BMEditMesh *em = me->edit_btmesh; + BMEditMesh *em = me->edit_mesh; + const bool draw_facedot = check_ob_drawface_dot(scene, v3d, ob->dt); + const bool use_faceselect = (select_mode & SCE_SELECT_FACE) != 0; BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE); - bbs_mesh_solid_EM(em, scene, v3d, ob, (select_mode & SCE_SELECT_FACE) != 0); + 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); + + bbs_mesh_face(geom_faces, use_faceselect, world_clip_planes); + + if (use_faceselect && draw_facedot) { + bbs_mesh_face_dot(geom_facedots, world_clip_planes); + } + if (select_mode & SCE_SELECT_FACE) bm_solidoffs = 1 + em->bm->totface; else { @@ -334,7 +338,7 @@ void draw_object_backbufsel( /* we draw edges if edge select mode */ if (select_mode & SCE_SELECT_EDGE) { - bbs_mesh_wire(em, bm_solidoffs); + bbs_mesh_wire(geom_edges, bm_solidoffs, world_clip_planes); bm_wireoffs = bm_solidoffs + em->bm->totedge; } else { @@ -342,9 +346,11 @@ void draw_object_backbufsel( bm_wireoffs = bm_solidoffs; } + ED_view3d_polygon_offset(rv3d, 1.1); + /* we draw verts if vert select mode. */ if (select_mode & SCE_SELECT_VERTEX) { - bbs_mesh_verts(em, bm_wireoffs); + bbs_mesh_verts(geom_verts, bm_wireoffs, world_clip_planes); bm_vertoffs = bm_wireoffs + em->bm->totvert; } else { @@ -354,15 +360,15 @@ void draw_object_backbufsel( ED_view3d_polygon_offset(rv3d, 0.0); } else { - Mesh *me = ob->data; + Mesh *me = DEG_get_original_object(ob)->data; if ((me->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))) { - 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; |