Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/engines/overlay/overlay_paint.c
| Show All 22 Lines | |||||
| #include "DRW_render.h" | #include "DRW_render.h" | ||||
| #include "DNA_mesh_types.h" | #include "DNA_mesh_types.h" | ||||
| #include "DEG_depsgraph_query.h" | #include "DEG_depsgraph_query.h" | ||||
| #include "overlay_private.h" | #include "overlay_private.h" | ||||
| /* Check if the given object is rendered (partially) transparent */ | |||||
| static bool paint_object_is_rendered_transparent(View3D *v3d, Object *ob) | |||||
| { | |||||
| if (v3d->shading.type == OB_WIRE) { | |||||
| return true; | |||||
| } | |||||
| else if (v3d->shading.type == OB_SOLID) { | |||||
| if (v3d->shading.flag & V3D_SHADING_XRAY) { | |||||
| return true; | |||||
| } | |||||
| if (v3d->shading.color_type == V3D_SHADING_OBJECT_COLOR) { | |||||
| return ob->color[3] < 1.0f; | |||||
| } | |||||
| else if (v3d->shading.color_type == V3D_SHADING_MATERIAL_COLOR) { | |||||
| Mesh *me = ob->data; | |||||
| for (int i = 0; i < me->totcol; i++) { | |||||
| Material *mat = me->mat[i]; | |||||
| if (mat->a < 1.0f) { | |||||
| return true; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| void OVERLAY_paint_init(OVERLAY_Data *vedata) | void OVERLAY_paint_init(OVERLAY_Data *vedata) | ||||
| { | { | ||||
| OVERLAY_StorageList *stl = vedata->stl; | OVERLAY_StorageList *stl = vedata->stl; | ||||
| OVERLAY_PrivateData *pd = stl->pd; | OVERLAY_PrivateData *pd = stl->pd; | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | const DRWContextState *draw_ctx = DRW_context_state_get(); | ||||
| pd->painting.in_front = draw_ctx->obact && (draw_ctx->obact->dtx & OB_DRAWXRAY); | pd->painting.in_front = draw_ctx->obact && (draw_ctx->obact->dtx & OB_DRAWXRAY); | ||||
| pd->painting.alpha_blending = paint_object_is_rendered_transparent(draw_ctx->v3d, | |||||
| draw_ctx->obact); | |||||
| } | } | ||||
| void OVERLAY_paint_cache_init(OVERLAY_Data *vedata) | void OVERLAY_paint_cache_init(OVERLAY_Data *vedata) | ||||
| { | { | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | const DRWContextState *draw_ctx = DRW_context_state_get(); | ||||
| OVERLAY_PassList *psl = vedata->psl; | OVERLAY_PassList *psl = vedata->psl; | ||||
| OVERLAY_PrivateData *pd = vedata->stl->pd; | OVERLAY_PrivateData *pd = vedata->stl->pd; | ||||
| struct GPUShader *sh; | struct GPUShader *sh; | ||||
| DRWShadingGroup *grp; | DRWShadingGroup *grp; | ||||
| DRWState state; | DRWState state; | ||||
| const bool use_alpha_blending = (draw_ctx->v3d->shading.type == OB_WIRE); | |||||
| const bool draw_contours = (pd->overlay.wpaint_flag & V3D_OVERLAY_WPAINT_CONTOURS) != 0; | const bool draw_contours = (pd->overlay.wpaint_flag & V3D_OVERLAY_WPAINT_CONTOURS) != 0; | ||||
| float opacity = 0.0f; | float opacity = 0.0f; | ||||
fclem: This is a bit more tricky, the object can be transparent even in solid mode because of material… | |||||
| pd->paint_depth_grp = NULL; | |||||
| psl->paint_depth_ps = NULL; | |||||
| switch (pd->ctx_mode) { | switch (pd->ctx_mode) { | ||||
| case CTX_MODE_POSE: | case CTX_MODE_POSE: | ||||
| case CTX_MODE_PAINT_WEIGHT: { | case CTX_MODE_PAINT_WEIGHT: { | ||||
| opacity = pd->overlay.weight_paint_mode_opacity; | opacity = pd->overlay.weight_paint_mode_opacity; | ||||
| if (opacity > 0.0f) { | if (opacity > 0.0f) { | ||||
| state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL; | state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL; | ||||
| state |= use_alpha_blending ? DRW_STATE_BLEND_ALPHA : DRW_STATE_BLEND_MUL; | state |= pd->painting.alpha_blending ? DRW_STATE_BLEND_ALPHA : DRW_STATE_BLEND_MUL; | ||||
| DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state); | DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state); | ||||
| sh = OVERLAY_shader_paint_weight(); | sh = OVERLAY_shader_paint_weight(); | ||||
| pd->paint_surf_grp = grp = DRW_shgroup_create(sh, psl->paint_color_ps); | pd->paint_surf_grp = grp = DRW_shgroup_create(sh, psl->paint_color_ps); | ||||
| DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); | DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); | ||||
| DRW_shgroup_uniform_bool_copy(grp, "drawContours", draw_contours); | DRW_shgroup_uniform_bool_copy(grp, "drawContours", draw_contours); | ||||
| DRW_shgroup_uniform_bool_copy(grp, "useAlphaBlend", use_alpha_blending); | DRW_shgroup_uniform_bool_copy(grp, "useAlphaBlend", pd->painting.alpha_blending); | ||||
| DRW_shgroup_uniform_float_copy(grp, "opacity", opacity); | DRW_shgroup_uniform_float_copy(grp, "opacity", opacity); | ||||
| DRW_shgroup_uniform_texture(grp, "colorramp", G_draw.weight_ramp); | DRW_shgroup_uniform_texture(grp, "colorramp", G_draw.weight_ramp); | ||||
| if (pd->painting.alpha_blending) { | |||||
| state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL; | |||||
| DRW_PASS_CREATE(psl->paint_depth_ps, state); | |||||
| sh = OVERLAY_shader_depth_only(); | |||||
| pd->paint_depth_grp = DRW_shgroup_create(sh, psl->paint_depth_ps); | |||||
| } | |||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case CTX_MODE_PAINT_VERTEX: { | case CTX_MODE_PAINT_VERTEX: { | ||||
| opacity = pd->overlay.vertex_paint_mode_opacity; | opacity = pd->overlay.vertex_paint_mode_opacity; | ||||
| if (opacity > 0.0f) { | if (opacity > 0.0f) { | ||||
| state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL; | state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL; | ||||
| state |= use_alpha_blending ? DRW_STATE_BLEND_ALPHA : DRW_STATE_BLEND_MUL; | state |= pd->painting.alpha_blending ? DRW_STATE_BLEND_ALPHA : DRW_STATE_BLEND_MUL; | ||||
| DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state); | DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state); | ||||
| sh = OVERLAY_shader_paint_vertcol(); | sh = OVERLAY_shader_paint_vertcol(); | ||||
| pd->paint_surf_grp = grp = DRW_shgroup_create(sh, psl->paint_color_ps); | pd->paint_surf_grp = grp = DRW_shgroup_create(sh, psl->paint_color_ps); | ||||
| DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); | DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); | ||||
| DRW_shgroup_uniform_bool_copy(grp, "useAlphaBlend", use_alpha_blending); | DRW_shgroup_uniform_bool_copy(grp, "useAlphaBlend", pd->painting.alpha_blending); | ||||
| DRW_shgroup_uniform_float_copy(grp, "opacity", opacity); | DRW_shgroup_uniform_float_copy(grp, "opacity", opacity); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case CTX_MODE_PAINT_TEXTURE: { | case CTX_MODE_PAINT_TEXTURE: { | ||||
| const ImagePaintSettings *imapaint = &draw_ctx->scene->toolsettings->imapaint; | const ImagePaintSettings *imapaint = &draw_ctx->scene->toolsettings->imapaint; | ||||
| const bool mask_enabled = imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL && | const bool mask_enabled = imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL && | ||||
| imapaint->stencil != NULL; | imapaint->stencil != NULL; | ||||
| ▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | void OVERLAY_paint_vertex_cache_populate(OVERLAY_Data *vedata, Object *ob) | ||||
| OVERLAY_PrivateData *pd = vedata->stl->pd; | OVERLAY_PrivateData *pd = vedata->stl->pd; | ||||
| struct GPUBatch *geom = NULL; | struct GPUBatch *geom = NULL; | ||||
| const Mesh *me_orig = DEG_get_original_object(ob)->data; | const Mesh *me_orig = DEG_get_original_object(ob)->data; | ||||
| const bool use_wire = (pd->overlay.paint_flag & V3D_OVERLAY_PAINT_WIRE) != 0; | const bool use_wire = (pd->overlay.paint_flag & V3D_OVERLAY_PAINT_WIRE) != 0; | ||||
| const bool use_face_sel = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; | const bool use_face_sel = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; | ||||
| const bool use_vert_sel = (me_orig->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; | const bool use_vert_sel = (me_orig->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; | ||||
| if (pd->paint_surf_grp) { | |||||
| if (ob->mode == OB_MODE_WEIGHT_PAINT) { | if (ob->mode == OB_MODE_WEIGHT_PAINT) { | ||||
| if (pd->paint_surf_grp) { | |||||
| geom = DRW_cache_mesh_surface_weights_get(ob); | geom = DRW_cache_mesh_surface_weights_get(ob); | ||||
| DRW_shgroup_call(pd->paint_surf_grp, geom, ob); | DRW_shgroup_call(pd->paint_surf_grp, geom, ob); | ||||
| } | } | ||||
| if (pd->paint_depth_grp) { | |||||
| geom = DRW_cache_mesh_surface_weights_get(ob); | |||||
Not Done Inline Actionsyou can reuse the same batch from DRW_cache_mesh_surface_weights_get to avoid creating more batches. fclem: you can reuse the same batch from `DRW_cache_mesh_surface_weights_get` to avoid creating more… | |||||
| DRW_shgroup_call(pd->paint_depth_grp, geom, ob); | |||||
| } | |||||
| } | } | ||||
| if (use_face_sel || use_wire) { | if (use_face_sel || use_wire) { | ||||
| geom = DRW_cache_mesh_surface_edges_get(ob); | geom = DRW_cache_mesh_surface_edges_get(ob); | ||||
| DRW_shgroup_call(use_face_sel ? pd->paint_wire_selected_grp : pd->paint_wire_grp, geom, ob); | DRW_shgroup_call(use_face_sel ? pd->paint_wire_selected_grp : pd->paint_wire_grp, geom, ob); | ||||
| } | } | ||||
| if (use_face_sel) { | if (use_face_sel) { | ||||
| Show All 16 Lines | |||||
| { | { | ||||
| OVERLAY_StorageList *stl = vedata->stl; | OVERLAY_StorageList *stl = vedata->stl; | ||||
| OVERLAY_PrivateData *pd = stl->pd; | OVERLAY_PrivateData *pd = stl->pd; | ||||
| OVERLAY_PassList *psl = vedata->psl; | OVERLAY_PassList *psl = vedata->psl; | ||||
| DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); | DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); | ||||
| if (DRW_state_is_fbo()) { | if (DRW_state_is_fbo()) { | ||||
| /* Pain overlay needs final color because of multiply blend mode. */ | /* Paint overlay needs final color because of multiply blend mode. */ | ||||
| GPU_framebuffer_bind(pd->painting.in_front ? dfbl->in_front_fb : dfbl->default_fb); | GPU_framebuffer_bind(pd->painting.in_front ? dfbl->in_front_fb : dfbl->default_fb); | ||||
| } | } | ||||
| if (psl->paint_depth_ps) { | |||||
| DRW_draw_pass(psl->paint_depth_ps); | |||||
| } | |||||
| if (psl->paint_color_ps) { | if (psl->paint_color_ps) { | ||||
| DRW_draw_pass(psl->paint_color_ps); | DRW_draw_pass(psl->paint_color_ps); | ||||
| } | } | ||||
| DRW_draw_pass(psl->paint_overlay_ps); | DRW_draw_pass(psl->paint_overlay_ps); | ||||
| } | } | ||||
This is a bit more tricky, the object can be transparent even in solid mode because of material alpha or object alpha.