static void vicon_keytype_draw_wrapper(int x, int y, int w, int h, float alpha, short key_type) { /* init dummy theme state for Action Editor - where these colors are defined * (since we're doing this offscreen, free from any particular space_id) */ struct bThemeState theme_state; int xco, yco; UI_Theme_Store(&theme_state); UI_SetTheme(SPACE_ACTION, RGN_TYPE_WINDOW); /* the "x" and "y" given are the bottom-left coordinates of the icon, * while the draw_keyframe_shape() function needs the midpoint for * the keyframe */ xco = x + w / 2; yco = y + h / 2; /* draw keyframe * - xscale: 1.0 (since there's no timeline scaling to compensate for) * - yscale: 0.3 * h (found out experimentally... dunno why!) * - sel: true (so that "keyframe" state shows the iconic yellow icon) */ draw_keyframe_shape(xco, yco, 1.0f, 0.3f * h, true, key_type, KEYFRAME_SHAPE_BOTH, alpha); UI_Theme_Restore(&theme_state); }
static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, float ypos, short channelLocked) { ActKeyColumn *ak; ActKeyBlock *ab; float alpha; float xscale; float iconsize = U.widget_unit / 4.0f; glEnable(GL_BLEND); /* get View2D scaling factor */ UI_view2d_scale_get(v2d, &xscale, NULL); /* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */ /* TODO: allow this opacity factor to be themed? */ alpha = (channelLocked) ? 0.25f : 1.0f; /* draw keyblocks */ if (blocks) { float sel_color[4], unsel_color[4]; /* cache colours first */ UI_GetThemeColor4fv(TH_STRIP_SELECT, sel_color); UI_GetThemeColor4fv(TH_STRIP, unsel_color); sel_color[3] *= alpha; unsel_color[3] *= alpha; /* NOTE: the tradeoff for changing colors between each draw is dwarfed by the cost of checking validity */ for (ab = blocks->first; ab; ab = ab->next) { if (actkeyblock_is_valid(ab, keys)) { /* draw block */ if (ab->sel) glColor4fv(sel_color); else glColor4fv(unsel_color); glRectf(ab->start, ypos - iconsize, ab->end, ypos + iconsize); } } } /* draw keys */ if (keys) { for (ak = keys->first; ak; ak = ak->next) { /* optimization: if keyframe doesn't appear within 5 units (screenspace) in visible area, don't draw * - this might give some improvements, since we current have to flip between view/region matrices */ if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax) == 0) continue; /* draw using OpenGL - uglier but faster */ /* NOTE1: a previous version of this didn't work nice for some intel cards * NOTE2: if we wanted to go back to icons, these are icon = (ak->sel & SELECT) ? ICON_SPACE2 : ICON_SPACE3; */ draw_keyframe_shape(ak->cfra, ypos, xscale, iconsize, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH, alpha); } } glDisable(GL_BLEND); }
/* draw the keyframes in the specified Action */ static void nla_action_draw_keyframes(AnimData *adt, bAction *act, View2D *v2d, float y, float ymin, float ymax) { DLRBT_Tree keys; ActKeyColumn *ak; float xscale, f1, f2; float color[4]; /* get a list of the keyframes with NLA-scaling applied */ BLI_dlrbTree_init(&keys); action_to_keylist(adt, act, &keys, NULL); BLI_dlrbTree_linkedlist_sync(&keys); if (ELEM(NULL, act, keys.first)) return; /* draw a darkened region behind the strips * - get and reset the background color, this time without the alpha to stand out better * (amplified alpha is used instead) */ nla_action_get_color(adt, act, color); color[3] *= 2.5f; glColor4fv(color); /* - draw a rect from the first to the last frame (no extra overlaps for now) * that is slightly stumpier than the track background (hardcoded 2-units here) */ f1 = ((ActKeyColumn *)keys.first)->cfra; f2 = ((ActKeyColumn *)keys.last)->cfra; glRectf(f1, ymin + 2, f2, ymax - 2); /* get View2D scaling factor */ UI_view2d_scale_get(v2d, &xscale, NULL); /* for now, color is hardcoded to be black */ glColor3f(0.0f, 0.0f, 0.0f); /* just draw each keyframe as a simple dot (regardless of the selection status) * - size is 3.0f which is smaller than the editable keyframes, so that there is a distinction */ for (ak = keys.first; ak; ak = ak->next) draw_keyframe_shape(ak->cfra, y, xscale, 3.0f, 0, ak->key_type, KEYFRAME_SHAPE_FRAME, 1.0f); /* free icons */ BLI_dlrbTree_free(&keys); }
void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) { MovieClip *clip = ED_space_clip_get_clip(sc); View2D *v2d = &ar->v2d; /* frame range */ clip_draw_sfra_efra(v2d, scene); if (clip) { MovieTracking *tracking = &clip->tracking; MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; MovieTrackingDopesheetChannel *channel; float strip[4], selected_strip[4]; float height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT); uint keyframe_len = 0; GPUVertFormat *format = immVertexFormat(); uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* don't use totrect set, as the width stays the same * (NOTE: this is ok here, the configuration is pretty straightforward) */ v2d->tot.ymin = (float)(-height); float y = (float)CHANNEL_FIRST; /* setup colors for regular and selected strips */ UI_GetThemeColor3fv(TH_STRIP, strip); UI_GetThemeColor3fv(TH_STRIP_SELECT, selected_strip); strip[3] = 0.5f; selected_strip[3] = 1.0f; GPU_blend(true); clip_draw_dopesheet_background(ar, clip, pos_id); for (channel = dopesheet->channels.first; channel; channel = channel->next) { float yminc = (float)(y - CHANNEL_HEIGHT_HALF); float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF); /* check if visible */ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { MovieTrackingTrack *track = channel->track; int i; bool sel = (track->flag & TRACK_DOPE_SEL) != 0; /* selection background */ if (sel) { float color[4] = {0.0f, 0.0f, 0.0f, 0.3f}; float default_color[4] = {0.8f, 0.93f, 0.8f, 0.3f}; track_channel_color(track, default_color, color); immUniformColor4fv(color); immRectf(pos_id, v2d->cur.xmin, (float)y - CHANNEL_HEIGHT_HALF, v2d->cur.xmax + EXTRA_SCROLL_PAD, (float)y + CHANNEL_HEIGHT_HALF); } /* tracked segments */ for (i = 0; i < channel->tot_segment; i++) { int start_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i]); int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i + 1]); immUniformColor4fv(sel ? selected_strip : strip); if (start_frame != end_frame) { immRectf(pos_id, start_frame, (float)y - STRIP_HEIGHT_HALF, end_frame, (float)y + STRIP_HEIGHT_HALF); keyframe_len += 2; } else { keyframe_len++; } } /* keyframes */ i = 0; while (i < track->markersnr) { MovieTrackingMarker *marker = &track->markers[i]; if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) { keyframe_len++; } i++; } } /* adjust y-position for next one */ y -= CHANNEL_STEP; } immUnbindProgram(); if (keyframe_len > 0) { /* draw keyframe markers */ format = immVertexFormat(); pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); uint outline_color_id = GPU_vertformat_attr_add( format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT); immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); GPU_program_point_size(true); immUniform2f( "ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1); immBegin(GPU_PRIM_POINTS, keyframe_len); /* all same size with black outline */ immAttr1f(size_id, 2.0f * STRIP_HEIGHT_HALF); immAttr4ub(outline_color_id, 0, 0, 0, 255); immAttr1u(flags_id, 0); y = (float)CHANNEL_FIRST; /* start again at the top */ for (channel = dopesheet->channels.first; channel; channel = channel->next) { float yminc = (float)(y - CHANNEL_HEIGHT_HALF); float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF); /* check if visible */ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { MovieTrackingTrack *track = channel->track; int i; bool sel = (track->flag & TRACK_DOPE_SEL) != 0; float alpha = (track->flag & TRACK_LOCKED) ? 0.5f : 1.0f; /* tracked segments */ for (i = 0; i < channel->tot_segment; i++) { int start_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i]); int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i + 1]); if (start_frame != end_frame) { draw_keyframe_shape(start_frame, y, sel, alpha, pos_id, color_id); draw_keyframe_shape(end_frame, y, sel, alpha, pos_id, color_id); } else { draw_keyframe_shape(start_frame, y, sel, alpha, pos_id, color_id); } } /* keyframes */ i = 0; while (i < track->markersnr) { MovieTrackingMarker *marker = &track->markers[i]; if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) { int framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr); draw_keyframe_shape(framenr, y, sel, alpha, pos_id, color_id); } i++; } } /* adjust y-position for next one */ y -= CHANNEL_STEP; } immEnd(); GPU_program_point_size(false); immUnbindProgram(); } GPU_blend(false); } }
void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) { MovieClip *clip = ED_space_clip_get_clip(sc); View2D *v2d = &ar->v2d; /* frame range */ clip_draw_sfra_efra(v2d, scene); if (clip) { MovieTracking *tracking = &clip->tracking; MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; MovieTrackingDopesheetChannel *channel; float y, xscale, yscale; float strip[4], selected_strip[4]; float height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT); /* don't use totrect set, as the width stays the same * (NOTE: this is ok here, the configuration is pretty straightforward) */ v2d->tot.ymin = (float)(-height); y = (float) CHANNEL_FIRST; UI_view2d_getscale(v2d, &xscale, &yscale); /* setup colors for regular and selected strips */ UI_GetThemeColor3fv(TH_STRIP, strip); UI_GetThemeColor3fv(TH_STRIP_SELECT, selected_strip); strip[3] = 0.5f; selected_strip[3] = 1.0f; glEnable(GL_BLEND); clip_draw_dopesheet_background(ar, clip); for (channel = dopesheet->channels.first; channel; channel = channel->next) { float yminc = (float) (y - CHANNEL_HEIGHT_HALF); float ymaxc = (float) (y + CHANNEL_HEIGHT_HALF); /* check if visible */ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) { MovieTrackingTrack *track = channel->track; float alpha; int i, sel = track->flag & TRACK_DOPE_SEL; /* selection background */ if (sel) { float color[4] = {0.0f, 0.0f, 0.0f, 0.3f}; float default_color[4] = {0.8f, 0.93f, 0.8f, 0.3f}; track_channel_color(track, default_color, color); glColor4fv(color); glRectf(v2d->cur.xmin, (float) y - CHANNEL_HEIGHT_HALF, v2d->cur.xmax + EXTRA_SCROLL_PAD, (float) y + CHANNEL_HEIGHT_HALF); } alpha = (track->flag & TRACK_LOCKED) ? 0.5f : 1.0f; /* tracked segments */ for (i = 0; i < channel->tot_segment; i++) { int start_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i]); int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i + 1]); if (sel) glColor4fv(selected_strip); else glColor4fv(strip); if (start_frame != end_frame) { glRectf(start_frame, (float) y - STRIP_HEIGHT_HALF, end_frame, (float) y + STRIP_HEIGHT_HALF); draw_keyframe_shape(start_frame, y, xscale, yscale, sel, alpha); draw_keyframe_shape(end_frame, y, xscale, yscale, sel, alpha); } else { draw_keyframe_shape(start_frame, y, xscale, yscale, sel, alpha); } } /* keyframes */ i = 0; while (i < track->markersnr) { MovieTrackingMarker *marker = &track->markers[i]; if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) { int framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr); draw_keyframe_shape(framenr, y, xscale, yscale, sel, alpha); } i++; } } /* adjust y-position for next one */ y -= CHANNEL_STEP; } glDisable(GL_BLEND); } /* current frame */ clip_draw_cfra(sc, ar, scene); }
/* draw the keyframes in the specified Action */ static void nla_action_draw_keyframes( View2D *v2d, AnimData *adt, bAction *act, float y, float ymin, float ymax) { /* get a list of the keyframes with NLA-scaling applied */ DLRBT_Tree keys; BLI_dlrbTree_init(&keys); action_to_keylist(adt, act, &keys, 0); if (ELEM(NULL, act, keys.first)) { return; } /* draw a darkened region behind the strips * - get and reset the background color, this time without the alpha to stand out better * (amplified alpha is used instead) */ float color[4]; nla_action_get_color(adt, act, color); color[3] *= 2.5f; GPUVertFormat *format = immVertexFormat(); uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(color); /* - draw a rect from the first to the last frame (no extra overlaps for now) * that is slightly stumpier than the track background (hardcoded 2-units here) */ float f1 = ((ActKeyColumn *)keys.first)->cfra; float f2 = ((ActKeyColumn *)keys.last)->cfra; immRectf(pos_id, f1, ymin + 2, f2, ymax - 2); immUnbindProgram(); /* count keys before drawing */ /* Note: It's safe to cast DLRBT_Tree, as it's designed to degrade down to a ListBase */ uint key_len = BLI_listbase_count((ListBase *)&keys); if (key_len > 0) { format = immVertexFormat(); pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); uint color_id = GPU_vertformat_attr_add( format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); uint outline_color_id = GPU_vertformat_attr_add( format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT); immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); GPU_program_point_size(true); immUniform2f("ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1); immBegin(GPU_PRIM_POINTS, key_len); /* - disregard the selection status of keyframes so they draw a certain way * - size is 6.0f which is smaller than the editable keyframes, so that there is a distinction */ for (ActKeyColumn *ak = keys.first; ak; ak = ak->next) { draw_keyframe_shape(ak->cfra, y, 6.0f, false, ak->key_type, KEYFRAME_SHAPE_FRAME, 1.0f, pos_id, size_id, color_id, outline_color_id, flags_id, KEYFRAME_HANDLE_NONE, KEYFRAME_EXTREME_NONE); } immEnd(); GPU_program_point_size(false); immUnbindProgram(); } /* free icons */ BLI_dlrbTree_free(&keys); }