예제 #1
0
void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
{
	ListBase anim_data = {NULL, NULL};
	bAnimListElem *ale;
	int filter;
	
	View2D *v2d = &ar->v2d;
	float y = 0.0f;
	size_t items;
	int height;
	
	/* build list of channels to draw */
	filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
	items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
	
	/* Update max-extent of channels here (taking into account scrollers):
	 *  - this is done to allow the channel list to be scrollable, but must be done here
	 *    to avoid regenerating the list again and/or also because channels list is drawn first
	 *	- offset of NLACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for 
	 *	  start of list offset, and the second is as a correction for the scrollers.
	 */
	height = ((items * NLACHANNEL_STEP(snla)) + (NLACHANNEL_HEIGHT(snla) * 2));
	/* 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);
	
	/* loop through channels, and set up drawing depending on their type  */
	y = (float)(-NLACHANNEL_HEIGHT(snla));
	
	for (ale = anim_data.first; ale; ale = ale->next) {
		const float yminc = (float)(y - NLACHANNEL_HEIGHT_HALF(snla));
		const float ymaxc = (float)(y + NLACHANNEL_HEIGHT_HALF(snla));
		
		/* check if visible */
		if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
		    IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
		{
			/* data to draw depends on the type of channel */
			switch (ale->type) {
				case ANIMTYPE_NLATRACK:
				{
					AnimData *adt = ale->adt;
					NlaTrack *nlt = (NlaTrack *)ale->data;
					NlaStrip *strip;
					int index;
					
					/* draw each strip in the track (if visible) */
					for (strip = nlt->strips.first, index = 1; strip; strip = strip->next, index++) {
						if (BKE_nlastrip_within_bounds(strip, v2d->cur.xmin, v2d->cur.xmax)) {
							/* draw the visualization of the strip */
							nla_draw_strip(snla, adt, nlt, strip, v2d, yminc, ymaxc);
							
							/* add the text for this strip to the cache */
							nla_draw_strip_text(adt, nlt, strip, index, v2d, yminc, ymaxc);
							
							/* if transforming strips (only real reason for temp-metas currently), 
							 * add to the cache the frame numbers of the strip's extents
							 */
							if (strip->flag & NLASTRIP_FLAG_TEMP_META)
								nla_draw_strip_frames_text(nlt, strip, v2d, yminc, ymaxc);
						}
					}
					break;
				}
				case ANIMTYPE_NLAACTION:
				{
					AnimData *adt = ale->adt;
					float color[4];
					
					/* just draw a semi-shaded rect spanning the width of the viewable area if there's data,
					 * and a second darker rect within which we draw keyframe indicator dots if there's data
					 */
					glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
					glEnable(GL_BLEND);
						
					/* get colors for drawing */
					nla_action_get_color(adt, ale->data, color);
					glColor4fv(color);
					
					/* draw slightly shifted up for greater separation from standard channels,
					 * but also slightly shorter for some more contrast when viewing the strips
					 */
					glRectf(v2d->cur.xmin, yminc + NLACHANNEL_SKIP, v2d->cur.xmax, ymaxc - NLACHANNEL_SKIP);
					
					/* draw keyframes in the action */
					nla_action_draw_keyframes(adt, ale->data, v2d, y, yminc + NLACHANNEL_SKIP, ymaxc - NLACHANNEL_SKIP);
					
					/* draw 'embossed' lines above and below the strip for effect */
					/* white base-lines */
					glLineWidth(2.0f);
					glColor4f(1.0f, 1.0f, 1.0f, 0.3);
					fdrawline(v2d->cur.xmin, yminc + NLACHANNEL_SKIP, v2d->cur.xmax, yminc + NLACHANNEL_SKIP);
					fdrawline(v2d->cur.xmin, ymaxc - NLACHANNEL_SKIP, v2d->cur.xmax, ymaxc - NLACHANNEL_SKIP);
					
					/* black top-lines */
					glLineWidth(1.0f);
					glColor3f(0.0f, 0.0f, 0.0f);
					fdrawline(v2d->cur.xmin, yminc + NLACHANNEL_SKIP, v2d->cur.xmax, yminc + NLACHANNEL_SKIP);
					fdrawline(v2d->cur.xmin, ymaxc - NLACHANNEL_SKIP, v2d->cur.xmax, ymaxc - NLACHANNEL_SKIP);
					
					glDisable(GL_BLEND);
					break;
				}
			}
		}
		
		/* adjust y-position for next one */
		y -= NLACHANNEL_STEP(snla);
	}
	
	/* free tempolary channels */
	ANIM_animdata_freelist(&anim_data);
}
예제 #2
0
파일: nla_draw.c 프로젝트: dfelinto/blender
void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
{
  View2D *v2d = &ar->v2d;
  const float pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
  const float text_margin_x = (8 * UI_DPI_FAC) * pixelx;

  /* build list of channels to draw */
  ListBase anim_data = {NULL, NULL};
  int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
  size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);

  /* Update max-extent of channels here (taking into account scrollers):
   * - this is done to allow the channel list to be scrollable, but must be done here
   *   to avoid regenerating the list again and/or also because channels list is drawn first
   * - offset of NLACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
   *   start of list offset, and the second is as a correction for the scrollers.
   */
  int height = NLACHANNEL_TOT_HEIGHT(ac, items);
  v2d->tot.ymin = -height;

  /* loop through channels, and set up drawing depending on their type  */
  float ymax = NLACHANNEL_FIRST_TOP(ac);

  for (bAnimListElem *ale = anim_data.first; ale; ale = ale->next, ymax -= NLACHANNEL_STEP(snla)) {
    float ymin = ymax - NLACHANNEL_HEIGHT(snla);
    float ycenter = (ymax + ymin) / 2.0f;

    /* check if visible */
    if (IN_RANGE(ymin, v2d->cur.ymin, v2d->cur.ymax) ||
        IN_RANGE(ymax, v2d->cur.ymin, v2d->cur.ymax)) {
      /* data to draw depends on the type of channel */
      switch (ale->type) {
        case ANIMTYPE_NLATRACK: {
          AnimData *adt = ale->adt;
          NlaTrack *nlt = (NlaTrack *)ale->data;
          NlaStrip *strip;
          int index;

          /* draw each strip in the track (if visible) */
          for (strip = nlt->strips.first, index = 1; strip; strip = strip->next, index++) {
            if (BKE_nlastrip_within_bounds(strip, v2d->cur.xmin, v2d->cur.xmax)) {
              const float xminc = strip->start + text_margin_x;
              const float xmaxc = strip->end + text_margin_x;

              /* draw the visualization of the strip */
              nla_draw_strip(snla, adt, nlt, strip, v2d, ymin, ymax);

              /* add the text for this strip to the cache */
              if (xminc < xmaxc) {
                nla_draw_strip_text(adt, nlt, strip, index, v2d, xminc, xmaxc, ymin, ymax);
              }

              /* if transforming strips (only real reason for temp-metas currently),
               * add to the cache the frame numbers of the strip's extents
               */
              if (strip->flag & NLASTRIP_FLAG_TEMP_META) {
                nla_draw_strip_frames_text(nlt, strip, v2d, ymin, ymax);
              }
            }
          }
          break;
        }
        case ANIMTYPE_NLAACTION: {
          AnimData *adt = ale->adt;

          uint pos = GPU_vertformat_attr_add(
              immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
          immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);

          /* just draw a semi-shaded rect spanning the width of the viewable area if there's data,
           * and a second darker rect within which we draw keyframe indicator dots if there's data
           */
          GPU_blend_set_func_separate(
              GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
          GPU_blend(true);

          /* get colors for drawing */
          float color[4];
          nla_action_get_color(adt, ale->data, color);
          immUniformColor4fv(color);

          /* draw slightly shifted up for greater separation from standard channels,
           * but also slightly shorter for some more contrast when viewing the strips
           */
          immRectf(
              pos, v2d->cur.xmin, ymin + NLACHANNEL_SKIP, v2d->cur.xmax, ymax - NLACHANNEL_SKIP);

          /* draw 'embossed' lines above and below the strip for effect */
          /* white base-lines */
          GPU_line_width(2.0f);
          immUniformColor4f(1.0f, 1.0f, 1.0f, 0.3f);
          immBegin(GPU_PRIM_LINES, 4);
          immVertex2f(pos, v2d->cur.xmin, ymin + NLACHANNEL_SKIP);
          immVertex2f(pos, v2d->cur.xmax, ymin + NLACHANNEL_SKIP);
          immVertex2f(pos, v2d->cur.xmin, ymax - NLACHANNEL_SKIP);
          immVertex2f(pos, v2d->cur.xmax, ymax - NLACHANNEL_SKIP);
          immEnd();

          /* black top-lines */
          GPU_line_width(1.0f);
          immUniformColor3f(0.0f, 0.0f, 0.0f);
          immBegin(GPU_PRIM_LINES, 4);
          immVertex2f(pos, v2d->cur.xmin, ymin + NLACHANNEL_SKIP);
          immVertex2f(pos, v2d->cur.xmax, ymin + NLACHANNEL_SKIP);
          immVertex2f(pos, v2d->cur.xmin, ymax - NLACHANNEL_SKIP);
          immVertex2f(pos, v2d->cur.xmax, ymax - NLACHANNEL_SKIP);
          immEnd();

          /* TODO: these lines but better --^ */

          immUnbindProgram();

          /* draw keyframes in the action */
          nla_action_draw_keyframes(
              v2d, adt, ale->data, ycenter, ymin + NLACHANNEL_SKIP, ymax - NLACHANNEL_SKIP);

          GPU_blend(false);
          break;
        }
      }
    }
  }

  /* free tempolary channels */
  ANIM_animdata_freelist(&anim_data);
}