triangle.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * 3D Engine
  3. * triangle.c:
  4. * Based on pikuma.com 3D software renderer in C
  5. * Copyright (c) 2021 986-Studio. All rights reserved.
  6. *
  7. * Created by Manoël Trapier on 04/03/2021.
  8. */
  9. #include <display.h>
  10. #include <triangle.h>
  11. void drawTriangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t colour)
  12. {
  13. drawLine(x0, y0, x1, y1, colour);
  14. drawLine(x1, y1, x2, y2, colour);
  15. drawLine(x2, y2, x0, y0, colour);
  16. }
  17. /* This function expect Point 0 to be the top, 1 to be the bottom left, 2 to be the bottom right */
  18. static void drawFillBottomFlatTriangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t colour)
  19. {
  20. int i;
  21. int32_t deltaXL = x1 - x0;
  22. int32_t deltaXR = x2 - x0;
  23. int32_t deltaY = y1 - y0;
  24. int32_t sideLength = abs(deltaY);
  25. double incrementXL = deltaXL / (double)sideLength;
  26. double incrementXR = deltaXR / (double)sideLength;
  27. double incrementY = deltaY / (double)sideLength;
  28. double currentXL = x0;
  29. double currentXR = x0;
  30. double currentY = y0;
  31. for(i = 0; i < sideLength; i++)
  32. {
  33. drawHLine(round(currentXL), round(currentY), round(currentXR), colour);
  34. currentXL += incrementXL;
  35. currentXR += incrementXR;
  36. currentY += incrementY;
  37. }
  38. }
  39. /* This function expect Point 2 to be the bottom, 0 to be the top left, 1 to be the top right */
  40. static void drawFillTopFlatTriangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t colour)
  41. {
  42. int i;
  43. int32_t deltaXL = x0 - x2;
  44. int32_t deltaXR = x1 - x2;
  45. int32_t deltaY = y0 - y2;
  46. int32_t sideLength = abs(deltaY);
  47. if (sideLength == 0)
  48. {
  49. return;
  50. }
  51. double incrementXL = deltaXL / (double)sideLength;
  52. double incrementXR = deltaXR / (double)sideLength;
  53. double incrementY = deltaY / (double)sideLength;
  54. double currentXL = x2;
  55. double currentXR = x2;
  56. double currentY = y2;
  57. for(i = 0; i <= sideLength; i++)
  58. {
  59. drawHLine(round(currentXL), round(currentY), round(currentXR), colour);
  60. currentXL += incrementXL;
  61. currentXR += incrementXR;
  62. currentY += incrementY;
  63. }
  64. }
  65. void drawFilledTriangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t colour)
  66. {
  67. int32_t My, Mx;
  68. if (y0 > y1)
  69. {
  70. intSwap(&x0, &x1); intSwap(&y0, &y1);
  71. }
  72. if (y1 > y2)
  73. {
  74. intSwap(&x1, &x2); intSwap(&y1, &y2);
  75. }
  76. if (y0 > y1)
  77. {
  78. intSwap(&x0, &x1); intSwap(&y0, &y1);
  79. }
  80. /* Determine the mid intersection and point */
  81. My = y1;
  82. Mx = x0 + (double)((x2 - x0) * (y1 - y0)) / (double)(y2 - y0);
  83. /* Fill top */
  84. drawFillBottomFlatTriangle(x0, y0, x1, y1, Mx, My,colour);
  85. /* Fill bottom */
  86. drawFillTopFlatTriangle(x1, y1, Mx, My, x2, y2, colour);
  87. }