Clean up weight/vertex painting code

Now passing selection state instead of colors for the wire/face mask
overlay thing. Also added masking indication on the faces in vertex
paint.
This commit is contained in:
Luca Rood 2017-05-05 14:25:43 +02:00
parent 14bf4ed194
commit 872d8993dd
9 changed files with 116 additions and 59 deletions

View File

@ -151,6 +151,8 @@ data_to_c_simple(modes/shaders/object_outline_expand_frag.glsl SRC)
data_to_c_simple(modes/shaders/object_outline_detect_frag.glsl SRC)
data_to_c_simple(modes/shaders/object_grid_frag.glsl SRC)
data_to_c_simple(modes/shaders/object_grid_vert.glsl SRC)
data_to_c_simple(modes/shaders/paint_wire_frag.glsl SRC)
data_to_c_simple(modes/shaders/paint_wire_vert.glsl SRC)
list(APPEND INC
)

View File

@ -1818,12 +1818,12 @@ Batch *DRW_cache_mesh_verts_get(Object *ob)
return DRW_mesh_batch_cache_get_all_verts(me);
}
Batch *DRW_cache_mesh_edges_paint_overlay_get(Object *ob, bool use_wire, bool use_sel, bool use_theme)
Batch *DRW_cache_mesh_edges_paint_overlay_get(Object *ob, bool use_wire, bool use_sel)
{
BLI_assert(ob->type == OB_MESH);
Mesh *me = ob->data;
return DRW_mesh_batch_cache_get_weight_overlay_edges(me, use_wire, use_sel, use_theme);
return DRW_mesh_batch_cache_get_weight_overlay_edges(me, use_wire, use_sel);
}
Batch *DRW_cache_mesh_faces_weight_overlay_get(Object *ob)

View File

@ -99,7 +99,7 @@ struct Batch *DRW_cache_mesh_surface_vert_colors_get(struct Object *ob);
struct Batch *DRW_cache_mesh_surface_verts_get(struct Object *ob);
struct Batch *DRW_cache_mesh_edges_get(struct Object *ob);
struct Batch *DRW_cache_mesh_verts_get(struct Object *ob);
struct Batch *DRW_cache_mesh_edges_paint_overlay_get(struct Object *ob, bool use_wire, bool use_sel, bool use_theme);
struct Batch *DRW_cache_mesh_edges_paint_overlay_get(struct Object *ob, bool use_wire, bool use_sel);
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);

View File

@ -68,7 +68,7 @@ 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_weight_overlay_edges(struct Mesh *me, bool use_wire, bool use_sel, bool use_theme);
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);
struct Batch *DRW_mesh_batch_cache_get_all_edges(struct Mesh *me);

View File

@ -51,8 +51,6 @@
#include "GPU_batch.h"
#include "GPU_draw.h"
#include "UI_resources.h"
#include "draw_cache_impl.h" /* own include */
static void mesh_batch_cache_clear(Mesh *me);
@ -1329,8 +1327,8 @@ static bool mesh_render_data_looptri_cos_select_id_get(
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],
bool use_wire, bool use_sel, bool use_theme)
float r_vert_cos[2][3], int *r_vert_sel,
bool use_wire, bool use_sel)
{
BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP));
@ -1361,20 +1359,11 @@ static bool mesh_render_data_edge_cos_sel_get(
}
if (use_sel && rdata->edge_selection[edge_idx]) {
if (use_theme) {
UI_GetThemeColorShade3fv(TH_EDGE_SELECT, -50, r_vert_col);
}
else {
r_vert_col[0] = 1.0f;
r_vert_col[1] = 1.0f;
r_vert_col[2] = 1.0f;
}
*r_vert_sel = true;
}
else {
if (use_wire) {
r_vert_col[0] = 0.5f;
r_vert_col[1] = 0.5f;
r_vert_col[2] = 0.5f;
*r_vert_sel = false;
}
else {
return false;
@ -1390,7 +1379,7 @@ static bool mesh_render_data_edge_cos_sel_get(
static bool mesh_render_data_tri_cos_sel_get(
MeshRenderData *rdata, const int tri_idx,
float r_vert_cos[3][3], float r_vert_col[4])
float r_vert_cos[3][3])
{
BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI));
@ -1401,13 +1390,7 @@ static bool mesh_render_data_tri_cos_sel_get(
const MLoopTri *mlt = &rdata->mlooptri[tri_idx];
if (rdata->mpoly[mlt->poly].flag & ME_FACE_SEL) {
r_vert_col[3] = 0.0f;
}
else {
r_vert_col[0] = 1.0f;
r_vert_col[1] = 1.0f;
r_vert_col[2] = 1.0f;
r_vert_col[3] = 0.2f;
return false;
}
copy_v3_v3(r_vert_cos[0], rdata->mvert[rdata->mloop[mlt->tri[0]].v].co);
@ -1663,7 +1646,7 @@ typedef struct MeshBatchCache {
Batch *overlay_loose_verts;
Batch *overlay_loose_edges;
Batch *overlay_facedots;
Batch *overlay_weight_edges;
Batch *overlay_paint_edges;
Batch *overlay_weight_faces;
Batch *overlay_weight_verts;
@ -1800,7 +1783,7 @@ static void mesh_batch_cache_clear(Mesh *me)
BATCH_DISCARD_ALL_SAFE(cache->overlay_loose_verts);
BATCH_DISCARD_ALL_SAFE(cache->overlay_loose_edges);
BATCH_DISCARD_ALL_SAFE(cache->overlay_facedots);
BATCH_DISCARD_ALL_SAFE(cache->overlay_weight_edges);
BATCH_DISCARD_ALL_SAFE(cache->overlay_paint_edges);
BATCH_DISCARD_ALL_SAFE(cache->overlay_weight_faces);
BATCH_DISCARD_ALL_SAFE(cache->overlay_weight_verts);
@ -2373,7 +2356,7 @@ static ElementList **mesh_batch_cache_get_shaded_triangles_in_order(MeshRenderDa
}
static VertexBuffer *mesh_batch_cache_get_edge_pos_with_sel(
MeshRenderData *rdata, MeshBatchCache *cache, bool use_wire, bool use_sel, bool use_theme)
MeshRenderData *rdata, MeshBatchCache *cache, bool use_wire, bool use_sel)
{
BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP));
@ -2385,7 +2368,7 @@ static VertexBuffer *mesh_batch_cache_get_edge_pos_with_sel(
if (format.attrib_ct == 0) {
/* initialize vertex format */
pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
col_id = VertexFormat_add_attrib(&format, "color", COMP_F32, 3, KEEP_FLOAT);
col_id = VertexFormat_add_attrib(&format, "select", COMP_U8, 1, KEEP_INT);
}
const int edge_len = mesh_render_data_edges_len_get(rdata);
@ -2397,13 +2380,14 @@ static VertexBuffer *mesh_batch_cache_get_edge_pos_with_sel(
VertexBuffer_allocate_data(vbo, vbo_len_capacity);
for (int i = 0; i < edge_len; i++) {
static float edge_vert_cos[2][3], edge_vert_col[3];
static float edge_vert_cos[2][3];
static int edge_vert_sel;
if (mesh_render_data_edge_cos_sel_get(
rdata, i, edge_vert_cos, edge_vert_col, use_wire, use_sel, use_theme))
rdata, i, edge_vert_cos, &edge_vert_sel, use_wire, use_sel))
{
VertexBuffer_set_attrib(vbo, col_id, cidx++, edge_vert_col);
VertexBuffer_set_attrib(vbo, col_id, cidx++, edge_vert_col);
VertexBuffer_set_attrib(vbo, col_id, cidx++, &edge_vert_sel);
VertexBuffer_set_attrib(vbo, col_id, cidx++, &edge_vert_sel);
VertexBuffer_set_attrib(vbo, pos_id, vidx++, edge_vert_cos[0]);
VertexBuffer_set_attrib(vbo, pos_id, vidx++, edge_vert_cos[1]);
@ -2425,14 +2409,13 @@ static VertexBuffer *mesh_batch_cache_get_tri_pos_with_sel(MeshRenderData *rdata
BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI));
if (cache->tri_pos_with_sel == NULL) {
unsigned int vidx = 0, cidx = 0;
unsigned int vidx = 0;
static VertexFormat format = { 0 };
static unsigned int pos_id, col_id;
static unsigned int pos_id;
if (format.attrib_ct == 0) {
/* initialize vertex format */
pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
col_id = VertexFormat_add_attrib(&format, "color", COMP_F32, 4, KEEP_FLOAT);
}
const int tri_len = mesh_render_data_looptri_len_get(rdata);
@ -2444,15 +2427,11 @@ static VertexBuffer *mesh_batch_cache_get_tri_pos_with_sel(MeshRenderData *rdata
VertexBuffer_allocate_data(vbo, vbo_len_capacity);
for (int i = 0; i < tri_len; i++) {
static float tri_vert_cos[3][3], tri_vert_col[4];
static float tri_vert_cos[3][3];
if (mesh_render_data_tri_cos_sel_get(
rdata, i, tri_vert_cos, tri_vert_col))
rdata, i, tri_vert_cos))
{
VertexBuffer_set_attrib(vbo, col_id, cidx++, tri_vert_col);
VertexBuffer_set_attrib(vbo, col_id, cidx++, tri_vert_col);
VertexBuffer_set_attrib(vbo, col_id, cidx++, tri_vert_col);
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]);
@ -2941,22 +2920,22 @@ Batch **DRW_mesh_batch_cache_get_surface_shaded(Mesh *me)
return cache->shaded_triangles;
}
Batch *DRW_mesh_batch_cache_get_weight_overlay_edges(Mesh *me, bool use_wire, bool use_sel, bool use_theme)
Batch *DRW_mesh_batch_cache_get_weight_overlay_edges(Mesh *me, bool use_wire, bool use_sel)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
if (cache->overlay_weight_edges == NULL) {
if (cache->overlay_paint_edges == NULL) {
/* create batch from Mesh */
const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP;
MeshRenderData *rdata = mesh_render_data_create(me, datatype);
cache->overlay_weight_edges = Batch_create(
PRIM_LINES, mesh_batch_cache_get_edge_pos_with_sel(rdata, cache, use_wire, use_sel, use_theme), NULL);
cache->overlay_paint_edges = Batch_create(
PRIM_LINES, mesh_batch_cache_get_edge_pos_with_sel(rdata, cache, use_wire, use_sel), NULL);
mesh_render_data_free(rdata);
}
return cache->overlay_weight_edges;
return cache->overlay_paint_edges;
}
Batch *DRW_mesh_batch_cache_get_weight_overlay_faces(Mesh *me)

View File

@ -38,11 +38,16 @@
extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
extern struct GlobalsUboStorage ts; /* draw_common.c */
extern char datatoc_paint_wire_vert_glsl[];
extern char datatoc_paint_wire_frag_glsl[];
extern char datatoc_common_globals_lib_glsl[];
/* *********** LISTS *********** */
typedef struct PAINT_VERTEX_PassList {
struct DRWPass *vcolor_faces;
struct DRWPass *wire_overlay;
struct DRWPass *face_overlay;
} PAINT_VERTEX_PassList;
typedef struct PAINT_VERTEX_StorageList {
@ -62,11 +67,13 @@ typedef struct PAINT_VERTEX_Data {
static struct {
struct GPUShader *vcolor_face_shader;
struct GPUShader *wire_overlay_shader;
struct GPUShader *face_overlay_shader;
} e_data = {NULL}; /* Engine data */
typedef struct PAINT_VERTEX_PrivateData {
DRWShadingGroup *fvcolor_shgrp;
DRWShadingGroup *lwire_shgrp;
DRWShadingGroup *face_shgrp;
} PAINT_VERTEX_PrivateData; /* Transient data */
/* *********** FUNCTIONS *********** */
@ -78,7 +85,14 @@ static void PAINT_VERTEX_engine_init(void *UNUSED(vedata))
}
if (!e_data.wire_overlay_shader) {
e_data.wire_overlay_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_FLAT_COLOR);
e_data.wire_overlay_shader = DRW_shader_create_with_lib(
datatoc_paint_wire_vert_glsl, NULL,
datatoc_paint_wire_frag_glsl,
datatoc_common_globals_lib_glsl, "#define VERTEX_MODE\n");
}
if (!e_data.face_overlay_shader) {
e_data.face_overlay_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
}
}
@ -112,6 +126,15 @@ static void PAINT_VERTEX_cache_init(void *vedata)
stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay);
}
{
psl->face_overlay = DRW_pass_create("Face Mask Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND);
stl->g_data->face_shgrp = DRW_shgroup_create(e_data.face_overlay_shader, psl->face_overlay);
static float col[4] = {1.0f, 1.0f, 1.0f, 0.2f};
DRW_shgroup_uniform_vec4(stl->g_data->face_shgrp, "color", col, 1);
}
}
static void PAINT_VERTEX_cache_populate(void *vedata, Object *ob)
@ -132,9 +155,14 @@ static void PAINT_VERTEX_cache_populate(void *vedata, Object *ob)
DRW_shgroup_call_add(stl->g_data->fvcolor_shgrp, geom, ob->obmat);
if (flag & ME_EDIT_PAINT_FACE_SEL || use_wire) {
geom = DRW_cache_mesh_edges_paint_overlay_get(ob, use_wire, flag & ME_EDIT_PAINT_FACE_SEL, true);
geom = DRW_cache_mesh_edges_paint_overlay_get(ob, use_wire, flag & ME_EDIT_PAINT_FACE_SEL);
DRW_shgroup_call_add(stl->g_data->lwire_shgrp, geom, ob->obmat);
}
if (flag & ME_EDIT_PAINT_FACE_SEL) {
geom = DRW_cache_mesh_faces_weight_overlay_get(ob);
DRW_shgroup_call_add(stl->g_data->face_shgrp, geom, ob->obmat);
}
}
}
@ -143,11 +171,13 @@ static void PAINT_VERTEX_draw_scene(void *vedata)
PAINT_VERTEX_PassList *psl = ((PAINT_VERTEX_Data *)vedata)->psl;
DRW_draw_pass(psl->vcolor_faces);
DRW_draw_pass(psl->face_overlay);
DRW_draw_pass(psl->wire_overlay);
}
static void PAINT_VERTEX_engine_free(void)
{
DRW_SHADER_FREE_SAFE(e_data.wire_overlay_shader);
}
void PAINT_VERTEX_collection_settings_create(IDProperty *properties)

