diff options
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_draw.c')
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 222 |
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; |