Example #1
0
gcc_const
static std::pair<unsigned,unsigned>
AngleToDonutVertices(Angle start, Angle end)
{
  static const Angle epsilon = Angle::FullCircle() / 64 / 2;

  const Angle delta = end - start;

  if (delta >= Angle::FullCircle() - epsilon)
    /* full circle */
    return std::make_pair(0, 64);

  const unsigned istart = AngleToDonutVertex(start);
  unsigned iend = AngleToDonutVertex(end);

  if (istart == iend && delta > epsilon) {
    if (end - start >= Angle::HalfCircle())
      /* nearly full circle, round down the end */
      iend = (iend - 2) & 0x3e;
    else
      /* slightly larger than epsilon: draw at least two indices */
      iend = (iend + 2) & 0x3e;
  }

  return std::make_pair(istart, iend);
}
Example #2
0
gcc_const
static std::pair<unsigned,unsigned>
AngleToDonutVertices(Angle start, Angle end)
{
  static constexpr Angle epsilon = Angle::FullCircle()
    / int(GLDonutVertices::CIRCLE_SIZE * 4u);

  const Angle delta = end - start;

  if (fabs(delta.AsDelta().Native()) <= epsilon.Native())
    /* full circle */
    return std::make_pair(0u, unsigned(GLDonutVertices::MAX_ANGLE));

  const unsigned istart = AngleToDonutVertex(start);
  unsigned iend = AngleToDonutVertex(end);

  if (istart == iend && delta > epsilon) {
    if (end - start >= Angle::HalfCircle())
      /* nearly full circle, round down the end */
      iend = GLDonutVertices::PreviousAngle(iend);
    else
      /* slightly larger than epsilon: draw at least two indices */
      iend = GLDonutVertices::NextAngle(iend);
  }

  return std::make_pair(istart, iend);
}
Example #3
0
void
Canvas::annulus(int x, int y, unsigned small_radius, unsigned big_radius,
                Angle start, Angle end)
{
  GLDonutVertices vertices(x, y, small_radius, big_radius);

  const unsigned istart = AngleToDonutVertex(start);
  const unsigned iend = AngleToDonutVertex(end);

  if (!brush.is_hollow()) {
    brush.set();
    vertices.bind();

    if (istart > iend) {
      glDrawArrays(GL_TRIANGLE_STRIP, istart, 64 - istart + 2);
      glDrawArrays(GL_TRIANGLE_STRIP, 0, iend + 2);
    } else {
      glDrawArrays(GL_TRIANGLE_STRIP, istart, iend - istart + 2);
    }
  }

  if (pen_over_brush()) {
    pen.set();

    if (istart != iend) {
      if (brush.is_hollow())
        vertices.bind();

      glDrawArrays(GL_LINE_STRIP, istart, 2);
      glDrawArrays(GL_LINE_STRIP, iend, 2);
    }

    const unsigned pstart = istart / 2;
    const unsigned pend = iend / 2;

    vertices.bind_inner_circle();
    if (pstart < pend) {
      glDrawArrays(GL_LINE_STRIP, pstart, pend - pstart + 1);
    } else {
      glDrawArrays(GL_LINE_STRIP, pstart, 32 - pstart + 1);
      glDrawArrays(GL_LINE_STRIP, 0, pend + 1);
    }

    vertices.bind_outer_circle();
    if (pstart < pend) {
      glDrawArrays(GL_LINE_STRIP, pstart, pend - pstart + 1);
    } else {
      glDrawArrays(GL_LINE_STRIP, pstart, 32 - pstart + 1);
      glDrawArrays(GL_LINE_STRIP, 0, pend + 1);
    }
  }
}