Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/engines/overlay/overlay_outline.cc
- This file was moved from source/blender/draw/engines/overlay/overlay_outline.c.
| Show All 10 Lines | |||||
| #include "BKE_gpencil.h" | #include "BKE_gpencil.h" | ||||
| #include "BKE_object.h" | #include "BKE_object.h" | ||||
| #include "DNA_gpencil_types.h" | #include "DNA_gpencil_types.h" | ||||
| #include "UI_resources.h" | #include "UI_resources.h" | ||||
| #include "overlay_private.h" | #include "overlay_private.hh" | ||||
| /* Returns the normal plane in NDC space. */ | /* Returns the normal plane in NDC space. */ | ||||
| static void gpencil_depth_plane(Object *ob, float r_plane[4]) | static void gpencil_depth_plane(Object *ob, float r_plane[4]) | ||||
| { | { | ||||
| /* TODO: put that into private data. */ | /* TODO: put that into private data. */ | ||||
| float viewinv[4][4]; | float viewinv[4][4]; | ||||
| DRW_view_viewmat_get(NULL, viewinv, true); | DRW_view_viewmat_get(nullptr, viewinv, true); | ||||
| float *camera_z_axis = viewinv[2]; | float *camera_z_axis = viewinv[2]; | ||||
| float *camera_pos = viewinv[3]; | float *camera_pos = viewinv[3]; | ||||
| /* Find the normal most likely to represent the grease pencil object. */ | /* Find the normal most likely to represent the grease pencil object. */ | ||||
| /* TODO: This does not work quite well if you use | /* TODO: This does not work quite well if you use | ||||
| * strokes not aligned with the object axes. Maybe we could try to | * strokes not aligned with the object axes. Maybe we could try to | ||||
| * compute the minimum axis of all strokes. But this would be more | * compute the minimum axis of all strokes. But this would be more | ||||
| * computationally heavy and should go into the GPData evaluation. */ | * computationally heavy and should go into the GPData evaluation. */ | ||||
| const BoundBox *bbox = BKE_object_boundbox_get(ob); | const BoundBox *bbox = BKE_object_boundbox_get(ob); | ||||
| /* Convert bbox to matrix */ | /* Convert bbox to matrix */ | ||||
| float mat[4][4], size[3], center[3]; | float mat[4][4], size[3], center[3]; | ||||
| BKE_boundbox_calc_size_aabb(bbox, size); | BKE_boundbox_calc_size_aabb(bbox, size); | ||||
| BKE_boundbox_calc_center_aabb(bbox, center); | BKE_boundbox_calc_center_aabb(bbox, center); | ||||
| unit_m4(mat); | unit_m4(mat); | ||||
| copy_v3_v3(mat[3], center); | copy_v3_v3(mat[3], center); | ||||
| /* Avoid division by 0.0 later. */ | /* Avoid division by 0.0 later. */ | ||||
| add_v3_fl(size, 1e-8f); | add_v3_fl(size, 1e-8f); | ||||
| rescale_m4(mat, size); | rescale_m4(mat, size); | ||||
| /* BBox space to World. */ | /* BBox space to World. */ | ||||
| mul_m4_m4m4(mat, ob->obmat, mat); | mul_m4_m4m4(mat, ob->obmat, mat); | ||||
| /* BBox center in world space. */ | /* BBox center in world space. */ | ||||
| copy_v3_v3(center, mat[3]); | copy_v3_v3(center, mat[3]); | ||||
| /* View Vector. */ | /* View Vector. */ | ||||
| if (DRW_view_is_persp_get(NULL)) { | if (DRW_view_is_persp_get(nullptr)) { | ||||
| /* BBox center to camera vector. */ | /* BBox center to camera vector. */ | ||||
| sub_v3_v3v3(r_plane, camera_pos, mat[3]); | sub_v3_v3v3(r_plane, camera_pos, mat[3]); | ||||
| } | } | ||||
| else { | else { | ||||
| copy_v3_v3(r_plane, camera_z_axis); | copy_v3_v3(r_plane, camera_z_axis); | ||||
| } | } | ||||
| /* World to BBox space. */ | /* World to BBox space. */ | ||||
| invert_m4(mat); | invert_m4(mat); | ||||
| Show All 14 Lines | |||||
| { | { | ||||
| OVERLAY_FramebufferList *fbl = vedata->fbl; | OVERLAY_FramebufferList *fbl = vedata->fbl; | ||||
| OVERLAY_TextureList *txl = vedata->txl; | OVERLAY_TextureList *txl = vedata->txl; | ||||
| OVERLAY_PrivateData *pd = vedata->stl->pd; | OVERLAY_PrivateData *pd = vedata->stl->pd; | ||||
| DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); | DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); | ||||
| if (DRW_state_is_fbo()) { | if (DRW_state_is_fbo()) { | ||||
| /* TODO: only alloc if needed. */ | /* TODO: only alloc if needed. */ | ||||
| DRW_texture_ensure_fullscreen_2d(&txl->temp_depth_tx, GPU_DEPTH24_STENCIL8, 0); | DRW_texture_ensure_fullscreen_2d(&txl->temp_depth_tx, GPU_DEPTH24_STENCIL8, DRWTextureFlag(0)); | ||||
| DRW_texture_ensure_fullscreen_2d(&txl->outlines_id_tx, GPU_R16UI, 0); | DRW_texture_ensure_fullscreen_2d(&txl->outlines_id_tx, GPU_R16UI, DRWTextureFlag(0)); | ||||
| GPU_framebuffer_ensure_config( | GPU_framebuffer_ensure_config( | ||||
| &fbl->outlines_prepass_fb, | &fbl->outlines_prepass_fb, | ||||
| {GPU_ATTACHMENT_TEXTURE(txl->temp_depth_tx), GPU_ATTACHMENT_TEXTURE(txl->outlines_id_tx)}); | {GPU_ATTACHMENT_TEXTURE(txl->temp_depth_tx), GPU_ATTACHMENT_TEXTURE(txl->outlines_id_tx)}); | ||||
| if (pd->antialiasing.enabled) { | if (pd->antialiasing.enabled) { | ||||
| GPU_framebuffer_ensure_config(&fbl->outlines_resolve_fb, | GPU_framebuffer_ensure_config(&fbl->outlines_resolve_fb, | ||||
| { | { | ||||
| Show All 13 Lines | |||||
| } | } | ||||
| void OVERLAY_outline_cache_init(OVERLAY_Data *vedata) | void OVERLAY_outline_cache_init(OVERLAY_Data *vedata) | ||||
| { | { | ||||
| OVERLAY_PassList *psl = vedata->psl; | OVERLAY_PassList *psl = vedata->psl; | ||||
| OVERLAY_TextureList *txl = vedata->txl; | OVERLAY_TextureList *txl = vedata->txl; | ||||
| OVERLAY_PrivateData *pd = vedata->stl->pd; | OVERLAY_PrivateData *pd = vedata->stl->pd; | ||||
| DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); | DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); | ||||
| DRWShadingGroup *grp = NULL; | DRWShadingGroup *grp = nullptr; | ||||
| const float outline_width = UI_GetThemeValuef(TH_OUTLINE_WIDTH); | const float outline_width = UI_GetThemeValuef(TH_OUTLINE_WIDTH); | ||||
| const bool do_expand = (U.pixelsize > 1.0) || (outline_width > 2.0f); | const bool do_expand = (U.pixelsize > 1.0) || (outline_width > 2.0f); | ||||
| { | { | ||||
| DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL; | DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL; | ||||
| DRW_PASS_CREATE(psl->outlines_prepass_ps, state | pd->clipping_state); | DRW_PASS_CREATE(psl->outlines_prepass_ps, state | pd->clipping_state); | ||||
| Show All 35 Lines | if (!(pd->v3d_flag & V3D_SELECT_OUTLINE)) { | ||||
| DRW_shgroup_uniform_float_copy(grp, "alphaOcclu", (pd->xray_enabled) ? 1.0f : 0.35f); | DRW_shgroup_uniform_float_copy(grp, "alphaOcclu", (pd->xray_enabled) ? 1.0f : 0.35f); | ||||
| DRW_shgroup_uniform_bool_copy(grp, "doThickOutlines", do_expand); | DRW_shgroup_uniform_bool_copy(grp, "doThickOutlines", do_expand); | ||||
| DRW_shgroup_uniform_bool_copy(grp, "doAntiAliasing", pd->antialiasing.enabled); | DRW_shgroup_uniform_bool_copy(grp, "doAntiAliasing", pd->antialiasing.enabled); | ||||
| DRW_shgroup_uniform_bool_copy(grp, "isXrayWires", pd->xray_enabled_and_not_wire); | DRW_shgroup_uniform_bool_copy(grp, "isXrayWires", pd->xray_enabled_and_not_wire); | ||||
| DRW_shgroup_uniform_texture_ref(grp, "outlineId", &txl->outlines_id_tx); | DRW_shgroup_uniform_texture_ref(grp, "outlineId", &txl->outlines_id_tx); | ||||
| DRW_shgroup_uniform_texture_ref(grp, "sceneDepth", &dtxl->depth); | DRW_shgroup_uniform_texture_ref(grp, "sceneDepth", &dtxl->depth); | ||||
| DRW_shgroup_uniform_texture_ref(grp, "outlineDepth", &txl->temp_depth_tx); | DRW_shgroup_uniform_texture_ref(grp, "outlineDepth", &txl->temp_depth_tx); | ||||
| DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); | DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); | ||||
| DRW_shgroup_call_procedural_triangles(grp, NULL, 1); | DRW_shgroup_call_procedural_triangles(grp, nullptr, 1); | ||||
| } | } | ||||
| } | } | ||||
| typedef struct iterData { | typedef struct iterData { | ||||
| Object *ob; | Object *ob; | ||||
| DRWShadingGroup *stroke_grp; | DRWShadingGroup *stroke_grp; | ||||
| DRWShadingGroup *fill_grp; | DRWShadingGroup *fill_grp; | ||||
| int cfra; | int cfra; | ||||
| ▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | iterData iter = { | ||||
| .fill_grp = DRW_shgroup_create_sub(pd->outlines_gpencil_grp), | .fill_grp = DRW_shgroup_create_sub(pd->outlines_gpencil_grp), | ||||
| .cfra = pd->cfra, | .cfra = pd->cfra, | ||||
| }; | }; | ||||
| if (gpd->draw_mode == GP_DRAWMODE_2D) { | if (gpd->draw_mode == GP_DRAWMODE_2D) { | ||||
| gpencil_depth_plane(ob, iter.plane); | gpencil_depth_plane(ob, iter.plane); | ||||
| } | } | ||||
| BKE_gpencil_visible_stroke_advanced_iter(NULL, | BKE_gpencil_visible_stroke_advanced_iter(nullptr, | ||||
| ob, | ob, | ||||
| gpencil_layer_cache_populate, | gpencil_layer_cache_populate, | ||||
| gpencil_stroke_cache_populate, | gpencil_stroke_cache_populate, | ||||
| &iter, | &iter, | ||||
| false, | false, | ||||
| pd->cfra); | pd->cfra); | ||||
| } | } | ||||
| static void OVERLAY_outline_volume(OVERLAY_PrivateData *pd, Object *ob) | static void OVERLAY_outline_volume(OVERLAY_PrivateData *pd, Object *ob) | ||||
| { | { | ||||
| struct GPUBatch *geom = DRW_cache_volume_selection_surface_get(ob); | struct GPUBatch *geom = DRW_cache_volume_selection_surface_get(ob); | ||||
| if (geom == NULL) { | if (geom == nullptr) { | ||||
| return; | return; | ||||
| } | } | ||||
| DRWShadingGroup *shgroup = pd->outlines_grp; | DRWShadingGroup *shgroup = pd->outlines_grp; | ||||
| DRW_shgroup_call(shgroup, geom, ob); | DRW_shgroup_call(shgroup, geom, ob); | ||||
| } | } | ||||
| static void OVERLAY_outline_curves(OVERLAY_PrivateData *pd, Object *ob) | static void OVERLAY_outline_curves(OVERLAY_PrivateData *pd, Object *ob) | ||||
| { | { | ||||
| DRWShadingGroup *shgroup = pd->outlines_curves_grp; | DRWShadingGroup *shgroup = pd->outlines_curves_grp; | ||||
| DRW_shgroup_curves_create_sub(ob, shgroup, NULL); | DRW_shgroup_curves_create_sub(ob, shgroup, nullptr); | ||||
| } | } | ||||
| void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata, | void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata, | ||||
| Object *ob, | Object *ob, | ||||
| OVERLAY_DupliData *dupli, | OVERLAY_DupliData *dupli, | ||||
| bool init_dupli) | bool init_dupli) | ||||
| { | { | ||||
| OVERLAY_PrivateData *pd = vedata->stl->pd; | OVERLAY_PrivateData *pd = vedata->stl->pd; | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | const DRWContextState *draw_ctx = DRW_context_state_get(); | ||||
| struct GPUBatch *geom; | struct GPUBatch *geom; | ||||
| DRWShadingGroup *shgroup = NULL; | DRWShadingGroup *shgroup = nullptr; | ||||
| const bool draw_outline = ob->dt > OB_BOUNDBOX; | const bool draw_outline = ob->dt > OB_BOUNDBOX; | ||||
| /* Early exit: outlines of bounding boxes are not drawn. */ | /* Early exit: outlines of bounding boxes are not drawn. */ | ||||
| if (!draw_outline) { | if (!draw_outline) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (ob->type == OB_GPENCIL) { | if (ob->type == OB_GPENCIL) { | ||||
| Show All 24 Lines | void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata, | ||||
| else { | else { | ||||
| /* This fixes only the biggest case which is a plane in ortho view. */ | /* This fixes only the biggest case which is a plane in ortho view. */ | ||||
| int flat_axis = 0; | int flat_axis = 0; | ||||
| bool is_flat_object_viewed_from_side = ((draw_ctx->rv3d->persp == RV3D_ORTHO) && | bool is_flat_object_viewed_from_side = ((draw_ctx->rv3d->persp == RV3D_ORTHO) && | ||||
| DRW_object_is_flat(ob, &flat_axis) && | DRW_object_is_flat(ob, &flat_axis) && | ||||
| DRW_object_axis_orthogonal_to_view(ob, flat_axis)); | DRW_object_axis_orthogonal_to_view(ob, flat_axis)); | ||||
| if (pd->xray_enabled_and_not_wire || is_flat_object_viewed_from_side) { | if (pd->xray_enabled_and_not_wire || is_flat_object_viewed_from_side) { | ||||
| geom = DRW_cache_object_edge_detection_get(ob, NULL); | geom = DRW_cache_object_edge_detection_get(ob, nullptr); | ||||
| } | } | ||||
| else { | else { | ||||
| geom = DRW_cache_object_surface_get(ob); | geom = DRW_cache_object_surface_get(ob); | ||||
| } | } | ||||
| if (geom) { | if (geom) { | ||||
| shgroup = (ob->type == OB_POINTCLOUD) ? pd->outlines_ptcloud_grp : pd->outlines_grp; | shgroup = (ob->type == OB_POINTCLOUD) ? pd->outlines_ptcloud_grp : pd->outlines_grp; | ||||
| } | } | ||||
| Show All 16 Lines | |||||
| } | } | ||||
| void OVERLAY_outline_draw(OVERLAY_Data *vedata) | void OVERLAY_outline_draw(OVERLAY_Data *vedata) | ||||
| { | { | ||||
| OVERLAY_FramebufferList *fbl = vedata->fbl; | OVERLAY_FramebufferList *fbl = vedata->fbl; | ||||
| OVERLAY_PassList *psl = vedata->psl; | OVERLAY_PassList *psl = vedata->psl; | ||||
| const float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f}; | const float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f}; | ||||
| bool do_outlines = psl->outlines_prepass_ps != NULL && | bool do_outlines = psl->outlines_prepass_ps != nullptr && | ||||
| !DRW_pass_is_empty(psl->outlines_prepass_ps); | !DRW_pass_is_empty(psl->outlines_prepass_ps); | ||||
| if (DRW_state_is_fbo() && do_outlines) { | if (DRW_state_is_fbo() && do_outlines) { | ||||
| DRW_stats_group_start("Outlines"); | DRW_stats_group_start("Outlines"); | ||||
| /* Render filled polygon on a separate framebuffer */ | /* Render filled polygon on a separate framebuffer */ | ||||
| GPU_framebuffer_bind(fbl->outlines_prepass_fb); | GPU_framebuffer_bind(fbl->outlines_prepass_fb); | ||||
| GPU_framebuffer_clear_color_depth_stencil(fbl->outlines_prepass_fb, clearcol, 1.0f, 0x00); | GPU_framebuffer_clear_color_depth_stencil(fbl->outlines_prepass_fb, clearcol, 1.0f, 0x00); | ||||
| Show All 9 Lines | |||||