diff options
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 8 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 10 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_common.c | 5 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_common.h | 4 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_fluid.c | 8 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 314 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_text.c | 130 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_view.c | 60 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_view.h | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/shaders/common_globals_lib.glsl | 2 |
10 files changed, 454 insertions, 88 deletions
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index e154a52b32f..8e3562216e9 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -736,9 +736,11 @@ bool DRW_state_draw_background(void); /* Avoid too many lookups while drawing */ typedef struct DRWContextState { - struct ARegion *region; /* 'CTX_wm_region(C)' */ - struct RegionView3D *rv3d; /* 'CTX_wm_region_view3d(C)' */ - struct View3D *v3d; /* 'CTX_wm_view3d(C)' */ + + struct ARegion *region; /* 'CTX_wm_region(C)' */ + struct RegionView3D *rv3d; /* 'CTX_wm_region_view3d(C)' */ + struct View3D *v3d; /* 'CTX_wm_view3d(C)' */ + struct SpaceLink *space_data; /* 'CTX_wm_space_data(C)' */ struct Scene *scene; /* 'CTX_data_scene(C)' */ struct ViewLayer *view_layer; /* 'CTX_data_view_layer(C)' */ diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index c7ba707d403..d090832dc4b 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -1559,8 +1559,14 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, scene, ts, use_hide); - /* TODO(jbakker): Work-around for threading issues in 2.90. See T79533, T79038. Needs to be - * solved or made permanent in 2.91. Underlying issue still needs to be researched. */ + + /* Ensure that all requested batches have finished. + * Ideally we want to remove this sync, but there are cases where this doesn't work. + * See T79038 for example. + * + * An idea to improve this is to separate the Object mode from the edit mode draw caches. And + * based on the mode the correct one will be updated. Other option is to look into using + * drw_batch_cache_generate_requested_delayed. */ BLI_task_graph_work_and_wait(task_graph); #ifdef DEBUG drw_mesh_batch_cache_check_available(task_graph, me); diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index ea5421f3965..56f31a69396 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -178,6 +178,9 @@ void DRW_globals_update(void) UI_GetThemeColorShadeAlpha4fv(TH_WIRE, 0, -30, gb->colorOutline); UI_GetThemeColorShadeAlpha4fv(TH_LIGHT, 0, 255, gb->colorLightNoAlpha); + /* UV colors */ + UI_GetThemeColor4fv(TH_UV_SHADOW, gb->colorUVShadow); + gb->sizePixel = U.pixelsize; gb->sizeObjectCenter = (UI_GetThemeValuef(TH_OBCENTER_DIA) + 1.0f) * U.pixelsize; gb->sizeLightCenter = (UI_GetThemeValuef(TH_OBCENTER_DIA) + 1.5f) * U.pixelsize; @@ -210,7 +213,7 @@ void DRW_globals_update(void) /* TODO more accurate transform. */ srgb_to_linearrgb_v4(color, color); color += 4; - } while (color != gb->UBO_LAST_COLOR); + } while (color <= gb->UBO_LAST_COLOR); } if (G_draw.block_ubo == NULL) { diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index 645848e7fe0..e3967678319 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -33,7 +33,7 @@ struct RegionView3D; struct ViewLayer; #define UBO_FIRST_COLOR colorWire -#define UBO_LAST_COLOR colorFaceFront +#define UBO_LAST_COLOR colorUVShadow /* Used as ubo but colors can be directly referenced as well */ /* Keep in sync with: common_globals_lib.glsl (globalsBlock) */ @@ -141,6 +141,8 @@ typedef struct GlobalsUboStorage { float colorFaceBack[4]; float colorFaceFront[4]; + float colorUVShadow[4]; + /* NOTE! Put all color before UBO_LAST_COLOR */ float screenVecs[2][4]; /* padded as vec4 */ float sizeViewport[2], sizeViewportInv[2]; /* packed as vec4 in glsl */ diff --git a/source/blender/draw/intern/draw_fluid.c b/source/blender/draw/intern/draw_fluid.c index af14f11e6e9..809512bd7dd 100644 --- a/source/blender/draw/intern/draw_fluid.c +++ b/source/blender/draw/intern/draw_fluid.c @@ -183,6 +183,10 @@ static GPUTexture *create_volume_texture(const int dim[3], GPUTexture *tex = NULL; int final_dim[3] = {UNPACK3(dim)}; + if (data == NULL) { + return NULL; + } + while (1) { tex = GPU_texture_create_3d("volume", UNPACK3(final_dim), 1, format, NULL); @@ -292,6 +296,10 @@ static GPUTexture *create_density_texture(FluidDomainSettings *fds, int highres) data = manta_smoke_get_density(fds->fluid); } + if (data == NULL) { + return NULL; + } + GPUTexture *tex = create_volume_texture(dim, GPU_R8, data); swizzle_texture_channel_single(tex); return tex; diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index e6d51bce54e..203f8af130d 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -78,6 +78,7 @@ #include "RE_pipeline.h" #include "UI_resources.h" +#include "UI_view2d.h" #include "WM_api.h" #include "wm_window.h" @@ -94,6 +95,7 @@ #include "engines/eevee/eevee_engine.h" #include "engines/external/external_engine.h" #include "engines/gpencil/gpencil_engine.h" +#include "engines/image/image_engine.h" #include "engines/overlay/overlay_engine.h" #include "engines/select/select_engine.h" #include "engines/workbench/workbench_engine.h" @@ -126,6 +128,25 @@ static void drw_state_ensure_not_reused(DRWManager *dst) } #endif +static bool drw_draw_show_annotation(void) +{ + if (DST.draw_ctx.space_data == NULL) { + View3D *v3d = DST.draw_ctx.v3d; + return (v3d && ((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) && + ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0)); + } + + switch (DST.draw_ctx.space_data->spacetype) { + case SPACE_IMAGE: { + SpaceImage *sima = (SpaceImage *)DST.draw_ctx.space_data; + return (sima->flag & SI_SHOW_GPENCIL) != 0; + } + default: + BLI_assert(""); + return false; + } +} + /* -------------------------------------------------------------------- */ /** \name Threading * \{ */ @@ -287,6 +308,7 @@ struct DupliObject *DRW_object_get_dupli(const Object *UNUSED(ob)) /** \name Color Management * \{ */ +/* TODO(fclem) This should be a render engine callback to determine if we need CM or not. */ static void drw_viewport_colormanagement_set(void) { Scene *scene = DST.draw_ctx.scene; @@ -296,21 +318,43 @@ static void drw_viewport_colormanagement_set(void) ColorManagedViewSettings view_settings; float dither = 0.0f; - /* TODO(fclem) This should be a render engine callback to determine if we need CM or not. */ - bool use_workbench = BKE_scene_uses_blender_workbench(scene); - - bool use_scene_lights = (!v3d || - ((v3d->shading.type == OB_MATERIAL) && - (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS)) || - ((v3d->shading.type == OB_RENDER) && - (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS_RENDER))); - bool use_scene_world = - (!v3d || - ((v3d->shading.type == OB_MATERIAL) && (v3d->shading.flag & V3D_SHADING_SCENE_WORLD)) || - ((v3d->shading.type == OB_RENDER) && (v3d->shading.flag & V3D_SHADING_SCENE_WORLD_RENDER))); - bool use_view_transform = v3d && (v3d->shading.type >= OB_MATERIAL); - bool use_render_settings = v3d && ((use_workbench && use_view_transform) || use_scene_lights || - use_scene_world); + bool use_render_settings = false; + bool use_view_transform = false; + + if (v3d) { + bool use_workbench = BKE_scene_uses_blender_workbench(scene); + + bool use_scene_lights = (!v3d || + ((v3d->shading.type == OB_MATERIAL) && + (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS)) || + ((v3d->shading.type == OB_RENDER) && + (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS_RENDER))); + bool use_scene_world = (!v3d || + ((v3d->shading.type == OB_MATERIAL) && + (v3d->shading.flag & V3D_SHADING_SCENE_WORLD)) || + ((v3d->shading.type == OB_RENDER) && + (v3d->shading.flag & V3D_SHADING_SCENE_WORLD_RENDER))); + use_view_transform = v3d && (v3d->shading.type >= OB_MATERIAL); + use_render_settings = v3d && ((use_workbench && use_view_transform) || use_scene_lights || + use_scene_world); + } + else if (DST.draw_ctx.space_data && DST.draw_ctx.space_data->spacetype == SPACE_IMAGE) { + SpaceImage *sima = (SpaceImage *)DST.draw_ctx.space_data; + Image *image = sima->image; + + /* Use inverse logic as there isn't a setting for `Color And Alpha`. */ + const eSpaceImage_Flag display_channels_mode = sima->flag; + const bool display_color_channel = (display_channels_mode & (SI_SHOW_ALPHA | SI_SHOW_ZBUF)) == + 0; + if (display_color_channel && image && (image->source != IMA_SRC_GENERATED) && + ((image->flag & IMA_VIEW_AS_RENDER) != 0)) { + use_render_settings = true; + } + } + else { + use_render_settings = true; + use_view_transform = false; + } if (use_render_settings) { /* Use full render settings, for renders with scene lighting. */ @@ -495,6 +539,8 @@ static void draw_unit_state_create(void) static void drw_viewport_var_init(void) { RegionView3D *rv3d = DST.draw_ctx.rv3d; + ARegion *region = DST.draw_ctx.region; + /* Refresh DST.size */ if (DST.viewport) { int size[2]; @@ -585,6 +631,24 @@ static void drw_viewport_var_init(void) DST.view_active = DST.view_default; DST.view_previous = NULL; } + else if (region) { + View2D *v2d = ®ion->v2d; + float viewmat[4][4]; + float winmat[4][4]; + + rctf region_space = {0.0f, 1.0f, 0.0f, 1.0f}; + BLI_rctf_transform_calc_m4_pivot_min(&v2d->cur, ®ion_space, viewmat); + + unit_m4(winmat); + winmat[0][0] = 2.0f; + winmat[1][1] = 2.0f; + winmat[3][0] = -1.0f; + winmat[3][1] = -1.0f; + + DST.view_default = DRW_view_create(viewmat, winmat, NULL, NULL, NULL); + DST.view_active = DST.view_default; + DST.view_previous = NULL; + } else { zero_v3(DST.screenvecs[0]); zero_v3(DST.screenvecs[1]); @@ -596,7 +660,7 @@ static void drw_viewport_var_init(void) } /* fclem: Is this still needed ? */ - if (DST.draw_ctx.object_edit) { + if (DST.draw_ctx.object_edit && rv3d) { ED_view3d_init_mats_rv3d(DST.draw_ctx.object_edit, rv3d); } @@ -1163,6 +1227,19 @@ static void drw_engines_enable_basic(void) use_drw_engine(&draw_engine_basic_type); } +static void drw_engines_enable_editors(void) +{ + SpaceLink *space_data = DST.draw_ctx.space_data; + if (!space_data) { + return; + } + + if (space_data->spacetype == SPACE_IMAGE) { + use_drw_engine(&draw_engine_image_type); + use_drw_engine(&draw_engine_overlay_type); + } +} + static void drw_engines_enable(ViewLayer *UNUSED(view_layer), RenderEngineType *engine_type, bool gpencil_engine_needed) @@ -1299,8 +1376,7 @@ void DRW_draw_callbacks_post_scene(void) View3D *v3d = DST.draw_ctx.v3d; Depsgraph *depsgraph = DST.draw_ctx.depsgraph; - const bool do_annotations = (v3d && ((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) && - ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0)); + const bool do_annotations = drw_draw_show_annotation(); if (DST.draw_ctx.evil_C) { DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); @@ -1387,21 +1463,30 @@ struct DRWTextStore *DRW_text_cache_ensure(void) * for each relevant engine / mode engine. */ void DRW_draw_view(const bContext *C) { - Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C); - ARegion *region = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); - Scene *scene = DEG_get_evaluated_scene(depsgraph); - RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type); - GPUViewport *viewport = WM_draw_region_get_bound_viewport(region); + if (v3d) { + Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C); + ARegion *region = CTX_wm_region(C); + Scene *scene = DEG_get_evaluated_scene(depsgraph); + RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type); + GPUViewport *viewport = WM_draw_region_get_bound_viewport(region); - /* Reset before using it. */ - drw_state_prepare_clean_for_draw(&DST); - DST.options.draw_text = ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 && - (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) != 0); - DST.options.draw_background = (scene->r.alphamode == R_ADDSKY) || - (v3d->shading.type != OB_RENDER); - DST.options.do_color_management = true; - DRW_draw_render_loop_ex(depsgraph, engine_type, region, v3d, viewport, C); + /* Reset before using it. */ + drw_state_prepare_clean_for_draw(&DST); + DST.options.draw_text = ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 && + (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) != 0); + DST.options.draw_background = (scene->r.alphamode == R_ADDSKY) || + (v3d->shading.type != OB_RENDER); + DST.options.do_color_management = true; + DRW_draw_render_loop_ex(depsgraph, engine_type, region, v3d, viewport, C); + } + else { + Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C); + ARegion *ar = CTX_wm_region(C); + GPUViewport *viewport = WM_draw_region_get_bound_viewport(ar); + drw_state_prepare_clean_for_draw(&DST); + DRW_draw_render_loop_2d_ex(depsgraph, ar, viewport, C); + } } /** @@ -1909,6 +1994,171 @@ void DRW_cache_restart(void) copy_v2_v2(DST.inv_size, inv_size); } +void DRW_draw_render_loop_2d_ex(struct Depsgraph *depsgraph, + ARegion *region, + GPUViewport *viewport, + const bContext *evil_C) +{ + Scene *scene = DEG_get_evaluated_scene(depsgraph); + ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); + + DST.draw_ctx.evil_C = evil_C; + DST.viewport = viewport; + + /* Setup viewport */ + DST.draw_ctx = (DRWContextState){ + .region = region, + .scene = scene, + .view_layer = view_layer, + .obact = OBACT(view_layer), + .depsgraph = depsgraph, + .space_data = CTX_wm_space_data(evil_C), + + /* reuse if caller sets */ + .evil_C = DST.draw_ctx.evil_C, + }; + + drw_context_state_init(); + drw_viewport_var_init(); + drw_viewport_colormanagement_set(); + + /* TODO(jbakker): Only populate when editor needs to draw object. + * for the image editor this is when showing UV's.*/ + const bool do_populate_loop = true; + const bool do_annotations = drw_draw_show_annotation(); + + /* Get list of enabled engines */ + drw_engines_enable_editors(); + drw_engines_data_validate(); + + /* Update ubos */ + DRW_globals_update(); + + drw_debug_init(); + + /* No framebuffer allowed before drawing. */ + BLI_assert(GPU_framebuffer_active_get() == GPU_framebuffer_back_get()); + GPU_framebuffer_bind(DST.default_framebuffer); + GPU_framebuffer_clear_depth_stencil(DST.default_framebuffer, 1.0f, 0xFF); + + /* Init engines */ + drw_engines_init(); + drw_task_graph_init(); + + /* Cache filling */ + { + PROFILE_START(stime); + drw_engines_cache_init(); + + /* Only iterate over objects when overlay uses object data. */ + if (do_populate_loop) { + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) { + drw_engines_cache_populate(ob); + } + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END; + } + + drw_engines_cache_finish(); + + DRW_render_instance_buffer_finish(); + +#ifdef USE_PROFILE + double *cache_time = GPU_viewport_cache_time_get(DST.viewport); + PROFILE_END_UPDATE(*cache_time, stime); +#endif + } + drw_task_graph_deinit(); + + DRW_stats_begin(); + + GPU_framebuffer_bind(DST.default_framebuffer); + + /* Start Drawing */ + DRW_state_reset(); + + if (DST.draw_ctx.evil_C) { + ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.region, REGION_DRAW_PRE_VIEW); + } + + drw_engines_draw_scene(); + + /* Fix 3D view being "laggy" on macos and win+nvidia. (See T56996, T61474) */ + GPU_flush(); + + if (DST.draw_ctx.evil_C) { + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + DRW_state_reset(); + + GPU_framebuffer_bind(dfbl->overlay_fb); + + if (do_annotations) { + GPU_depth_test(false); + GPU_matrix_push_projection(); + wmOrtho2( + region->v2d.cur.xmin, region->v2d.cur.xmax, region->v2d.cur.ymin, region->v2d.cur.ymax); + ED_annotation_draw_view2d(DST.draw_ctx.evil_C, true); + GPU_matrix_pop_projection(); + + GPU_depth_test(true); + } + + GPU_depth_test(false); + ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.region, REGION_DRAW_POST_VIEW); + GPU_depth_test(true); + /* Callback can be nasty and do whatever they want with the state. + * Don't trust them! */ + DRW_state_reset(); + + GPU_depth_test(false); + drw_engines_draw_text(); + GPU_depth_test(true); + + if (do_annotations) { + GPU_depth_test(false); + ED_annotation_draw_view2d(DST.draw_ctx.evil_C, false); + GPU_depth_test(true); + } + } + + DRW_draw_cursor_2d(); + ED_region_pixelspace(DST.draw_ctx.region); + + { + GPU_depth_test(false); + DRW_draw_gizmo_2d(); + GPU_depth_test(true); + } + + DRW_stats_reset(); + + if (G.debug_value > 20 && G.debug_value < 30) { + GPU_depth_test(false); + /* local coordinate visible rect inside region, to accommodate overlapping ui */ + const rcti *rect = ED_region_visible_rect(DST.draw_ctx.region); + DRW_stats_draw(rect); + GPU_depth_test(true); + } + + if (WM_draw_region_get_bound_viewport(region)) { + /* Don't unbind the framebuffer yet in this case and let + * GPU_viewport_unbind do it, so that we can still do further + * drawing of action zones on top. */ + } + else { + GPU_framebuffer_restore(); + } + + DRW_state_reset(); + drw_engines_disable(); + + drw_viewport_cache_resize(); + +#ifdef DEBUG + /* Avoid accidental reuse. */ + drw_state_ensure_not_reused(&DST); +#endif +} + static struct DRWSelectBuffer { struct GPUFrameBuffer *framebuffer_depth_only; struct GPUTexture *texture_depth; @@ -2637,6 +2887,8 @@ void DRW_engines_register(void) DRW_engine_register(&draw_engine_select_type); DRW_engine_register(&draw_engine_basic_type); + DRW_engine_register(&draw_engine_image_type); + /* setup callbacks */ { BKE_mball_batch_cache_dirty_tag_cb = DRW_mball_batch_cache_dirty_tag; diff --git a/source/blender/draw/intern/draw_manager_text.c b/source/blender/draw/intern/draw_manager_text.c index adcac15ab85..e3d0dab6767 100644 --- a/source/blender/draw/intern/draw_manager_text.c +++ b/source/blender/draw/intern/draw_manager_text.c @@ -24,6 +24,7 @@ #include "BLI_math.h" #include "BLI_memiter.h" +#include "BLI_rect.h" #include "BLI_string.h" #include "BKE_editmesh.h" @@ -122,76 +123,105 @@ void DRW_text_cache_add(DRWTextStore *dt, } } -void DRW_text_cache_draw(DRWTextStore *dt, ARegion *region, struct View3D *v3d) +static void drw_text_cache_draw_ex(DRWTextStore *dt, ARegion *region) { - RegionView3D *rv3d = region->regiondata; ViewCachedString *vos; - int tot = 0; - - /* project first and test */ BLI_memiter_handle it; - BLI_memiter_iter_init(dt->cache_strings, &it); - while ((vos = BLI_memiter_iter_step(&it))) { - if (ED_view3d_project_short_ex( - region, - (vos->flag & DRW_TEXT_CACHE_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob, - (vos->flag & DRW_TEXT_CACHE_LOCALCLIP) != 0, - vos->vec, - vos->sco, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == - V3D_PROJ_RET_OK) { - tot++; - } - else { - vos->sco[0] = IS_CLIPPED; - } - } + int col_pack_prev = 0; - if (tot) { - int col_pack_prev = 0; + float original_proj[4][4]; + GPU_matrix_projection_get(original_proj); + wmOrtho2_region_pixelspace(region); - /* Disable clipping for text */ - if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) { - GPU_clip_distances(0); - } + GPU_matrix_push(); + GPU_matrix_identity_set(); - float original_proj[4][4]; - GPU_matrix_projection_get(original_proj); - wmOrtho2_region_pixelspace(region); + const int font_id = BLF_default(); - GPU_matrix_push(); - GPU_matrix_identity_set(); + const uiStyle *style = UI_style_get(); - const int font_id = BLF_default(); + BLF_size(font_id, style->widget.points * U.pixelsize, U.dpi); - const uiStyle *style = UI_style_get(); + BLI_memiter_iter_init(dt->cache_strings, &it); + while ((vos = BLI_memiter_iter_step(&it))) { + if (vos->sco[0] != IS_CLIPPED) { + if (col_pack_prev != vos->col.pack) { + BLF_color4ubv(font_id, vos->col.ub); + col_pack_prev = vos->col.pack; + } + + BLF_position( + font_id, (float)(vos->sco[0] + vos->xoffs), (float)(vos->sco[1] + vos->yoffs), 2.0f); + + ((vos->flag & DRW_TEXT_CACHE_ASCII) ? BLF_draw_ascii : BLF_draw)( + font_id, + (vos->flag & DRW_TEXT_CACHE_STRING_PTR) ? *((const char **)vos->str) : vos->str, + vos->str_len); + } + } - BLF_size(font_id, style->widget.points * U.pixelsize, U.dpi); + GPU_matrix_pop(); + GPU_matrix_projection_set(original_proj); +} +void DRW_text_cache_draw(DRWTextStore *dt, ARegion *region, struct View3D *v3d) +{ + ViewCachedString *vos; + if (v3d) { + RegionView3D *rv3d = region->regiondata; + int tot = 0; + /* project first and test */ + BLI_memiter_handle it; BLI_memiter_iter_init(dt->cache_strings, &it); while ((vos = BLI_memiter_iter_step(&it))) { - if (vos->sco[0] != IS_CLIPPED) { - if (col_pack_prev != vos->col.pack) { - BLF_color4ubv(font_id, vos->col.ub); - col_pack_prev = vos->col.pack; - } + if (ED_view3d_project_short_ex( + region, + (vos->flag & DRW_TEXT_CACHE_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob, + (vos->flag & DRW_TEXT_CACHE_LOCALCLIP) != 0, + vos->vec, + vos->sco, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == + V3D_PROJ_RET_OK) { + tot++; + } + else { + vos->sco[0] = IS_CLIPPED; + } + } - BLF_position( - font_id, (float)(vos->sco[0] + vos->xoffs), (float)(vos->sco[1] + vos->yoffs), 2.0f); + if (tot) { + /* Disable clipping for text */ + const bool rv3d_clipping_enabled = RV3D_CLIPPING_ENABLED(v3d, rv3d); + if (rv3d_clipping_enabled) { + GPU_clip_distances(0); + } + + drw_text_cache_draw_ex(dt, region); - ((vos->flag & DRW_TEXT_CACHE_ASCII) ? BLF_draw_ascii : BLF_draw)( - font_id, - (vos->flag & DRW_TEXT_CACHE_STRING_PTR) ? *((const char **)vos->str) : vos->str, - vos->str_len); + if (rv3d_clipping_enabled) { + GPU_clip_distances(6); } } + } + else { + /* project first */ + BLI_memiter_handle it; + BLI_memiter_iter_init(dt->cache_strings, &it); + View2D *v2d = ®ion->v2d; + float viewmat[4][4]; + rctf region_space = {0.0f, region->winx, 0.0f, region->winy}; + BLI_rctf_transform_calc_m4_pivot_min(&v2d->cur, ®ion_space, viewmat); - GPU_matrix_pop(); - GPU_matrix_projection_set(original_proj); + while ((vos = BLI_memiter_iter_step(&it))) { + float p[3]; + copy_v3_v3(p, vos->vec); + mul_m4_v3(viewmat, p); - if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) { - GPU_clip_distances(6); + vos->sco[0] = p[0]; + vos->sco[1] = p[1]; } + + drw_text_cache_draw_ex(dt, region); } } diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index d01e1a51080..3033cf70b29 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -35,6 +35,7 @@ #include "GPU_shader.h" #include "UI_resources.h" +#include "UI_view2d.h" #include "WM_types.h" @@ -196,6 +197,65 @@ void DRW_draw_cursor(void) } } +/* -------------------------------------------------------------------- */ + +/** \name 2D Cursor + * \{ */ + +static bool is_cursor_visible_2d(const DRWContextState *draw_ctx) +{ + SpaceInfo *space_data = (SpaceInfo *)draw_ctx->space_data; + if (space_data == NULL) { + return false; + } + if (space_data->spacetype == SPACE_IMAGE) { + SpaceImage *sima = (SpaceImage *)draw_ctx->space_data; + return sima->mode == SI_MODE_UV; + } + return false; +} + +void DRW_draw_cursor_2d(void) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + ARegion *region = draw_ctx->region; + + GPU_color_mask(true, true, true, true); + GPU_depth_mask(false); + GPU_depth_test(GPU_DEPTH_NONE); + + if (is_cursor_visible_2d(draw_ctx)) { + SpaceImage *sima = (SpaceImage *)draw_ctx->space_data; + int co[2]; + UI_view2d_view_to_region(®ion->v2d, sima->cursor[0], sima->cursor[1], &co[0], &co[1]); + + /* Draw nice Anti Aliased cursor. */ + GPU_line_width(1.0f); + GPU_blend(true); + GPU_line_smooth(true); + + /* Draw lines */ + float original_proj[4][4]; + GPU_matrix_projection_get(original_proj); + GPU_matrix_push(); + ED_region_pixelspace(region); + GPU_matrix_translate_2f(co[0] + 0.5f, co[1] + 0.5f); + GPU_matrix_scale_2f(U.widget_unit, U.widget_unit); + + GPUBatch *cursor_batch = DRW_cache_cursor_get(true); + GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_FLAT_COLOR); + GPU_batch_set_shader(cursor_batch, shader); + + GPU_batch_draw(cursor_batch); + + GPU_blend(false); + GPU_line_smooth(false); + GPU_matrix_pop(); + GPU_matrix_projection_set(original_proj); + } +} +/* \} */ + /* **************************** 3D Gizmo ******************************** */ void DRW_draw_gizmo_3d(void) diff --git a/source/blender/draw/intern/draw_view.h b/source/blender/draw/intern/draw_view.h index a01a2d0dcce..24fabaae05e 100644 --- a/source/blender/draw/intern/draw_view.h +++ b/source/blender/draw/intern/draw_view.h @@ -25,5 +25,6 @@ void DRW_draw_region_info(void); void DRW_clear_background(void); void DRW_draw_cursor(void); +void DRW_draw_cursor_2d(void); void DRW_draw_gizmo_3d(void); void DRW_draw_gizmo_2d(void); diff --git a/source/blender/draw/intern/shaders/common_globals_lib.glsl b/source/blender/draw/intern/shaders/common_globals_lib.glsl index bd1b1fb6f3a..691f1d5e519 100644 --- a/source/blender/draw/intern/shaders/common_globals_lib.glsl +++ b/source/blender/draw/intern/shaders/common_globals_lib.glsl @@ -103,6 +103,8 @@ layout(std140) uniform globalsBlock vec4 colorFaceBack; vec4 colorFaceFront; + vec4 colorUVShadow; + vec4 screenVecs[2]; vec4 sizeViewport; /* Inverted size in zw. */ |