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:
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_draw.c')
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c222
1 files changed, 196 insertions, 26 deletions
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 33c883822a0..f933e0778a8 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1947,16 +1947,19 @@ typedef struct View3DAfter {
struct View3DAfter *next, *prev;
struct Base *base;
short dflag;
+ float obmat[4][4];
} View3DAfter;
/* temp storage of Objects that need to be drawn as last */
void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag)
{
View3DAfter *v3da = MEM_callocN(sizeof(View3DAfter), "View 3d after");
- BLI_assert((base->flag & OB_FROMDUPLI) == 0);
BLI_addtail(lb, v3da);
v3da->base = base;
v3da->dflag = dflag;
+ if (base->flag & OB_FROMDUPLI) {
+ copy_m4_m4(v3da->obmat, base->object->obmat);
+ }
}
/* disables write in zbuffer and draws it over */
@@ -1968,8 +1971,17 @@ static void view3d_draw_transp(Scene *scene, ARegion *ar, View3D *v3d)
v3d->transp = true;
for (v3da = v3d->afterdraw_transp.first; v3da; v3da = next) {
+ float obmat[4][4];
next = v3da->next;
+ if (v3da->base->flag & OB_FROMDUPLI) {
+ copy_m4_m4(obmat, v3da->base->object->obmat);
+ copy_m4_m4(v3da->base->object->obmat, v3da->obmat);
+ }
draw_object(scene, ar, v3d, v3da->base, v3da->dflag);
+ if (v3da->base->flag & OB_FROMDUPLI) {
+ copy_m4_m4(v3da->base->object->obmat, obmat);
+ MEM_freeN(v3da->base);
+ }
BLI_remlink(&v3d->afterdraw_transp, v3da);
MEM_freeN(v3da);
}
@@ -2004,6 +2016,7 @@ static void view3d_draw_xray(Scene *scene, ARegion *ar, View3D *v3d, bool *clear
static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, const bool clear)
{
View3DAfter *v3da, *next;
+ float obmat[4][4];
if (clear && v3d->zbuf)
glClear(GL_DEPTH_BUFFER_BIT);
@@ -2015,7 +2028,15 @@ static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, const
for (v3da = v3d->afterdraw_xraytransp.first; v3da; v3da = next) {
next = v3da->next;
+ if (v3da->base->flag & OB_FROMDUPLI) {
+ copy_m4_m4(obmat, v3da->base->object->obmat);
+ copy_m4_m4(v3da->base->object->obmat, v3da->obmat);
+ }
draw_object(scene, ar, v3d, v3da->base, v3da->dflag);
+ if (v3da->base->flag & OB_FROMDUPLI) {
+ copy_m4_m4(v3da->base->object->obmat, obmat);
+ MEM_freeN(v3da->base);
+ }
BLI_remlink(&v3d->afterdraw_xraytransp, v3da);
MEM_freeN(v3da);
}
@@ -2026,6 +2047,46 @@ static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, const
glDepthMask(GL_TRUE);
}
+static void view3d_draw_nodepth(Scene *scene, ARegion *ar, View3D *v3d)
+{
+ View3DAfter *v3da, *next;
+
+ RegionView3D *rv3d = ar->regiondata;
+
+ glDepthMask(GL_FALSE);
+
+ /* setup drawing environment for paths */
+
+ for (v3da = v3d->afterdraw_nodepth.first; v3da; v3da = next) {
+ Object *ob = v3da->base->object;
+ next = v3da->next;
+
+ glPushMatrix();
+ ED_view3d_init_mats_rv3d_gl(ob, rv3d);
+ view3d_cached_text_draw_begin();
+ if (ob->type == OB_MESH) {
+ bAnimVizSettings *avs = &ob->avs;
+ /* draw motion path for object */
+ draw_motion_paths_init(v3d, ar);
+ draw_motion_path_instance(scene, ob, NULL, avs, ob->mpath);
+ draw_motion_paths_cleanup(v3d);
+ }
+ else if (ob->type == OB_ARMATURE) {
+ draw_pose_paths(scene, v3d, ar, ob);
+ }
+ view3d_cached_text_draw_end(v3d, ar, 1, NULL);
+ ED_view3d_clear_mats_rv3d(rv3d);
+
+ glPopMatrix();
+
+ BLI_remlink(&v3d->afterdraw_nodepth, v3da);
+ MEM_freeN(v3da);
+ }
+
+ /* cleanup after drawing */
+ glDepthMask(GL_TRUE);
+}
+
/* *********************** */
/*
@@ -2046,6 +2107,27 @@ int dupli_ob_sort(void *arg1, void *arg2)
}
#endif
+static void draw_dupli_object(Scene *scene, ARegion *ar, View3D *v3d,
+ Base *base, DupliObject *UNUSED(dob), DupliObjectData *dob_data,
+ short dflag, bool draw_dupli_strands)
+{
+ draw_object(scene, ar, v3d, base, dflag);
+
+ if (dob_data) {
+
+ /* draw strands only when not editing */
+ if (draw_dupli_strands) {
+ DupliObjectDataStrands *link;
+
+ for (link = dob_data->strands.first; link; link = link->next) {
+ struct Strands *strands = link->strands;
+ struct StrandsChildren *children = link->strands_children;
+
+ draw_strands(scene, v3d, ar, base->object, strands, children, dflag);
+ }
+ }
+ }
+}
static DupliObject *dupli_step(DupliObject *dob)
{
@@ -2067,6 +2149,7 @@ static void draw_dupli_objects_color(
GLuint displist = 0;
unsigned char color_rgb[3];
const short dflag_dupli = dflag | DRAW_CONSTCOLOR;
+ const bool draw_dupli_strands = !(base->object->mode & OB_MODE_HAIR_EDIT);
short transflag;
bool use_displist = false; /* -1 is initialize */
char dt;
@@ -2084,7 +2167,7 @@ static void draw_dupli_objects_color(
UI_GetThemeColorBlend3ubv(color, TH_BACK, 0.5f, color_rgb);
}
- tbase.flag = OB_FROMDUPLI | base->flag;
+ tbase.flag |= OB_FROMDUPLI;
lb = object_duplilist(G.main->eval_ctx, scene, base->object);
// BLI_listbase_sort(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */
@@ -2094,7 +2177,12 @@ static void draw_dupli_objects_color(
if (dob) dob_next = dupli_step(dob->next);
for (; dob; dob_prev = dob, dob = dob_next, dob_next = dob_next ? dupli_step(dob_next->next) : NULL) {
+ /* for restoring after override */
+ DupliObjectData *dob_data = NULL;
+ DerivedMesh *store_final_dm;
+
tbase.object = dob->ob;
+ store_final_dm = dob->ob->derivedFinal;
/* Make sure lod is updated from dupli's position */
@@ -2116,7 +2204,7 @@ static void draw_dupli_objects_color(
* slow it down too much */
dtx = tbase.object->dtx;
if (tbase.object->dt != OB_BOUNDBOX)
- tbase.object->dtx = base->object->dtx;
+ tbase.object->dtx = base->object->dtx | (dtx & OB_DRAWTRANSP);
/* negative scale flag has to propagate */
transflag = tbase.object->transflag;
@@ -2131,6 +2219,21 @@ static void draw_dupli_objects_color(
glColor3ubv(color_rgb);
}
+ /* override final DM */
+ bb_tmp = NULL;
+ tbase.object->transflag &= ~OB_IS_DUPLI_CACHE;
+ if (base->object->dup_cache) {
+ dob_data = BKE_dupli_cache_find_data(base->object->dup_cache, tbase.object);
+ if (dob_data && dob_data->dm) {
+ tbase.object->transflag |= OB_IS_DUPLI_CACHE;
+
+ tbase.object->derivedFinal = dob_data->dm;
+ bb_tmp = &dob_data->bb;
+ }
+ }
+ if (!bb_tmp)
+ bb_tmp = BKE_object_boundbox_get(dob->ob);
+
/* generate displist, test for new object */
if (dob_prev && dob_prev->ob != dob->ob) {
if (use_displist == true)
@@ -2139,7 +2242,7 @@ static void draw_dupli_objects_color(
use_displist = false;
}
- if ((bb_tmp = BKE_object_boundbox_get(dob->ob))) {
+ if (bb_tmp) {
bb = *bb_tmp; /* must make a copy */
testbb = true;
}
@@ -2161,7 +2264,8 @@ static void draw_dupli_objects_color(
!bb_tmp ||
draw_glsl_material(scene, dob->ob, v3d, dt) ||
check_object_draw_texture(scene, v3d, dt) ||
- (v3d->flag2 & V3D_SOLID_MATCAP) != 0)
+ (v3d->flag2 & V3D_SOLID_MATCAP) != 0 ||
+ ((dtx & OB_DRAWTRANSP) != 0))
{
// printf("draw_dupli_objects_color: skipping displist for %s\n", dob->ob->id.name + 2);
use_displist = false;
@@ -2176,7 +2280,7 @@ static void draw_dupli_objects_color(
displist = glGenLists(1);
glNewList(displist, GL_COMPILE);
- draw_object(scene, ar, v3d, &tbase, dflag_dupli);
+ draw_dupli_object(scene, ar, v3d, &tbase, dob, dob_data, dflag_dupli, draw_dupli_strands);
glEndList();
use_displist = true;
@@ -2192,10 +2296,26 @@ static void draw_dupli_objects_color(
}
else {
copy_m4_m4(dob->ob->obmat, dob->mat);
- draw_object(scene, ar, v3d, &tbase, dflag_dupli);
+ draw_dupli_object(scene, ar, v3d, &tbase, dob, dob_data, dflag_dupli, draw_dupli_strands);
}
}
+ /* restore final DM */
+ if (tbase.object->transflag & OB_IS_DUPLI_CACHE) {
+ DerivedMesh *cur = tbase.object->derivedFinal;
+
+ /* in some cases drawing code can recreate the derivedFinal,
+ * make sure we free those first before restoring
+ */
+ if (cur && cur != dob_data->dm) {
+ cur->needsFree = 1;
+ cur->release(cur);
+ }
+
+ tbase.object->transflag &= ~OB_IS_DUPLI_CACHE;
+ tbase.object->derivedFinal = store_final_dm;
+ }
+
tbase.object->dt = dt;
tbase.object->dtx = dtx;
tbase.object->transflag = transflag;
@@ -2213,17 +2333,27 @@ static void draw_dupli_objects_color(
glDeleteLists(displist, 1);
}
-static void draw_dupli_objects(Scene *scene, ARegion *ar, View3D *v3d, Base *base)
+static void draw_dupli_objects(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const bool is_wire_color)
{
/* define the color here so draw_dupli_objects_color can be called
* from the set loop */
-
- int color = (base->flag & SELECT) ? TH_SELECT : TH_WIRE;
- /* debug */
- if (base->object->dup_group && base->object->dup_group->id.us < 1)
- color = TH_REDALERT;
-
- draw_dupli_objects_color(scene, ar, v3d, base, 0, color);
+ short dflag;
+ int color;
+
+ if (is_wire_color) {
+ glColor3fv(base->object->col);
+ color = TH_UNDEFINED;
+ dflag = DRAW_CONSTCOLOR;
+ }
+ else {
+ color = (base->flag & SELECT) ? TH_SELECT : TH_WIRE;
+ /* debug */
+ if (base->object->dup_group && base->object->dup_group->id.us < 1)
+ color = TH_REDALERT;
+ dflag = 0;
+ }
+
+ draw_dupli_objects_color(scene, ar, v3d, base, dflag, color);
}
/* XXX warning, not using gpu offscreen here */
@@ -2724,6 +2854,7 @@ static void view3d_draw_objects(
RegionView3D *rv3d = ar->regiondata;
Base *base;
const bool do_camera_frame = !draw_offscreen;
+ const bool is_wire_color = V3D_IS_WIRECOLOR(scene, v3d);
const bool draw_grids = !draw_offscreen && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0;
const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO);
/* only draw grids after in solid modes, else it hovers over mesh wires */
@@ -2814,7 +2945,7 @@ static void view3d_draw_objects(
if (v3d->lay & base->lay) {
/* dupli drawing */
if (base->object->transflag & OB_DUPLI)
- draw_dupli_objects(scene, ar, v3d, base);
+ draw_dupli_objects(scene, ar, v3d, base, is_wire_color && (base->object->dtx & OB_DRAW_WIRECOLOR));
draw_object(scene, ar, v3d, base, 0);
}
@@ -2831,7 +2962,7 @@ static void view3d_draw_objects(
/* dupli drawing */
if (base->object->transflag & OB_DUPLI) {
- draw_dupli_objects(scene, ar, v3d, base);
+ draw_dupli_objects(scene, ar, v3d, base, is_wire_color && (base->object->dtx & OB_DRAW_WIRECOLOR));
}
if ((base->flag & SELECT) == 0) {
if (base->object != scene->obedit)
@@ -2843,6 +2974,10 @@ static void view3d_draw_objects(
/* mask out localview */
v3d->lay_used = lay_used & ((1 << 20) - 1);
+ if (is_wire_color && (v3d->drawtype <= OB_WIRE)) {
+ glClear(GL_DEPTH_BUFFER_BIT);
+ }
+
/* draw selected and editmode */
for (base = scene->base.first; base; base = base->next) {
if (v3d->lay & base->lay) {
@@ -2878,6 +3013,8 @@ static void view3d_draw_objects(
if (v3d->afterdraw_xray.first) view3d_draw_xray(scene, ar, v3d, &xrayclear);
if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, v3d, xrayclear);
+ if (v3d->afterdraw_nodepth.first) view3d_draw_nodepth(scene, ar, v3d);
+
if (fx && do_composite_xray) {
GPU_fx_compositor_XRay_resolve(fx);
}
@@ -2894,10 +3031,6 @@ static void view3d_draw_objects(
view3d_draw_bgpic_test(scene, ar, v3d, true, do_camera_frame);
}
- if (!draw_offscreen) {
- BIF_draw_manipulator(C);
- }
-
/* cleanup */
if (v3d->zbuf) {
v3d->zbuf = false;
@@ -2934,6 +3067,8 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d)
*/
static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
{
+ const bool is_wire_color = V3D_IS_WIRECOLOR(scene, v3d);
+
if (scene->world && (v3d->flag3 & V3D_SHOW_WORLD)) {
bool glsl = GPU_glsl_support() && BKE_scene_use_new_shading_nodes(scene) && scene->world->nodetree && scene->world->use_nodes;
@@ -3096,6 +3231,12 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
#undef VIEWGRAD_RES_X
#undef VIEWGRAD_RES_Y
+
+ if (is_wire_color) {
+ float col_mid[3];
+ mid_v3_v3v3(col_mid, col_hor, col_zen);
+ draw_object_bg_wire_color_set(col_mid);
+ }
}
else { /* solid sky */
float col_hor[3];
@@ -3104,10 +3245,18 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
glClearColor(col_hor[0], col_hor[1], col_hor[2], 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if (is_wire_color) {
+ draw_object_bg_wire_color_set(col_hor);
+ }
}
}
else {
if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
+ float col_low[3], col_high[3];
+
+ UI_GetThemeColor3fv(TH_HIGH_GRAD, col_high);
+ UI_GetThemeColor3fv(TH_LOW_GRAD, col_low);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
@@ -3119,10 +3268,10 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
glDepthFunc(GL_ALWAYS);
glShadeModel(GL_SMOOTH);
glBegin(GL_QUADS);
- UI_ThemeColor(TH_LOW_GRAD);
+ glColor3fv(col_low);
glVertex3f(-1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, 1.0);
- UI_ThemeColor(TH_HIGH_GRAD);
+ glColor3fv(col_high);
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0);
glEnd();
@@ -3136,10 +3285,23 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
+
+ if (is_wire_color) {
+ float col_mid[3];
+ mid_v3_v3v3(col_mid, col_low, col_high);
+ draw_object_bg_wire_color_set(col_mid);
+ }
}
else {
+ float col[3];
+
+ UI_GetThemeColor3fv(TH_HIGH_GRAD, col);
UI_ThemeClearColorAlpha(TH_HIGH_GRAD, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if (is_wire_color) {
+ draw_object_bg_wire_color_set(col);
+ }
}
}
}
@@ -3759,6 +3921,8 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3
/* main drawing call */
view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false, do_compositing ? rv3d->compositor : NULL);
+ WM_widgets_draw(C, ar->widgetmaps.first, true);
+
/* post process */
if (do_compositing) {
GPU_fx_do_composite_pass(rv3d->compositor, rv3d->winmat, rv3d->is_persp, scene, NULL);
@@ -3872,7 +4036,7 @@ static void view3d_main_area_draw_info(const bContext *C, Scene *scene,
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
wmWindowManager *wm = CTX_wm_manager(C);
- if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_playing(wm)) {
+ if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {
ED_scene_draw_fps(scene, &rect);
}
else if (U.uiflag & USER_SHOW_VIEWPORTNAME) {
@@ -3907,6 +4071,8 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
render_border = ED_view3d_calc_render_border(scene, v3d, ar, &border_rect);
clip_border = (render_border && !BLI_rcti_compare(&ar->drawrct, &border_rect));
+ WM_widgets_update(C, ar->widgetmaps.first);
+
/* draw viewport using opengl */
if (v3d->drawtype != OB_RENDER || !view3d_main_area_do_render_draw(scene) || clip_border) {
view3d_main_area_draw_objects(C, scene, v3d, ar, &grid_unit);
@@ -3916,14 +4082,18 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
#endif
if (G.debug & G_DEBUG_SIMDATA)
draw_sim_debug_data(scene, v3d, ar);
-
- ED_region_pixelspace(ar);
}
/* draw viewport using external renderer */
if (v3d->drawtype == OB_RENDER)
view3d_main_area_draw_engine(C, scene, ar, v3d, clip_border, &border_rect);
+ view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL);
+ glClear(GL_DEPTH_BUFFER_BIT);
+ WM_widgets_draw(C, ar->widgetmaps.first, false);
+ BIF_draw_manipulator(C);
+ ED_region_pixelspace(ar);
+
view3d_main_area_draw_info(C, scene, ar, v3d, grid_unit, render_border);
v3d->flag |= V3D_INVALID_BACKBUF;