shapes_kaleidoscope.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*******************************************************************************************
  2. *
  3. * raylib [shapes] example - kaleidoscope
  4. *
  5. * Example complexity rating: [★★☆☆] 2/4
  6. *
  7. * Example originally created with raylib 5.5, last time updated with raylib 5.6
  8. *
  9. * Example contributed by Hugo ARNAL (@hugoarnal) and reviewed by Ramon Santamaria (@raysan5)
  10. *
  11. * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
  12. * BSD-like license that allows static linking with closed source software
  13. *
  14. * Copyright (c) 2025 Hugo ARNAL (@hugoarnal) and Ramon Santamaria (@raysan5)
  15. *
  16. ********************************************************************************************/
  17. #include "raylib.h"
  18. #include <string.h>
  19. #define RAYGUI_IMPLEMENTATION
  20. #include "raygui.h"
  21. #include "raymath.h"
  22. #define MAX_DRAW_LINES 8192
  23. // Line data type
  24. typedef struct {
  25. Vector2 start;
  26. Vector2 end;
  27. } Line;
  28. // Lines array as a global static variable to be stored
  29. // in heap and avoid potential stack overflow (on Web platform)
  30. static Line lines[MAX_DRAW_LINES] = { 0 };
  31. //------------------------------------------------------------------------------------
  32. // Program main entry point
  33. //------------------------------------------------------------------------------------
  34. int main(void)
  35. {
  36. // Initialization
  37. //--------------------------------------------------------------------------------------
  38. const int screenWidth = 800;
  39. const int screenHeight = 450;
  40. InitWindow(screenWidth, screenHeight, "raylib [shapes] example - kaleidoscope");
  41. // Line drawing properties
  42. int symmetry = 6;
  43. float angle = 360.0f/(float)symmetry;
  44. float thickness = 3.0f;
  45. Rectangle resetButtonRec = { screenWidth - 55, 5, 50, 25 };
  46. Rectangle backButtonRec = { screenWidth - 55, screenHeight - 30, 25, 25 };
  47. Rectangle nextButtonRec = { screenWidth - 30, screenHeight - 30, 25, 25 };
  48. Vector2 mousePos = { 0 };
  49. Vector2 prevMousePos = { 0 };
  50. Vector2 scaleVector = { 1.0f, -1.0f };
  51. Vector2 offset = { (float)screenWidth/2.0f, (float)screenHeight/2.0f };
  52. Camera2D camera = { 0 };
  53. camera.target = (Vector2){ 0 };
  54. camera.offset = offset;
  55. camera.rotation = 0.0f;
  56. camera.zoom = 1.0f;
  57. int currentLineCounter = 0;
  58. int totalLineCounter = 0;
  59. int resetButtonClicked = false;
  60. int backButtonClicked = false;
  61. int nextButtonClicked = false;
  62. SetTargetFPS(20);
  63. //--------------------------------------------------------------------------------------
  64. // Main game loop
  65. while (!WindowShouldClose()) // Detect window close button or ESC key
  66. {
  67. // Update
  68. //----------------------------------------------------------------------------------
  69. prevMousePos = mousePos;
  70. mousePos = GetMousePosition();
  71. Vector2 lineStart = Vector2Subtract(mousePos, offset);
  72. Vector2 lineEnd = Vector2Subtract(prevMousePos, offset);
  73. if (
  74. IsMouseButtonDown(MOUSE_LEFT_BUTTON)
  75. && (CheckCollisionPointRec(mousePos, resetButtonRec) == false)
  76. && (CheckCollisionPointRec(mousePos, backButtonRec) == false)
  77. && (CheckCollisionPointRec(mousePos, nextButtonRec) == false)
  78. )
  79. {
  80. for (int s = 0; (s < symmetry) && (totalLineCounter < (MAX_DRAW_LINES - 1)); s++)
  81. {
  82. lineStart = Vector2Rotate(lineStart, angle*DEG2RAD);
  83. lineEnd = Vector2Rotate(lineEnd, angle*DEG2RAD);
  84. // Store mouse line
  85. lines[totalLineCounter].start = lineStart;
  86. lines[totalLineCounter].end = lineEnd;
  87. // Store reflective line
  88. lines[totalLineCounter + 1].start = Vector2Multiply(lineStart, scaleVector);
  89. lines[totalLineCounter + 1].end = Vector2Multiply(lineEnd, scaleVector);
  90. totalLineCounter += 2;
  91. currentLineCounter = totalLineCounter;
  92. }
  93. }
  94. if (resetButtonClicked)
  95. {
  96. memset(&lines, 0, sizeof(Line)*MAX_DRAW_LINES);
  97. currentLineCounter = 0;
  98. totalLineCounter = 0;
  99. }
  100. if (backButtonClicked && (currentLineCounter > 0))
  101. {
  102. currentLineCounter -= 1;
  103. }
  104. if (nextButtonClicked && (currentLineCounter < MAX_DRAW_LINES) && ((currentLineCounter + 1) <= totalLineCounter))
  105. {
  106. currentLineCounter += 1;
  107. }
  108. //----------------------------------------------------------------------------------
  109. // Draw
  110. //----------------------------------------------------------------------------------
  111. BeginDrawing();
  112. ClearBackground(RAYWHITE);
  113. BeginMode2D(camera);
  114. for (int s = 0; s < symmetry; s++)
  115. {
  116. for (int i = 0; i < currentLineCounter; i += 2)
  117. {
  118. DrawLineEx(lines[i].start, lines[i].end, thickness, BLACK);
  119. DrawLineEx(lines[i + 1].start, lines[i + 1].end, thickness, BLACK);
  120. }
  121. }
  122. EndMode2D();
  123. if ((currentLineCounter - 1) < 0) GuiDisable();
  124. backButtonClicked = GuiButton(backButtonRec, "<");
  125. GuiEnable();
  126. if ((currentLineCounter + 1) > totalLineCounter) GuiDisable();
  127. nextButtonClicked = GuiButton(nextButtonRec, ">");
  128. GuiEnable();
  129. resetButtonClicked = GuiButton(resetButtonRec, "Reset");
  130. DrawText(TextFormat("LINES: %i/%i", currentLineCounter, MAX_DRAW_LINES), 10, screenHeight - 30, 20, MAROON);
  131. DrawFPS(10, 10);
  132. EndDrawing();
  133. //----------------------------------------------------------------------------------
  134. }
  135. // De-Initialization
  136. //--------------------------------------------------------------------------------------
  137. CloseWindow(); // Close window and OpenGL context
  138. //--------------------------------------------------------------------------------------
  139. return 0;
  140. }