您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

192 行
7.1 KiB

  1. /*******************************************************************************************
  2. *
  3. * raylib [models] example - procedural mesh generation
  4. *
  5. * Example complexity rating: [] 2/4
  6. *
  7. * Example originally created with raylib 1.8, last time updated with raylib 4.0
  8. *
  9. * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
  10. * BSD-like license that allows static linking with closed source software
  11. *
  12. * Copyright (c) 2017-2025 Ramon Santamaria (@raysan5)
  13. *
  14. ********************************************************************************************/
  15. #include "raylib.h"
  16. #define NUM_MODELS 9 // Parametric 3d shapes to generate
  17. static Mesh GenMeshCustom(void); // Generate a simple triangle mesh from code
  18. //------------------------------------------------------------------------------------
  19. // Program main entry point
  20. //------------------------------------------------------------------------------------
  21. int main(void)
  22. {
  23. // Initialization
  24. //--------------------------------------------------------------------------------------
  25. const int screenWidth = 800;
  26. const int screenHeight = 450;
  27. InitWindow(screenWidth, screenHeight, "raylib [models] example - mesh generation");
  28. // We generate a checked image for texturing
  29. Image checked = GenImageChecked(2, 2, 1, 1, RED, GREEN);
  30. Texture2D texture = LoadTextureFromImage(checked);
  31. UnloadImage(checked);
  32. Model models[NUM_MODELS] = { 0 };
  33. models[0] = LoadModelFromMesh(GenMeshPlane(2, 2, 4, 3));
  34. models[1] = LoadModelFromMesh(GenMeshCube(2.0f, 1.0f, 2.0f));
  35. models[2] = LoadModelFromMesh(GenMeshSphere(2, 32, 32));
  36. models[3] = LoadModelFromMesh(GenMeshHemiSphere(2, 16, 16));
  37. models[4] = LoadModelFromMesh(GenMeshCylinder(1, 2, 16));
  38. models[5] = LoadModelFromMesh(GenMeshTorus(0.25f, 4.0f, 16, 32));
  39. models[6] = LoadModelFromMesh(GenMeshKnot(1.0f, 2.0f, 16, 128));
  40. models[7] = LoadModelFromMesh(GenMeshPoly(5, 2.0f));
  41. models[8] = LoadModelFromMesh(GenMeshCustom());
  42. // Generated meshes could be exported as .obj files
  43. //ExportMesh(models[0].meshes[0], "plane.obj");
  44. //ExportMesh(models[1].meshes[0], "cube.obj");
  45. //ExportMesh(models[2].meshes[0], "sphere.obj");
  46. //ExportMesh(models[3].meshes[0], "hemisphere.obj");
  47. //ExportMesh(models[4].meshes[0], "cylinder.obj");
  48. //ExportMesh(models[5].meshes[0], "torus.obj");
  49. //ExportMesh(models[6].meshes[0], "knot.obj");
  50. //ExportMesh(models[7].meshes[0], "poly.obj");
  51. //ExportMesh(models[8].meshes[0], "custom.obj");
  52. // Set checked texture as default diffuse component for all models material
  53. for (int i = 0; i < NUM_MODELS; i++) models[i].materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture;
  54. // Define the camera to look into our 3d world
  55. Camera camera = { { 5.0f, 5.0f, 5.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
  56. // Model drawing position
  57. Vector3 position = { 0.0f, 0.0f, 0.0f };
  58. int currentModel = 0;
  59. SetTargetFPS(60); // Set our game to run at 60 frames-per-second
  60. //--------------------------------------------------------------------------------------
  61. // Main game loop
  62. while (!WindowShouldClose()) // Detect window close button or ESC key
  63. {
  64. // Update
  65. //----------------------------------------------------------------------------------
  66. UpdateCamera(&camera, CAMERA_ORBITAL);
  67. if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
  68. {
  69. currentModel = (currentModel + 1)%NUM_MODELS; // Cycle between the textures
  70. }
  71. if (IsKeyPressed(KEY_RIGHT))
  72. {
  73. currentModel++;
  74. if (currentModel >= NUM_MODELS) currentModel = 0;
  75. }
  76. else if (IsKeyPressed(KEY_LEFT))
  77. {
  78. currentModel--;
  79. if (currentModel < 0) currentModel = NUM_MODELS - 1;
  80. }
  81. //----------------------------------------------------------------------------------
  82. // Draw
  83. //----------------------------------------------------------------------------------
  84. BeginDrawing();
  85. ClearBackground(RAYWHITE);
  86. BeginMode3D(camera);
  87. DrawModel(models[currentModel], position, 1.0f, WHITE);
  88. DrawGrid(10, 1.0);
  89. EndMode3D();
  90. DrawRectangle(30, 400, 310, 30, Fade(SKYBLUE, 0.5f));
  91. DrawRectangleLines(30, 400, 310, 30, Fade(DARKBLUE, 0.5f));
  92. DrawText("MOUSE LEFT BUTTON to CYCLE PROCEDURAL MODELS", 40, 410, 10, BLUE);
  93. switch (currentModel)
  94. {
  95. case 0: DrawText("PLANE", 680, 10, 20, DARKBLUE); break;
  96. case 1: DrawText("CUBE", 680, 10, 20, DARKBLUE); break;
  97. case 2: DrawText("SPHERE", 680, 10, 20, DARKBLUE); break;
  98. case 3: DrawText("HEMISPHERE", 640, 10, 20, DARKBLUE); break;
  99. case 4: DrawText("CYLINDER", 680, 10, 20, DARKBLUE); break;
  100. case 5: DrawText("TORUS", 680, 10, 20, DARKBLUE); break;
  101. case 6: DrawText("KNOT", 680, 10, 20, DARKBLUE); break;
  102. case 7: DrawText("POLY", 680, 10, 20, DARKBLUE); break;
  103. case 8: DrawText("Custom (triangle)", 580, 10, 20, DARKBLUE); break;
  104. default: break;
  105. }
  106. EndDrawing();
  107. //----------------------------------------------------------------------------------
  108. }
  109. // De-Initialization
  110. //--------------------------------------------------------------------------------------
  111. UnloadTexture(texture); // Unload texture
  112. // Unload models data (GPU VRAM)
  113. for (int i = 0; i < NUM_MODELS; i++) UnloadModel(models[i]);
  114. CloseWindow(); // Close window and OpenGL context
  115. //--------------------------------------------------------------------------------------
  116. return 0;
  117. }
  118. // Generate a simple triangle mesh from code
  119. static Mesh GenMeshCustom(void)
  120. {
  121. Mesh mesh = { 0 };
  122. mesh.triangleCount = 1;
  123. mesh.vertexCount = mesh.triangleCount*3;
  124. mesh.vertices = (float *)MemAlloc(mesh.vertexCount*3*sizeof(float)); // 3 vertices, 3 coordinates each (x, y, z)
  125. mesh.texcoords = (float *)MemAlloc(mesh.vertexCount*2*sizeof(float)); // 3 vertices, 2 coordinates each (x, y)
  126. mesh.normals = (float *)MemAlloc(mesh.vertexCount*3*sizeof(float)); // 3 vertices, 3 coordinates each (x, y, z)
  127. // Vertex at (0, 0, 0)
  128. mesh.vertices[0] = 0;
  129. mesh.vertices[1] = 0;
  130. mesh.vertices[2] = 0;
  131. mesh.normals[0] = 0;
  132. mesh.normals[1] = 1;
  133. mesh.normals[2] = 0;
  134. mesh.texcoords[0] = 0;
  135. mesh.texcoords[1] = 0;
  136. // Vertex at (1, 0, 2)
  137. mesh.vertices[3] = 1;
  138. mesh.vertices[4] = 0;
  139. mesh.vertices[5] = 2;
  140. mesh.normals[3] = 0;
  141. mesh.normals[4] = 1;
  142. mesh.normals[5] = 0;
  143. mesh.texcoords[2] = 0.5f;
  144. mesh.texcoords[3] = 1.0f;
  145. // Vertex at (2, 0, 0)
  146. mesh.vertices[6] = 2;
  147. mesh.vertices[7] = 0;
  148. mesh.vertices[8] = 0;
  149. mesh.normals[6] = 0;
  150. mesh.normals[7] = 1;
  151. mesh.normals[8] = 0;
  152. mesh.texcoords[4] = 1;
  153. mesh.texcoords[5] =0;
  154. // Upload mesh data from CPU (RAM) to GPU (VRAM) memory
  155. UploadMesh(&mesh, false);
  156. return mesh;
  157. }