Пример #1
0
/* main call for drawing a single NLA-strip */
static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStrip *strip, View2D *v2d, float yminc, float ymaxc)
{
	const bool non_solo = ((adt && (adt->flag & ADT_NLA_SOLO_TRACK)) && (nlt->flag & NLATRACK_SOLO) == 0);
	float color[3];
	
	/* get color of strip */
	nla_strip_get_color_inside(adt, strip, color);
	
	/* draw extrapolation info first (as backdrop)
	 *	- but this should only be drawn if track has some contribution
	 */
	if ((strip->extendmode != NLASTRIP_EXTEND_NOTHING) && (non_solo == 0)) {
		/* enable transparency... */
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glEnable(GL_BLEND);
		
		switch (strip->extendmode) {
			/* since this does both sides, only do the 'before' side, and leave the rest to the next case */
			case NLASTRIP_EXTEND_HOLD: 
				/* only need to draw here if there's no strip before since 
				 * it only applies in such a situation 
				 */
				if (strip->prev == NULL) {
					/* set the drawing color to the color of the strip, but with very faint alpha */
					glColor4f(color[0], color[1], color[2], 0.15f);
					
					/* draw the rect to the edge of the screen */
					glBegin(GL_QUADS);
					glVertex2f(v2d->cur.xmin, yminc);
					glVertex2f(v2d->cur.xmin, ymaxc);
					glVertex2f(strip->start, ymaxc);
					glVertex2f(strip->start, yminc);
					glEnd();
				}
				ATTR_FALLTHROUGH;

			/* this only draws after the strip */
			case NLASTRIP_EXTEND_HOLD_FORWARD: 
				/* only need to try and draw if the next strip doesn't occur immediately after */
				if ((strip->next == NULL) || (IS_EQF(strip->next->start, strip->end) == 0)) {
					/* set the drawing color to the color of the strip, but this time less faint */
					glColor4f(color[0], color[1], color[2], 0.3f);
					
					/* draw the rect to the next strip or the edge of the screen */
					glBegin(GL_QUADS);
					glVertex2f(strip->end, yminc);
					glVertex2f(strip->end, ymaxc);
						
					if (strip->next) {
						glVertex2f(strip->next->start, ymaxc);
						glVertex2f(strip->next->start, yminc);
					}
					else {
						glVertex2f(v2d->cur.xmax, ymaxc);
						glVertex2f(v2d->cur.xmax, yminc);
					}
					glEnd();
				}
				break;
		}
		
		glDisable(GL_BLEND);
	}
	
	
	/* draw 'inside' of strip itself */
	if (non_solo == 0) {
		/* strip is in normal track */
		glColor3fv(color);
		UI_draw_roundbox_corner_set(UI_CNR_ALL); /* all corners rounded */
		
		UI_draw_roundbox_shade_x(GL_POLYGON, strip->start, yminc, strip->end, ymaxc, 0.0, 0.5, 0.1);
	}
	else {
		/* strip is in disabled track - make less visible */
		glColor4f(color[0], color[1], color[2], 0.1f);
		
		glEnable(GL_BLEND);
		glRectf(strip->start, yminc, strip->end, ymaxc);
		glDisable(GL_BLEND);
	}
	
	
	/* draw strip's control 'curves'
	 *	- only if user hasn't hidden them...
	 */
	if ((snla->flag & SNLA_NOSTRIPCURVES) == 0)
		nla_draw_strip_curves(strip, yminc, ymaxc);
	
	
	/* draw markings indicating locations of local markers (useful for lining up different actions) */
	if ((snla->flag & SNLA_NOLOCALMARKERS) == 0)
		nla_strip_draw_markers(strip, yminc, ymaxc);
	
	/* draw strip outline 
	 *	- color used here is to indicate active vs non-active
	 */
	if (strip->flag & NLASTRIP_FLAG_ACTIVE) {
		/* strip should appear 'sunken', so draw a light border around it */
		glColor3f(0.9f, 1.0f, 0.9f); // FIXME: hardcoded temp-hack colors
	}
	else {
		/* strip should appear to stand out, so draw a dark border around it */
		glColor3f(0.0f, 0.0f, 0.0f);
	}
	
	/* - line style: dotted for muted */
	if ((nlt->flag & NLATRACK_MUTED) || (strip->flag & NLASTRIP_FLAG_MUTED))
		setlinestyle(4);
		
	/* draw outline */
	UI_draw_roundbox_shade_x(GL_LINE_LOOP, strip->start, yminc, strip->end, ymaxc, 0.0, 0.0, 0.1);
	
	/* if action-clip strip, draw lines delimiting repeats too (in the same color as outline) */
	if ((strip->type == NLASTRIP_TYPE_CLIP) && IS_EQF(strip->repeat, 1.0f) == 0) {
		float repeatLen = (strip->actend - strip->actstart) * strip->scale;
		int i;
		
		/* only draw lines for whole-numbered repeats, starting from the first full-repeat
		 * up to the last full repeat (but not if it lies on the end of the strip)
		 */
		for (i = 1; i < strip->repeat; i++) {
			float repeatPos = strip->start + (repeatLen * i);
			
			/* don't draw if line would end up on or after the end of the strip */
			if (repeatPos < strip->end)
				fdrawline(repeatPos, yminc + 4, repeatPos, ymaxc - 4);
		}
	}
	/* or if meta-strip, draw lines delimiting extents of sub-strips (in same color as outline, if more than 1 exists) */
	else if ((strip->type == NLASTRIP_TYPE_META) && (strip->strips.first != strip->strips.last)) {
		NlaStrip *cs;
		float y = (ymaxc - yminc) / 2.0f + yminc;
		
		/* only draw first-level of child-strips, but don't draw any lines on the endpoints */
		for (cs = strip->strips.first; cs; cs = cs->next) {
			/* draw start-line if not same as end of previous (and only if not the first strip) 
			 *	- on upper half of strip
			 */
			if ((cs->prev) && IS_EQF(cs->prev->end, cs->start) == 0)
				fdrawline(cs->start, y, cs->start, ymaxc);
				
			/* draw end-line if not the last strip
			 *	- on lower half of strip
			 */
			if (cs->next) 
				fdrawline(cs->end, yminc, cs->end, y);
		}
	}
	
	/* reset linestyle */
	setlinestyle(0);
} 
Пример #2
0
/* main call for drawing a single NLA-strip */
static void nla_draw_strip(SpaceNla *snla,
                           AnimData *adt,
                           NlaTrack *nlt,
                           NlaStrip *strip,
                           View2D *v2d,
                           float yminc,
                           float ymaxc)
{
  const bool non_solo = ((adt && (adt->flag & ADT_NLA_SOLO_TRACK)) &&
                         (nlt->flag & NLATRACK_SOLO) == 0);
  const bool muted = ((nlt->flag & NLATRACK_MUTED) || (strip->flag & NLASTRIP_FLAG_MUTED));
  float color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
  uint shdr_pos;

  /* get color of strip */
  nla_strip_get_color_inside(adt, strip, color);

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

  /* draw extrapolation info first (as backdrop)
   * - but this should only be drawn if track has some contribution
   */
  if ((strip->extendmode != NLASTRIP_EXTEND_NOTHING) && (non_solo == 0)) {
    /* enable transparency... */
    GPU_blend_set_func_separate(
        GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
    GPU_blend(true);

    switch (strip->extendmode) {
      /* since this does both sides,
       * only do the 'before' side, and leave the rest to the next case */
      case NLASTRIP_EXTEND_HOLD:
        /* only need to draw here if there's no strip before since
         * it only applies in such a situation
         */
        if (strip->prev == NULL) {
          /* set the drawing color to the color of the strip, but with very faint alpha */
          immUniformColor3fvAlpha(color, 0.15f);

          /* draw the rect to the edge of the screen */
          immRectf(shdr_pos, v2d->cur.xmin, yminc, strip->start, ymaxc);
        }
        ATTR_FALLTHROUGH;

      /* this only draws after the strip */
      case NLASTRIP_EXTEND_HOLD_FORWARD:
        /* only need to try and draw if the next strip doesn't occur immediately after */
        if ((strip->next == NULL) || (IS_EQF(strip->next->start, strip->end) == 0)) {
          /* set the drawing color to the color of the strip, but this time less faint */
          immUniformColor3fvAlpha(color, 0.3f);

          /* draw the rect to the next strip or the edge of the screen */
          float x2 = strip->next ? strip->next->start : v2d->cur.xmax;
          immRectf(shdr_pos, strip->end, yminc, x2, ymaxc);
        }
        break;
    }

    GPU_blend(false);
  }

  /* draw 'inside' of strip itself */
  if (non_solo == 0) {
    immUnbindProgram();

    /* strip is in normal track */
    UI_draw_roundbox_corner_set(UI_CNR_ALL); /* all corners rounded */
    UI_draw_roundbox_shade_x(true, strip->start, yminc, strip->end, ymaxc, 0.0, 0.5, 0.1, color);

    /* restore current vertex format & program (roundbox trashes it) */
    shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
    immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
  }
  else {
    /* strip is in disabled track - make less visible */
    immUniformColor3fvAlpha(color, 0.1f);

    GPU_blend(true);
    immRectf(shdr_pos, strip->start, yminc, strip->end, ymaxc);
    GPU_blend(false);
  }

  /* draw strip's control 'curves'
   * - only if user hasn't hidden them...
   */
  if ((snla->flag & SNLA_NOSTRIPCURVES) == 0) {
    nla_draw_strip_curves(strip, yminc, ymaxc, shdr_pos);
  }

  immUnbindProgram();

  /* draw markings indicating locations of local markers
   * (useful for lining up different actions) */
  if ((snla->flag & SNLA_NOLOCALMARKERS) == 0) {
    nla_strip_draw_markers(strip, yminc, ymaxc);
  }

  /* draw strip outline
   * - color used here is to indicate active vs non-active
   */
  if (strip->flag & NLASTRIP_FLAG_ACTIVE) {
    /* strip should appear 'sunken', so draw a light border around it */
    color[0] = 0.9f; /* FIXME: hardcoded temp-hack colors */
    color[1] = 1.0f;
    color[2] = 0.9f;
  }
  else {
    /* strip should appear to stand out, so draw a dark border around it */
    color[0] = color[1] = color[2] = 0.0f; /* FIXME: or 1.0f ?? */
  }

  /* draw outline
   * - dashed-line shader is loaded after this block
   */
  if (muted) {
    /* muted - draw dotted, squarish outline (for simplicity) */
    shdr_pos = nla_draw_use_dashed_outlines(color, muted);
    imm_draw_box_wire_2d(shdr_pos, strip->start, yminc, strip->end, ymaxc);
  }
  else {
    /* non-muted - draw solid, rounded outline */
    UI_draw_roundbox_shade_x(false, strip->start, yminc, strip->end, ymaxc, 0.0, 0.0, 0.1, color);

    /* restore current vertex format & program (roundbox trashes it) */
    shdr_pos = nla_draw_use_dashed_outlines(color, muted);
  }

  /* if action-clip strip, draw lines delimiting repeats too (in the same color as outline) */
  if ((strip->type == NLASTRIP_TYPE_CLIP) && strip->repeat > 1.0f) {
    float repeatLen = (strip->actend - strip->actstart) * strip->scale;

    /* only draw lines for whole-numbered repeats, starting from the first full-repeat
     * up to the last full repeat (but not if it lies on the end of the strip)
     */
    immBeginAtMost(GPU_PRIM_LINES, 2 * floorf(strip->repeat));
    for (int i = 1; i < strip->repeat; i++) {
      float repeatPos = strip->start + (repeatLen * i);

      /* don't draw if line would end up on or after the end of the strip */
      if (repeatPos < strip->end) {
        immVertex2f(shdr_pos, repeatPos, yminc + 4);
        immVertex2f(shdr_pos, repeatPos, ymaxc - 4);
      }
    }
    immEnd();
  }
  /* or if meta-strip, draw lines delimiting extents of sub-strips
   * (in same color as outline, if more than 1 exists) */
  else if ((strip->type == NLASTRIP_TYPE_META) && (strip->strips.first != strip->strips.last)) {
    const float y = (ymaxc - yminc) * 0.5f + yminc;

    /* up to 2 lines per strip */
    immBeginAtMost(GPU_PRIM_LINES, 4 * BLI_listbase_count(&strip->strips));

    /* only draw first-level of child-strips, but don't draw any lines on the endpoints */
    for (NlaStrip *cs = strip->strips.first; cs; cs = cs->next) {
      /* draw start-line if not same as end of previous (and only if not the first strip)
       * - on upper half of strip
       */
      if ((cs->prev) && IS_EQF(cs->prev->end, cs->start) == 0) {
        immVertex2f(shdr_pos, cs->start, y);
        immVertex2f(shdr_pos, cs->start, ymaxc);
      }

      /* draw end-line if not the last strip
       * - on lower half of strip
       */
      if (cs->next) {
        immVertex2f(shdr_pos, cs->end, yminc);
        immVertex2f(shdr_pos, cs->end, y);
      }
    }

    immEnd();
  }

  immUnbindProgram();
}