Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Bakker <jeroen@blender.org>2020-09-11 08:59:48 +0300
committerJeroen Bakker <jeroen@blender.org>2020-09-11 09:08:46 +0300
commitd6525e8d133b787655bdb2c2fcef218591a457c3 (patch)
treeb4dbb06b75005deee918d7816c074a5735be930c /source/blender/draw/intern
parentd023c4104cb642c839d5868411a3b719f3528421 (diff)
Use DrawManager for Image/UV Editor
This project moves the current UV/Image editor drawing to the draw manager. Why would we do this: **Performance**: Current implementation would draw each texel per time. Multiple texels could be drawn per pixel what would overwrite the previous result. You can notice this when working with large textures. Repeat image drawing made this visible by drawing for a small period of time and stop drawing the rest. Now the rendering is fast and all repeated images are drawn. **Alpha drawing**: Current implementation would draw directly in display space. Giving incorrect results when displaying alpha transparent images. This addresses {T52680}, {T74709}, {T79518} The image editor now can show emission only colors. See {D8234} for examples. **Current Limitations** Using images that are larger than supported by your GPU are resized (eg larger than 16000x16000 are resized to 8k). This leaves some blurring artifacts. It is a low priority to add support back of displaying individual pixels of huge images. There is a design task {T80113} with more detail. **Implementation overview** Introduced an Image Engine in the draw module. this engine is responsible for drawing the texture in the main area of the UV/Image editor. The overlay engine has a edit_uv overlay which is responsible to draw the UV's, shadows and overlays specifically for the UV Image editor. The background + checker pattern is drawn by the overlay_background. The patch will allow us to share overlays between the 3d viewport and UV/Image editor more easily. In most cases we just need to switch the `pos` with the `u` attribute in the vertex shader. The project can be activated in the user preferences as experimental features. In a later commit this will be reversed. Reviewed By: Clément Foucault Differential Revision: https://developer.blender.org/D8234
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r--source/blender/draw/intern/DRW_render.h8
-rw-r--r--source/blender/draw/intern/draw_common.c5
-rw-r--r--source/blender/draw/intern/draw_common.h4
-rw-r--r--source/blender/draw/intern/draw_manager.c314
-rw-r--r--source/blender/draw/intern/draw_manager_text.c130
-rw-r--r--source/blender/draw/intern/draw_view.c60
-rw-r--r--source/blender/draw/intern/draw_view.h1
-rw-r--r--source/blender/draw/intern/shaders/common_globals_lib.glsl2
8 files changed, 438 insertions, 86 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_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_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 = &region->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, &region_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 = &region->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, &region_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(&region->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. */