View File

@ -40,6 +40,10 @@
extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
extern struct GlobalsUboStorage ts; /* draw_common.c */
extern char datatoc_paint_wire_vert_glsl[];
extern char datatoc_paint_wire_frag_glsl[];
extern char datatoc_common_globals_lib_glsl[];
/* *********** LISTS *********** */
typedef struct PAINT_WEIGHT_PassList {
@ -65,7 +69,8 @@ typedef struct PAINT_WEIGHT_Data {
static struct {
struct GPUShader *weight_face_shader;
struct GPUShader *flat_overlay_shader;
struct GPUShader *wire_overlay_shader;
struct GPUShader *face_overlay_shader;
struct GPUShader *vert_overlay_shader;
int actdef;
} e_data = {NULL}; /* Engine data */
@ -93,8 +98,15 @@ static void PAINT_WEIGHT_engine_init(void *UNUSED(vedata))
e_data.weight_face_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA);
}
if (!e_data.flat_overlay_shader) {
e_data.flat_overlay_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_FLAT_COLOR);
if (!e_data.wire_overlay_shader) {
e_data.wire_overlay_shader = DRW_shader_create_with_lib(
datatoc_paint_wire_vert_glsl, NULL,
datatoc_paint_wire_frag_glsl,
datatoc_common_globals_lib_glsl, "#define WEIGHT_MODE\n");
}
if (!e_data.face_overlay_shader) {
e_data.face_overlay_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
}
if (!e_data.vert_overlay_shader) {
@ -130,17 +142,20 @@ 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);
stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.flat_overlay_shader, psl->wire_overlay);
stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay);
}
{
psl->face_overlay = DRW_pass_create("Wire Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND);
psl->face_overlay = DRW_pass_create("Face Mask Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND);
stl->g_data->face_shgrp = DRW_shgroup_create(e_data.flat_overlay_shader, psl->face_overlay);
stl->g_data->face_shgrp = DRW_shgroup_create(e_data.face_overlay_shader, psl->face_overlay);
static float col[4] = {1.0f, 1.0f, 1.0f, 0.2f};
DRW_shgroup_uniform_vec4(stl->g_data->face_shgrp, "color", col, 1);
}
{
psl->vert_overlay = DRW_pass_create("Wire Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
psl->vert_overlay = DRW_pass_create("Vert Mask Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
stl->g_data->vert_shgrp = DRW_shgroup_create(e_data.vert_overlay_shader, psl->vert_overlay);
}
@ -164,7 +179,7 @@ static void PAINT_WEIGHT_cache_populate(void *vedata, Object *ob)
DRW_shgroup_call_add(stl->g_data->fweights_shgrp, geom, ob->obmat);
if (flag & ME_EDIT_PAINT_FACE_SEL || use_wire) {
geom = DRW_cache_mesh_edges_paint_overlay_get(ob, use_wire, flag & ME_EDIT_PAINT_FACE_SEL, false);
geom = DRW_cache_mesh_edges_paint_overlay_get(ob, use_wire, flag & ME_EDIT_PAINT_FACE_SEL);
DRW_shgroup_call_add(stl->g_data->lwire_shgrp, geom, ob->obmat);
}
@ -192,6 +207,7 @@ static void PAINT_WEIGHT_draw_scene(void *vedata)
static void PAINT_WEIGHT_engine_free(void)
{
DRW_SHADER_FREE_SAFE(e_data.wire_overlay_shader);
}
void PAINT_WEIGHT_collection_settings_create(IDProperty *properties)

View File

@ -0,0 +1,17 @@
flat in int finalSelect;
out vec4 fragColor;
void main()
{
#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
const vec4 colUnsel = vec4(0.5, 0.5, 0.5, 1.0);
fragColor = bool(finalSelect) ? colSel : colUnsel;
}

View File

@ -0,0 +1,13 @@
uniform mat4 ModelViewProjectionMatrix;
in vec3 pos;
in int select;
flat out int finalSelect;
void main()
{
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
finalSelect = select;
}