diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-12-17 23:24:43 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-12-18 04:19:52 +0300 |
commit | 6a1315d6e72689907207a1202b6372402ace59af (patch) | |
tree | 8938905d8d8d8e43cbb6ff0f7341873183d46e58 | |
parent | 4fceaf3848b6ff926a8f0ffdb8f5a7b1537da57b (diff) |
Weight Paint Overlay: Refactor wire drawing
This reduce the number of batch/data needed. Stores a select/visiblee
flag inside the vert/loop normals.
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 16 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.h | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl.h | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 95 | ||||
-rw-r--r-- | source/blender/draw/modes/paint_texture_mode.c | 1 | ||||
-rw-r--r-- | source/blender/draw/modes/paint_weight_mode.c | 16 | ||||
-rw-r--r-- | source/blender/draw/modes/shaders/paint_vert_frag.glsl | 8 | ||||
-rw-r--r-- | source/blender/draw/modes/shaders/paint_wire_frag.glsl | 21 | ||||
-rw-r--r-- | source/blender/draw/modes/shaders/paint_wire_vert.glsl | 23 |
9 files changed, 60 insertions, 123 deletions
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index d5c99e149f9..c30362a044e 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -2992,22 +2992,6 @@ GPUBatch *DRW_cache_single_vert_get(void) /** \name Meshes * \{ */ -GPUBatch *DRW_cache_mesh_surface_overlay_get(Object *ob) -{ - BLI_assert(ob->type == OB_MESH); - Mesh *me = ob->data; - return DRW_mesh_batch_cache_get_all_triangles(me); -} - -GPUBatch *DRW_cache_face_centers_get(Object *ob) -{ - BLI_assert(ob->type == OB_MESH); - - Mesh *me = ob->data; - - return DRW_mesh_batch_cache_get_edit_facedots(me); -} - GPUBatch *DRW_cache_mesh_wire_outline_get(Object *ob) { BLI_assert(ob->type == OB_MESH); diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index f503c0de76d..a4beb84f1f1 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -124,8 +124,6 @@ struct GPUBatch *DRW_cache_bone_dof_sphere_get(void); struct GPUBatch *DRW_cache_bone_dof_lines_get(void); /* Meshes */ -struct GPUBatch *DRW_cache_mesh_surface_overlay_get(struct Object *ob); -struct GPUBatch *DRW_cache_face_centers_get(struct Object *ob); struct GPUBatch *DRW_cache_mesh_wire_outline_get(struct Object *ob); struct GPUBatch *DRW_cache_mesh_edge_detection_get(struct Object *ob, bool *r_is_manifold); struct GPUBatch *DRW_cache_mesh_surface_get(struct Object *ob); diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index ffaa99b9d4e..b5aa31f95a6 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -130,7 +130,6 @@ struct GPUBatch *DRW_mesh_batch_cache_get_wire_loops(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_faces(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_verts(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_all_edges(struct Mesh *me); -struct GPUBatch *DRW_mesh_batch_cache_get_all_triangles(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(struct Mesh *me, const struct DRW_MeshWeightState *wstate); struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(struct Mesh *me); diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index c0d71fe4c36..1d3b04b510c 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -53,6 +53,7 @@ #include "BKE_mesh.h" #include "BKE_mesh_tangent.h" #include "BKE_mesh_runtime.h" +#include "BKE_object.h" #include "BKE_colorband.h" #include "BKE_cdderivedmesh.h" @@ -3345,7 +3346,7 @@ static void mesh_create_pos_and_nor(MeshRenderData *rdata, GPUVertBuf *vbo) static struct { uint pos, nor; } attr_id; if (format.attr_len == 0) { attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); + attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I10, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); } GPU_vertbuf_init_with_format(vbo, &format); @@ -3359,19 +3360,22 @@ static void mesh_create_pos_and_nor(MeshRenderData *rdata, GPUVertBuf *vbo) BMVert *eve; uint i; - BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { - static short no_short[4]; - normal_float_to_short_v3(no_short, eve->no); + mesh_render_data_ensure_vert_normals_pack(rdata); + GPUPackedNormal *vnor = rdata->vert_normals_pack; + BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { GPU_vertbuf_attr_set(vbo, attr_id.pos, i, eve->co); - GPU_vertbuf_attr_set(vbo, attr_id.nor, i, no_short); + GPU_vertbuf_attr_set(vbo, attr_id.nor, i, &vnor[i]); } BLI_assert(i == vbo_len_capacity); } else { for (int i = 0; i < vbo_len_capacity; i++) { + const MVert *mv = &rdata->mvert[i]; + GPUPackedNormal vnor_pack = GPU_normal_convert_i10_s3(mv->no); + vnor_pack.w = (mv->flag & ME_HIDE) ? -1 : ((mv->flag & SELECT) ? 1 : 0); GPU_vertbuf_attr_set(vbo, attr_id.pos, i, rdata->mvert[i].co); - GPU_vertbuf_attr_set(vbo, attr_id.nor, i, rdata->mvert[i].no); + GPU_vertbuf_attr_set(vbo, attr_id.nor, i, &vnor_pack); } } } @@ -3382,8 +3386,10 @@ static void mesh_create_pos_and_nor(MeshRenderData *rdata, GPUVertBuf *vbo) const int v_orig = v_origindex[i]; if (v_orig != ORIGINDEX_NONE) { const MVert *mv = &mvert[i]; + GPUPackedNormal vnor_pack = GPU_normal_convert_i10_s3(mv->no); + vnor_pack.w = (mv->flag & ME_HIDE) ? -1 : ((mv->flag & SELECT) ? 1 : 0); GPU_vertbuf_attr_set(vbo, attr_id.pos, i, mv->co); - GPU_vertbuf_attr_set(vbo, attr_id.nor, i, mv->no); + GPU_vertbuf_attr_set(vbo, attr_id.nor, i, &vnor_pack); } } } @@ -3471,7 +3477,7 @@ static void mesh_create_loop_pos_and_nor(MeshRenderData *rdata, GPUVertBuf *vbo, *pnor = GPU_normal_convert_i10_s3(mvert[mloop->v].no); } if (use_face_sel) { - pnor->w = (mpoly->flag & ME_FACE_SEL) ? 1 : 0; + pnor->w = (mpoly->flag & ME_HIDE) ? -1 : ((mpoly->flag & ME_FACE_SEL) ? 1 : 0); } } } @@ -4297,42 +4303,6 @@ static void mesh_create_wireframe_data_tess(MeshRenderData *rdata, GPUVertBuf *v MEM_freeN(adj_data); } -static GPUIndexBuf *mesh_batch_cache_get_triangles_in_order(MeshRenderData *rdata, MeshBatchCache *cache) -{ - BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI)); - - if (cache->triangles_in_order == NULL) { - const int vert_len = mesh_render_data_verts_len_get(rdata); - const int tri_len = mesh_render_data_looptri_len_get(rdata); - - GPUIndexBufBuilder elb; - GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tri_len, vert_len); - - if (rdata->edit_bmesh) { - for (int i = 0; i < tri_len; i++) { - const BMLoop **ltri = (const BMLoop **)rdata->edit_bmesh->looptris[i]; - if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) { - for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { - GPU_indexbuf_add_generic_vert(&elb, BM_elem_index_get(ltri[tri_corner]->v)); - } - } - } - } - else { - for (int i = 0; i < tri_len; i++) { - const MLoopTri *mlt = &rdata->mlooptri[i]; - for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { - GPU_indexbuf_add_generic_vert(&elb, mlt->tri[tri_corner]); - } - } - } - cache->triangles_in_order = GPU_indexbuf_build(&elb); - } - - return cache->triangles_in_order; -} - - static GPUIndexBuf *mesh_batch_cache_get_loose_edges(MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI)); @@ -4575,6 +4545,12 @@ static GPUVertBuf *mesh_create_vert_pos_with_overlay_data( /** \name Public API * \{ */ +GPUBatch *DRW_mesh_batch_cache_get_all_verts(Mesh *me) +{ + MeshBatchCache *cache = mesh_batch_cache_get(me); + return DRW_batch_request(&cache->batch.all_verts); +} + GPUBatch *DRW_mesh_batch_cache_get_all_edges(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -4594,25 +4570,6 @@ GPUBatch *DRW_mesh_batch_cache_get_all_edges(Mesh *me) return cache->all_edges; } -GPUBatch *DRW_mesh_batch_cache_get_all_triangles(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - - if (cache->all_triangles == NULL) { - /* create batch from DM */ - const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI; - MeshRenderData *rdata = mesh_render_data_create(me, datatype); - - cache->all_triangles = GPU_batch_create( - GPU_PRIM_TRIS, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), - mesh_batch_cache_get_triangles_in_order(rdata, cache)); - - mesh_render_data_free(rdata); - } - - return cache->all_triangles; -} - GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -4764,12 +4721,6 @@ GPUBatch *DRW_mesh_batch_cache_get_points_with_normals(Mesh *me) return cache->points_with_normals; } -GPUBatch *DRW_mesh_batch_cache_get_all_verts(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - return DRW_batch_request(&cache->batch.all_verts); -} - GPUBatch *DRW_mesh_batch_cache_get_fancy_edges(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -5611,11 +5562,13 @@ void DRW_mesh_batch_cache_create_requested(Object *ob, Mesh *me) { const DRWContextState *draw_ctx = DRW_context_state_get(); const int mode = CTX_data_mode_enum_ex(draw_ctx->object_edit, draw_ctx->obact, draw_ctx->object_mode); - const bool use_hide = false; /* TODO */ + const bool is_paint_mode = ELEM(mode, CTX_MODE_PAINT_TEXTURE, CTX_MODE_PAINT_VERTEX, CTX_MODE_PAINT_WEIGHT); + const bool use_hide = (ob->type == OB_MESH) && ((is_paint_mode && (ob == draw_ctx->obact)) || + ((mode == CTX_MODE_EDIT_MESH) && BKE_object_is_in_editmode(ob))); bool use_face_sel = false; /* Tex paint face select */ - if ((mode == CTX_MODE_PAINT_TEXTURE) && (ob->type == OB_MESH) && (draw_ctx->obact == ob)) { + if (is_paint_mode && (ob->type == OB_MESH) && (draw_ctx->obact == ob)) { const Mesh *me_orig = DEG_get_original_object(ob)->data; use_face_sel = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; } diff --git a/source/blender/draw/modes/paint_texture_mode.c b/source/blender/draw/modes/paint_texture_mode.c index 8fb854efd0d..985ab5455e3 100644 --- a/source/blender/draw/modes/paint_texture_mode.c +++ b/source/blender/draw/modes/paint_texture_mode.c @@ -351,6 +351,7 @@ static void PAINT_TEXTURE_engine_free(void) { DRW_SHADER_FREE_SAFE(e_data.image_sh); DRW_SHADER_FREE_SAFE(e_data.wire_overlay_shader); + DRW_SHADER_FREE_SAFE(e_data.face_overlay_shader); } static const DrawEngineDataSize PAINT_TEXTURE_data_size = DRW_VIEWPORT_DATA_SIZE(PAINT_TEXTURE_Data); diff --git a/source/blender/draw/modes/paint_weight_mode.c b/source/blender/draw/modes/paint_weight_mode.c index c050df43e24..ac04af728dd 100644 --- a/source/blender/draw/modes/paint_weight_mode.c +++ b/source/blender/draw/modes/paint_weight_mode.c @@ -45,6 +45,7 @@ extern struct GlobalsUboStorage ts; /* draw_common.c */ extern struct GPUTexture *globals_weight_ramp; /* draw_common.c */ +extern char datatoc_paint_face_vert_glsl[]; extern char datatoc_paint_weight_vert_glsl[]; extern char datatoc_paint_weight_frag_glsl[]; extern char datatoc_paint_wire_vert_glsl[]; @@ -52,6 +53,8 @@ extern char datatoc_paint_wire_frag_glsl[]; extern char datatoc_paint_vert_frag_glsl[]; extern char datatoc_common_globals_lib_glsl[]; +extern char datatoc_gpu_shader_uniform_color_frag_glsl[]; + /* *********** LISTS *********** */ typedef struct PAINT_WEIGHT_PassList { @@ -109,7 +112,9 @@ static void PAINT_WEIGHT_engine_init(void *UNUSED(vedata)) } if (!e_data.face_overlay_shader) { - e_data.face_overlay_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); + e_data.face_overlay_shader = DRW_shader_create( + datatoc_paint_face_vert_glsl, NULL, + datatoc_gpu_shader_uniform_color_frag_glsl, NULL); } if (!e_data.vert_overlay_shader) { @@ -150,7 +155,7 @@ static void PAINT_WEIGHT_cache_init(void *vedata) { psl->wire_overlay = DRW_pass_create( "Wire Pass", - DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL); + DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_OFFSET_NEGATIVE); stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay); DRW_shgroup_uniform_block(stl->g_data->lwire_shgrp, "globalsBlock", globals_ubo); @@ -170,7 +175,7 @@ static void PAINT_WEIGHT_cache_init(void *vedata) { psl->vert_overlay = DRW_pass_create( "Vert Mask Pass", - DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL); + DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_OFFSET_NEGATIVE); stl->g_data->vert_shgrp = DRW_shgroup_create(e_data.vert_overlay_shader, psl->vert_overlay); DRW_shgroup_uniform_block(stl->g_data->vert_shgrp, "globalsBlock", globals_ubo); @@ -202,12 +207,12 @@ static void PAINT_WEIGHT_cache_populate(void *vedata, Object *ob) } if (use_face_sel) { - geom = DRW_cache_mesh_faces_weight_overlay_get(ob); + geom = DRW_cache_mesh_surface_get(ob); DRW_shgroup_call_add(stl->g_data->face_shgrp, geom, ob->obmat); } if (use_vert_sel) { - geom = DRW_cache_mesh_verts_weight_overlay_get(ob); + geom = DRW_cache_mesh_verts_get(ob); DRW_shgroup_call_add(stl->g_data->vert_shgrp, geom, ob->obmat); } } @@ -228,6 +233,7 @@ static void PAINT_WEIGHT_engine_free(void) DRW_SHADER_FREE_SAFE(e_data.weight_face_shader); DRW_SHADER_FREE_SAFE(e_data.wire_overlay_shader); DRW_SHADER_FREE_SAFE(e_data.vert_overlay_shader); + DRW_SHADER_FREE_SAFE(e_data.face_overlay_shader); } static const DrawEngineDataSize PAINT_WEIGHT_data_size = DRW_VIEWPORT_DATA_SIZE(PAINT_WEIGHT_Data); diff --git a/source/blender/draw/modes/shaders/paint_vert_frag.glsl b/source/blender/draw/modes/shaders/paint_vert_frag.glsl index 5ea8c11ff9a..d7f604d5c2c 100644 --- a/source/blender/draw/modes/shaders/paint_vert_frag.glsl +++ b/source/blender/draw/modes/shaders/paint_vert_frag.glsl @@ -1,5 +1,5 @@ -flat in int finalFlag; +flat in vec4 finalColor; out vec4 fragColor; #define VERTEX_SELECTED (1 << 0) @@ -7,10 +7,6 @@ out vec4 fragColor; void main() { - if (bool(finalFlag & VERTEX_HIDE)) { - discard; - } - vec2 centered = gl_PointCoord - vec2(0.5); float dist_squared = dot(centered, centered); const float rad_squared = 0.25; @@ -22,5 +18,5 @@ void main() discard; } - fragColor = bool(finalFlag & VERTEX_SELECTED) ? colSel : colUnsel; + fragColor = finalColor; } diff --git a/source/blender/draw/modes/shaders/paint_wire_frag.glsl b/source/blender/draw/modes/shaders/paint_wire_frag.glsl index c5d6198fc21..d738ed5ddb2 100644 --- a/source/blender/draw/modes/shaders/paint_wire_frag.glsl +++ b/source/blender/draw/modes/shaders/paint_wire_frag.glsl @@ -1,25 +1,8 @@ -flat in int finalFlag; +flat in vec4 finalColor; out vec4 fragColor; -#define VERTEX_SELECTED (1 << 0) -#define VERTEX_HIDE (1 << 4) - void main() { - if (bool(finalFlag & VERTEX_HIDE)) { - discard; - } - - /* Apply depth offset by taking slope and distance into account. */ - gl_FragDepth = gl_FragCoord.z - mix(exp2(-10), exp2(-23), gl_FragCoord.z) - 2.0 * fwidth(gl_FragCoord.z); - -#ifdef VERTEX_MODE - vec4 colSel = colorEdgeSelect; - colSel.rgb = clamp(colSel.rgb - 0.2, 0.0, 1.0); -#else - const vec4 colSel = vec4(1.0, 1.0, 1.0, 1.0); -#endif - - fragColor = bool(finalFlag & VERTEX_SELECTED) ? colSel : colorWire; + fragColor = finalColor; } diff --git a/source/blender/draw/modes/shaders/paint_wire_vert.glsl b/source/blender/draw/modes/shaders/paint_wire_vert.glsl index 253c21745e2..a92591b957d 100644 --- a/source/blender/draw/modes/shaders/paint_wire_vert.glsl +++ b/source/blender/draw/modes/shaders/paint_wire_vert.glsl @@ -2,13 +2,30 @@ uniform mat4 ModelViewProjectionMatrix; in vec3 pos; -in int data; +in vec4 nor; /* flag stored in w */ -flat out int finalFlag; +flat out vec4 finalColor; void main() { + bool is_select = (nor.w > 0.0); + bool is_hidden = (nor.w < 0.0); gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + /* Add offset in Z to avoid zfighting and render selected wires on top. */ + /* TODO scale this bias using znear and zfar range. */ + gl_Position.zw -= exp2(-20) * (is_select ? 2.0 : 1.0); - finalFlag = data; + if (is_hidden) { + gl_Position = vec4(-2.0, -2.0, -2.0, 1.0); + } + +#ifdef VERTEX_MODE + vec4 colSel = colorEdgeSelect; + colSel.rgb = clamp(colSel.rgb - 0.2, 0.0, 1.0); +#else + const vec4 colSel = vec4(1.0, 1.0, 1.0, 1.0); +#endif + + finalColor = (is_select) ? colSel : colorWire; + finalColor.a = nor.w; } |