diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-05-22 16:31:46 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-05-23 10:40:48 +0300 |
commit | f21c235c6fa6782dfc9c0ba7a66fa3c1005b2897 (patch) | |
tree | 2059c43758cfa26d15bd4fed1e9af29d332a1fe6 /source/blender/draw/intern | |
parent | 44f91a9a18d6d942d958e7640f4d1c301d230150 (diff) |
DwM: texture paint support & mask mode
Uses workaround so material slots are used when neither blender-internal
or cycles are enabled.
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 17 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.h | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl.h | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 116 |
4 files changed, 137 insertions, 0 deletions
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index a75b1434721..4ec4cc5bda8 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -2065,6 +2065,23 @@ Batch **DRW_cache_mesh_surface_shaded_get(Object *ob) return DRW_mesh_batch_cache_get_surface_shaded(me); } +/* Return list of batches */ +Batch **DRW_cache_mesh_surface_texpaint_get(Object *ob) +{ + BLI_assert(ob->type == OB_MESH); + + Mesh *me = ob->data; + return DRW_mesh_batch_cache_get_surface_texpaint(me); +} + +Batch *DRW_cache_mesh_surface_texpaint_single_get(Object *ob) +{ + BLI_assert(ob->type == OB_MESH); + + Mesh *me = ob->data; + return DRW_mesh_batch_cache_get_surface_texpaint_single(me); +} + Batch *DRW_cache_mesh_surface_verts_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 b440f9969b3..f2c140923a8 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -112,6 +112,8 @@ struct Batch *DRW_cache_mesh_edges_paint_overlay_get(struct Object *ob, bool use struct Batch *DRW_cache_mesh_faces_weight_overlay_get(struct Object *ob); struct Batch *DRW_cache_mesh_verts_weight_overlay_get(struct Object *ob); struct Batch **DRW_cache_mesh_surface_shaded_get(struct Object *ob); +struct Batch **DRW_cache_mesh_surface_texpaint_get(struct Object *ob); +struct Batch *DRW_cache_mesh_surface_texpaint_single_get(struct Object *ob); /* Curve */ struct Batch *DRW_cache_curve_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 812c873c153..bfb61199674 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -72,6 +72,8 @@ struct Batch *DRW_lattice_batch_cache_get_overlay_verts(struct Lattice *lt); /* Mesh */ struct Batch **DRW_mesh_batch_cache_get_surface_shaded(struct Mesh *me); +struct Batch **DRW_mesh_batch_cache_get_surface_texpaint(struct Mesh *me); +struct Batch *DRW_mesh_batch_cache_get_surface_texpaint_single(struct Mesh *me); struct Batch *DRW_mesh_batch_cache_get_weight_overlay_edges(struct Mesh *me, bool use_wire, bool use_sel); struct Batch *DRW_mesh_batch_cache_get_weight_overlay_faces(struct Mesh *me); struct Batch *DRW_mesh_batch_cache_get_weight_overlay_verts(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 a01e1d4beff..8286c2ea23a 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -130,6 +130,7 @@ typedef struct MeshRenderData { MPoly *mpoly; float (*orco)[3]; MDeformVert *dvert; + MLoopUV *mloopuv; MLoopCol *mloopcol; /* CustomData 'cd' cache for efficient access. */ @@ -200,6 +201,7 @@ enum { MR_DATATYPE_SHADING = 1 << 6, MR_DATATYPE_DVERT = 1 << 7, MR_DATATYPE_LOOPCOL = 1 << 8, + MR_DATATYPE_LOOPUV = 1 << 9, }; /** @@ -348,6 +350,10 @@ static MeshRenderData *mesh_render_data_create(Mesh *me, const int types) rdata->loop_len = me->totloop; rdata->mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL); } + if (types & MR_DATATYPE_LOOPUV) { + rdata->loop_len = me->totloop; + rdata->mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV); + } } if (types & MR_DATATYPE_SHADING) { @@ -1469,6 +1475,7 @@ typedef struct MeshBatchCache { VertexBuffer *tri_aligned_weights; VertexBuffer *tri_aligned_vert_colors; VertexBuffer *tri_aligned_select_id; + VertexBuffer *tri_aligned_uv; /* Active UV layer (mloopuv) */ VertexBuffer *edge_pos_with_select_bool; VertexBuffer *pos_with_select_bool; Batch *triangles_with_normals; @@ -1490,6 +1497,11 @@ typedef struct MeshBatchCache { ElementList **shaded_triangles_in_order; Batch **shaded_triangles; + /* Texture Paint.*/ + /* per-texture batch */ + Batch **texpaint_triangles; + Batch *texpaint_triangles_single; + /* Edit Cage Mesh buffers */ VertexBuffer *ed_tri_pos; VertexBuffer *ed_tri_nor; /* LoopNor, VertNor */ @@ -1683,6 +1695,7 @@ static void mesh_batch_cache_clear(Mesh *me) BATCH_DISCARD_SAFE(cache->triangles_with_weights); BATCH_DISCARD_SAFE(cache->triangles_with_vert_colors); VERTEXBUFFER_DISCARD_SAFE(cache->tri_aligned_select_id); + VERTEXBUFFER_DISCARD_SAFE(cache->tri_aligned_uv); BATCH_DISCARD_SAFE(cache->triangles_with_select_id); BATCH_DISCARD_ALL_SAFE(cache->fancy_edges); @@ -1701,6 +1714,16 @@ static void mesh_batch_cache_clear(Mesh *me) MEM_SAFE_FREE(cache->shaded_triangles_in_order); MEM_SAFE_FREE(cache->shaded_triangles); + + if (cache->texpaint_triangles) { + for (int i = 0; i < cache->mat_len; ++i) { + BATCH_DISCARD_SAFE(cache->texpaint_triangles[i]); + } + } + MEM_SAFE_FREE(cache->texpaint_triangles); + + BATCH_DISCARD_SAFE(cache->texpaint_triangles_single); + } void DRW_mesh_batch_cache_free(Mesh *me) @@ -1856,6 +1879,45 @@ static VertexBuffer *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata return cache->shaded_triangles_data; } +static VertexBuffer *mesh_batch_cache_get_tri_uv_active( + MeshRenderData *rdata, MeshBatchCache *cache) +{ + BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPUV)); + BLI_assert(rdata->edit_bmesh == NULL); + + if (cache->tri_aligned_uv == NULL) { + unsigned int vidx = 0; + + static VertexFormat format = { 0 }; + static struct { uint uv; } attr_id; + if (format.attrib_ct == 0) { + attr_id.uv = VertexFormat_add_attrib(&format, "uv", COMP_F32, 2, KEEP_FLOAT); + } + + const int tri_len = mesh_render_data_looptri_len_get(rdata); + + VertexBuffer *vbo = cache->tri_aligned_uv = 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); + + const MLoopUV *mloopuv = rdata->mloopuv; + + for (int i = 0; i < tri_len; i++) { + const MLoopTri *mlt = &rdata->mlooptri[i]; + VertexBuffer_set_attrib(vbo, attr_id.uv, vidx++, mloopuv[mlt->tri[0]].uv); + VertexBuffer_set_attrib(vbo, attr_id.uv, vidx++, mloopuv[mlt->tri[1]].uv); + VertexBuffer_set_attrib(vbo, attr_id.uv, vidx++, mloopuv[mlt->tri[2]].uv); + } + vbo_len_used = vidx; + + BLI_assert(vbo_len_capacity == vbo_len_used); + } + + return cache->tri_aligned_uv; +} + static VertexBuffer *mesh_batch_cache_get_tri_pos_and_normals_ex( MeshRenderData *rdata, const bool use_hide, VertexBuffer **r_vbo) @@ -3146,6 +3208,60 @@ Batch **DRW_mesh_batch_cache_get_surface_shaded(Mesh *me) return cache->shaded_triangles; } +Batch **DRW_mesh_batch_cache_get_surface_texpaint(Mesh *me) +{ + MeshBatchCache *cache = mesh_batch_cache_get(me); + + if (cache->texpaint_triangles == NULL) { + /* create batch from DM */ + const int datatype = + MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOPUV; + MeshRenderData *rdata = mesh_render_data_create(me, datatype); + + const int mat_len = mesh_render_data_mat_len_get(rdata); + + cache->texpaint_triangles = MEM_callocN(sizeof(*cache->texpaint_triangles) * mat_len, __func__); + + ElementList **el = mesh_batch_cache_get_shaded_triangles_in_order(rdata, cache); + + VertexBuffer *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache); + for (int i = 0; i < mat_len; ++i) { + cache->texpaint_triangles[i] = Batch_create( + PRIM_TRIANGLES, vbo, el[i]); + VertexBuffer *vbo_uv = mesh_batch_cache_get_tri_uv_active(rdata, cache); + if (vbo_uv) { + Batch_add_VertexBuffer(cache->texpaint_triangles[i], vbo_uv); + } + } + mesh_render_data_free(rdata); + } + + return cache->texpaint_triangles; +} + +Batch *DRW_mesh_batch_cache_get_surface_texpaint_single(Mesh *me) +{ + MeshBatchCache *cache = mesh_batch_cache_get(me); + + if (cache->texpaint_triangles_single == NULL) { + /* create batch from DM */ + const int datatype = + MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOPUV; + MeshRenderData *rdata = mesh_render_data_create(me, datatype); + + VertexBuffer *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache); + + cache->texpaint_triangles_single = Batch_create( + PRIM_TRIANGLES, vbo, NULL); + VertexBuffer *vbo_uv = mesh_batch_cache_get_tri_uv_active(rdata, cache); + if (vbo_uv) { + Batch_add_VertexBuffer(cache->texpaint_triangles_single, vbo_uv); + } + mesh_render_data_free(rdata); + } + return cache->texpaint_triangles_single; +} + Batch *DRW_mesh_batch_cache_get_weight_overlay_edges(Mesh *me, bool use_wire, bool use_sel) { MeshBatchCache *cache = mesh_batch_cache_get(me); |