models_point_rendering.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*******************************************************************************************
  2. *
  3. * raylib [models] example - point rendering
  4. *
  5. * Example complexity rating: [★★★☆] 3/4
  6. *
  7. * Example originally created with raylib 5.0, last time updated with raylib 5.0
  8. *
  9. * Example contributed by Reese Gallagher (@satchelfrost) 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) 2024-2025 Reese Gallagher (@satchelfrost)
  15. *
  16. ********************************************************************************************/
  17. #include "raylib.h"
  18. #include <stdlib.h> // Required for: rand()
  19. #include <math.h> // Required for: cosf(), sinf()
  20. #define MAX_POINTS 10000000 // 10 million
  21. #define MIN_POINTS 1000 // 1 thousand
  22. //------------------------------------------------------------------------------------
  23. // Module Functions Declaration
  24. //------------------------------------------------------------------------------------
  25. // Generate mesh using points
  26. static Mesh GenMeshPoints(int numPoints);
  27. //------------------------------------------------------------------------------------
  28. // Program main entry point
  29. //------------------------------------------------------------------------------------
  30. int main(void)
  31. {
  32. // Initialization
  33. //--------------------------------------------------------------------------------------
  34. const int screenWidth = 800;
  35. const int screenHeight = 450;
  36. InitWindow(screenWidth, screenHeight, "raylib [models] example - point rendering");
  37. Camera camera = {
  38. .position = { 3.0f, 3.0f, 3.0f },
  39. .target = { 0.0f, 0.0f, 0.0f },
  40. .up = { 0.0f, 1.0f, 0.0f },
  41. .fovy = 45.0f,
  42. .projection = CAMERA_PERSPECTIVE
  43. };
  44. Vector3 position = { 0.0f, 0.0f, 0.0f };
  45. bool useDrawModelPoints = true;
  46. bool numPointsChanged = false;
  47. int numPoints = 1000;
  48. Mesh mesh = GenMeshPoints(numPoints);
  49. Model model = LoadModelFromMesh(mesh);
  50. SetTargetFPS(60);
  51. //--------------------------------------------------------------------------------------
  52. // Main game loop
  53. while (!WindowShouldClose())
  54. {
  55. // Update
  56. //----------------------------------------------------------------------------------
  57. UpdateCamera(&camera, CAMERA_ORBITAL);
  58. if (IsKeyPressed(KEY_SPACE)) useDrawModelPoints = !useDrawModelPoints;
  59. if (IsKeyPressed(KEY_UP))
  60. {
  61. numPoints = (numPoints*10 > MAX_POINTS)? MAX_POINTS : numPoints*10;
  62. numPointsChanged = true;
  63. }
  64. if (IsKeyPressed(KEY_DOWN))
  65. {
  66. numPoints = (numPoints/10 < MIN_POINTS)? MIN_POINTS : numPoints/10;
  67. numPointsChanged = true;
  68. }
  69. // Upload a different point cloud size
  70. if (numPointsChanged)
  71. {
  72. UnloadModel(model);
  73. mesh = GenMeshPoints(numPoints);
  74. model = LoadModelFromMesh(mesh);
  75. numPointsChanged = false;
  76. }
  77. //----------------------------------------------------------------------------------
  78. // Draw
  79. //----------------------------------------------------------------------------------
  80. BeginDrawing();
  81. ClearBackground(BLACK);
  82. BeginMode3D(camera);
  83. // The new method only uploads the points once to the GPU
  84. if (useDrawModelPoints) DrawModelPoints(model, position, 1.0f, WHITE);
  85. else
  86. {
  87. // The old method must continually draw the "points" (lines)
  88. for (int i = 0; i < numPoints; i++)
  89. {
  90. Vector3 pos = {
  91. .x = mesh.vertices[i*3 + 0],
  92. .y = mesh.vertices[i*3 + 1],
  93. .z = mesh.vertices[i*3 + 2],
  94. };
  95. Color color = {
  96. .r = mesh.colors[i*4 + 0],
  97. .g = mesh.colors[i*4 + 1],
  98. .b = mesh.colors[i*4 + 2],
  99. .a = mesh.colors[i*4 + 3],
  100. };
  101. DrawPoint3D(pos, color);
  102. }
  103. }
  104. // Draw a unit sphere for reference
  105. DrawSphereWires(position, 1.0f, 10, 10, YELLOW);
  106. EndMode3D();
  107. // Draw UI text
  108. DrawText(TextFormat("Point Count: %d", numPoints), 10, screenHeight - 50, 40, WHITE);
  109. DrawText("UP - Increase points", 10, 40, 20, WHITE);
  110. DrawText("DOWN - Decrease points", 10, 70, 20, WHITE);
  111. DrawText("SPACE - Drawing function", 10, 100, 20, WHITE);
  112. if (useDrawModelPoints) DrawText("Using: DrawModelPoints()", 10, 130, 20, GREEN);
  113. else DrawText("Using: DrawPoint3D()", 10, 130, 20, RED);
  114. DrawFPS(10, 10);
  115. EndDrawing();
  116. //----------------------------------------------------------------------------------
  117. }
  118. // De-Initialization
  119. //--------------------------------------------------------------------------------------
  120. UnloadModel(model);
  121. CloseWindow();
  122. //--------------------------------------------------------------------------------------
  123. return 0;
  124. }
  125. //------------------------------------------------------------------------------------
  126. // Module Functions Definition
  127. //------------------------------------------------------------------------------------
  128. // Generate a spherical point cloud
  129. static Mesh GenMeshPoints(int numPoints)
  130. {
  131. Mesh mesh = {
  132. .triangleCount = 1,
  133. .vertexCount = numPoints,
  134. .vertices = (float *)MemAlloc(numPoints*3*sizeof(float)),
  135. .colors = (unsigned char*)MemAlloc(numPoints*4*sizeof(unsigned char)),
  136. };
  137. // REF: https://en.wikipedia.org/wiki/Spherical_coordinate_system
  138. for (int i = 0; i < numPoints; i++)
  139. {
  140. float theta = ((float)PI*rand())/((float)RAND_MAX);
  141. float phi = (2.0f*PI*rand())/((float)RAND_MAX);
  142. float r = (10.0f*rand())/((float)RAND_MAX);
  143. mesh.vertices[i*3 + 0] = r*sinf(theta)*cosf(phi);
  144. mesh.vertices[i*3 + 1] = r*sinf(theta)*sinf(phi);
  145. mesh.vertices[i*3 + 2] = r*cosf(theta);
  146. Color color = ColorFromHSV(r*360.0f, 1.0f, 1.0f);
  147. mesh.colors[i*4 + 0] = color.r;
  148. mesh.colors[i*4 + 1] = color.g;
  149. mesh.colors[i*4 + 2] = color.b;
  150. mesh.colors[i*4 + 3] = color.a;
  151. }
  152. // Upload mesh data from CPU (RAM) to GPU (VRAM) memory
  153. UploadMesh(&mesh, false);
  154. return mesh;
  155. }