Beispiel #1
0
 int round(int x) {
     return ipart(x + 128);
 }
void drawLine(sf::RenderTarget& target, float x1, float y1, float x2, float y2, const sf::Color& color)
{
    float dx = x2 - x1;
    float dy = y2 - y1;

    // Store all points in an arrry
    sf::VertexArray va(sf::Points);

    if (std::fabs(dx) > std::fabs(dy))
    {
        if(x2 < x1)
        {
            std::swap(x1, x2);
            std::swap(y1, y2);
        }

        float gradient = dy / dx;
        float xend = static_cast<float>(round(x1));
        float yend = y1 + gradient * (xend - x1);
        float xgap = rfpart(x1 + 0.5f);

        int xpxl1 = static_cast<int>(xend);
        int ypxl1 = ipart(yend);

        // Add the first endpoint
        plot(va, xpxl1, ypxl1, rfpart(yend) * xgap, color);
        plot(va, xpxl1, ypxl1 + 1, fpart(yend) * xgap, color);

        float intery = yend + gradient;

        xend = static_cast<float>(round(x2));
        yend = y2 + gradient * (xend - x2);
        xgap = fpart(x2 + 0.5f);

        int xpxl2 = static_cast<int>(xend);
        int ypxl2 = ipart(yend);

        // Add the second endpoint
        plot(va, xpxl2, ypxl2, rfpart(yend) * xgap, color);
        plot(va, xpxl2, ypxl2 + 1, fpart(yend) * xgap, color);

        // Add all the points between the endpoints
        for(int x = xpxl1 + 1; x <= xpxl2 - 1; ++x)
        {
            plot(va, x, ipart(intery), rfpart(intery), color);
            plot(va, x, ipart(intery) + 1, fpart(intery), color);
            intery += gradient;
        }
    }
    else
    {
        if(y2 < y1)
        {
            std::swap(x1, x2);
            std::swap(y1, y2);
        }

        float gradient = dx / dy;
        float yend = static_cast<float>(round(y1));
        float xend = x1 + gradient * (yend - y1);
        float ygap = rfpart(y1 + 0.5f);

        int ypxl1 = static_cast<int>(yend);
        int xpxl1 = ipart(xend);

        // Add the first endpoint
        plot(va, xpxl1, ypxl1, rfpart(xend) * ygap, color);
        plot(va, xpxl1, ypxl1 + 1, fpart(xend) * ygap, color);

        float interx = xend + gradient;

        yend = static_cast<float>(round(y2));
        xend = x2 + gradient * (yend - y2);
        ygap = fpart(y2 + 0.5f);

        int ypxl2 = static_cast<int>(yend);
        int xpxl2 = ipart(xend);

        // Add the second endpoint
        plot(va, xpxl2, ypxl2, rfpart(xend) * ygap, color);
        plot(va, xpxl2, ypxl2 + 1, fpart(xend) * ygap, color);

        // Add all the points between the endpoints
        for(int y = ypxl1 + 1; y <= ypxl2 - 1; ++y)
        {
            plot(va, ipart(interx), y, rfpart(interx), color);
            plot(va, ipart(interx) + 1, y, fpart(interx), color);
            interx += gradient;
        }
    }

    target.draw(va);
}
Beispiel #3
0
// ---------------------------------------------------------------------------------------------------------------------
void WuLine(pixel* frame, Fix16 x1, Fix16 y1, Fix16 x2, Fix16 y2, ColourChoice cc)
{
  byte r = 0;
  byte g = 0;

  Fix16 dx = x2 - x1;
  Fix16 dy = y2 - y1;

  bool swapXY = false;
  if (Fix16::abs(dx) < Fix16::abs(dy))
  {
    XORByteSwap(x1.value, y1.value);
    XORByteSwap(x2.value, y2.value);
    XORByteSwap(dx.value, dy.value);
    swapXY = true;
  }

  if (x2 < x1)
  {
    XORByteSwap(x1.value, x2.value);
    XORByteSwap(y1.value, y2.value);
  }

  Fix16 gradient = dy / dx;

  Fix16 xend = round(x1);
  Fix16 yend = y1 + gradient * (xend - x1);
  Fix16 xgap = rfpart(x1 + 0.5f);
  int16_t xpxl1 = xend.asInt();  // this will be used in the main loop
  int16_t ypxl1 = ipart(yend).asInt();

  GetBasicColour(rfpart(yend) * xgap, cc, r, g);
  setLED(frame, xpxl1, ypxl1, r, g, true, swapXY);

  GetBasicColour(fpart(yend) * xgap, cc, r, g);
  setLED(frame, xpxl1, ypxl1 + 1, r, g, true, swapXY);


  Fix16 intery = yend + gradient; // first y-intersection for the main loop


  // handle second endpoint
  xend = round(x2);
  yend = y2 + gradient * (xend - x2);
  xgap = fpart(x2 + 0.5f);
  int16_t xpxl2 = xend.asInt();  // this will be used in the main loop
  int16_t ypxl2 = ipart(yend).asInt();

  GetBasicColour(rfpart(yend) * xgap, cc, r, g);
  setLED(frame, xpxl2, ypxl2, r, g, true, swapXY);

  GetBasicColour(fpart(yend) * xgap, cc, r, g);
  setLED(frame, xpxl2, ypxl2 + 1, r, g, true, swapXY);

  int16_t xa = xpxl1 + 1;
  int16_t xb = xpxl2 - 1;
  
  if (xb - xa > 120)
    return;

  for (; xa <= xb; xa ++)
  {
    GetBasicColour(rfpart(intery), cc, r, g);
    setLED(frame, xa, ipart(intery).asInt(), r, g, true, swapXY);

    GetBasicColour(fpart(intery), cc, r, g);
    setLED(frame, xa, ipart(intery).asInt() + 1, r, g, true, swapXY);

    intery = intery + gradient;
  }
}
static float fpart(float x)
{
    return x - ipart(x);
}
static int round(float x)
{
    return ipart(x + 0.5f);
}
Beispiel #6
0
void muiBBWindow::DrawLineFloat(float x0, float y0, float x1, float y1, muiColor clr)
// Xiaolin Wu's line algorithm 
{
	if (!pclrBitmap) return;

	int ix, iy, ie;

    float dx = x1 - x0, x;
    float dy = y1 - y0, y;
	float c, v, gradient, xend, yend, gap;
   
	if (fabsf(dx) > fabsf(dy)) {
		
		// Handle "horizontal" lines
		if (x1 < x0) {
			swap(x0, x1);
			swap(y0, y1);
		}	
		gradient = dy / dx;
   
		// Handle 1st endpoint
		xend = fround(x0);
		yend = y0 + gradient * (xend - x0);
		gap = rfpart(x0 + 0.5f);
		ix = int(floorf(xend));
		iy = int(floorf(yend));
		c = fpart(yend);

		DrawPixelBlend({ ix, iy++ }, clr, (1.0f - c) * gap);
		DrawPixelBlend({ ix++, iy }, clr, (c)* gap);
     
		y = yend + gradient; // first y-intersection for the main loop
 
		// Handle 2nd endpoint
		xend = fround(x1);
		yend = y1 + gradient * (xend - x1);
		gap = fpart(x1 + 0.5f);
		ie = int(ipart(xend));
		iy  = int(ipart(yend));
		c = fpart(yend);

		DrawPixelBlend({ ie, iy++ }, clr, (1.0f - c) * gap);
		DrawPixelBlend({ ie--, iy }, clr, (c)* gap);

		// Handle mid-points
		while (ix <= ie) {

			v = ipart(y);
			iy = int(v);
			c = y - v;
			y += gradient;

			DrawPixelBlend({ ix, iy++ }, clr, (1.0f - c));
			DrawPixelBlend({ ix++, iy }, clr, (c));
		}

	} else {
		// Handle "vertical" lines
		if (y1 < y0) {
			swap(y0, y1);
			swap(x0, x1);
		}	
		gradient = dx / dy;
   
		// Handle 1st endpoint
		yend = fround(y0);
		xend = x0 + gradient * (yend - y0);
		gap = rfpart(y0 + 0.5f);
		iy = int(ipart(yend));
		ix = int(ipart(xend));
		c = fpart(xend);

		DrawPixelBlend({ ix++, iy }, clr, (1.0f - c) * gap);
		DrawPixelBlend({ ix, iy++ }, clr, (c)* gap);
     
		x = xend + gradient; // first x-intersection for the main loop
 
		// Handle 2nd endpoint
		yend = fround(y1);
		xend = x1 + gradient * (yend - y1);
		gap = fpart(y1 + 0.5f);
		ie = int(ipart(yend));
		ix  = int(ipart(xend));
		c = fpart(xend);

		DrawPixelBlend({ ix++, ie }, clr, (1.0f - c) * gap);
		DrawPixelBlend({ ix, ie-- }, clr, (c)* gap);

		// Handle mid-points
		while (iy <= ie) {

			v = ipart(x);
			ix = int(v);
			c = x - v;
			x += gradient;

			DrawPixelBlend({ ix++, iy }, clr, (1.0f - c));
			DrawPixelBlend({ ix, iy++ }, clr, (c));
		}
	}
}
Beispiel #7
0
// ---------------------------------------------------------------------------------------------------------------------
bool tick(const FrameInput& input, FXState& state, FrameOutput& output)
{
  switch (gCurrentInterfaceStage)
  {
  case InterfaceStage::IS_GUI:
    {
      output.clear();

      if (input.dialChange[1] == 0)
        ticksSinceAdjust ++;
      else
        ticksSinceAdjust = 0;

      const int16_t radioLen = sizeof(radioGUI) / sizeof(gui_entry);

      Fix16 max_target = fix16_from_int(radioLen);
      Fix16 max_value = fix16_from_int(radioLen - 1);

      Fix16 dial16 = fix16_from_int( input.dialChange[1] );
      Fix16 pt05 = fix16_from_float(-1.0f);

      vTargetA += dial16 * fix16_from_float(0.2f);
      if (vTargetA < fix16_neg_one)
        vTargetA = fix16_neg_one;

      if (vTargetA > max_target)
        vTargetA = max_target;

      vCurA += (vTargetA - vCurA) * fix16_from_float(0.035f);

      if (vCurA < fix16_zero)
        vCurA = fix16_zero;
      if (vCurA > max_value)
        vCurA = max_value;

      if (ticksSinceAdjust > 30)
      {
        vTargetA -= fpart(vTargetA);
      }

      int16_t off = ipart(vCurA).asInt();
      if (off < 0)
        off = 0;
      if (off > radioLen - 1)
        off = radioLen - 1;

      const gui_entry* guient[3] = {&radioGUI[off], &radioGUI[off], &radioGUI[off]};

      if (off - 1 >= 0)
        guient[2] = &radioGUI[off - 1];
      if (off + 1 <= radioLen - 1)
        guient[1] = &radioGUI[off + 1];



      Fix16 charASlide = fpart(vCurA);


      charASlide *= Fix16(-16.0f);
      int16_t slideAInt = charASlide.asInt();


      IconGlyph(output.frame, guient[0]->gly, slideAInt, 0, true);

      IconGlyph(output.frame, guient[1]->gly, 16 + slideAInt, 0, false);

      if (off > 0)
        IconGlyph(output.frame, guient[2]->gly, slideAInt - 16, 0, false);

      

      if (fadeTick < 15)
      {
        fadeTick ++;
        output.fade(15 - fadeTick);
      }

      if (input.dialClick)
      {
        gCurrentInterfaceStage = InterfaceStage::IS_FADETO;

        gNextDisplayMode = guient[0]->mode;
      }
    }
    break;

  case InterfaceStage::IS_FADETO:
    {
      output.fade(1);

      fadeTick --;
      if (fadeTick <= 0)
      {
        vTargetA = vCurA;

        gCurrentDisplayMode = gNextDisplayMode;

        for(int i = 0; i < Constants::MemoryPool; ++i)
          state.store[i] = 0xFF;

        DisplayMode::doInitFor(gCurrentDisplayMode, state);
        fadeTick = 0;

        gCurrentInterfaceStage = InterfaceStage::IS_FX;
      }
    }
    break;

  case InterfaceStage::IS_FX:
    {
      DisplayMode::doTickFor(gCurrentDisplayMode, input, output, state);

      if (fadeTick < 15)
      {
        fadeTick ++;
        output.fade(15 - fadeTick);
      }

      if (input.dialClick)
      {
        gCurrentInterfaceStage = InterfaceStage::IS_FADEFROM;
      }
    }
    break;

  case InterfaceStage::IS_FADEFROM:
    {
      DisplayMode::doTickFor(gCurrentDisplayMode, input, output, state);

      output.fade(15 - fadeTick);

      fadeTick --;
      if (fadeTick <= 0)
      {
        gCurrentInterfaceStage = InterfaceStage::IS_GUI;
        fadeTick = 0;
      }
    }
    break;

  }

//  
/*
   dial --;
   if (dial <= 0)
   {
     // clear the frame
  output.clear();
   for (int y=0; y<Constants::FrameHeight; y++)
   {
     for (int x=0; x<Constants::FrameWidth; x++)
     {
       int32_t RR = state.rng.genInt32(-4, 4);
       if (RR<0)
       RR =0;
       int32_t GG = state.rng.genInt32(-4, 4);
       if (GG<0)
       GG =0;
     
       setLED(output.frame, x, y, RR, GG);
     }
   }
dial = 6;   
}  */



  /*
  byte red, green;
  for (int y=0; y<Constants::FrameHeight; y++)
  {
    for (int x=0; x<Constants::FrameWidth; x++)
    {
      pixel &LEDpixel = output.frame[y * Constants::FrameWidth + x];  
      
      DecodeByte(LEDpixel, red, green);
      if (red > 0)
        red --;
      if (green > 0)
        green --;

      LEDpixel = red | (green << 4);
    }
  }

  vTargetA += fix16_from_int( input.dialChange[1] );
  vTargetB += fix16_from_int( input.dialChange[2] );
  

  vCurA += (vTargetA - vCurA) * fix16_from_float(0.05f);
  vCurB += (vTargetB - vCurB) * fix16_from_float(0.05f);


  Fix16 xo = fix16_from_float(8.0f);
  Fix16 yo = fix16_from_float(8.0f);

  Fix16 ss1 = fix16_sin(vCurA * fix16_from_float(0.1f));
  Fix16 cc1 = fix16_cos(vCurA * fix16_from_float(0.1f));

  Fix16 ss2 = fix16_sin(vCurB * fix16_from_float(0.1f));
  Fix16 cc2 = fix16_cos(vCurB * fix16_from_float(0.1f));

  Fix16 rad1(-2.0f), rad2(12.0f);

  draw::WuLine(
    output.frame, 
    xo + (ss1 * rad1), 
    yo + (cc1 * rad1), 
    xo + (ss1 * rad2), 
    yo + (cc1 * rad2), 
    Red);

  draw::WuLine(
    output.frame, 
    xo + (ss2 * rad1), 
    yo + (cc2 * rad1), 
    xo + (ss2 * rad2), 
    yo + (cc2 * rad2), 
    Green);

  */



  return true;
}
Beispiel #8
0
// Draw antialiased line using Wu's algorithm.
void Line::lineWu(int x0, int y0, int x1, int y1, std::vector<Point>& points, std::vector<float>& alpha)
{
	bool bSteep = abs(int(y1 - y0)) > abs(int(x1 - x0));
 
	if(bSteep)
	{
		std::swap(x0, y0);
		std::swap(x1, y1);
	}

	if(x0 > x1)
	{
		std::swap(x0, x1);
		std::swap(y0, y1);
	}
 
	float dx = float(x1 - x0);
	float dy = float(y1 - y0);
	float gradient = float(dy) / dx;
 
	// handle first endpoint
	uint xend = round(float(x0));
	float yend = y0 + gradient * (xend - x0);
	float xgap = rfpart(x0 + 0.5f);
	uint xpxl1 = xend;   //this will be used in the main loop
	uint ypxl1 = ipart(yend);

	if(bSteep)
	{
		points.push_back(Point(ypxl1, xpxl1));
		alpha.push_back(rfpart(yend) * xgap);

		points.push_back(Point(ypxl1+1, xpxl1));
		alpha.push_back(fpart(yend) * xgap);
	}
	else
	{
		points.push_back(Point(xpxl1, ypxl1));
		alpha.push_back(rfpart(yend) * xgap);

		points.push_back(Point(xpxl1, ypxl1+1));
		alpha.push_back(fpart(yend) * xgap);
	}

	float intery = yend + gradient; // first y-intersection for the main loop
 
     // handle second endpoint
	xend = round(float(x1));
	yend = y1 + gradient * (xend - x1);
	xgap = fpart(x1 + 0.5f);
	uint xpxl2 = xend; //this will be used in the main loop
	uint ypxl2 = ipart(yend);
	if(bSteep)
	{
		points.push_back(Point(ypxl2, xpxl2));
		alpha.push_back(rfpart(yend) * xgap);

		points.push_back(Point(ypxl2+1, xpxl2));
		alpha.push_back(fpart(yend) * xgap);
	}
	else
	{
		points.push_back(Point(xpxl2, ypxl2));
		alpha.push_back(rfpart(yend) * xgap);

		points.push_back(Point(xpxl2, ypxl2+1));
		alpha.push_back(fpart(yend) * xgap);
	}

	// main loop
	for(uint x = xpxl1 + 1; x < xpxl2; ++x)
	{
		if(bSteep)
		{
			points.push_back(Point(ipart(intery), x));
			alpha.push_back(rfpart(intery));

			points.push_back(Point(ipart(intery)+1, x));
			alpha.push_back(fpart(intery));
		}
		else
		{
			points.push_back(Point(x, ipart(intery)));
			alpha.push_back(rfpart(intery));

			points.push_back(Point(x, ipart(intery)+1));
			alpha.push_back(fpart(intery));
		}
		intery = intery + gradient;
	}
}