diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-05-04 22:17:31 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-05-04 22:17:31 +0300 |
commit | 4bd2429f3519a58ccd1f93200dae42e52c45956e (patch) | |
tree | 90370ccbb2029ae2850fcc09bfbb43167a76e2cc /source | |
parent | 9869436b89449a346fac07ca8061221ce8d4ce7e (diff) |
Use mesh draw cache for back-buffer selection
Vertex/weight paint now work with core profile, resolves T51380.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl.h | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 136 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 16 | ||||
-rw-r--r-- | source/blender/gpu/GPU_shader.h | 1 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_shader.c | 26 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_3D_flat_color_vert.glsl | 17 |
6 files changed, 192 insertions, 5 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index 9216e05604e..bbb1c820f63 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -76,6 +76,7 @@ struct Batch *DRW_mesh_batch_cache_get_all_triangles(struct Mesh *me); struct Batch *DRW_mesh_batch_cache_get_triangles_with_normals(struct Mesh *me); struct Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(struct Mesh *me, int defgroup); struct Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(struct Mesh *me); +struct Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide); struct Batch *DRW_mesh_batch_cache_get_points_with_normals(struct Mesh *me); struct Batch *DRW_mesh_batch_cache_get_all_verts(struct Mesh *me); struct Batch *DRW_mesh_batch_cache_get_fancy_edges(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 a5bd33137b8..cf43f1ec002 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -49,6 +49,7 @@ #include "bmesh.h" #include "GPU_batch.h" +#include "GPU_draw.h" #include "UI_resources.h" @@ -1274,6 +1275,58 @@ static bool mesh_render_data_looptri_cos_vert_colors_get( return true; } +static bool mesh_render_data_looptri_cos_select_id_get( + MeshRenderData *rdata, const int tri_idx, const bool use_hide, + float *(*r_vert_cos)[3], + short **r_tri_nor, int *r_select_id) +{ + BLI_assert( + rdata->types & + (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_DVERT)); + + if (rdata->edit_bmesh) { + const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[tri_idx]; + const int poly_index = BM_elem_index_get(bm_looptri[0]->f); + + if (use_hide && BM_elem_flag_test(bm_looptri[0]->f, BM_ELEM_HIDDEN)) { + return false; + } + + mesh_render_data_ensure_poly_normals_short(rdata); + + short (*pnors_short)[3] = rdata->poly_normals_short; + + + (*r_vert_cos)[0] = bm_looptri[0]->v->co; + (*r_vert_cos)[1] = bm_looptri[1]->v->co; + (*r_vert_cos)[2] = bm_looptri[2]->v->co; + *r_tri_nor = pnors_short[poly_index]; + + GPU_select_index_get(poly_index + 1, r_select_id); + } + else { + const MLoopTri *mlt = &rdata->mlooptri[tri_idx]; + const int poly_index = mlt->poly; + + if (use_hide && (rdata->mpoly[poly_index].flag & ME_HIDE)) { + return false; + } + + mesh_render_data_ensure_poly_normals_short(rdata); + + short (*pnors_short)[3] = rdata->poly_normals_short; + + (*r_vert_cos)[0] = rdata->mvert[rdata->mloop[mlt->tri[0]].v].co; + (*r_vert_cos)[1] = rdata->mvert[rdata->mloop[mlt->tri[1]].v].co; + (*r_vert_cos)[2] = rdata->mvert[rdata->mloop[mlt->tri[2]].v].co; + *r_tri_nor = pnors_short[poly_index]; + + GPU_select_index_get(poly_index + 1, r_select_id); + } + + return true; +} + static bool mesh_render_data_edge_cos_sel_get( MeshRenderData *rdata, const int edge_idx, float r_vert_cos[2][3], float r_vert_col[3], @@ -1587,9 +1640,11 @@ typedef struct MeshBatchCache { VertexBuffer *edge_pos_with_sel; VertexBuffer *tri_pos_with_sel; VertexBuffer *pos_with_sel; + VertexBuffer *pos_with_sel_id; Batch *triangles_with_normals; Batch *triangles_with_weights; Batch *triangles_with_vert_colors; + Batch *triangles_with_select_id; Batch *points_with_normals; Batch *fancy_edges; /* owns its vertex buffer (not shared) */ @@ -1754,6 +1809,8 @@ static void mesh_batch_cache_clear(Mesh *me) VERTEXBUFFER_DISCARD_SAFE(cache->pos_with_normals); BATCH_DISCARD_ALL_SAFE(cache->triangles_with_weights); BATCH_DISCARD_ALL_SAFE(cache->triangles_with_vert_colors); + VERTEXBUFFER_DISCARD_SAFE(cache->pos_with_sel_id); + BATCH_DISCARD_SAFE(cache->triangles_with_select_id); BATCH_DISCARD_ALL_SAFE(cache->fancy_edges); @@ -2135,6 +2192,66 @@ static VertexBuffer *mesh_batch_cache_get_pos_normals_and_vert_colors( return cache->pos_with_vert_colors; } +static VertexBuffer *mesh_batch_cache_get_pos_normals_and_select_id( + MeshRenderData *rdata, MeshBatchCache *cache, bool use_hide) +{ + BLI_assert( + rdata->types & + (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY)); + + if (cache->pos_with_sel_id == NULL) { + unsigned int vidx = 0, cidx = 0, nidx = 0; + + static VertexFormat format = { 0 }; + static unsigned int pos_id, col_id, nor_id; + if (format.attrib_ct == 0) { + /* initialize vertex format */ + pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT); + nor_id = VertexFormat_add_attrib(&format, "nor", COMP_I16, 3, NORMALIZE_INT_TO_FLOAT); + col_id = VertexFormat_add_attrib(&format, "color", COMP_I32, 1, KEEP_INT); + } + + const int tri_len = mesh_render_data_looptri_len_get(rdata); + + VertexBuffer *vbo = cache->pos_with_sel_id = VertexBuffer_create_with_format(&format); + + const int vbo_len_capacity = tri_len * 3; + int vbo_len_used = 0; + VertexBuffer_allocate_data(vbo, vbo_len_capacity); + + for (int i = 0; i < tri_len; i++) { + float *tri_vert_cos[3]; + short *tri_nor; + int select_id; + + if (mesh_render_data_looptri_cos_select_id_get( + rdata, i, use_hide, &tri_vert_cos, &tri_nor, &select_id)) + { + /* TODO, one elem per tri */ + VertexBuffer_set_attrib(vbo, col_id, cidx++, &select_id); + VertexBuffer_set_attrib(vbo, col_id, cidx++, &select_id); + VertexBuffer_set_attrib(vbo, col_id, cidx++, &select_id); + + VertexBuffer_set_attrib(vbo, pos_id, vidx++, tri_vert_cos[0]); + VertexBuffer_set_attrib(vbo, pos_id, vidx++, tri_vert_cos[1]); + VertexBuffer_set_attrib(vbo, pos_id, vidx++, tri_vert_cos[2]); + + /* TODO, one elem per tri */ + VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_nor); + VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_nor); + VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_nor); + } + } + vbo_len_used = vidx; + + if (vbo_len_capacity != vbo_len_used) { + VertexBuffer_resize_data(vbo, vbo_len_used); + } + } + + return cache->pos_with_sel_id; +} + static VertexBuffer *mesh_batch_cache_get_pos_and_nor_in_order(MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & MR_DATATYPE_VERT); @@ -2493,6 +2610,25 @@ Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(Mesh *me) return cache->triangles_with_vert_colors; } + +struct Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide) +{ + MeshBatchCache *cache = mesh_batch_cache_get(me); + + if (cache->triangles_with_select_id == NULL) { + const int datatype = + MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY; + MeshRenderData *rdata = mesh_render_data_create(me, datatype); + + cache->triangles_with_select_id = Batch_create( + PRIM_TRIANGLES, mesh_batch_cache_get_pos_normals_and_select_id(rdata, cache, use_hide), NULL); + + mesh_render_data_free(rdata); + } + + return cache->triangles_with_select_id; +} + Batch *DRW_mesh_batch_cache_get_points_with_normals(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 254a48fccbb..63b44e6daa3 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -9542,8 +9542,9 @@ static void bbs_mesh_solid_verts(Scene *scene, Object *ob) static void bbs_mesh_solid_faces(Scene *scene, Object *ob) { - DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask); Mesh *me = ob->data; +#if defined(WITH_LEGACY_OPENGL) + DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask); DM_update_materials(dm, ob); @@ -9553,6 +9554,19 @@ static void bbs_mesh_solid_faces(Scene *scene, Object *ob) dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, NULL, NULL, me, 0); dm->release(dm); +#else + UNUSED_VARS(scene, bbs_mesh_solid_hide__setDrawOpts, bbs_mesh_solid__setDrawOpts); + Batch *batch; + if ((me->editflag & ME_EDIT_PAINT_FACE_SEL)) { + batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true); + } + else { + batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, false); + } + Batch_set_builtin_program(batch, GPU_SHADER_3D_FLAT_COLOR_U32); + Batch_draw(batch); + +#endif } void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob) diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index d26218382c8..d6e3585b686 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -119,6 +119,7 @@ typedef enum GPUBuiltinShader { GPU_SHADER_3D_UNIFORM_COLOR, GPU_SHADER_3D_UNIFORM_COLOR_INSTANCE, GPU_SHADER_3D_FLAT_COLOR, + GPU_SHADER_3D_FLAT_COLOR_U32, /* use for select-id's */ GPU_SHADER_3D_SMOOTH_COLOR, GPU_SHADER_3D_DEPTH_ONLY, GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR, diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index d72d7f7c2b5..431bc4f5d43 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -702,6 +702,8 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) [GPU_SHADER_3D_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl }, [GPU_SHADER_3D_FLAT_COLOR] = { datatoc_gpu_shader_3D_flat_color_vert_glsl, datatoc_gpu_shader_flat_color_frag_glsl }, + [GPU_SHADER_3D_FLAT_COLOR_U32] = { datatoc_gpu_shader_3D_flat_color_vert_glsl, + datatoc_gpu_shader_flat_color_frag_glsl }, [GPU_SHADER_3D_SMOOTH_COLOR] = { datatoc_gpu_shader_3D_smooth_color_vert_glsl, datatoc_gpu_shader_3D_smooth_color_frag_glsl }, [GPU_SHADER_3D_DEPTH_ONLY] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_depth_only_frag_glsl }, @@ -781,10 +783,26 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) if (builtin_shaders[shader] == NULL) { /* just a few special cases */ - const char *defines = (shader == GPU_SHADER_SMOKE_COBA) ? "#define USE_COBA;\n" : - (shader == GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE) ? "#define UNIFORM_SCALE;\n" : - (shader == GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS) ? "#define AXIS_NAME;\n" : - (shader == GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR) ? "#define USE_INSTANCE_COLOR;\n" : NULL; + const char *defines = NULL; + switch (shader) { + case GPU_SHADER_SMOKE_COBA: + defines = "#define USE_COBA;\n"; + break; + case GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE: + defines = "#define UNIFORM_SCALE;\n"; + break; + case GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS: + defines = "#define AXIS_NAME;\n"; + break; + case GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR: + defines = "#define USE_INSTANCE_COLOR;\n"; + break; + case GPU_SHADER_3D_FLAT_COLOR_U32: + defines = "#define USE_COLOR_U32;\n"; + break; + default: + break; + } const GPUShaderStages *stages = builtin_shader_stages + shader; diff --git a/source/blender/gpu/shaders/gpu_shader_3D_flat_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_flat_color_vert.glsl index 8c241cff5d4..f65fbe2a2e2 100644 --- a/source/blender/gpu/shaders/gpu_shader_3D_flat_color_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_3D_flat_color_vert.glsl @@ -3,12 +3,20 @@ uniform mat4 ModelViewProjectionMatrix; #if __VERSION__ == 120 attribute vec3 pos; +#if defined(USE_COLOR_U32) + attribute int color; +#else attribute vec4 color; +#endif flat varying vec4 finalColor; #else in vec3 pos; +#if defined(USE_COLOR_U32) + in int color; +#else in vec4 color; +#endif flat out vec4 finalColor; #endif @@ -16,5 +24,14 @@ uniform mat4 ModelViewProjectionMatrix; void main() { gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + +#if defined(USE_COLOR_U32) + finalColor = vec4( + ((color ) & 0xFF) * (1.0f / 255.0f), + ((color >> 8) & 0xFF) * (1.0f / 255.0f), + ((color >> 16) & 0xFF) * (1.0f / 255.0f), + ((color >> 24) ) * (1.0f / 255.0f)); +#else finalColor = color; +#endif } |