1 | /******************************************************************************************* |
2 | * |
3 | * raylib [models] example - Models loading |
4 | * |
5 | * raylib supports multiple models file formats: |
6 | * |
7 | * - OBJ > Text file, must include vertex position-texcoords-normals information, |
8 | * if files references some .mtl materials file, it will be loaded (or try to) |
9 | * - GLTF > Modern text/binary file format, includes lot of information and it could |
10 | * also reference external files, raylib will try loading mesh and materials data |
11 | * - IQM > Binary file format including mesh vertex data but also animation data, |
12 | * raylib can load .iqm animations. |
13 | * |
14 | * This example has been created using raylib 2.6 (www.raylib.com) |
15 | * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) |
16 | * |
17 | * Copyright (c) 2014-2019 Ramon Santamaria (@raysan5) |
18 | * |
19 | ********************************************************************************************/ |
20 | |
21 | #include "raylib.h" |
22 | |
23 | int main(void) |
24 | { |
25 | // Initialization |
26 | //-------------------------------------------------------------------------------------- |
27 | const int screenWidth = 800; |
28 | const int screenHeight = 450; |
29 | |
30 | InitWindow(screenWidth, screenHeight, "raylib [models] example - models loading" ); |
31 | |
32 | // Define the camera to look into our 3d world |
33 | Camera camera = { 0 }; |
34 | camera.position = (Vector3){ 50.0f, 50.0f, 50.0f }; // Camera position |
35 | camera.target = (Vector3){ 0.0f, 10.0f, 0.0f }; // Camera looking at point |
36 | camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) |
37 | camera.fovy = 45.0f; // Camera field-of-view Y |
38 | camera.type = CAMERA_PERSPECTIVE; // Camera mode type |
39 | |
40 | Model model = LoadModel("resources/models/castle.obj" ); // Load model |
41 | Texture2D texture = LoadTexture("resources/models/castle_diffuse.png" ); // Load model texture |
42 | model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set map diffuse texture |
43 | |
44 | Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position |
45 | |
46 | BoundingBox bounds = MeshBoundingBox(model.meshes[0]); // Set model bounds |
47 | |
48 | // NOTE: bounds are calculated from the original size of the model, |
49 | // if model is scaled on drawing, bounds must be also scaled |
50 | |
51 | SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode |
52 | |
53 | bool selected = false; // Selected object flag |
54 | |
55 | SetTargetFPS(60); // Set our game to run at 60 frames-per-second |
56 | //-------------------------------------------------------------------------------------- |
57 | |
58 | // Main game loop |
59 | while (!WindowShouldClose()) // Detect window close button or ESC key |
60 | { |
61 | // Update |
62 | //---------------------------------------------------------------------------------- |
63 | UpdateCamera(&camera); |
64 | |
65 | // Load new models/textures on drag&drop |
66 | if (IsFileDropped()) |
67 | { |
68 | int count = 0; |
69 | char **droppedFiles = GetDroppedFiles(&count); |
70 | |
71 | if (count == 1) // Only support one file dropped |
72 | { |
73 | if (IsFileExtension(droppedFiles[0], ".obj" ) || |
74 | IsFileExtension(droppedFiles[0], ".gltf" ) || |
75 | IsFileExtension(droppedFiles[0], ".iqm" )) // Model file formats supported |
76 | { |
77 | UnloadModel(model); // Unload previous model |
78 | model = LoadModel(droppedFiles[0]); // Load new model |
79 | model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set current map diffuse texture |
80 | |
81 | bounds = MeshBoundingBox(model.meshes[0]); |
82 | |
83 | // TODO: Move camera position from target enough distance to visualize model properly |
84 | } |
85 | else if (IsFileExtension(droppedFiles[0], ".png" )) // Texture file formats supported |
86 | { |
87 | // Unload current model texture and load new one |
88 | UnloadTexture(texture); |
89 | texture = LoadTexture(droppedFiles[0]); |
90 | model.materials[0].maps[MAP_DIFFUSE].texture = texture; |
91 | } |
92 | } |
93 | |
94 | ClearDroppedFiles(); // Clear internal buffers |
95 | } |
96 | |
97 | // Select model on mouse click |
98 | if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) |
99 | { |
100 | // Check collision between ray and box |
101 | if (CheckCollisionRayBox(GetMouseRay(GetMousePosition(), camera), bounds)) selected = !selected; |
102 | else selected = false; |
103 | } |
104 | //---------------------------------------------------------------------------------- |
105 | |
106 | // Draw |
107 | //---------------------------------------------------------------------------------- |
108 | BeginDrawing(); |
109 | |
110 | ClearBackground(RAYWHITE); |
111 | |
112 | BeginMode3D(camera); |
113 | |
114 | DrawModel(model, position, 1.0f, WHITE); // Draw 3d model with texture |
115 | |
116 | DrawGrid(20, 10.0f); // Draw a grid |
117 | |
118 | if (selected) DrawBoundingBox(bounds, GREEN); // Draw selection box |
119 | |
120 | EndMode3D(); |
121 | |
122 | DrawText("Drag & drop model to load mesh/texture." , 10, GetScreenHeight() - 20, 10, DARKGRAY); |
123 | if (selected) DrawText("MODEL SELECTED" , GetScreenWidth() - 110, 10, 10, GREEN); |
124 | |
125 | DrawText("(c) Castle 3D model by Alberto Cano" , screenWidth - 200, screenHeight - 20, 10, GRAY); |
126 | |
127 | DrawFPS(10, 10); |
128 | |
129 | EndDrawing(); |
130 | //---------------------------------------------------------------------------------- |
131 | } |
132 | |
133 | // De-Initialization |
134 | //-------------------------------------------------------------------------------------- |
135 | UnloadTexture(texture); // Unload texture |
136 | UnloadModel(model); // Unload model |
137 | |
138 | CloseWindow(); // Close window and OpenGL context |
139 | //-------------------------------------------------------------------------------------- |
140 | |
141 | return 0; |
142 | } |