diff options
-rw-r--r-- | source/blender/draw/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/blender/draw/DRW_engine.h | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 7 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_armature.c | 39 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 67 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_text.c | 199 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_text.h | 54 | ||||
-rw-r--r-- | source/blender/draw/modes/object_mode.c | 27 | ||||
-rw-r--r-- | source/blender/gpu/GPU_viewport.h | 3 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_viewport.c | 7 |
10 files changed, 400 insertions, 6 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 805971ebeae..20298e064f1 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -61,6 +61,7 @@ set(SRC intern/draw_cache_impl_mesh.c intern/draw_common.c intern/draw_manager.c + intern/draw_manager_text.c intern/draw_view.c modes/edit_armature_mode.c modes/edit_curve_mode.c @@ -87,6 +88,7 @@ set(SRC intern/draw_cache.h intern/draw_cache_impl.h intern/draw_common.h + intern/draw_manager_text.h intern/draw_view.h modes/draw_mode_engines.h engines/basic/basic_engine.h diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index 187ea6c1a11..dbb25796050 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -38,6 +38,7 @@ struct bContext; struct Object; struct SceneLayer; struct ViewContext; +struct ViewportEngineData; struct View3D; struct rcti; diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index a5b193483ce..39b8e23db80 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -62,6 +62,7 @@ struct Object; struct Batch; struct DefaultFramebufferList; struct DefaultTextureList; +struct DRWTextStore; struct LampEngineData; struct RenderEngineType; struct ViewportEngineData; @@ -310,6 +311,8 @@ bool DRW_is_object_renderable(struct Object *ob); /* Draw commands */ void DRW_draw_pass(DRWPass *pass); +void DRW_draw_text_cache_queue(struct DRWTextStore *dt); + void DRW_draw_callbacks_pre_scene(void); void DRW_draw_callbacks_post_scene(void); @@ -322,6 +325,10 @@ void DRW_select_load_id(unsigned int id); void DRW_state_dfdy_factors_get(float dfdyfac[2]); bool DRW_state_is_fbo(void); bool DRW_state_is_select(void); +bool DRW_state_is_depth(void); +bool DRW_state_show_text(void); + +struct DRWTextStore *DRW_state_text_cache_get(void); /* Avoid too many lookups while drawing */ typedef struct DRWContextState { diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c index 676170de64e..64568d92efc 100644 --- a/source/blender/draw/intern/draw_armature.c +++ b/source/blender/draw/intern/draw_armature.c @@ -60,6 +60,7 @@ #include "UI_resources.h" #include "draw_common.h" +#include "draw_manager_text.h" #define BONE_VAR(eBone, pchan, var) ((eBone) ? (eBone->var) : (pchan->var)) #define BONE_FLAG(eBone, pchan) ((eBone) ? (eBone->flag) : (pchan->bone->flag)) @@ -485,6 +486,8 @@ static void draw_armature_edit(Object *ob) update_color(NULL); + const bool show_text = DRW_state_show_text(); + for (eBone = arm->edbo->first, index = 0; eBone; eBone = eBone->next, index++) { if (eBone->layer & arm->layer) { if ((eBone->flag & BONE_HIDDEN_A) == 0) { @@ -508,6 +511,21 @@ static void draw_armature_edit(Object *ob) draw_bone_octahedral(eBone, NULL, arm, select_id); } + /* Draw names of bone */ + if (show_text && (arm->flag & ARM_DRAWNAMES)) { + unsigned char color[4]; + UI_GetThemeColor4ubv((eBone->flag & BONE_SELECTED) ? TH_TEXT_HI : TH_TEXT, color); + + float vec[3]; + mid_v3_v3v3(vec, eBone->head, eBone->tail); + mul_m4_v3(ob->obmat, vec); + + struct DRWTextStore *dt = DRW_text_cache_ensure(); + DRW_text_cache_add( + dt, vec, eBone->name, strlen(eBone->name), + 10, DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_STRING_PTR, color); + } + /* Draw additional axes */ if (arm->flag & ARM_DRAWAXES) { draw_axes(eBone, NULL); @@ -543,7 +561,8 @@ static void draw_armature_pose(Object *ob, const float const_color[4]) } } - bool is_pose_select = (arm->flag & ARM_POSEMODE) && DRW_state_is_select(); + const bool is_pose_select = (arm->flag & ARM_POSEMODE) && DRW_state_is_select(); + const bool show_text = DRW_state_show_text(); /* being set below */ arm->layer_used = 0; @@ -578,9 +597,25 @@ static void draw_armature_pose(Object *ob, const float const_color[4]) draw_bone_octahedral(NULL, pchan, arm, select_id); } + /* Draw names of bone */ + if (show_text && (arm->flag & ARM_DRAWNAMES)) { + unsigned char color[4]; + UI_GetThemeColor4ubv((arm->flag & ARM_POSEMODE) && + (pchan->bone->flag & BONE_SELECTED) ? TH_TEXT_HI : TH_TEXT, color); + float vec[3]; + mid_v3_v3v3(vec, pchan->pose_head, pchan->pose_tail); + mul_m4_v3(ob->obmat, vec); + + struct DRWTextStore *dt = DRW_text_cache_ensure(); + DRW_text_cache_add( + dt, vec, pchan->name, strlen(pchan->name), + 10, DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_STRING_PTR, color); + } + /* Draw additional axes */ - if (arm->flag & ARM_DRAWAXES) + if (arm->flag & ARM_DRAWAXES) { draw_axes(NULL, pchan); + } if (is_pose_select) { index += 0x10000; diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 6c85a2c83ee..0748d37b6ea 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -64,6 +64,8 @@ #include "UI_resources.h" +#include "draw_manager_text.h" + /* only for callbacks */ #include "draw_cache_impl.h" @@ -227,9 +229,17 @@ static struct DRWGlobalState { float screenvecs[2][3]; float pixsize; + struct { + unsigned int is_select : 1; + unsigned int is_depth : 1; + } options; + /* Current rendering context */ DRWContextState draw_ctx; + /* Convenience pointer to text_store owned by the viewport */ + struct DRWTextStore **text_store_p; + ListBase enabled_engines; /* RenderEngineType */ } DST = {NULL}; @@ -1351,6 +1361,16 @@ void DRW_state_reset(void) {} /** \} */ +struct DRWTextStore *DRW_text_cache_ensure(void) +{ + BLI_assert(DST.text_store_p); + if (*DST.text_store_p == NULL) { + *DST.text_store_p = DRW_text_cache_create(); + } + return *DST.text_store_p; +} + + /* -------------------------------------------------------------------- */ /** \name Settings @@ -1699,6 +1719,15 @@ static void DRW_engines_cache_init(void) for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { DrawEngineType *engine = link->data; ViewportEngineData *data = DRW_viewport_engine_data_get(engine); + + if (data->text_draw_cache) { + DRW_text_cache_destroy(data->text_draw_cache); + data->text_draw_cache = NULL; + } + if (DST.text_store_p == NULL) { + DST.text_store_p = &data->text_draw_cache; + } + double stime = PIL_check_seconds_timer(); data->cache_time = 0.0; @@ -1776,6 +1805,22 @@ static void DRW_engines_draw_scene(void) } } +static void DRW_engines_draw_text(void) +{ + for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { + DrawEngineType *engine = link->data; + ViewportEngineData *data = DRW_viewport_engine_data_get(engine); + double stime = PIL_check_seconds_timer(); + + if (data->text_draw_cache) { + DRW_text_cache_draw(data->text_draw_cache, DST.draw_ctx.v3d, DST.draw_ctx.ar, false); + } + + double ftime = (PIL_check_seconds_timer() - stime) * 1e3; + data->render_time = data->render_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */ + } +} + static void use_drw_engine(DrawEngineType *engine) { LinkData *ld = MEM_callocN(sizeof(LinkData), "enabled engine link data"); @@ -2081,6 +2126,8 @@ void DRW_draw_view(const bContext *C) DRW_draw_callbacks_post_scene(); ED_region_draw_cb_draw(C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW); + DRW_engines_draw_text(); + /* needed so manipulator isn't obscured */ glClear(GL_DEPTH_BUFFER_BIT); @@ -2139,6 +2186,8 @@ void DRW_draw_select_loop( DST.viewport = viewport; v3d->zbuf = true; + DST.options.is_select = true; + /* Get list of enabled engines */ if (use_obedit) { DRW_engines_enable_from_mode(obedit_mode); @@ -2228,6 +2277,8 @@ void DRW_draw_depth_loop( DST.viewport = viewport; v3d->zbuf = true; + DST.options.is_depth = true; + /* Get list of enabled engines */ { DRW_engines_enable_basic(); @@ -2312,7 +2363,21 @@ bool DRW_state_is_fbo(void) */ bool DRW_state_is_select(void) { - return (G.f & G_PICKSEL) != 0; + return DST.options.is_select; +} + +bool DRW_state_is_depth(void) +{ + return DST.options.is_depth; +} + +/** + * Should text draw in this mode? + */ +bool DRW_state_show_text(void) +{ + return (DST.options.is_select) == 0 && + (DST.options.is_depth) == 0; } /** \} */ diff --git a/source/blender/draw/intern/draw_manager_text.c b/source/blender/draw/intern/draw_manager_text.c new file mode 100644 index 00000000000..56255af98ce --- /dev/null +++ b/source/blender/draw/intern/draw_manager_text.c @@ -0,0 +1,199 @@ +/* + * Copyright 2016, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/** \file blender/draw/intern/draw_manager_text.c + * \ingroup draw + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_math.h" + +#include "BIF_gl.h" + +#include "GPU_matrix.h" + +#include "ED_screen.h" +#include "ED_view3d.h" + +#include "UI_resources.h" +#include "UI_interface.h" + +#include "WM_api.h" +#include "BLF_api.h" + +#include "draw_manager_text.h" + +typedef struct ViewCachedString { + struct ViewCachedString *next, *prev; + float vec[3]; + union { + unsigned char ub[4]; + int pack; + } col; + short sco[2]; + short xoffs; + short flag; + int str_len; + + /* str is allocated past the end */ + char str[0]; +} ViewCachedString; + +typedef struct DRWTextStore { + ListBase list; +} DRWTextStore; + +DRWTextStore *DRW_text_cache_create(void) +{ + DRWTextStore *dt = MEM_callocN(sizeof(*dt), __func__); + return dt; +} + +void DRW_text_cache_destroy(struct DRWTextStore *dt) +{ + BLI_freelistN(&dt->list); + MEM_freeN(dt); +} + +void DRW_text_cache_add( + DRWTextStore *dt, + const float co[3], + const char *str, const int str_len, + short xoffs, short flag, + const unsigned char col[4]) +{ + int alloc_len; + ViewCachedString *vos; + + if (flag & DRW_TEXT_CACHE_STRING_PTR) { + BLI_assert(str_len == strlen(str)); + alloc_len = sizeof(void *); + } + else { + alloc_len = str_len + 1; + } + + vos = MEM_mallocN(sizeof(ViewCachedString) + alloc_len, __func__); + + BLI_addtail(&dt->list, vos); + + copy_v3_v3(vos->vec, co); + copy_v4_v4_uchar(vos->col.ub, col); + vos->xoffs = xoffs; + vos->flag = flag; + vos->str_len = str_len; + + /* allocate past the end */ + if (flag & DRW_TEXT_CACHE_STRING_PTR) { + memcpy(vos->str, &str, alloc_len); + } + else { + memcpy(vos->str, str, alloc_len); + } +} + +void DRW_text_cache_draw( + DRWTextStore *dt, + View3D *v3d, ARegion *ar, bool depth_write) +{ + RegionView3D *rv3d = ar->regiondata; + ViewCachedString *vos; + int tot = 0; + + /* project first and test */ + for (vos = dt->list.first; vos; vos = vos->next) { + if (ED_view3d_project_short_ex( + ar, + (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; + } + } + + if (tot) { + int col_pack_prev = 0; + + if (rv3d->rflag & RV3D_CLIPPING) { + ED_view3d_clipping_disable(); + } + + float original_proj[4][4]; + gpuGetProjectionMatrix(original_proj); + wmOrtho2_region_pixelspace(ar); + + gpuPushMatrix(); + gpuLoadIdentity(); + + if (depth_write) { + if (v3d->zbuf) glDisable(GL_DEPTH_TEST); + } + else { + glDepthMask(GL_FALSE); + } + + const int font_id = BLF_default(); + + const uiStyle *style = UI_style_get(); + + BLF_size(font_id, style->widget.points * U.pixelsize, U.dpi); + + for (vos = dt->list.first; vos; vos = vos->next) { + 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]), (depth_write) ? 0.0f : 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); + } + } + + if (depth_write) { + if (v3d->zbuf) glEnable(GL_DEPTH_TEST); + } + else { + glDepthMask(GL_TRUE); + } + + gpuPopMatrix(); + gpuLoadProjectionMatrix(original_proj); + + if (rv3d->rflag & RV3D_CLIPPING) { + ED_view3d_clipping_enable(); + } + } +} diff --git a/source/blender/draw/intern/draw_manager_text.h b/source/blender/draw/intern/draw_manager_text.h new file mode 100644 index 00000000000..a58e167be0d --- /dev/null +++ b/source/blender/draw/intern/draw_manager_text.h @@ -0,0 +1,54 @@ +/* + * Copyright 2016, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/** \file blender/draw/intern/draw_manager_text.h + * \ingroup draw + */ + +#ifndef __DRAW_MANAGER_TEXT_H__ +#define __DRAW_MANAGER_TEXT_H__ + +struct DRWTextStore; + +struct DRWTextStore *DRW_text_cache_create(void); +void DRW_text_cache_destroy(struct DRWTextStore *dt); + +void DRW_text_cache_add( + struct DRWTextStore *dt, + const float co[3], + const char *str, const int str_len, + short xoffs, short flag, + const unsigned char col[4]); + +void DRW_text_cache_draw( + struct DRWTextStore *dt, + struct View3D *v3d, struct ARegion *ar, bool depth_write); + +enum { + DRW_TEXT_CACHE_ASCII = (1 << 0), + DRW_TEXT_CACHE_GLOBALSPACE = (1 << 1), + DRW_TEXT_CACHE_LOCALCLIP = (1 << 2), + /* reference the string by pointer */ + DRW_TEXT_CACHE_STRING_PTR = (1 << 3), +}; + +/* draw_manager.c */ +struct DRWTextStore *DRW_text_cache_ensure(void); + +#endif /* __DRAW_MANAGER_TEXT_H__ */ diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index efff11ce1ce..e626060a8b5 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -47,6 +47,7 @@ #include "UI_resources.h" #include "draw_mode_engines.h" +#include "draw_manager_text.h" #include "draw_common.h" extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */ @@ -1179,6 +1180,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) const DRWContextState *draw_ctx = DRW_context_state_get(); Scene *scene = draw_ctx->scene; SceneLayer *sl = draw_ctx->sl; + int theme_id = TH_UNDEFINED; //CollectionEngineSettings *ces_mode_ob = BKE_object_collection_engine_get(ob, COLLECTION_MODE_OBJECT, ""); @@ -1190,7 +1192,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) if (ob != obedit) { struct Batch *geom = DRW_cache_object_surface_get(ob); if (geom) { - int theme_id = DRW_object_wire_theme_get(ob, sl, NULL); + theme_id = DRW_object_wire_theme_get(ob, sl, NULL); DRWShadingGroup *shgroup = shgroup_theme_id_to_outline_or(stl, theme_id, NULL); if (shgroup != NULL) { DRW_shgroup_call_add(shgroup, geom, ob->obmat); @@ -1208,7 +1210,9 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) Object *obedit = scene->obedit; if (ob != obedit) { struct Batch *geom = DRW_cache_lattice_wire_get(ob); - int theme_id = DRW_object_wire_theme_get(ob, sl, NULL); + if (theme_id == TH_UNDEFINED) { + theme_id = DRW_object_wire_theme_get(ob, sl, NULL); + } DRWShadingGroup *shgroup = shgroup_theme_id_to_wire_or(stl, theme_id, stl->g_data->wire); DRW_shgroup_call_add(shgroup, geom, ob->obmat); @@ -1221,7 +1225,9 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) Object *obedit = scene->obedit; if (ob != obedit) { struct Batch *geom = DRW_cache_curve_edge_wire_get(ob); - int theme_id = DRW_object_wire_theme_get(ob, sl, NULL); + if (theme_id == TH_UNDEFINED) { + theme_id = DRW_object_wire_theme_get(ob, sl, NULL); + } DRWShadingGroup *shgroup = shgroup_theme_id_to_wire_or(stl, theme_id, stl->g_data->wire); DRW_shgroup_call_add(shgroup, geom, ob->obmat); } @@ -1266,6 +1272,21 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) DRW_shgroup_object_center(stl, ob); DRW_shgroup_relationship_lines(stl, ob); + + if ((ob->dtx & OB_DRAWNAME) && DRW_state_show_text()) { + struct DRWTextStore *dt = DRW_text_cache_ensure(); + if (theme_id == TH_UNDEFINED) { + theme_id = DRW_object_wire_theme_get(ob, sl, NULL); + } + + unsigned char color[4]; + UI_GetThemeColor4ubv(theme_id, color); + + DRW_text_cache_add( + dt, ob->obmat[3], + ob->id.name + 2, strlen(ob->id.name + 2), + 10, DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_STRING_PTR, color); + } } static void OBJECT_draw_scene(void *vedata) diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h index f1a4e0bbcdb..93bf96a5830 100644 --- a/source/blender/gpu/GPU_viewport.h +++ b/source/blender/gpu/GPU_viewport.h @@ -66,6 +66,9 @@ typedef struct ViewportEngineData { PassList *psl; StorageList *stl; + /* we may want to put this elsewhere */ + struct DRWTextStore *text_draw_cache; + /* Profiling data */ double init_time; double cache_time; diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index 3781a9c8be0..94c2b022e86 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -123,6 +123,13 @@ static void gpu_viewport_engines_data_free(GPUViewport *viewport) MEM_freeN(data->psl); MEM_freeN(data->stl); + /* We could handle this in the DRW module */ + if (data->text_draw_cache) { + extern void DRW_text_cache_destroy(struct DRWTextStore *dt); + DRW_text_cache_destroy(data->text_draw_cache); + data->text_draw_cache = NULL; + } + MEM_freeN(data); BLI_remlink(&viewport->data, link); |