Advertisement
Guest User

Govnokod.ru

a guest
Jun 22nd, 2017
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.37 KB | None | 0 0
  1. void DrawLine(Vec2Si32 a, Vec2Si32 b, Rgba color_a, Rgba color_b) {
  2.     Vec2Si32 ab = b - a;
  3.     Vec2Si32 abs_ab(std::abs(ab.x), std::abs(ab.y));
  4.     if (abs_ab.x >= abs_ab.y) {
  5.         if (a.x > b.x) {
  6.             DrawLine(b, a, color_b, color_a);
  7.         } else {
  8.             Sprite back = GetEngine()->GetBackbuffer();
  9.             Vec2Si32 back_size = back.Size();
  10.             if (ab.x == 0) {
  11.                 if (a.x >= 0 && a.x < back_size.x &&
  12.                         a.y >= 0 && a.y < back_size.y) {
  13.                     back.RgbaData()[a.x + a.y * back.StridePixels()] = color_a;
  14.                 }
  15.                 return;
  16.             }
  17.             Si32 x1 = std::max(0, a.x);
  18.             Si32 x2 = std::min(back_size.x - 1, b.x);
  19.             Si32 y1 = a.y + ab.y * (x1 - a.x) / ab.x;
  20.             Si32 y2 = a.y + ab.y * (x2 - a.x) / ab.x;
  21.             if (y1 < 0) {
  22.                 if (y2 < 0) {
  23.                     return;
  24.                 }
  25.                 // lower left -> upper right
  26.                 y1 = 0;
  27.                 x1 = a.x + ab.x * (y1 - a.y) / ab.y;
  28.                 x1 = std::max(0, x1);
  29.             } else if (y1 >= back_size.y) {
  30.                 if (y2 >= back_size.y) {
  31.                     return;
  32.                 }
  33.                 // upper left -> lower right
  34.                 y1 = back_size.y - 1;
  35.                 x1 = a.x + ab.x * (y1 - a.y) / ab.y;
  36.                 x1 = std::max(0, x1);
  37.             }
  38.             if (y2 < 0) {
  39.                 // upper left -> lower right
  40.                 y2 = 0;
  41.                 x2 = a.x + ab.x * (y2 - a.y) / ab.y;
  42.                 x2 = std::min(back_size.x - 1, x2);
  43.             } else if (y2 >= back_size.y) {
  44.                 // lower left -> upper right
  45.                 y2 = back_size.y - 1;
  46.                 x2 = a.x + ab.x * (y2 - a.y) / ab.y;
  47.                 x2 = std::min(back_size.x - 1, x2);
  48.             }
  49.             Vec4Si32 rgba_a(static_cast<Si32>(color_a.r),static_cast<Si32>(color_a.g),static_cast<Si32>(color_a.b),static_cast<Si32>(color_a.a));
  50.             Vec4Si32 rgba_b(static_cast<Si32>(color_b.r),static_cast<Si32>(color_b.g),static_cast<Si32>(color_b.b),static_cast<Si32>(color_b.a));
  51.             Vec4Si32 rgba_ab = rgba_b - rgba_a;
  52.             Vec4Si32 rgba_1 = rgba_a + rgba_ab * (x1 - a.x) / ab.x;
  53.             Vec4Si32 rgba_2 = rgba_a + rgba_ab * (x2 - a.x) / ab.x;
  54.             Vec4Si32 rgba_12 = rgba_2 - rgba_1;
  55.             if (x2 <= x1) {
  56.                 if (x2 == x1) {
  57.                     Rgba color(rgba_1.x, rgba_1.y, rgba_1.z, rgba_1.w);
  58.                     back.RgbaData()[x1 + y1 * back.StridePixels()] = color;
  59.                 }
  60.                 return;
  61.             }
  62.             Vec4Si32 rgba_16 = rgba_1 * 65536;
  63.             Vec4Si32 rgba_12_16 = rgba_12 * 65536;
  64.             Vec4Si32 rgba_12_16_step = rgba_12_16 / (x2 - x1);
  65.             Si32 y_16 = y1 * 65536;
  66.             Si32 y12_16_step = ((y2 - y1) * 65536) / (x2 - x1);
  67.             Si32 stride = back.StridePixels();
  68.             for (Si32 x = x1; x <= x2; ++x) {
  69.                 Rgba color(rgba_16.x >> 16,rgba_16.y >> 16,rgba_16.z >> 16,rgba_16.w >> 16);
  70.                 back.RgbaData()[x + (y_16 >> 16) * stride] = color;
  71.                 rgba_16 += rgba_12_16_step;
  72.                 y_16 += y12_16_step;
  73.             }
  74.         }
  75.     } else {
  76.         if (a.y > b.y) {
  77.             DrawLine(b, a, color_b, color_a);
  78.         } else {
  79.             Sprite back = GetEngine()->GetBackbuffer();
  80.             Vec2Si32 back_size = back.Size();
  81.             if (ab.y == 0) {
  82.                 if (a.y >= 0 && a.y < back_size.y && a.x >= 0 && a.x < back_size.x) {
  83.                     back.RgbaData()[a.x + a.y * back.StridePixels()] = color_a;
  84.                 }
  85.                 return;
  86.             }
  87.             Si32 y1 = std::max(0, a.y);
  88.             Si32 y2 = std::min(back_size.y - 1, b.y);
  89.             Si32 x1 = a.x + ab.x * (y1 - a.y) / ab.y;
  90.             Si32 x2 = a.x + ab.x * (y2 - a.y) / ab.y;
  91.             if (x1 < 0) {
  92.                 if (x2 < 0) {
  93.                     return;
  94.                 }
  95.                 // lower left -> upper right
  96.                 x1 = 0;
  97.                 y1 = a.y + ab.y * (x1 - a.x) / ab.x;
  98.                 y1 = std::max(0, y1);
  99.             } else if (x1 >= back_size.x) {
  100.                 if (x2 >= back_size.x) {
  101.                     return;
  102.                 }
  103.                 // lower right -> upper left
  104.                 x1 = back_size.x - 1;
  105.                 y1 = a.y + ab.y * (x1 - a.x) / ab.x;
  106.                 y1 = std::max(0, y1);
  107.             }
  108.             if (x2 < 0) {
  109.                 // lower right -> upper left
  110.                 x2 = 0;
  111.                 y2 = a.y + ab.y * (x2 - a.x) / ab.x;
  112.                 y2 = std::min(back_size.y - 1, y2);
  113.             } else if (x2 >= back_size.x) {
  114.                 // lower left -> upper right
  115.                 x2 = back_size.x - 1;
  116.                 y2 = a.y + ab.y * (x2 - a.x) / ab.x;
  117.                 y2 = std::min(back_size.y - 1, y2);
  118.             }
  119.             Vec4Si32 rgba_a(static_cast<Si32>(color_a.r),static_cast<Si32>(color_a.g),static_cast<Si32>(color_a.b),static_cast<Si32>(color_a.a));
  120.             Vec4Si32 rgba_b(static_cast<Si32>(color_b.r),static_cast<Si32>(color_b.g),static_cast<Si32>(color_b.b),static_cast<Si32>(color_b.a));
  121.             Vec4Si32 rgba_ab = rgba_b - rgba_a;
  122.             Vec4Si32 rgba_1 = rgba_a + rgba_ab * (y1 - a.y) / ab.y;
  123.             Vec4Si32 rgba_2 = rgba_a + rgba_ab * (y2 - a.y) / ab.y;
  124.             Vec4Si32 rgba_12 = rgba_2 - rgba_1;
  125.             if (y2 <= y1) {
  126.                 if (y2 == y1) {
  127.                     Rgba color(rgba_1.y, rgba_1.x, rgba_1.z, rgba_1.w);
  128.                     back.RgbaData()[x1 + y1 * back.StridePixels()] = color;
  129.                 }
  130.                 return;
  131.             }
  132.             Vec4Si32 rgba_16 = rgba_1 * 65536;
  133.             Vec4Si32 rgba_12_16 = rgba_12 * 65536;
  134.             Vec4Si32 rgba_12_16_step = rgba_12_16 / (y2 - y1);
  135.             Si32 x_16 = x1 * 65536;
  136.             Si32 x12_16_step = ((x2 - x1) * 65536) / (y2 - y1);
  137.             Si32 stride = back.StridePixels();
  138.             for (Si32 y = y1; y <= y2; ++y) {
  139.                 Rgba color(rgba_16.x >> 16,rgba_16.y >> 16,rgba_16.z >> 16,rgba_16.w >> 16);
  140.                 back.RgbaData()[(x_16 >> 16) + y * stride] = color;
  141.                 rgba_16 += rgba_12_16_step;
  142.                 x_16 += x12_16_step;
  143.             }
  144.         }
  145.     }
  146. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement