aboutsummaryrefslogtreecommitdiff
path: root/raylib/examples/models
diff options
context:
space:
mode:
Diffstat (limited to 'raylib/examples/models')
-rw-r--r--raylib/examples/models/models_animation.c111
-rw-r--r--raylib/examples/models/models_animation.pngbin0 -> 67020 bytes
-rw-r--r--raylib/examples/models/models_billboard.c111
-rw-r--r--raylib/examples/models/models_billboard.pngbin0 -> 54859 bytes
-rw-r--r--raylib/examples/models/models_box_collisions.c126
-rw-r--r--raylib/examples/models/models_box_collisions.pngbin0 -> 22077 bytes
-rw-r--r--raylib/examples/models/models_cubicmap.c95
-rw-r--r--raylib/examples/models/models_cubicmap.pngbin0 -> 412536 bytes
-rw-r--r--raylib/examples/models/models_draw_cube_texture.c245
-rw-r--r--raylib/examples/models/models_draw_cube_texture.pngbin0 -> 63170 bytes
-rw-r--r--raylib/examples/models/models_first_person_maze.c133
-rw-r--r--raylib/examples/models/models_first_person_maze.pngbin0 -> 327996 bytes
-rw-r--r--raylib/examples/models/models_geometric_shapes.c88
-rw-r--r--raylib/examples/models/models_geometric_shapes.pngbin0 -> 22450 bytes
-rw-r--r--raylib/examples/models/models_heightmap.c90
-rw-r--r--raylib/examples/models/models_heightmap.pngbin0 -> 96976 bytes
-rw-r--r--raylib/examples/models/models_loading.c153
-rw-r--r--raylib/examples/models/models_loading.pngbin0 -> 222339 bytes
-rw-r--r--raylib/examples/models/models_loading_gltf.c103
-rw-r--r--raylib/examples/models/models_loading_gltf.pngbin0 -> 26632 bytes
-rw-r--r--raylib/examples/models/models_loading_m3d.c174
-rw-r--r--raylib/examples/models/models_loading_m3d.pngbin0 -> 25881 bytes
-rw-r--r--raylib/examples/models/models_loading_vox.c133
-rw-r--r--raylib/examples/models/models_loading_vox.pngbin0 -> 23252 bytes
-rw-r--r--raylib/examples/models/models_mesh_generation.c190
-rw-r--r--raylib/examples/models/models_mesh_generation.pngbin0 -> 27504 bytes
-rw-r--r--raylib/examples/models/models_mesh_picking.c246
-rw-r--r--raylib/examples/models/models_mesh_picking.pngbin0 -> 138786 bytes
-rw-r--r--raylib/examples/models/models_orthographic_projection.c102
-rw-r--r--raylib/examples/models/models_orthographic_projection.pngbin0 -> 32775 bytes
-rw-r--r--raylib/examples/models/models_rlgl_solar_system.c172
-rw-r--r--raylib/examples/models/models_rlgl_solar_system.pngbin0 -> 30443 bytes
-rw-r--r--raylib/examples/models/models_skybox.c271
-rw-r--r--raylib/examples/models/models_skybox.pngbin0 -> 427348 bytes
-rw-r--r--raylib/examples/models/models_waving_cubes.c117
-rw-r--r--raylib/examples/models/models_waving_cubes.pngbin0 -> 37712 bytes
-rw-r--r--raylib/examples/models/models_yaw_pitch_roll.c122
-rw-r--r--raylib/examples/models/models_yaw_pitch_roll.pngbin0 -> 146882 bytes
-rw-r--r--raylib/examples/models/resources/LICENSE.md22
-rw-r--r--raylib/examples/models/resources/billboard.pngbin0 -> 22374 bytes
-rw-r--r--raylib/examples/models/resources/cubicmap.pngbin0 -> 164 bytes
-rw-r--r--raylib/examples/models/resources/cubicmap_atlas.pngbin0 -> 37160 bytes
-rw-r--r--raylib/examples/models/resources/dresden_square_1k.hdrbin0 -> 1524733 bytes
-rw-r--r--raylib/examples/models/resources/dresden_square_2k.hdrbin0 -> 6019615 bytes
-rw-r--r--raylib/examples/models/resources/heightmap.pngbin0 -> 10883 bytes
-rw-r--r--raylib/examples/models/resources/models/gltf/LICENSE2
-rw-r--r--raylib/examples/models/resources/models/gltf/raylib_logo_3d.glbbin0 -> 266724 bytes
-rw-r--r--raylib/examples/models/resources/models/gltf/robot.blendbin0 -> 2107372 bytes
-rw-r--r--raylib/examples/models/resources/models/gltf/robot.glbbin0 -> 1602604 bytes
-rw-r--r--raylib/examples/models/resources/models/iqm/guy.blendbin0 -> 665304 bytes
-rw-r--r--raylib/examples/models/resources/models/iqm/guy.iqmbin0 -> 39408 bytes
-rw-r--r--raylib/examples/models/resources/models/iqm/guyanim.iqmbin0 -> 18244 bytes
-rw-r--r--raylib/examples/models/resources/models/iqm/guytex.pngbin0 -> 301935 bytes
-rw-r--r--raylib/examples/models/resources/models/m3d/cesium_man.m3dbin0 -> 73844 bytes
-rw-r--r--raylib/examples/models/resources/models/m3d/seagull.m3dbin0 -> 10263 bytes
-rw-r--r--raylib/examples/models/resources/models/m3d/suzanne.m3dbin0 -> 11645 bytes
-rw-r--r--raylib/examples/models/resources/models/obj/bridge_diffuse.pngbin0 -> 318466 bytes
-rw-r--r--raylib/examples/models/resources/models/obj/castle_diffuse.pngbin0 -> 444213 bytes
-rw-r--r--raylib/examples/models/resources/models/obj/cube_diffuse.pngbin0 -> 23330 bytes
-rw-r--r--raylib/examples/models/resources/models/obj/house_diffuse.pngbin0 -> 392528 bytes
-rw-r--r--raylib/examples/models/resources/models/obj/market_diffuse.pngbin0 -> 389458 bytes
-rw-r--r--raylib/examples/models/resources/models/obj/plane_diffuse.pngbin0 -> 823493 bytes
-rw-r--r--raylib/examples/models/resources/models/obj/turret_diffuse.pngbin0 -> 380120 bytes
-rw-r--r--raylib/examples/models/resources/models/obj/well_diffuse.pngbin0 -> 342387 bytes
-rw-r--r--raylib/examples/models/resources/models/vox/LICENSE9
-rw-r--r--raylib/examples/models/resources/models/vox/chr_knight.voxbin0 -> 31031 bytes
-rw-r--r--raylib/examples/models/resources/models/vox/chr_sword.voxbin0 -> 30775 bytes
-rw-r--r--raylib/examples/models/resources/models/vox/monu9.voxbin0 -> 160767 bytes
-rw-r--r--raylib/examples/models/resources/shaders/glsl100/cubemap.fs29
-rw-r--r--raylib/examples/models/resources/shaders/glsl100/cubemap.vs20
-rw-r--r--raylib/examples/models/resources/shaders/glsl100/skybox.fs31
-rw-r--r--raylib/examples/models/resources/shaders/glsl100/skybox.vs24
-rw-r--r--raylib/examples/models/resources/shaders/glsl330/cubemap.fs30
-rw-r--r--raylib/examples/models/resources/shaders/glsl330/cubemap.vs20
-rw-r--r--raylib/examples/models/resources/shaders/glsl330/skybox.fs30
-rw-r--r--raylib/examples/models/resources/shaders/glsl330/skybox.vs24
-rw-r--r--raylib/examples/models/resources/skybox.pngbin0 -> 10992 bytes
77 files changed, 3023 insertions, 0 deletions
diff --git a/raylib/examples/models/models_animation.c b/raylib/examples/models/models_animation.c
new file mode 100644
index 0000000..ffe2d01
--- /dev/null
+++ b/raylib/examples/models/models_animation.c
@@ -0,0 +1,111 @@
+/*******************************************************************************************
+*
+* raylib [models] example - Load 3d model with animations and play them
+*
+* Example originally created with raylib 2.5, last time updated with raylib 3.5
+*
+* Example contributed by Culacant (@culacant) and reviewed by Ramon Santamaria (@raysan5)
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2019-2023 Culacant (@culacant) and Ramon Santamaria (@raysan5)
+*
+********************************************************************************************
+*
+* NOTE: To export a model from blender, make sure it is not posed, the vertices need to be
+* in the same position as they would be in edit mode and the scale of your models is
+* set to 0. Scaling can be done from the export menu.
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - model animation");
+
+ // Define the camera to look into our 3d world
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position
+ camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
+ camera.fovy = 45.0f; // Camera field-of-view Y
+ camera.projection = CAMERA_PERSPECTIVE; // Camera mode type
+
+ Model model = LoadModel("resources/models/iqm/guy.iqm"); // Load the animated model mesh and basic data
+ Texture2D texture = LoadTexture("resources/models/iqm/guytex.png"); // Load model texture and set material
+ SetMaterialTexture(&model.materials[0], MATERIAL_MAP_DIFFUSE, texture); // Set model material map texture
+
+ Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
+
+ // Load animation data
+ unsigned int animsCount = 0;
+ ModelAnimation *anims = LoadModelAnimations("resources/models/iqm/guyanim.iqm", &animsCount);
+ int animFrameCounter = 0;
+
+ DisableCursor(); // Catch cursor
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ UpdateCamera(&camera, CAMERA_FIRST_PERSON);
+
+ // Play animation when spacebar is held down
+ if (IsKeyDown(KEY_SPACE))
+ {
+ animFrameCounter++;
+ UpdateModelAnimation(model, anims[0], animFrameCounter);
+ if (animFrameCounter >= anims[0].frameCount) animFrameCounter = 0;
+ }
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+
+ DrawModelEx(model, position, (Vector3){ 1.0f, 0.0f, 0.0f }, -90.0f, (Vector3){ 1.0f, 1.0f, 1.0f }, WHITE);
+
+ for (int i = 0; i < model.boneCount; i++)
+ {
+ DrawCube(anims[0].framePoses[animFrameCounter][i].translation, 0.2f, 0.2f, 0.2f, RED);
+ }
+
+ DrawGrid(10, 1.0f); // Draw a grid
+
+ EndMode3D();
+
+ DrawText("PRESS SPACE to PLAY MODEL ANIMATION", 10, 10, 20, MAROON);
+ DrawText("(c) Guy IQM 3D model by @culacant", screenWidth - 200, screenHeight - 20, 10, GRAY);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadTexture(texture); // Unload texture
+ UnloadModelAnimations(anims, animsCount); // Unload model animations data
+ UnloadModel(model); // Unload model
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/raylib/examples/models/models_animation.png b/raylib/examples/models/models_animation.png
new file mode 100644
index 0000000..57e39dd
--- /dev/null
+++ b/raylib/examples/models/models_animation.png
Binary files differ
diff --git a/raylib/examples/models/models_billboard.c b/raylib/examples/models/models_billboard.c
new file mode 100644
index 0000000..9b02a8a
--- /dev/null
+++ b/raylib/examples/models/models_billboard.c
@@ -0,0 +1,111 @@
+/*******************************************************************************************
+*
+* raylib [models] example - Drawing billboards
+*
+* Example originally created with raylib 1.3, last time updated with raylib 3.5
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2015-2023 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+#include "raymath.h"
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - drawing billboards");
+
+ // Define the camera to look into our 3d world
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 5.0f, 4.0f, 5.0f }; // Camera position
+ camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
+ camera.fovy = 45.0f; // Camera field-of-view Y
+ camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
+
+ Texture2D bill = LoadTexture("resources/billboard.png"); // Our billboard texture
+ Vector3 billPositionStatic = { 0.0f, 2.0f, 0.0f }; // Position of static billboard
+ Vector3 billPositionRotating = { 1.0f, 2.0f, 1.0f }; // Position of rotating billboard
+
+ // Entire billboard texture, source is used to take a segment from a larger texture.
+ Rectangle source = { 0.0f, 0.0f, (float)bill.width, (float)bill.height };
+
+ // NOTE: Billboard locked on axis-Y
+ Vector3 billUp = { 0.0f, 1.0f, 0.0f };
+
+ // Rotate around origin
+ // Here we choose to rotate around the image center
+ // NOTE: (-1, 1) is the range where origin.x, origin.y is inside the texture
+ Vector2 rotateOrigin = { 0.0f };
+
+ // Distance is needed for the correct billboard draw order
+ // Larger distance (further away from the camera) should be drawn prior to smaller distance.
+ float distanceStatic;
+ float distanceRotating;
+ float rotation = 0.0f;
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ UpdateCamera(&camera, CAMERA_ORBITAL);
+
+ rotation += 0.4f;
+ distanceStatic = Vector3Distance(camera.position, billPositionStatic);
+ distanceRotating = Vector3Distance(camera.position, billPositionRotating);
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+
+ DrawGrid(10, 1.0f); // Draw a grid
+
+ // Draw order matters!
+ if (distanceStatic > distanceRotating)
+ {
+ DrawBillboard(camera, bill, billPositionStatic, 2.0f, WHITE);
+ DrawBillboardPro(camera, bill, source, billPositionRotating, billUp, (Vector2) {1.0f, 1.0f}, rotateOrigin, rotation, WHITE);
+ }
+ else
+ {
+ DrawBillboardPro(camera, bill, source, billPositionRotating, billUp, (Vector2) {1.0f, 1.0f}, rotateOrigin, rotation, WHITE);
+ DrawBillboard(camera, bill, billPositionStatic, 2.0f, WHITE);
+ }
+
+ EndMode3D();
+
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadTexture(bill); // Unload texture
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+} \ No newline at end of file
diff --git a/raylib/examples/models/models_billboard.png b/raylib/examples/models/models_billboard.png
new file mode 100644
index 0000000..dad1e55
--- /dev/null
+++ b/raylib/examples/models/models_billboard.png
Binary files differ
diff --git a/raylib/examples/models/models_box_collisions.c b/raylib/examples/models/models_box_collisions.c
new file mode 100644
index 0000000..9cff5e0
--- /dev/null
+++ b/raylib/examples/models/models_box_collisions.c
@@ -0,0 +1,126 @@
+/*******************************************************************************************
+*
+* raylib [models] example - Detect basic 3d collisions (box vs sphere vs box)
+*
+* Example originally created with raylib 1.3, last time updated with raylib 3.5
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2015-2023 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - box collisions");
+
+ // Define the camera to look into our 3d world
+ Camera camera = { { 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
+
+ Vector3 playerPosition = { 0.0f, 1.0f, 2.0f };
+ Vector3 playerSize = { 1.0f, 2.0f, 1.0f };
+ Color playerColor = GREEN;
+
+ Vector3 enemyBoxPos = { -4.0f, 1.0f, 0.0f };
+ Vector3 enemyBoxSize = { 2.0f, 2.0f, 2.0f };
+
+ Vector3 enemySpherePos = { 4.0f, 0.0f, 0.0f };
+ float enemySphereSize = 1.5f;
+
+ bool collision = false;
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+
+ // Move player
+ if (IsKeyDown(KEY_RIGHT)) playerPosition.x += 0.2f;
+ else if (IsKeyDown(KEY_LEFT)) playerPosition.x -= 0.2f;
+ else if (IsKeyDown(KEY_DOWN)) playerPosition.z += 0.2f;
+ else if (IsKeyDown(KEY_UP)) playerPosition.z -= 0.2f;
+
+ collision = false;
+
+ // Check collisions player vs enemy-box
+ if (CheckCollisionBoxes(
+ (BoundingBox){(Vector3){ playerPosition.x - playerSize.x/2,
+ playerPosition.y - playerSize.y/2,
+ playerPosition.z - playerSize.z/2 },
+ (Vector3){ playerPosition.x + playerSize.x/2,
+ playerPosition.y + playerSize.y/2,
+ playerPosition.z + playerSize.z/2 }},
+ (BoundingBox){(Vector3){ enemyBoxPos.x - enemyBoxSize.x/2,
+ enemyBoxPos.y - enemyBoxSize.y/2,
+ enemyBoxPos.z - enemyBoxSize.z/2 },
+ (Vector3){ enemyBoxPos.x + enemyBoxSize.x/2,
+ enemyBoxPos.y + enemyBoxSize.y/2,
+ enemyBoxPos.z + enemyBoxSize.z/2 }})) collision = true;
+
+ // Check collisions player vs enemy-sphere
+ if (CheckCollisionBoxSphere(
+ (BoundingBox){(Vector3){ playerPosition.x - playerSize.x/2,
+ playerPosition.y - playerSize.y/2,
+ playerPosition.z - playerSize.z/2 },
+ (Vector3){ playerPosition.x + playerSize.x/2,
+ playerPosition.y + playerSize.y/2,
+ playerPosition.z + playerSize.z/2 }},
+ enemySpherePos, enemySphereSize)) collision = true;
+
+ if (collision) playerColor = RED;
+ else playerColor = GREEN;
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+
+ // Draw enemy-box
+ DrawCube(enemyBoxPos, enemyBoxSize.x, enemyBoxSize.y, enemyBoxSize.z, GRAY);
+ DrawCubeWires(enemyBoxPos, enemyBoxSize.x, enemyBoxSize.y, enemyBoxSize.z, DARKGRAY);
+
+ // Draw enemy-sphere
+ DrawSphere(enemySpherePos, enemySphereSize, GRAY);
+ DrawSphereWires(enemySpherePos, enemySphereSize, 16, 16, DARKGRAY);
+
+ // Draw player
+ DrawCubeV(playerPosition, playerSize, playerColor);
+
+ DrawGrid(10, 1.0f); // Draw a grid
+
+ EndMode3D();
+
+ DrawText("Move player with cursors to collide", 220, 40, 20, GRAY);
+
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+} \ No newline at end of file
diff --git a/raylib/examples/models/models_box_collisions.png b/raylib/examples/models/models_box_collisions.png
new file mode 100644
index 0000000..d01fd9d
--- /dev/null
+++ b/raylib/examples/models/models_box_collisions.png
Binary files differ
diff --git a/raylib/examples/models/models_cubicmap.c b/raylib/examples/models/models_cubicmap.c
new file mode 100644
index 0000000..e0a2b30
--- /dev/null
+++ b/raylib/examples/models/models_cubicmap.c
@@ -0,0 +1,95 @@
+/*******************************************************************************************
+*
+* raylib [models] example - Cubicmap loading and drawing
+*
+* Example originally created with raylib 1.8, last time updated with raylib 3.5
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2015-2023 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - cubesmap loading and drawing");
+
+ // Define the camera to look into our 3d world
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 16.0f, 14.0f, 16.0f }; // Camera position
+ camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
+ camera.fovy = 45.0f; // Camera field-of-view Y
+ camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
+
+ Image image = LoadImage("resources/cubicmap.png"); // Load cubicmap image (RAM)
+ Texture2D cubicmap = LoadTextureFromImage(image); // Convert image to texture to display (VRAM)
+
+ Mesh mesh = GenMeshCubicmap(image, (Vector3){ 1.0f, 1.0f, 1.0f });
+ Model model = LoadModelFromMesh(mesh);
+
+ // NOTE: By default each cube is mapped to one part of texture atlas
+ Texture2D texture = LoadTexture("resources/cubicmap_atlas.png"); // Load map texture
+ model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture
+
+ Vector3 mapPosition = { -16.0f, 0.0f, -8.0f }; // Set model position
+
+ UnloadImage(image); // Unload cubesmap image from RAM, already uploaded to VRAM
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ UpdateCamera(&camera, CAMERA_ORBITAL);
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+
+ DrawModel(model, mapPosition, 1.0f, WHITE);
+
+ EndMode3D();
+
+ DrawTextureEx(cubicmap, (Vector2){ screenWidth - cubicmap.width*4.0f - 20, 20.0f }, 0.0f, 4.0f, WHITE);
+ DrawRectangleLines(screenWidth - cubicmap.width*4 - 20, 20, cubicmap.width*4, cubicmap.height*4, GREEN);
+
+ DrawText("cubicmap image used to", 658, 90, 10, GRAY);
+ DrawText("generate map 3d model", 658, 104, 10, GRAY);
+
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadTexture(cubicmap); // Unload cubicmap texture
+ UnloadTexture(texture); // Unload map texture
+ UnloadModel(model); // Unload map model
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/raylib/examples/models/models_cubicmap.png b/raylib/examples/models/models_cubicmap.png
new file mode 100644
index 0000000..9cb854c
--- /dev/null
+++ b/raylib/examples/models/models_cubicmap.png
Binary files differ
diff --git a/raylib/examples/models/models_draw_cube_texture.c b/raylib/examples/models/models_draw_cube_texture.c
new file mode 100644
index 0000000..e43c3c8
--- /dev/null
+++ b/raylib/examples/models/models_draw_cube_texture.c
@@ -0,0 +1,245 @@
+/*******************************************************************************************
+*
+* raylib [models] example - Draw textured cube
+*
+* Example originally created with raylib 4.5, last time updated with raylib 4.5
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2022-2023 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include "rlgl.h" // Required to define vertex data (immediate-mode style)
+
+//------------------------------------------------------------------------------------
+// Custom Functions Declaration
+//------------------------------------------------------------------------------------
+void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color); // Draw cube textured
+void DrawCubeTextureRec(Texture2D texture, Rectangle source, Vector3 position, float width, float height, float length, Color color); // Draw cube with a region of a texture
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - draw cube texture");
+
+ // Define the camera to look into our 3d world
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 0.0f, 10.0f, 10.0f };
+ camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
+ camera.fovy = 45.0f;
+ camera.projection = CAMERA_PERSPECTIVE;
+
+ // Load texture to be applied to the cubes sides
+ Texture2D texture = LoadTexture("resources/cubicmap_atlas.png");
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ // TODO: Update your variables here
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+
+ // Draw cube with an applied texture
+ DrawCubeTexture(texture, (Vector3){ -2.0f, 2.0f, 0.0f }, 2.0f, 4.0f, 2.0f, WHITE);
+
+ // Draw cube with an applied texture, but only a defined rectangle piece of the texture
+ DrawCubeTextureRec(texture, (Rectangle){ 0, texture.height/2, texture.width/2, texture.height/2 },
+ (Vector3){ 2.0f, 1.0f, 0.0f }, 2.0f, 2.0f, 2.0f, WHITE);
+
+ DrawGrid(10, 1.0f); // Draw a grid
+
+ EndMode3D();
+
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadTexture(texture); // Unload texture
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------------
+// Custom Functions Definition
+//------------------------------------------------------------------------------------
+// Draw cube textured
+// NOTE: Cube position is the center position
+void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color)
+{
+ float x = position.x;
+ float y = position.y;
+ float z = position.z;
+
+ // Set desired texture to be enabled while drawing following vertex data
+ rlSetTexture(texture.id);
+
+ // Vertex data transformation can be defined with the commented lines,
+ // but in this example we calculate the transformed vertex data directly when calling rlVertex3f()
+ //rlPushMatrix();
+ // NOTE: Transformation is applied in inverse order (scale -> rotate -> translate)
+ //rlTranslatef(2.0f, 0.0f, 0.0f);
+ //rlRotatef(45, 0, 1, 0);
+ //rlScalef(2.0f, 2.0f, 2.0f);
+
+ rlBegin(RL_QUADS);
+ rlColor4ub(color.r, color.g, color.b, color.a);
+ // Front Face
+ rlNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
+ rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Left Of The Texture and Quad
+ rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Right Of The Texture and Quad
+ rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z + length/2); // Top Right Of The Texture and Quad
+ rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z + length/2); // Top Left Of The Texture and Quad
+ // Back Face
+ rlNormal3f(0.0f, 0.0f, - 1.0f); // Normal Pointing Away From Viewer
+ rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Bottom Right Of The Texture and Quad
+ rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Right Of The Texture and Quad
+ rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Left Of The Texture and Quad
+ rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom Left Of The Texture and Quad
+ // Top Face
+ rlNormal3f(0.0f, 1.0f, 0.0f); // Normal Pointing Up
+ rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Left Of The Texture and Quad
+ rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y + height/2, z + length/2); // Bottom Left Of The Texture and Quad
+ rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y + height/2, z + length/2); // Bottom Right Of The Texture and Quad
+ rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Right Of The Texture and Quad
+ // Bottom Face
+ rlNormal3f(0.0f, - 1.0f, 0.0f); // Normal Pointing Down
+ rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Top Right Of The Texture and Quad
+ rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y - height/2, z - length/2); // Top Left Of The Texture and Quad
+ rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Left Of The Texture and Quad
+ rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Right Of The Texture and Quad
+ // Right face
+ rlNormal3f(1.0f, 0.0f, 0.0f); // Normal Pointing Right
+ rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom Right Of The Texture and Quad
+ rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Right Of The Texture and Quad
+ rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z + length/2); // Top Left Of The Texture and Quad
+ rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Left Of The Texture and Quad
+ // Left Face
+ rlNormal3f( - 1.0f, 0.0f, 0.0f); // Normal Pointing Left
+ rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Bottom Left Of The Texture and Quad
+ rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Right Of The Texture and Quad
+ rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z + length/2); // Top Right Of The Texture and Quad
+ rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Left Of The Texture and Quad
+ rlEnd();
+ //rlPopMatrix();
+
+ rlSetTexture(0);
+}
+
+// Draw cube with texture piece applied to all faces
+void DrawCubeTextureRec(Texture2D texture, Rectangle source, Vector3 position, float width, float height, float length, Color color)
+{
+ float x = position.x;
+ float y = position.y;
+ float z = position.z;
+ float texWidth = (float)texture.width;
+ float texHeight = (float)texture.height;
+
+ // Set desired texture to be enabled while drawing following vertex data
+ rlSetTexture(texture.id);
+
+ // We calculate the normalized texture coordinates for the desired texture-source-rectangle
+ // It means converting from (tex.width, tex.height) coordinates to [0.0f, 1.0f] equivalent
+ rlBegin(RL_QUADS);
+ rlColor4ub(color.r, color.g, color.b, color.a);
+
+ // Front face
+ rlNormal3f(0.0f, 0.0f, 1.0f);
+ rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
+ rlVertex3f(x - width/2, y - height/2, z + length/2);
+ rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
+ rlVertex3f(x + width/2, y - height/2, z + length/2);
+ rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
+ rlVertex3f(x + width/2, y + height/2, z + length/2);
+ rlTexCoord2f(source.x/texWidth, source.y/texHeight);
+ rlVertex3f(x - width/2, y + height/2, z + length/2);
+
+ // Back face
+ rlNormal3f(0.0f, 0.0f, - 1.0f);
+ rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
+ rlVertex3f(x - width/2, y - height/2, z - length/2);
+ rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
+ rlVertex3f(x - width/2, y + height/2, z - length/2);
+ rlTexCoord2f(source.x/texWidth, source.y/texHeight);
+ rlVertex3f(x + width/2, y + height/2, z - length/2);
+ rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
+ rlVertex3f(x + width/2, y - height/2, z - length/2);
+
+ // Top face
+ rlNormal3f(0.0f, 1.0f, 0.0f);
+ rlTexCoord2f(source.x/texWidth, source.y/texHeight);
+ rlVertex3f(x - width/2, y + height/2, z - length/2);
+ rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
+ rlVertex3f(x - width/2, y + height/2, z + length/2);
+ rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
+ rlVertex3f(x + width/2, y + height/2, z + length/2);
+ rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
+ rlVertex3f(x + width/2, y + height/2, z - length/2);
+
+ // Bottom face
+ rlNormal3f(0.0f, - 1.0f, 0.0f);
+ rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
+ rlVertex3f(x - width/2, y - height/2, z - length/2);
+ rlTexCoord2f(source.x/texWidth, source.y/texHeight);
+ rlVertex3f(x + width/2, y - height/2, z - length/2);
+ rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
+ rlVertex3f(x + width/2, y - height/2, z + length/2);
+ rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
+ rlVertex3f(x - width/2, y - height/2, z + length/2);
+
+ // Right face
+ rlNormal3f(1.0f, 0.0f, 0.0f);
+ rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
+ rlVertex3f(x + width/2, y - height/2, z - length/2);
+ rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
+ rlVertex3f(x + width/2, y + height/2, z - length/2);
+ rlTexCoord2f(source.x/texWidth, source.y/texHeight);
+ rlVertex3f(x + width/2, y + height/2, z + length/2);
+ rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
+ rlVertex3f(x + width/2, y - height/2, z + length/2);
+
+ // Left face
+ rlNormal3f( - 1.0f, 0.0f, 0.0f);
+ rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
+ rlVertex3f(x - width/2, y - height/2, z - length/2);
+ rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
+ rlVertex3f(x - width/2, y - height/2, z + length/2);
+ rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
+ rlVertex3f(x - width/2, y + height/2, z + length/2);
+ rlTexCoord2f(source.x/texWidth, source.y/texHeight);
+ rlVertex3f(x - width/2, y + height/2, z - length/2);
+
+ rlEnd();
+
+ rlSetTexture(0);
+} \ No newline at end of file
diff --git a/raylib/examples/models/models_draw_cube_texture.png b/raylib/examples/models/models_draw_cube_texture.png
new file mode 100644
index 0000000..45b3a13
--- /dev/null
+++ b/raylib/examples/models/models_draw_cube_texture.png
Binary files differ
diff --git a/raylib/examples/models/models_first_person_maze.c b/raylib/examples/models/models_first_person_maze.c
new file mode 100644
index 0000000..6a4345a
--- /dev/null
+++ b/raylib/examples/models/models_first_person_maze.c
@@ -0,0 +1,133 @@
+/*******************************************************************************************
+*
+* raylib [models] example - first person maze
+*
+* Example originally created with raylib 2.5, last time updated with raylib 3.5
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2019-2023 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include <stdlib.h> // Required for: free()
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - first person maze");
+
+ // Define the camera to look into our 3d world
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 0.2f, 0.4f, 0.2f }; // Camera position
+ camera.target = (Vector3){ 0.185f, 0.4f, 0.0f }; // Camera looking at point
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
+ camera.fovy = 45.0f; // Camera field-of-view Y
+ camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
+ Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
+
+ Image imMap = LoadImage("resources/cubicmap.png"); // Load cubicmap image (RAM)
+ Texture2D cubicmap = LoadTextureFromImage(imMap); // Convert image to texture to display (VRAM)
+ Mesh mesh = GenMeshCubicmap(imMap, (Vector3){ 1.0f, 1.0f, 1.0f });
+ Model model = LoadModelFromMesh(mesh);
+
+ // NOTE: By default each cube is mapped to one part of texture atlas
+ Texture2D texture = LoadTexture("resources/cubicmap_atlas.png"); // Load map texture
+ model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture
+
+ // Get map image data to be used for collision detection
+ Color *mapPixels = LoadImageColors(imMap);
+ UnloadImage(imMap); // Unload image from RAM
+
+ Vector3 mapPosition = { -16.0f, 0.0f, -8.0f }; // Set model position
+
+ DisableCursor(); // Limit cursor to relative movement inside the window
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ Vector3 oldCamPos = camera.position; // Store old camera position
+
+ UpdateCamera(&camera, CAMERA_FIRST_PERSON);
+
+ // Check player collision (we simplify to 2D collision detection)
+ Vector2 playerPos = { camera.position.x, camera.position.z };
+ float playerRadius = 0.1f; // Collision radius (player is modelled as a cilinder for collision)
+
+ int playerCellX = (int)(playerPos.x - mapPosition.x + 0.5f);
+ int playerCellY = (int)(playerPos.y - mapPosition.z + 0.5f);
+
+ // Out-of-limits security check
+ if (playerCellX < 0) playerCellX = 0;
+ else if (playerCellX >= cubicmap.width) playerCellX = cubicmap.width - 1;
+
+ if (playerCellY < 0) playerCellY = 0;
+ else if (playerCellY >= cubicmap.height) playerCellY = cubicmap.height - 1;
+
+ // Check map collisions using image data and player position
+ // TODO: Improvement: Just check player surrounding cells for collision
+ for (int y = 0; y < cubicmap.height; y++)
+ {
+ for (int x = 0; x < cubicmap.width; x++)
+ {
+ if ((mapPixels[y*cubicmap.width + x].r == 255) && // Collision: white pixel, only check R channel
+ (CheckCollisionCircleRec(playerPos, playerRadius,
+ (Rectangle){ mapPosition.x - 0.5f + x*1.0f, mapPosition.z - 0.5f + y*1.0f, 1.0f, 1.0f })))
+ {
+ // Collision detected, reset camera position
+ camera.position = oldCamPos;
+ }
+ }
+ }
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+ DrawModel(model, mapPosition, 1.0f, WHITE); // Draw maze map
+ EndMode3D();
+
+ DrawTextureEx(cubicmap, (Vector2){ GetScreenWidth() - cubicmap.width*4.0f - 20, 20.0f }, 0.0f, 4.0f, WHITE);
+ DrawRectangleLines(GetScreenWidth() - cubicmap.width*4 - 20, 20, cubicmap.width*4, cubicmap.height*4, GREEN);
+
+ // Draw player position radar
+ DrawRectangle(GetScreenWidth() - cubicmap.width*4 - 20 + playerCellX*4, 20 + playerCellY*4, 4, 4, RED);
+
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadImageColors(mapPixels); // Unload color array
+
+ UnloadTexture(cubicmap); // Unload cubicmap texture
+ UnloadTexture(texture); // Unload map texture
+ UnloadModel(model); // Unload map model
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/raylib/examples/models/models_first_person_maze.png b/raylib/examples/models/models_first_person_maze.png
new file mode 100644
index 0000000..ed6047e
--- /dev/null
+++ b/raylib/examples/models/models_first_person_maze.png
Binary files differ
diff --git a/raylib/examples/models/models_geometric_shapes.c b/raylib/examples/models/models_geometric_shapes.c
new file mode 100644
index 0000000..33c4063
--- /dev/null
+++ b/raylib/examples/models/models_geometric_shapes.c
@@ -0,0 +1,88 @@
+/*******************************************************************************************
+*
+* raylib [models] example - Draw some basic geometric shapes (cube, sphere, cylinder...)
+*
+* Example originally created with raylib 1.0, last time updated with raylib 3.5
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2014-2023 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - geometric shapes");
+
+ // Define the camera to look into our 3d world
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 0.0f, 10.0f, 10.0f };
+ camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
+ camera.fovy = 45.0f;
+ camera.projection = CAMERA_PERSPECTIVE;
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ // TODO: Update your variables here
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+
+ DrawCube((Vector3){-4.0f, 0.0f, 2.0f}, 2.0f, 5.0f, 2.0f, RED);
+ DrawCubeWires((Vector3){-4.0f, 0.0f, 2.0f}, 2.0f, 5.0f, 2.0f, GOLD);
+ DrawCubeWires((Vector3){-4.0f, 0.0f, -2.0f}, 3.0f, 6.0f, 2.0f, MAROON);
+
+ DrawSphere((Vector3){-1.0f, 0.0f, -2.0f}, 1.0f, GREEN);
+ DrawSphereWires((Vector3){1.0f, 0.0f, 2.0f}, 2.0f, 16, 16, LIME);
+
+ DrawCylinder((Vector3){4.0f, 0.0f, -2.0f}, 1.0f, 2.0f, 3.0f, 4, SKYBLUE);
+ DrawCylinderWires((Vector3){4.0f, 0.0f, -2.0f}, 1.0f, 2.0f, 3.0f, 4, DARKBLUE);
+ DrawCylinderWires((Vector3){4.5f, -1.0f, 2.0f}, 1.0f, 1.0f, 2.0f, 6, BROWN);
+
+ DrawCylinder((Vector3){1.0f, 0.0f, -4.0f}, 0.0f, 1.5f, 3.0f, 8, GOLD);
+ DrawCylinderWires((Vector3){1.0f, 0.0f, -4.0f}, 0.0f, 1.5f, 3.0f, 8, PINK);
+
+ DrawCapsule ((Vector3){-3.0f, 1.5f, -4.0f}, (Vector3){-4.0f, -1.0f, -4.0f}, 1.2f, 8, 8, VIOLET);
+ DrawCapsuleWires((Vector3){-3.0f, 1.5f, -4.0f}, (Vector3){-4.0f, -1.0f, -4.0f}, 1.2f, 8, 8, PURPLE);
+
+ DrawGrid(10, 1.0f); // Draw a grid
+
+ EndMode3D();
+
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+} \ No newline at end of file
diff --git a/raylib/examples/models/models_geometric_shapes.png b/raylib/examples/models/models_geometric_shapes.png
new file mode 100644
index 0000000..765abe1
--- /dev/null
+++ b/raylib/examples/models/models_geometric_shapes.png
Binary files differ
diff --git a/raylib/examples/models/models_heightmap.c b/raylib/examples/models/models_heightmap.c
new file mode 100644
index 0000000..e1c3e4f
--- /dev/null
+++ b/raylib/examples/models/models_heightmap.c
@@ -0,0 +1,90 @@
+/*******************************************************************************************
+*
+* raylib [models] example - Heightmap loading and drawing
+*
+* Example originally created with raylib 1.8, last time updated with raylib 3.5
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2015-2023 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - heightmap loading and drawing");
+
+ // Define our custom camera to look into our 3d world
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 18.0f, 21.0f, 18.0f }; // Camera position
+ camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
+ camera.fovy = 45.0f; // Camera field-of-view Y
+ camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
+
+ Image image = LoadImage("resources/heightmap.png"); // Load heightmap image (RAM)
+ Texture2D texture = LoadTextureFromImage(image); // Convert image to texture (VRAM)
+
+ Mesh mesh = GenMeshHeightmap(image, (Vector3){ 16, 8, 16 }); // Generate heightmap mesh (RAM and VRAM)
+ Model model = LoadModelFromMesh(mesh); // Load model from generated mesh
+
+ model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture
+ Vector3 mapPosition = { -8.0f, 0.0f, -8.0f }; // Define model position
+
+ UnloadImage(image); // Unload heightmap image from RAM, already uploaded to VRAM
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ UpdateCamera(&camera, CAMERA_ORBITAL);
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+
+ DrawModel(model, mapPosition, 1.0f, RED);
+
+ DrawGrid(20, 1.0f);
+
+ EndMode3D();
+
+ DrawTexture(texture, screenWidth - texture.width - 20, 20, WHITE);
+ DrawRectangleLines(screenWidth - texture.width - 20, 20, texture.width, texture.height, GREEN);
+
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadTexture(texture); // Unload texture
+ UnloadModel(model); // Unload model
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+} \ No newline at end of file
diff --git a/raylib/examples/models/models_heightmap.png b/raylib/examples/models/models_heightmap.png
new file mode 100644
index 0000000..6dcf01f
--- /dev/null
+++ b/raylib/examples/models/models_heightmap.png
Binary files differ
diff --git a/raylib/examples/models/models_loading.c b/raylib/examples/models/models_loading.c
new file mode 100644
index 0000000..4bce2a7
--- /dev/null
+++ b/raylib/examples/models/models_loading.c
@@ -0,0 +1,153 @@
+/*******************************************************************************************
+*
+* raylib [models] example - Models loading
+*
+* NOTE: raylib supports multiple models file formats:
+*
+* - OBJ > Text file format. Must include vertex position-texcoords-normals information,
+* if files references some .mtl materials file, it will be loaded (or try to).
+* - GLTF > Text/binary file format. Includes lot of information and it could
+* also reference external files, raylib will try loading mesh and materials data.
+* - IQM > Binary file format. Includes mesh vertex data but also animation data,
+* raylib can load .iqm animations.
+* - VOX > Binary file format. MagikaVoxel mesh format:
+* https://github.com/ephtracy/voxel-model/blob/master/MagicaVoxel-file-format-vox.txt
+* - M3D > Binary file format. Model 3D format:
+* https://bztsrc.gitlab.io/model3d
+*
+* Example originally created with raylib 2.0, last time updated with raylib 4.2
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2014-2023 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - models loading");
+
+ // Define the camera to look into our 3d world
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 50.0f, 50.0f, 50.0f }; // Camera position
+ camera.target = (Vector3){ 0.0f, 10.0f, 0.0f }; // Camera looking at point
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
+ camera.fovy = 45.0f; // Camera field-of-view Y
+ camera.projection = CAMERA_PERSPECTIVE; // Camera mode type
+
+ Model model = LoadModel("resources/models/obj/castle.obj"); // Load model
+ Texture2D texture = LoadTexture("resources/models/obj/castle_diffuse.png"); // Load model texture
+ model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture
+
+ Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
+
+ BoundingBox bounds = GetMeshBoundingBox(model.meshes[0]); // Set model bounds
+
+ // NOTE: bounds are calculated from the original size of the model,
+ // if model is scaled on drawing, bounds must be also scaled
+
+ bool selected = false; // Selected object flag
+
+ DisableCursor(); // Limit cursor to relative movement inside the window
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ UpdateCamera(&camera, CAMERA_FIRST_PERSON);
+
+ // Load new models/textures on drag&drop
+ if (IsFileDropped())
+ {
+ FilePathList droppedFiles = LoadDroppedFiles();
+
+ if (droppedFiles.count == 1) // Only support one file dropped
+ {
+ if (IsFileExtension(droppedFiles.paths[0], ".obj") ||
+ IsFileExtension(droppedFiles.paths[0], ".gltf") ||
+ IsFileExtension(droppedFiles.paths[0], ".glb") ||
+ IsFileExtension(droppedFiles.paths[0], ".vox") ||
+ IsFileExtension(droppedFiles.paths[0], ".iqm") ||
+ IsFileExtension(droppedFiles.paths[0], ".m3d")) // Model file formats supported
+ {
+ UnloadModel(model); // Unload previous model
+ model = LoadModel(droppedFiles.paths[0]); // Load new model
+ model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set current map diffuse texture
+
+ bounds = GetMeshBoundingBox(model.meshes[0]);
+
+ // TODO: Move camera position from target enough distance to visualize model properly
+ }
+ else if (IsFileExtension(droppedFiles.paths[0], ".png")) // Texture file formats supported
+ {
+ // Unload current model texture and load new one
+ UnloadTexture(texture);
+ texture = LoadTexture(droppedFiles.paths[0]);
+ model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture;
+ }
+ }
+
+ UnloadDroppedFiles(droppedFiles); // Unload filepaths from memory
+ }
+
+ // Select model on mouse click
+ if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
+ {
+ // Check collision between ray and box
+ if (GetRayCollisionBox(GetMouseRay(GetMousePosition(), camera), bounds).hit) selected = !selected;
+ else selected = false;
+ }
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+
+ DrawModel(model, position, 1.0f, WHITE); // Draw 3d model with texture
+
+ DrawGrid(20, 10.0f); // Draw a grid
+
+ if (selected) DrawBoundingBox(bounds, GREEN); // Draw selection box
+
+ EndMode3D();
+
+ DrawText("Drag & drop model to load mesh/texture.", 10, GetScreenHeight() - 20, 10, DARKGRAY);
+ if (selected) DrawText("MODEL SELECTED", GetScreenWidth() - 110, 10, 10, GREEN);
+
+ DrawText("(c) Castle 3D model by Alberto Cano", screenWidth - 200, screenHeight - 20, 10, GRAY);
+
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadTexture(texture); // Unload texture
+ UnloadModel(model); // Unload model
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+} \ No newline at end of file
diff --git a/raylib/examples/models/models_loading.png b/raylib/examples/models/models_loading.png
new file mode 100644
index 0000000..8ad8cb1
--- /dev/null
+++ b/raylib/examples/models/models_loading.png
Binary files differ
diff --git a/raylib/examples/models/models_loading_gltf.c b/raylib/examples/models/models_loading_gltf.c
new file mode 100644
index 0000000..2884731
--- /dev/null
+++ b/raylib/examples/models/models_loading_gltf.c
@@ -0,0 +1,103 @@
+/*******************************************************************************************
+*
+* raylib [models] example - loading gltf with animations
+*
+* LIMITATIONS:
+* - Only supports 1 armature per file, and skips loading it if there are multiple armatures
+* - Only supports linear interpolation (default method in Blender when checked
+* "Always Sample Animations" when exporting a GLTF file)
+* - Only supports translation/rotation/scale animation channel.path,
+* weights not considered (i.e. morph targets)
+*
+* Example originally created with raylib 3.7, last time updated with raylib 4.2
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2020-2023 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - loading gltf");
+
+ // Define the camera to look into our 3d world
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position
+ camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
+ camera.fovy = 45.0f; // Camera field-of-view Y
+ camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
+
+ // Load gltf model
+ Model model = LoadModel("resources/models/gltf/robot.glb");
+
+ // Load gltf model animations
+ unsigned int animsCount = 0;
+ unsigned int animIndex = 0;
+ unsigned int animCurrentFrame = 0;
+ ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/robot.glb", &animsCount);
+
+ Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
+
+ DisableCursor(); // Limit cursor to relative movement inside the window
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ UpdateCamera(&camera, CAMERA_THIRD_PERSON);
+ // Select current animation
+ if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) animIndex = (animIndex + 1)%animsCount;
+ else if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) animIndex = (animIndex + animsCount - 1)%animsCount;
+
+ // Update model animation
+ ModelAnimation anim = modelAnimations[animIndex];
+ animCurrentFrame = (animCurrentFrame + 1)%anim.frameCount;
+ UpdateModelAnimation(model, anim, animCurrentFrame);
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+
+ DrawModel(model, position, 1.0f, WHITE); // Draw animated model
+ DrawGrid(10, 1.0f);
+
+ EndMode3D();
+
+ DrawText("Use the LEFT/RIGHT mouse buttons to switch animation", 10, 10, 20, GRAY);
+ DrawText(TextFormat("Animation: %s", anim.name), 10, GetScreenHeight() - 20, 10, DARKGRAY);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadModel(model); // Unload model and meshes/material
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/raylib/examples/models/models_loading_gltf.png b/raylib/examples/models/models_loading_gltf.png
new file mode 100644
index 0000000..ce2a852
--- /dev/null
+++ b/raylib/examples/models/models_loading_gltf.png
Binary files differ
diff --git a/raylib/examples/models/models_loading_m3d.c b/raylib/examples/models/models_loading_m3d.c
new file mode 100644
index 0000000..1e56d51
--- /dev/null
+++ b/raylib/examples/models/models_loading_m3d.c
@@ -0,0 +1,174 @@
+/*******************************************************************************************
+*
+* raylib [models] example - Load models M3D
+*
+* Example originally created with raylib 4.5, last time updated with raylib 4.5
+*
+* Example contributed by bzt (@bztsrc) and reviewed by Ramon Santamaria (@raysan5)
+*
+* NOTES:
+* - Model3D (M3D) fileformat specs: https://gitlab.com/bztsrc/model3d
+* - Bender M3D exported: https://gitlab.com/bztsrc/model3d/-/tree/master/blender
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2022-2023 bzt (@bztsrc)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - M3D model loading");
+
+ // Define the camera to look into our 3d world
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 1.5f, 1.5f, 1.5f }; // Camera position
+ camera.target = (Vector3){ 0.0f, 0.4f, 0.0f }; // Camera looking at point
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
+ camera.fovy = 45.0f; // Camera field-of-view Y
+ camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
+
+ Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
+
+ char modelFileName[128] = "resources/models/m3d/cesium_man.m3d";
+ bool drawMesh = 1;
+ bool drawSkeleton = 1;
+ bool animPlaying = false; // Store anim state, what to draw
+
+ // Load model
+ Model model = LoadModel(modelFileName); // Load the bind-pose model mesh and basic data
+
+ // Load animations
+ unsigned int animsCount = 0;
+ int animFrameCounter = 0, animId = 0;
+ ModelAnimation *anims = LoadModelAnimations(modelFileName, &animsCount); // Load skeletal animation data
+
+ DisableCursor(); // Limit cursor to relative movement inside the window
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ UpdateCamera(&camera, CAMERA_FIRST_PERSON);
+
+ if (animsCount)
+ {
+ // Play animation when spacebar is held down (or step one frame with N)
+ if (IsKeyDown(KEY_SPACE) || IsKeyPressed(KEY_N))
+ {
+ animFrameCounter++;
+
+ if (animFrameCounter >= anims[animId].frameCount) animFrameCounter = 0;
+
+ UpdateModelAnimation(model, anims[animId], animFrameCounter);
+ animPlaying = true;
+ }
+
+ // Select animation by pressing C
+ if (IsKeyPressed(KEY_C))
+ {
+ animFrameCounter = 0;
+ animId++;
+
+ if (animId >= animsCount) animId = 0;
+ UpdateModelAnimation(model, anims[animId], 0);
+ animPlaying = true;
+ }
+ }
+
+ // Toggle skeleton drawing
+ if (IsKeyPressed(KEY_B)) drawSkeleton ^= 1;
+
+ // Toggle mesh drawing
+ if (IsKeyPressed(KEY_M)) drawMesh ^= 1;
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+
+ // Draw 3d model with texture
+ if (drawMesh) DrawModel(model, position, 1.0f, WHITE);
+
+ // Draw the animated skeleton
+ if (drawSkeleton)
+ {
+ // Loop to (boneCount - 1) because the last one is a special "no bone" bone,
+ // needed to workaround buggy models
+ // without a -1, we would always draw a cube at the origin
+ for (int i = 0; i < model.boneCount - 1; i++)
+ {
+ // By default the model is loaded in bind-pose by LoadModel().
+ // But if UpdateModelAnimation() has been called at least once
+ // then the model is already in animation pose, so we need the animated skeleton
+ if (!animPlaying || !animsCount)
+ {
+ // Display the bind-pose skeleton
+ DrawCube(model.bindPose[i].translation, 0.04f, 0.04f, 0.04f, RED);
+
+ if (model.bones[i].parent >= 0)
+ {
+ DrawLine3D(model.bindPose[i].translation,
+ model.bindPose[model.bones[i].parent].translation, RED);
+ }
+ }
+ else
+ {
+ // Display the frame-pose skeleton
+ DrawCube(anims[animId].framePoses[animFrameCounter][i].translation, 0.05f, 0.05f, 0.05f, RED);
+
+ if (anims[animId].bones[i].parent >= 0)
+ {
+ DrawLine3D(anims[animId].framePoses[animFrameCounter][i].translation,
+ anims[animId].framePoses[animFrameCounter][anims[animId].bones[i].parent].translation, RED);
+ }
+ }
+ }
+ }
+
+ DrawGrid(10, 1.0f); // Draw a grid
+
+ EndMode3D();
+
+ DrawText("PRESS SPACE to PLAY MODEL ANIMATION", 10, GetScreenHeight() - 80, 10, MAROON);
+ DrawText("PRESS N to STEP ONE ANIMATION FRAME", 10, GetScreenHeight() - 60, 10, DARKGRAY);
+ DrawText("PRESS C to CYCLE THROUGH ANIMATIONS", 10, GetScreenHeight() - 40, 10, DARKGRAY);
+ DrawText("PRESS M to toggle MESH, B to toggle SKELETON DRAWING", 10, GetScreenHeight() - 20, 10, DARKGRAY);
+ DrawText("(c) CesiumMan model by KhronosGroup", GetScreenWidth() - 210, GetScreenHeight() - 20, 10, GRAY);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+
+ // Unload model animations data
+ UnloadModelAnimations(anims, animsCount);
+
+ UnloadModel(model); // Unload model
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/raylib/examples/models/models_loading_m3d.png b/raylib/examples/models/models_loading_m3d.png
new file mode 100644
index 0000000..9220419
--- /dev/null
+++ b/raylib/examples/models/models_loading_m3d.png
Binary files differ
diff --git a/raylib/examples/models/models_loading_vox.c b/raylib/examples/models/models_loading_vox.c
new file mode 100644
index 0000000..e148fd9
--- /dev/null
+++ b/raylib/examples/models/models_loading_vox.c
@@ -0,0 +1,133 @@
+/*******************************************************************************************
+*
+* raylib [models] example - Load models vox (MagicaVoxel)
+*
+* Example originally created with raylib 4.0, last time updated with raylib 4.0
+*
+* Example contributed by Johann Nadalutti (@procfxgen) and reviewed by Ramon Santamaria (@raysan5)
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2021-2023 Johann Nadalutti (@procfxgen) and Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include "raymath.h" // Required for: MatrixTranslate()
+
+#define MAX_VOX_FILES 3
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ const char *voxFileNames[] = {
+ "resources/models/vox/chr_knight.vox",
+ "resources/models/vox/chr_sword.vox",
+ "resources/models/vox/monu9.vox"
+ };
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - magicavoxel loading");
+
+ // Define the camera to look into our 3d world
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position
+ camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
+ camera.fovy = 45.0f; // Camera field-of-view Y
+ camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
+
+ // Load MagicaVoxel files
+ Model models[MAX_VOX_FILES] = { 0 };
+
+ for (int i = 0; i < MAX_VOX_FILES; i++)
+ {
+ // Load VOX file and measure time
+ double t0 = GetTime()*1000.0;
+ models[i] = LoadModel(voxFileNames[i]);
+ double t1 = GetTime()*1000.0;
+
+ TraceLog(LOG_WARNING, TextFormat("[%s] File loaded in %.3f ms", voxFileNames[i], t1 - t0));
+
+ // Compute model translation matrix to center model on draw position (0, 0 , 0)
+ BoundingBox bb = GetModelBoundingBox(models[i]);
+ Vector3 center = { 0 };
+ center.x = bb.min.x + (((bb.max.x - bb.min.x)/2));
+ center.z = bb.min.z + (((bb.max.z - bb.min.z)/2));
+
+ Matrix matTranslate = MatrixTranslate(-center.x, 0, -center.z);
+ models[i].transform = matTranslate;
+ }
+
+ int currentModel = 0;
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ UpdateCamera(&camera, CAMERA_ORBITAL);
+
+ // Cycle between models on mouse click
+ if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1)%MAX_VOX_FILES;
+
+ // Cycle between models on key pressed
+ if (IsKeyPressed(KEY_RIGHT))
+ {
+ currentModel++;
+ if (currentModel >= MAX_VOX_FILES) currentModel = 0;
+ }
+ else if (IsKeyPressed(KEY_LEFT))
+ {
+ currentModel--;
+ if (currentModel < 0) currentModel = MAX_VOX_FILES - 1;
+ }
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ // Draw 3D model
+ BeginMode3D(camera);
+
+ DrawModel(models[currentModel], (Vector3){ 0, 0, 0 }, 1.0f, WHITE);
+ DrawGrid(10, 1.0);
+
+ EndMode3D();
+
+ // Display info
+ DrawRectangle(10, 400, 310, 30, Fade(SKYBLUE, 0.5f));
+ DrawRectangleLines(10, 400, 310, 30, Fade(DARKBLUE, 0.5f));
+ DrawText("MOUSE LEFT BUTTON to CYCLE VOX MODELS", 40, 410, 10, BLUE);
+ DrawText(TextFormat("File: %s", GetFileName(voxFileNames[currentModel])), 10, 10, 20, GRAY);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ // Unload models data (GPU VRAM)
+ for (int i = 0; i < MAX_VOX_FILES; i++) UnloadModel(models[i]);
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
+
+
diff --git a/raylib/examples/models/models_loading_vox.png b/raylib/examples/models/models_loading_vox.png
new file mode 100644
index 0000000..417d887
--- /dev/null
+++ b/raylib/examples/models/models_loading_vox.png
Binary files differ
diff --git a/raylib/examples/models/models_mesh_generation.c b/raylib/examples/models/models_mesh_generation.c
new file mode 100644
index 0000000..d17a20a
--- /dev/null
+++ b/raylib/examples/models/models_mesh_generation.c
@@ -0,0 +1,190 @@
+/*******************************************************************************************
+*
+* raylib example - procedural mesh generation
+*
+* Example originally created with raylib 1.8, last time updated with raylib 4.0
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2017-2023 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#define NUM_MODELS 9 // Parametric 3d shapes to generate
+
+static Mesh GenMeshCustom(void); // Generate a simple triangle mesh from code
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - mesh generation");
+
+ // We generate a checked image for texturing
+ Image checked = GenImageChecked(2, 2, 1, 1, RED, GREEN);
+ Texture2D texture = LoadTextureFromImage(checked);
+ UnloadImage(checked);
+
+ Model models[NUM_MODELS] = { 0 };
+
+ models[0] = LoadModelFromMesh(GenMeshPlane(2, 2, 5, 5));
+ models[1] = LoadModelFromMesh(GenMeshCube(2.0f, 1.0f, 2.0f));
+ models[2] = LoadModelFromMesh(GenMeshSphere(2, 32, 32));
+ models[3] = LoadModelFromMesh(GenMeshHemiSphere(2, 16, 16));
+ models[4] = LoadModelFromMesh(GenMeshCylinder(1, 2, 16));
+ models[5] = LoadModelFromMesh(GenMeshTorus(0.25f, 4.0f, 16, 32));
+ models[6] = LoadModelFromMesh(GenMeshKnot(1.0f, 2.0f, 16, 128));
+ models[7] = LoadModelFromMesh(GenMeshPoly(5, 2.0f));
+ models[8] = LoadModelFromMesh(GenMeshCustom());
+
+ // Generated meshes could be exported as .obj files
+ //ExportMesh(models[0].meshes[0], "plane.obj");
+ //ExportMesh(models[1].meshes[0], "cube.obj");
+ //ExportMesh(models[2].meshes[0], "sphere.obj");
+ //ExportMesh(models[3].meshes[0], "hemisphere.obj");
+ //ExportMesh(models[4].meshes[0], "cylinder.obj");
+ //ExportMesh(models[5].meshes[0], "torus.obj");
+ //ExportMesh(models[6].meshes[0], "knot.obj");
+ //ExportMesh(models[7].meshes[0], "poly.obj");
+ //ExportMesh(models[8].meshes[0], "custom.obj");
+
+ // Set checked texture as default diffuse component for all models material
+ for (int i = 0; i < NUM_MODELS; i++) models[i].materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture;
+
+ // Define the camera to look into our 3d world
+ Camera camera = { { 5.0f, 5.0f, 5.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
+
+ // Model drawing position
+ Vector3 position = { 0.0f, 0.0f, 0.0f };
+
+ int currentModel = 0;
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ UpdateCamera(&camera, CAMERA_ORBITAL);
+
+ if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
+ {
+ currentModel = (currentModel + 1)%NUM_MODELS; // Cycle between the textures
+ }
+
+ if (IsKeyPressed(KEY_RIGHT))
+ {
+ currentModel++;
+ if (currentModel >= NUM_MODELS) currentModel = 0;
+ }
+ else if (IsKeyPressed(KEY_LEFT))
+ {
+ currentModel--;
+ if (currentModel < 0) currentModel = NUM_MODELS - 1;
+ }
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+
+ DrawModel(models[currentModel], position, 1.0f, WHITE);
+ DrawGrid(10, 1.0);
+
+ EndMode3D();
+
+ DrawRectangle(30, 400, 310, 30, Fade(SKYBLUE, 0.5f));
+ DrawRectangleLines(30, 400, 310, 30, Fade(DARKBLUE, 0.5f));
+ DrawText("MOUSE LEFT BUTTON to CYCLE PROCEDURAL MODELS", 40, 410, 10, BLUE);
+
+ switch(currentModel)
+ {
+ case 0: DrawText("PLANE", 680, 10, 20, DARKBLUE); break;
+ case 1: DrawText("CUBE", 680, 10, 20, DARKBLUE); break;
+ case 2: DrawText("SPHERE", 680, 10, 20, DARKBLUE); break;
+ case 3: DrawText("HEMISPHERE", 640, 10, 20, DARKBLUE); break;
+ case 4: DrawText("CYLINDER", 680, 10, 20, DARKBLUE); break;
+ case 5: DrawText("TORUS", 680, 10, 20, DARKBLUE); break;
+ case 6: DrawText("KNOT", 680, 10, 20, DARKBLUE); break;
+ case 7: DrawText("POLY", 680, 10, 20, DARKBLUE); break;
+ case 8: DrawText("Custom (triangle)", 580, 10, 20, DARKBLUE); break;
+ default: break;
+ }
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadTexture(texture); // Unload texture
+
+ // Unload models data (GPU VRAM)
+ for (int i = 0; i < NUM_MODELS; i++) UnloadModel(models[i]);
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
+
+// Generate a simple triangle mesh from code
+static Mesh GenMeshCustom(void)
+{
+ Mesh mesh = { 0 };
+ mesh.triangleCount = 1;
+ mesh.vertexCount = mesh.triangleCount*3;
+ mesh.vertices = (float *)MemAlloc(mesh.vertexCount*3*sizeof(float)); // 3 vertices, 3 coordinates each (x, y, z)
+ mesh.texcoords = (float *)MemAlloc(mesh.vertexCount*2*sizeof(float)); // 3 vertices, 2 coordinates each (x, y)
+ mesh.normals = (float *)MemAlloc(mesh.vertexCount*3*sizeof(float)); // 3 vertices, 3 coordinates each (x, y, z)
+
+ // Vertex at (0, 0, 0)
+ mesh.vertices[0] = 0;
+ mesh.vertices[1] = 0;
+ mesh.vertices[2] = 0;
+ mesh.normals[0] = 0;
+ mesh.normals[1] = 1;
+ mesh.normals[2] = 0;
+ mesh.texcoords[0] = 0;
+ mesh.texcoords[1] = 0;
+
+ // Vertex at (1, 0, 2)
+ mesh.vertices[3] = 1;
+ mesh.vertices[4] = 0;
+ mesh.vertices[5] = 2;
+ mesh.normals[3] = 0;
+ mesh.normals[4] = 1;
+ mesh.normals[5] = 0;
+ mesh.texcoords[2] = 0.5f;
+ mesh.texcoords[3] = 1.0f;
+
+ // Vertex at (2, 0, 0)
+ mesh.vertices[6] = 2;
+ mesh.vertices[7] = 0;
+ mesh.vertices[8] = 0;
+ mesh.normals[6] = 0;
+ mesh.normals[7] = 1;
+ mesh.normals[8] = 0;
+ mesh.texcoords[4] = 1;
+ mesh.texcoords[5] =0;
+
+ // Upload mesh data from CPU (RAM) to GPU (VRAM) memory
+ UploadMesh(&mesh, false);
+
+ return mesh;
+}
diff --git a/raylib/examples/models/models_mesh_generation.png b/raylib/examples/models/models_mesh_generation.png
new file mode 100644
index 0000000..d8eb364
--- /dev/null
+++ b/raylib/examples/models/models_mesh_generation.png
Binary files differ
diff --git a/raylib/examples/models/models_mesh_picking.c b/raylib/examples/models/models_mesh_picking.c
new file mode 100644
index 0000000..69d98aa
--- /dev/null
+++ b/raylib/examples/models/models_mesh_picking.c
@@ -0,0 +1,246 @@
+/*******************************************************************************************
+*
+* raylib [models] example - Mesh picking in 3d mode, ground plane, triangle, mesh
+*
+* Example originally created with raylib 1.7, last time updated with raylib 4.0
+*
+* Example contributed by Joel Davis (@joeld42) and reviewed by Ramon Santamaria (@raysan5)
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2017-2023 Joel Davis (@joeld42) and Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+#include "raymath.h"
+
+#define FLT_MAX 340282346638528859811704183484516925440.0f // Maximum value of a float, from bit pattern 01111111011111111111111111111111
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - mesh picking");
+
+ // Define the camera to look into our 3d world
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 20.0f, 20.0f, 20.0f }; // Camera position
+ camera.target = (Vector3){ 0.0f, 8.0f, 0.0f }; // Camera looking at point
+ camera.up = (Vector3){ 0.0f, 1.6f, 0.0f }; // Camera up vector (rotation towards target)
+ camera.fovy = 45.0f; // Camera field-of-view Y
+ camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
+
+ Ray ray = { 0 }; // Picking ray
+
+ Model tower = LoadModel("resources/models/obj/turret.obj"); // Load OBJ model
+ Texture2D texture = LoadTexture("resources/models/obj/turret_diffuse.png"); // Load model texture
+ tower.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set model diffuse texture
+
+ Vector3 towerPos = { 0.0f, 0.0f, 0.0f }; // Set model position
+ BoundingBox towerBBox = GetMeshBoundingBox(tower.meshes[0]); // Get mesh bounding box
+
+ // Ground quad
+ Vector3 g0 = (Vector3){ -50.0f, 0.0f, -50.0f };
+ Vector3 g1 = (Vector3){ -50.0f, 0.0f, 50.0f };
+ Vector3 g2 = (Vector3){ 50.0f, 0.0f, 50.0f };
+ Vector3 g3 = (Vector3){ 50.0f, 0.0f, -50.0f };
+
+ // Test triangle
+ Vector3 ta = (Vector3){ -25.0f, 0.5f, 0.0f };
+ Vector3 tb = (Vector3){ -4.0f, 2.5f, 1.0f };
+ Vector3 tc = (Vector3){ -8.0f, 6.5f, 0.0f };
+
+ Vector3 bary = { 0.0f, 0.0f, 0.0f };
+
+ // Test sphere
+ Vector3 sp = (Vector3){ -30.0f, 5.0f, 5.0f };
+ float sr = 4.0f;
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ if (IsCursorHidden()) UpdateCamera(&camera, CAMERA_FIRST_PERSON); // Update camera
+
+ // Toggle camera controls
+ if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT))
+ {
+ if (IsCursorHidden()) EnableCursor();
+ else DisableCursor();
+ }
+
+ // Display information about closest hit
+ RayCollision collision = { 0 };
+ char *hitObjectName = "None";
+ collision.distance = FLT_MAX;
+ collision.hit = false;
+ Color cursorColor = WHITE;
+
+ // Get ray and test against objects
+ ray = GetMouseRay(GetMousePosition(), camera);
+
+ // Check ray collision against ground quad
+ RayCollision groundHitInfo = GetRayCollisionQuad(ray, g0, g1, g2, g3);
+
+ if ((groundHitInfo.hit) && (groundHitInfo.distance < collision.distance))
+ {
+ collision = groundHitInfo;
+ cursorColor = GREEN;
+ hitObjectName = "Ground";
+ }
+
+ // Check ray collision against test triangle
+ RayCollision triHitInfo = GetRayCollisionTriangle(ray, ta, tb, tc);
+
+ if ((triHitInfo.hit) && (triHitInfo.distance < collision.distance))
+ {
+ collision = triHitInfo;
+ cursorColor = PURPLE;
+ hitObjectName = "Triangle";
+
+ bary = Vector3Barycenter(collision.point, ta, tb, tc);
+ }
+
+ // Check ray collision against test sphere
+ RayCollision sphereHitInfo = GetRayCollisionSphere(ray, sp, sr);
+
+ if ((sphereHitInfo.hit) && (sphereHitInfo.distance < collision.distance))
+ {
+ collision = sphereHitInfo;
+ cursorColor = ORANGE;
+ hitObjectName = "Sphere";
+ }
+
+ // Check ray collision against bounding box first, before trying the full ray-mesh test
+ RayCollision boxHitInfo = GetRayCollisionBox(ray, towerBBox);
+
+ if ((boxHitInfo.hit) && (boxHitInfo.distance < collision.distance))
+ {
+ collision = boxHitInfo;
+ cursorColor = ORANGE;
+ hitObjectName = "Box";
+
+ // Check ray collision against model meshes
+ RayCollision meshHitInfo = { 0 };
+ for (int m = 0; m < tower.meshCount; m++)
+ {
+ // NOTE: We consider the model.transform for the collision check but
+ // it can be checked against any transform Matrix, used when checking against same
+ // model drawn multiple times with multiple transforms
+ meshHitInfo = GetRayCollisionMesh(ray, tower.meshes[m], tower.transform);
+ if (meshHitInfo.hit)
+ {
+ // Save the closest hit mesh
+ if ((!collision.hit) || (collision.distance > meshHitInfo.distance)) collision = meshHitInfo;
+
+ break; // Stop once one mesh collision is detected, the colliding mesh is m
+ }
+ }
+
+ if (meshHitInfo.hit)
+ {
+ collision = meshHitInfo;
+ cursorColor = ORANGE;
+ hitObjectName = "Mesh";
+ }
+ }
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+
+ // Draw the tower
+ // WARNING: If scale is different than 1.0f,
+ // not considered by GetRayCollisionModel()
+ DrawModel(tower, towerPos, 1.0f, WHITE);
+
+ // Draw the test triangle
+ DrawLine3D(ta, tb, PURPLE);
+ DrawLine3D(tb, tc, PURPLE);
+ DrawLine3D(tc, ta, PURPLE);
+
+ // Draw the test sphere
+ DrawSphereWires(sp, sr, 8, 8, PURPLE);
+
+ // Draw the mesh bbox if we hit it
+ if (boxHitInfo.hit) DrawBoundingBox(towerBBox, LIME);
+
+ // If we hit something, draw the cursor at the hit point
+ if (collision.hit)
+ {
+ DrawCube(collision.point, 0.3f, 0.3f, 0.3f, cursorColor);
+ DrawCubeWires(collision.point, 0.3f, 0.3f, 0.3f, RED);
+
+ Vector3 normalEnd;
+ normalEnd.x = collision.point.x + collision.normal.x;
+ normalEnd.y = collision.point.y + collision.normal.y;
+ normalEnd.z = collision.point.z + collision.normal.z;
+
+ DrawLine3D(collision.point, normalEnd, RED);
+ }
+
+ DrawRay(ray, MAROON);
+
+ DrawGrid(10, 10.0f);
+
+ EndMode3D();
+
+ // Draw some debug GUI text
+ DrawText(TextFormat("Hit Object: %s", hitObjectName), 10, 50, 10, BLACK);
+
+ if (collision.hit)
+ {
+ int ypos = 70;
+
+ DrawText(TextFormat("Distance: %3.2f", collision.distance), 10, ypos, 10, BLACK);
+
+ DrawText(TextFormat("Hit Pos: %3.2f %3.2f %3.2f",
+ collision.point.x,
+ collision.point.y,
+ collision.point.z), 10, ypos + 15, 10, BLACK);
+
+ DrawText(TextFormat("Hit Norm: %3.2f %3.2f %3.2f",
+ collision.normal.x,
+ collision.normal.y,
+ collision.normal.z), 10, ypos + 30, 10, BLACK);
+
+ if (triHitInfo.hit && TextIsEqual(hitObjectName, "Triangle"))
+ DrawText(TextFormat("Barycenter: %3.2f %3.2f %3.2f", bary.x, bary.y, bary.z), 10, ypos + 45, 10, BLACK);
+ }
+
+ DrawText("Right click mouse to toggle camera controls", 10, 430, 10, GRAY);
+
+ DrawText("(c) Turret 3D model by Alberto Cano", screenWidth - 200, screenHeight - 20, 10, GRAY);
+
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadModel(tower); // Unload model
+ UnloadTexture(texture); // Unload texture
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+} \ No newline at end of file
diff --git a/raylib/examples/models/models_mesh_picking.png b/raylib/examples/models/models_mesh_picking.png
new file mode 100644
index 0000000..0972f94
--- /dev/null
+++ b/raylib/examples/models/models_mesh_picking.png
Binary files differ
diff --git a/raylib/examples/models/models_orthographic_projection.c b/raylib/examples/models/models_orthographic_projection.c
new file mode 100644
index 0000000..098e4b2
--- /dev/null
+++ b/raylib/examples/models/models_orthographic_projection.c
@@ -0,0 +1,102 @@
+/*******************************************************************************************
+*
+* raylib [models] example - Show the difference between perspective and orthographic projection
+*
+* Example originally created with raylib 2.0, last time updated with raylib 3.7
+*
+* Example contributed by Max Danielsson (@autious) and reviewed by Ramon Santamaria (@raysan5)
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2018-2023 Max Danielsson (@autious) and Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#define FOVY_PERSPECTIVE 45.0f
+#define WIDTH_ORTHOGRAPHIC 10.0f
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - geometric shapes");
+
+ // Define the camera to look into our 3d world
+ Camera camera = { { 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, FOVY_PERSPECTIVE, CAMERA_PERSPECTIVE };
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ if (IsKeyPressed(KEY_SPACE))
+ {
+ if (camera.projection == CAMERA_PERSPECTIVE)
+ {
+ camera.fovy = WIDTH_ORTHOGRAPHIC;
+ camera.projection = CAMERA_ORTHOGRAPHIC;
+ }
+ else
+ {
+ camera.fovy = FOVY_PERSPECTIVE;
+ camera.projection = CAMERA_PERSPECTIVE;
+ }
+ }
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+
+ DrawCube((Vector3){-4.0f, 0.0f, 2.0f}, 2.0f, 5.0f, 2.0f, RED);
+ DrawCubeWires((Vector3){-4.0f, 0.0f, 2.0f}, 2.0f, 5.0f, 2.0f, GOLD);
+ DrawCubeWires((Vector3){-4.0f, 0.0f, -2.0f}, 3.0f, 6.0f, 2.0f, MAROON);
+
+ DrawSphere((Vector3){-1.0f, 0.0f, -2.0f}, 1.0f, GREEN);
+ DrawSphereWires((Vector3){1.0f, 0.0f, 2.0f}, 2.0f, 16, 16, LIME);
+
+ DrawCylinder((Vector3){4.0f, 0.0f, -2.0f}, 1.0f, 2.0f, 3.0f, 4, SKYBLUE);
+ DrawCylinderWires((Vector3){4.0f, 0.0f, -2.0f}, 1.0f, 2.0f, 3.0f, 4, DARKBLUE);
+ DrawCylinderWires((Vector3){4.5f, -1.0f, 2.0f}, 1.0f, 1.0f, 2.0f, 6, BROWN);
+
+ DrawCylinder((Vector3){1.0f, 0.0f, -4.0f}, 0.0f, 1.5f, 3.0f, 8, GOLD);
+ DrawCylinderWires((Vector3){1.0f, 0.0f, -4.0f}, 0.0f, 1.5f, 3.0f, 8, PINK);
+
+ DrawGrid(10, 1.0f); // Draw a grid
+
+ EndMode3D();
+
+ DrawText("Press Spacebar to switch camera type", 10, GetScreenHeight() - 30, 20, DARKGRAY);
+
+ if (camera.projection == CAMERA_ORTHOGRAPHIC) DrawText("ORTHOGRAPHIC", 10, 40, 20, BLACK);
+ else if (camera.projection == CAMERA_PERSPECTIVE) DrawText("PERSPECTIVE", 10, 40, 20, BLACK);
+
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/raylib/examples/models/models_orthographic_projection.png b/raylib/examples/models/models_orthographic_projection.png
new file mode 100644
index 0000000..2942eee
--- /dev/null
+++ b/raylib/examples/models/models_orthographic_projection.png
Binary files differ
diff --git a/raylib/examples/models/models_rlgl_solar_system.c b/raylib/examples/models/models_rlgl_solar_system.c
new file mode 100644
index 0000000..e458036
--- /dev/null
+++ b/raylib/examples/models/models_rlgl_solar_system.c
@@ -0,0 +1,172 @@
+/*******************************************************************************************
+*
+* raylib [models] example - rlgl module usage with push/pop matrix transformations
+*
+* NOTE: This example uses [rlgl] module functionality (pseudo-OpenGL 1.1 style coding)
+*
+* Example originally created with raylib 2.5, last time updated with raylib 4.0
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2018-2023 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+#include "rlgl.h"
+
+#include <math.h> // Required for: cosf(), sinf()
+
+//------------------------------------------------------------------------------------
+// Module Functions Declaration
+//------------------------------------------------------------------------------------
+void DrawSphereBasic(Color color); // Draw sphere without any matrix transformation
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ const float sunRadius = 4.0f;
+ const float earthRadius = 0.6f;
+ const float earthOrbitRadius = 8.0f;
+ const float moonRadius = 0.16f;
+ const float moonOrbitRadius = 1.5f;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - rlgl module usage with push/pop matrix transformations");
+
+ // Define the camera to look into our 3d world
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 16.0f, 16.0f, 16.0f }; // Camera position
+ camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
+ camera.fovy = 45.0f; // Camera field-of-view Y
+ camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
+
+ float rotationSpeed = 0.2f; // General system rotation speed
+
+ float earthRotation = 0.0f; // Rotation of earth around itself (days) in degrees
+ float earthOrbitRotation = 0.0f; // Rotation of earth around the Sun (years) in degrees
+ float moonRotation = 0.0f; // Rotation of moon around itself
+ float moonOrbitRotation = 0.0f; // Rotation of moon around earth in degrees
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ UpdateCamera(&camera, CAMERA_ORBITAL);
+
+ earthRotation += (5.0f*rotationSpeed);
+ earthOrbitRotation += (365/360.0f*(5.0f*rotationSpeed)*rotationSpeed);
+ moonRotation += (2.0f*rotationSpeed);
+ moonOrbitRotation += (8.0f*rotationSpeed);
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+
+ rlPushMatrix();
+ rlScalef(sunRadius, sunRadius, sunRadius); // Scale Sun
+ DrawSphereBasic(GOLD); // Draw the Sun
+ rlPopMatrix();
+
+ rlPushMatrix();
+ rlRotatef(earthOrbitRotation, 0.0f, 1.0f, 0.0f); // Rotation for Earth orbit around Sun
+ rlTranslatef(earthOrbitRadius, 0.0f, 0.0f); // Translation for Earth orbit
+
+ rlPushMatrix();
+ rlRotatef(earthRotation, 0.25, 1.0, 0.0); // Rotation for Earth itself
+ rlScalef(earthRadius, earthRadius, earthRadius);// Scale Earth
+
+ DrawSphereBasic(BLUE); // Draw the Earth
+ rlPopMatrix();
+
+ rlRotatef(moonOrbitRotation, 0.0f, 1.0f, 0.0f); // Rotation for Moon orbit around Earth
+ rlTranslatef(moonOrbitRadius, 0.0f, 0.0f); // Translation for Moon orbit
+ rlRotatef(moonRotation, 0.0f, 1.0f, 0.0f); // Rotation for Moon itself
+ rlScalef(moonRadius, moonRadius, moonRadius); // Scale Moon
+
+ DrawSphereBasic(LIGHTGRAY); // Draw the Moon
+ rlPopMatrix();
+
+ // Some reference elements (not affected by previous matrix transformations)
+ DrawCircle3D((Vector3){ 0.0f, 0.0f, 0.0f }, earthOrbitRadius, (Vector3){ 1, 0, 0 }, 90.0f, Fade(RED, 0.5f));
+ DrawGrid(20, 1.0f);
+
+ EndMode3D();
+
+ DrawText("EARTH ORBITING AROUND THE SUN!", 400, 10, 20, MAROON);
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
+
+//--------------------------------------------------------------------------------------------
+// Module Functions Definitions (local)
+//--------------------------------------------------------------------------------------------
+
+// Draw sphere without any matrix transformation
+// NOTE: Sphere is drawn in world position ( 0, 0, 0 ) with radius 1.0f
+void DrawSphereBasic(Color color)
+{
+ int rings = 16;
+ int slices = 16;
+
+ // Make sure there is enough space in the internal render batch
+ // buffer to store all required vertex, batch is reseted if required
+ rlCheckRenderBatchLimit((rings + 2)*slices*6);
+
+ rlBegin(RL_TRIANGLES);
+ rlColor4ub(color.r, color.g, color.b, color.a);
+
+ for (int i = 0; i < (rings + 2); i++)
+ {
+ for (int j = 0; j < slices; j++)
+ {
+ rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)),
+ sinf(DEG2RAD*(270+(180/(rings + 1))*i)),
+ cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices)));
+ rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)),
+ sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
+ cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices)));
+ rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360/slices)),
+ sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
+ cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360/slices)));
+
+ rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)),
+ sinf(DEG2RAD*(270+(180/(rings + 1))*i)),
+ cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices)));
+ rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*sinf(DEG2RAD*((j+1)*360/slices)),
+ sinf(DEG2RAD*(270+(180/(rings + 1))*(i))),
+ cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*cosf(DEG2RAD*((j+1)*360/slices)));
+ rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)),
+ sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
+ cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices)));
+ }
+ }
+ rlEnd();
+}
diff --git a/raylib/examples/models/models_rlgl_solar_system.png b/raylib/examples/models/models_rlgl_solar_system.png
new file mode 100644
index 0000000..576510c
--- /dev/null
+++ b/raylib/examples/models/models_rlgl_solar_system.png
Binary files differ
diff --git a/raylib/examples/models/models_skybox.c b/raylib/examples/models/models_skybox.c
new file mode 100644
index 0000000..7a500e0
--- /dev/null
+++ b/raylib/examples/models/models_skybox.c
@@ -0,0 +1,271 @@
+/*******************************************************************************************
+*
+* raylib [models] example - Skybox loading and drawing
+*
+* Example originally created with raylib 1.8, last time updated with raylib 4.0
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2017-2023 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include "rlgl.h"
+#include "raymath.h" // Required for: MatrixPerspective(), MatrixLookAt()
+
+#if defined(PLATFORM_DESKTOP)
+ #define GLSL_VERSION 330
+#else // PLATFORM_ANDROID, PLATFORM_WEB
+ #define GLSL_VERSION 100
+#endif
+
+// Generate cubemap (6 faces) from equirectangular (panorama) texture
+static TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, int format);
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - skybox loading and drawing");
+
+ // Define the camera to look into our 3d world
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 1.0f, 1.0f, 1.0f }; // Camera position
+ camera.target = (Vector3){ 4.0f, 1.0f, 4.0f }; // Camera looking at point
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
+ camera.fovy = 45.0f; // Camera field-of-view Y
+ camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
+
+ // Load skybox model
+ Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f);
+ Model skybox = LoadModelFromMesh(cube);
+
+ bool useHDR = true;
+
+ // Load skybox shader and set required locations
+ // NOTE: Some locations are automatically set at shader loading
+ skybox.materials[0].shader = LoadShader(TextFormat("resources/shaders/glsl%i/skybox.vs", GLSL_VERSION),
+ TextFormat("resources/shaders/glsl%i/skybox.fs", GLSL_VERSION));
+
+ SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "environmentMap"), (int[1]){ MATERIAL_MAP_CUBEMAP }, SHADER_UNIFORM_INT);
+ SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "doGamma"), (int[1]) { useHDR ? 1 : 0 }, SHADER_UNIFORM_INT);
+ SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "vflipped"), (int[1]){ useHDR ? 1 : 0 }, SHADER_UNIFORM_INT);
+
+ // Load cubemap shader and setup required shader locations
+ Shader shdrCubemap = LoadShader(TextFormat("resources/shaders/glsl%i/cubemap.vs", GLSL_VERSION),
+ TextFormat("resources/shaders/glsl%i/cubemap.fs", GLSL_VERSION));
+
+ SetShaderValue(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, SHADER_UNIFORM_INT);
+
+ char skyboxFileName[256] = { 0 };
+
+ Texture2D panorama;
+
+ if (useHDR)
+ {
+ TextCopy(skyboxFileName, "resources/dresden_square_2k.hdr");
+
+ // Load HDR panorama (sphere) texture
+ panorama = LoadTexture(skyboxFileName);
+
+ // Generate cubemap (texture with 6 quads-cube-mapping) from panorama HDR texture
+ // NOTE 1: New texture is generated rendering to texture, shader calculates the sphere->cube coordinates mapping
+ // NOTE 2: It seems on some Android devices WebGL, fbo does not properly support a FLOAT-based attachment,
+ // despite texture can be successfully created.. so using PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 instead of PIXELFORMAT_UNCOMPRESSED_R32G32B32A32
+ skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = GenTextureCubemap(shdrCubemap, panorama, 1024, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8);
+
+ //UnloadTexture(panorama); // Texture not required anymore, cubemap already generated
+ }
+ else
+ {
+ Image img = LoadImage("resources/skybox.png");
+ skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(img, CUBEMAP_LAYOUT_AUTO_DETECT); // CUBEMAP_LAYOUT_PANORAMA
+ UnloadImage(img);
+ }
+
+ DisableCursor(); // Limit cursor to relative movement inside the window
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ UpdateCamera(&camera, CAMERA_FIRST_PERSON);
+
+ // Load new cubemap texture on drag&drop
+ if (IsFileDropped())
+ {
+ FilePathList droppedFiles = LoadDroppedFiles();
+
+ if (droppedFiles.count == 1) // Only support one file dropped
+ {
+ if (IsFileExtension(droppedFiles.paths[0], ".png;.jpg;.hdr;.bmp;.tga"))
+ {
+ // Unload current cubemap texture and load new one
+ UnloadTexture(skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture);
+ if (useHDR)
+ {
+ Texture2D panorama = LoadTexture(droppedFiles.paths[0]);
+
+ // Generate cubemap from panorama texture
+ skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = GenTextureCubemap(shdrCubemap, panorama, 1024, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8);
+ UnloadTexture(panorama);
+ }
+ else
+ {
+ Image img = LoadImage(droppedFiles.paths[0]);
+ skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(img, CUBEMAP_LAYOUT_AUTO_DETECT);
+ UnloadImage(img);
+ }
+
+ TextCopy(skyboxFileName, droppedFiles.paths[0]);
+ }
+ }
+
+ UnloadDroppedFiles(droppedFiles); // Unload filepaths from memory
+ }
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+
+ // We are inside the cube, we need to disable backface culling!
+ rlDisableBackfaceCulling();
+ rlDisableDepthMask();
+ DrawModel(skybox, (Vector3){0, 0, 0}, 1.0f, WHITE);
+ rlEnableBackfaceCulling();
+ rlEnableDepthMask();
+
+ DrawGrid(10, 1.0f);
+
+ EndMode3D();
+
+ //DrawTextureEx(panorama, (Vector2){ 0, 0 }, 0.0f, 0.5f, WHITE);
+
+ if (useHDR) DrawText(TextFormat("Panorama image from hdrihaven.com: %s", GetFileName(skyboxFileName)), 10, GetScreenHeight() - 20, 10, BLACK);
+ else DrawText(TextFormat(": %s", GetFileName(skyboxFileName)), 10, GetScreenHeight() - 20, 10, BLACK);
+
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadShader(skybox.materials[0].shader);
+ UnloadTexture(skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture);
+
+ UnloadModel(skybox); // Unload skybox model
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
+
+// Generate cubemap texture from HDR texture
+static TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, int format)
+{
+ TextureCubemap cubemap = { 0 };
+
+ rlDisableBackfaceCulling(); // Disable backface culling to render inside the cube
+
+ // STEP 1: Setup framebuffer
+ //------------------------------------------------------------------------------------------
+ unsigned int rbo = rlLoadTextureDepth(size, size, true);
+ cubemap.id = rlLoadTextureCubemap(0, size, format);
+
+ unsigned int fbo = rlLoadFramebuffer(size, size);
+ rlFramebufferAttach(fbo, rbo, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER, 0);
+ rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X, 0);
+
+ // Check if framebuffer is complete with attachments (valid)
+ if (rlFramebufferComplete(fbo)) TraceLog(LOG_INFO, "FBO: [ID %i] Framebuffer object created successfully", fbo);
+ //------------------------------------------------------------------------------------------
+
+ // STEP 2: Draw to framebuffer
+ //------------------------------------------------------------------------------------------
+ // NOTE: Shader is used to convert HDR equirectangular environment map to cubemap equivalent (6 faces)
+ rlEnableShader(shader.id);
+
+ // Define projection matrix and send it to shader
+ Matrix matFboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR);
+ rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_PROJECTION], matFboProjection);
+
+ // Define view matrix for every side of the cubemap
+ Matrix fboViews[6] = {
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ -1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f })
+ };
+
+ rlViewport(0, 0, size, size); // Set viewport to current fbo dimensions
+
+ // Activate and enable texture for drawing to cubemap faces
+ rlActiveTextureSlot(0);
+ rlEnableTexture(panorama.id);
+
+ for (int i = 0; i < 6; i++)
+ {
+ // Set the view matrix for the current cube face
+ rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_VIEW], fboViews[i]);
+
+ // Select the current cubemap face attachment for the fbo
+ // WARNING: This function by default enables->attach->disables fbo!!!
+ rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X + i, 0);
+ rlEnableFramebuffer(fbo);
+
+ // Load and draw a cube, it uses the current enabled texture
+ rlClearScreenBuffers();
+ rlLoadDrawCube();
+
+ // ALTERNATIVE: Try to use internal batch system to draw the cube instead of rlLoadDrawCube
+ // for some reason this method does not work, maybe due to cube triangles definition? normals pointing out?
+ // TODO: Investigate this issue...
+ //rlSetTexture(panorama.id); // WARNING: It must be called after enabling current framebuffer if using internal batch system!
+ //rlClearScreenBuffers();
+ //DrawCubeV(Vector3Zero(), Vector3One(), WHITE);
+ //rlDrawRenderBatchActive();
+ }
+ //------------------------------------------------------------------------------------------
+
+ // STEP 3: Unload framebuffer and reset state
+ //------------------------------------------------------------------------------------------
+ rlDisableShader(); // Unbind shader
+ rlDisableTexture(); // Unbind texture
+ rlDisableFramebuffer(); // Unbind framebuffer
+ rlUnloadFramebuffer(fbo); // Unload framebuffer (and automatically attached depth texture/renderbuffer)
+
+ // Reset viewport dimensions to default
+ rlViewport(0, 0, rlGetFramebufferWidth(), rlGetFramebufferHeight());
+ rlEnableBackfaceCulling();
+ //------------------------------------------------------------------------------------------
+
+ cubemap.width = size;
+ cubemap.height = size;
+ cubemap.mipmaps = 1;
+ cubemap.format = format;
+
+ return cubemap;
+}
diff --git a/raylib/examples/models/models_skybox.png b/raylib/examples/models/models_skybox.png
new file mode 100644
index 0000000..feb0f73
--- /dev/null
+++ b/raylib/examples/models/models_skybox.png
Binary files differ
diff --git a/raylib/examples/models/models_waving_cubes.c b/raylib/examples/models/models_waving_cubes.c
new file mode 100644
index 0000000..d382c99
--- /dev/null
+++ b/raylib/examples/models/models_waving_cubes.c
@@ -0,0 +1,117 @@
+/*******************************************************************************************
+*
+* raylib [models] example - Waving cubes
+*
+* Example originally created with raylib 2.5, last time updated with raylib 3.7
+*
+* Example contributed by Codecat (@codecat) and reviewed by Ramon Santamaria (@raysan5)
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2019-2023 Codecat (@codecat) and Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include <math.h> // Required for: sinf()
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main()
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - waving cubes");
+
+ // Initialize the camera
+ Camera3D camera = { 0 };
+ camera.position = (Vector3){ 30.0f, 20.0f, 30.0f }; // Camera position
+ camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
+ camera.fovy = 70.0f; // Camera field-of-view Y
+ camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
+
+ // Specify the amount of blocks in each direction
+ const int numBlocks = 15;
+
+ SetTargetFPS(60);
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ double time = GetTime();
+
+ // Calculate time scale for cube position and size
+ float scale = (2.0f + (float)sin(time))*0.7f;
+
+ // Move camera around the scene
+ double cameraTime = time*0.3;
+ camera.position.x = (float)cos(cameraTime)*40.0f;
+ camera.position.z = (float)sin(cameraTime)*40.0f;
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+
+ DrawGrid(10, 5.0f);
+
+ for (int x = 0; x < numBlocks; x++)
+ {
+ for (int y = 0; y < numBlocks; y++)
+ {
+ for (int z = 0; z < numBlocks; z++)
+ {
+ // Scale of the blocks depends on x/y/z positions
+ float blockScale = (x + y + z)/30.0f;
+
+ // Scatter makes the waving effect by adding blockScale over time
+ float scatter = sinf(blockScale*20.0f + (float)(time*4.0f));
+
+ // Calculate the cube position
+ Vector3 cubePos = {
+ (float)(x - numBlocks/2)*(scale*3.0f) + scatter,
+ (float)(y - numBlocks/2)*(scale*2.0f) + scatter,
+ (float)(z - numBlocks/2)*(scale*3.0f) + scatter
+ };
+
+ // Pick a color with a hue depending on cube position for the rainbow color effect
+ Color cubeColor = ColorFromHSV((float)(((x + y + z)*18)%360), 0.75f, 0.9f);
+
+ // Calculate cube size
+ float cubeSize = (2.4f - scale)*blockScale;
+
+ // And finally, draw the cube!
+ DrawCube(cubePos, cubeSize, cubeSize, cubeSize, cubeColor);
+ }
+ }
+ }
+
+ EndMode3D();
+
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/raylib/examples/models/models_waving_cubes.png b/raylib/examples/models/models_waving_cubes.png
new file mode 100644
index 0000000..37a1761
--- /dev/null
+++ b/raylib/examples/models/models_waving_cubes.png
Binary files differ
diff --git a/raylib/examples/models/models_yaw_pitch_roll.c b/raylib/examples/models/models_yaw_pitch_roll.c
new file mode 100644
index 0000000..611ee31
--- /dev/null
+++ b/raylib/examples/models/models_yaw_pitch_roll.c
@@ -0,0 +1,122 @@
+/*******************************************************************************************
+*
+* raylib [models] example - Plane rotations (yaw, pitch, roll)
+*
+* Example originally created with raylib 1.8, last time updated with raylib 4.0
+*
+* Example contributed by Berni (@Berni8k) and reviewed by Ramon Santamaria (@raysan5)
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2017-2023 Berni (@Berni8k) and Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include "raymath.h" // Required for: MatrixRotateXYZ()
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ //SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI);
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - plane rotations (yaw, pitch, roll)");
+
+ Camera camera = { 0 };
+ camera.position = (Vector3){ 0.0f, 50.0f, -120.0f };// Camera position perspective
+ camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
+ camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
+ camera.fovy = 30.0f; // Camera field-of-view Y
+ camera.projection = CAMERA_PERSPECTIVE; // Camera type
+
+ Model model = LoadModel("resources/models/obj/plane.obj"); // Load model
+ Texture2D texture = LoadTexture("resources/models/obj/plane_diffuse.png"); // Load model texture
+ model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture
+
+ float pitch = 0.0f;
+ float roll = 0.0f;
+ float yaw = 0.0f;
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ // Plane pitch (x-axis) controls
+ if (IsKeyDown(KEY_DOWN)) pitch += 0.6f;
+ else if (IsKeyDown(KEY_UP)) pitch -= 0.6f;
+ else
+ {
+ if (pitch > 0.3f) pitch -= 0.3f;
+ else if (pitch < -0.3f) pitch += 0.3f;
+ }
+
+ // Plane yaw (y-axis) controls
+ if (IsKeyDown(KEY_S)) yaw -= 1.0f;
+ else if (IsKeyDown(KEY_A)) yaw += 1.0f;
+ else
+ {
+ if (yaw > 0.0f) yaw -= 0.5f;
+ else if (yaw < 0.0f) yaw += 0.5f;
+ }
+
+ // Plane roll (z-axis) controls
+ if (IsKeyDown(KEY_LEFT)) roll -= 1.0f;
+ else if (IsKeyDown(KEY_RIGHT)) roll += 1.0f;
+ else
+ {
+ if (roll > 0.0f) roll -= 0.5f;
+ else if (roll < 0.0f) roll += 0.5f;
+ }
+
+ // Tranformation matrix for rotations
+ model.transform = MatrixRotateXYZ((Vector3){ DEG2RAD*pitch, DEG2RAD*yaw, DEG2RAD*roll });
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ // Draw 3D model (recomended to draw 3D always before 2D)
+ BeginMode3D(camera);
+
+ DrawModel(model, (Vector3){ 0.0f, -8.0f, 0.0f }, 1.0f, WHITE); // Draw 3d model with texture
+ DrawGrid(10, 10.0f);
+
+ EndMode3D();
+
+ // Draw controls info
+ DrawRectangle(30, 370, 260, 70, Fade(GREEN, 0.5f));
+ DrawRectangleLines(30, 370, 260, 70, Fade(DARKGREEN, 0.5f));
+ DrawText("Pitch controlled with: KEY_UP / KEY_DOWN", 40, 380, 10, DARKGRAY);
+ DrawText("Roll controlled with: KEY_LEFT / KEY_RIGHT", 40, 400, 10, DARKGRAY);
+ DrawText("Yaw controlled with: KEY_A / KEY_S", 40, 420, 10, DARKGRAY);
+
+ DrawText("(c) WWI Plane Model created by GiaHanLam", screenWidth - 240, screenHeight - 20, 10, DARKGRAY);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadModel(model); // Unload model data
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/raylib/examples/models/models_yaw_pitch_roll.png b/raylib/examples/models/models_yaw_pitch_roll.png
new file mode 100644
index 0000000..8b36fe3
--- /dev/null
+++ b/raylib/examples/models/models_yaw_pitch_roll.png
Binary files differ
diff --git a/raylib/examples/models/resources/LICENSE.md b/raylib/examples/models/resources/LICENSE.md
new file mode 100644
index 0000000..d7f85c0
--- /dev/null
+++ b/raylib/examples/models/resources/LICENSE.md
@@ -0,0 +1,22 @@
+| resource | author | licence | notes |
+| :------------------- | :---------: | :------ | :---- |
+| models/obj/castle.obj,<br>models/obj/castle_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
+| models/obj/bridge.obj,<br>models/obj/bridge_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
+| models/obj/house.obj,<br>models/obj/house_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
+| models/obj/market.obj,<br>models/obj/market_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
+| models/obj/turret.obj,<br>models/obj/turret_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
+| models/obj/well.obj,<br>models/obj/well_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
+| models/obj/cube.obj,<br>models/obj/cube_diffuse.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
+| models/obj/plane.obj,<br>models/obj/plane_diffuse.png | [GiaHanLam](https://sketchfab.com/GiaHanLam) | [CC-BY](https://creativecommons.org/licenses/by/4.0/) | Used by: [`models_yaw_pitch_roll.c`](https://github.com/raysan5/raylib/blob/master/examples/models/models_yaw_pitch_roll.c)
+| models/iqm/guy.iqm,<br>models/iqm/guyanim.iqm,<br>models/iqm/guytex.png,<br>models/iqm/guy.blend | [@culacant](https://github.com/culacant) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
+| models/gltf/robot.glb,<br>models/gltf/robot.blend | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
+| models/vox/chr_knight.vox | ❔ | ❔ | - |
+| models/vox/chr_sword.vox | ❔ | ❔ | - |
+| models/vox/monu9.vox | ❔ | ❔ | - |
+| billboard.png | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
+| cubicmap.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
+| cubicmap_atlas.png | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
+| heightmap.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
+| dresden_square_1k.hdr | [HDRIHaven](https://hdrihaven.com/hdri/?h=dresden_square) | [CC0](https://hdrihaven.com/p/license.php) | - |
+| dresden_square_2k.hdr | [HDRIHaven](https://hdrihaven.com/hdri/?h=dresden_square) | [CC0](https://hdrihaven.com/p/license.php) | - |
+| skybox.png | ❔ | ❔ | - | \ No newline at end of file
diff --git a/raylib/examples/models/resources/billboard.png b/raylib/examples/models/resources/billboard.png
new file mode 100644
index 0000000..8c99118
--- /dev/null
+++ b/raylib/examples/models/resources/billboard.png
Binary files differ
diff --git a/raylib/examples/models/resources/cubicmap.png b/raylib/examples/models/resources/cubicmap.png
new file mode 100644
index 0000000..392dbf2
--- /dev/null
+++ b/raylib/examples/models/resources/cubicmap.png
Binary files differ
diff --git a/raylib/examples/models/resources/cubicmap_atlas.png b/raylib/examples/models/resources/cubicmap_atlas.png
new file mode 100644
index 0000000..9fc404a
--- /dev/null
+++ b/raylib/examples/models/resources/cubicmap_atlas.png
Binary files differ
diff --git a/raylib/examples/models/resources/dresden_square_1k.hdr b/raylib/examples/models/resources/dresden_square_1k.hdr
new file mode 100644
index 0000000..b6d0e77
--- /dev/null
+++ b/raylib/examples/models/resources/dresden_square_1k.hdr
Binary files differ
diff --git a/raylib/examples/models/resources/dresden_square_2k.hdr b/raylib/examples/models/resources/dresden_square_2k.hdr
new file mode 100644
index 0000000..60b4a4c
--- /dev/null
+++ b/raylib/examples/models/resources/dresden_square_2k.hdr
Binary files differ
diff --git a/raylib/examples/models/resources/heightmap.png b/raylib/examples/models/resources/heightmap.png
new file mode 100644
index 0000000..474db87
--- /dev/null
+++ b/raylib/examples/models/resources/heightmap.png
Binary files differ
diff --git a/raylib/examples/models/resources/models/gltf/LICENSE b/raylib/examples/models/resources/models/gltf/LICENSE
new file mode 100644
index 0000000..3c9a38d
--- /dev/null
+++ b/raylib/examples/models/resources/models/gltf/LICENSE
@@ -0,0 +1,2 @@
+robot.glb model by @Quaternius (https://www.patreon.com/quaternius)
+Licensed under CC0 1.0 Universal (CC0 1.0) - Public Domain Dedication (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file
diff --git a/raylib/examples/models/resources/models/gltf/raylib_logo_3d.glb b/raylib/examples/models/resources/models/gltf/raylib_logo_3d.glb
new file mode 100644
index 0000000..4fc56ad
--- /dev/null
+++ b/raylib/examples/models/resources/models/gltf/raylib_logo_3d.glb
Binary files differ
diff --git a/raylib/examples/models/resources/models/gltf/robot.blend b/raylib/examples/models/resources/models/gltf/robot.blend
new file mode 100644
index 0000000..efe43c5
--- /dev/null
+++ b/raylib/examples/models/resources/models/gltf/robot.blend
Binary files differ
diff --git a/raylib/examples/models/resources/models/gltf/robot.glb b/raylib/examples/models/resources/models/gltf/robot.glb
new file mode 100644
index 0000000..549011e
--- /dev/null
+++ b/raylib/examples/models/resources/models/gltf/robot.glb
Binary files differ
diff --git a/raylib/examples/models/resources/models/iqm/guy.blend b/raylib/examples/models/resources/models/iqm/guy.blend
new file mode 100644
index 0000000..3880467
--- /dev/null
+++ b/raylib/examples/models/resources/models/iqm/guy.blend
Binary files differ
diff --git a/raylib/examples/models/resources/models/iqm/guy.iqm b/raylib/examples/models/resources/models/iqm/guy.iqm
new file mode 100644
index 0000000..36bed5e
--- /dev/null
+++ b/raylib/examples/models/resources/models/iqm/guy.iqm
Binary files differ
diff --git a/raylib/examples/models/resources/models/iqm/guyanim.iqm b/raylib/examples/models/resources/models/iqm/guyanim.iqm
new file mode 100644
index 0000000..824a68a
--- /dev/null
+++ b/raylib/examples/models/resources/models/iqm/guyanim.iqm
Binary files differ
diff --git a/raylib/examples/models/resources/models/iqm/guytex.png b/raylib/examples/models/resources/models/iqm/guytex.png
new file mode 100644
index 0000000..05a58ee
--- /dev/null
+++ b/raylib/examples/models/resources/models/iqm/guytex.png
Binary files differ
diff --git a/raylib/examples/models/resources/models/m3d/cesium_man.m3d b/raylib/examples/models/resources/models/m3d/cesium_man.m3d
new file mode 100644
index 0000000..ddf9f50
--- /dev/null
+++ b/raylib/examples/models/resources/models/m3d/cesium_man.m3d
Binary files differ
diff --git a/raylib/examples/models/resources/models/m3d/seagull.m3d b/raylib/examples/models/resources/models/m3d/seagull.m3d
new file mode 100644
index 0000000..8236820
--- /dev/null
+++ b/raylib/examples/models/resources/models/m3d/seagull.m3d
Binary files differ
diff --git a/raylib/examples/models/resources/models/m3d/suzanne.m3d b/raylib/examples/models/resources/models/m3d/suzanne.m3d
new file mode 100644
index 0000000..9bc64d7
--- /dev/null
+++ b/raylib/examples/models/resources/models/m3d/suzanne.m3d
Binary files differ
diff --git a/raylib/examples/models/resources/models/obj/bridge_diffuse.png b/raylib/examples/models/resources/models/obj/bridge_diffuse.png
new file mode 100644
index 0000000..45a86b5
--- /dev/null
+++ b/raylib/examples/models/resources/models/obj/bridge_diffuse.png
Binary files differ
diff --git a/raylib/examples/models/resources/models/obj/castle_diffuse.png b/raylib/examples/models/resources/models/obj/castle_diffuse.png
new file mode 100644
index 0000000..c7085a3
--- /dev/null
+++ b/raylib/examples/models/resources/models/obj/castle_diffuse.png
Binary files differ
diff --git a/raylib/examples/models/resources/models/obj/cube_diffuse.png b/raylib/examples/models/resources/models/obj/cube_diffuse.png
new file mode 100644
index 0000000..6becd47
--- /dev/null
+++ b/raylib/examples/models/resources/models/obj/cube_diffuse.png
Binary files differ
diff --git a/raylib/examples/models/resources/models/obj/house_diffuse.png b/raylib/examples/models/resources/models/obj/house_diffuse.png
new file mode 100644
index 0000000..b36a58a
--- /dev/null
+++ b/raylib/examples/models/resources/models/obj/house_diffuse.png
Binary files differ
diff --git a/raylib/examples/models/resources/models/obj/market_diffuse.png b/raylib/examples/models/resources/models/obj/market_diffuse.png
new file mode 100644
index 0000000..3ad3046
--- /dev/null
+++ b/raylib/examples/models/resources/models/obj/market_diffuse.png
Binary files differ
diff --git a/raylib/examples/models/resources/models/obj/plane_diffuse.png b/raylib/examples/models/resources/models/obj/plane_diffuse.png
new file mode 100644
index 0000000..07371c0
--- /dev/null
+++ b/raylib/examples/models/resources/models/obj/plane_diffuse.png
Binary files differ
diff --git a/raylib/examples/models/resources/models/obj/turret_diffuse.png b/raylib/examples/models/resources/models/obj/turret_diffuse.png
new file mode 100644
index 0000000..33628e3
--- /dev/null
+++ b/raylib/examples/models/resources/models/obj/turret_diffuse.png
Binary files differ
diff --git a/raylib/examples/models/resources/models/obj/well_diffuse.png b/raylib/examples/models/resources/models/obj/well_diffuse.png
new file mode 100644
index 0000000..f8f6686
--- /dev/null
+++ b/raylib/examples/models/resources/models/obj/well_diffuse.png
Binary files differ
diff --git a/raylib/examples/models/resources/models/vox/LICENSE b/raylib/examples/models/resources/models/vox/LICENSE
new file mode 100644
index 0000000..afb6608
--- /dev/null
+++ b/raylib/examples/models/resources/models/vox/LICENSE
@@ -0,0 +1,9 @@
+The following models are provided by the official github repo of voxel-model format by MagikaVoxel developer @ephtracy
+
+GitHub official repo: https://github.com/ephtracy/voxel-model
+
+ - chr_knight.vox - https://github.com/ephtracy/voxel-model/blob/master/vox/character/chr_knight.vox
+ - chr_sword.vox - https://github.com/ephtracy/voxel-model/blob/master/vox/character/chr_sword.vox
+ - monu9.vox - https://github.com/ephtracy/voxel-model/blob/master/vox/monument/monu9.vox
+
+Worth mentioning there is no license specified for the models yet: https://github.com/ephtracy/voxel-model/issues/22
diff --git a/raylib/examples/models/resources/models/vox/chr_knight.vox b/raylib/examples/models/resources/models/vox/chr_knight.vox
new file mode 100644
index 0000000..c921bf5
--- /dev/null
+++ b/raylib/examples/models/resources/models/vox/chr_knight.vox
Binary files differ
diff --git a/raylib/examples/models/resources/models/vox/chr_sword.vox b/raylib/examples/models/resources/models/vox/chr_sword.vox
new file mode 100644
index 0000000..05fc482
--- /dev/null
+++ b/raylib/examples/models/resources/models/vox/chr_sword.vox
Binary files differ
diff --git a/raylib/examples/models/resources/models/vox/monu9.vox b/raylib/examples/models/resources/models/vox/monu9.vox
new file mode 100644
index 0000000..fd77111
--- /dev/null
+++ b/raylib/examples/models/resources/models/vox/monu9.vox
Binary files differ
diff --git a/raylib/examples/models/resources/shaders/glsl100/cubemap.fs b/raylib/examples/models/resources/shaders/glsl100/cubemap.fs
new file mode 100644
index 0000000..7d1bde0
--- /dev/null
+++ b/raylib/examples/models/resources/shaders/glsl100/cubemap.fs
@@ -0,0 +1,29 @@
+#version 100
+
+precision mediump float;
+
+// Input vertex attributes (from vertex shader)
+varying vec3 fragPosition;
+
+// Input uniform values
+uniform sampler2D equirectangularMap;
+
+vec2 SampleSphericalMap(vec3 v)
+{
+ vec2 uv = vec2(atan(v.z, v.x), asin(v.y));
+ uv *= vec2(0.1591, 0.3183);
+ uv += 0.5;
+ return uv;
+}
+
+void main()
+{
+ // Normalize local position
+ vec2 uv = SampleSphericalMap(normalize(fragPosition));
+
+ // Fetch color from texture map
+ vec3 color = texture2D(equirectangularMap, uv).rgb;
+
+ // Calculate final fragment color
+ gl_FragColor = vec4(color, 1.0);
+}
diff --git a/raylib/examples/models/resources/shaders/glsl100/cubemap.vs b/raylib/examples/models/resources/shaders/glsl100/cubemap.vs
new file mode 100644
index 0000000..6f486fb
--- /dev/null
+++ b/raylib/examples/models/resources/shaders/glsl100/cubemap.vs
@@ -0,0 +1,20 @@
+#version 100
+
+// Input vertex attributes
+attribute vec3 vertexPosition;
+
+// Input uniform values
+uniform mat4 matProjection;
+uniform mat4 matView;
+
+// Output vertex attributes (to fragment shader)
+varying vec3 fragPosition;
+
+void main()
+{
+ // Calculate fragment position based on model transformations
+ fragPosition = vertexPosition;
+
+ // Calculate final vertex position
+ gl_Position = matProjection*matView*vec4(vertexPosition, 1.0);
+}
diff --git a/raylib/examples/models/resources/shaders/glsl100/skybox.fs b/raylib/examples/models/resources/shaders/glsl100/skybox.fs
new file mode 100644
index 0000000..0ea6876
--- /dev/null
+++ b/raylib/examples/models/resources/shaders/glsl100/skybox.fs
@@ -0,0 +1,31 @@
+#version 100
+
+precision mediump float;
+
+// Input vertex attributes (from vertex shader)
+varying vec3 fragPosition;
+
+// Input uniform values
+uniform samplerCube environmentMap;
+uniform bool vflipped;
+uniform bool doGamma;
+
+void main()
+{
+ // Fetch color from texture map
+ vec4 texelColor = vec4(0.0);
+
+ if (vflipped) texelColor = textureCube(environmentMap, vec3(fragPosition.x, -fragPosition.y, fragPosition.z));
+ else texelColor = textureCube(environmentMap, fragPosition);
+
+ vec3 color = vec3(texelColor.x, texelColor.y, texelColor.z);
+
+ if (doGamma) // Apply gamma correction
+ {
+ color = color/(color + vec3(1.0));
+ color = pow(color, vec3(1.0/2.2));
+ }
+
+ // Calculate final fragment color
+ gl_FragColor = vec4(color, 1.0);
+}
diff --git a/raylib/examples/models/resources/shaders/glsl100/skybox.vs b/raylib/examples/models/resources/shaders/glsl100/skybox.vs
new file mode 100644
index 0000000..e440ace
--- /dev/null
+++ b/raylib/examples/models/resources/shaders/glsl100/skybox.vs
@@ -0,0 +1,24 @@
+#version 100
+
+// Input vertex attributes
+attribute vec3 vertexPosition;
+
+// Input uniform values
+uniform mat4 matProjection;
+uniform mat4 matView;
+
+// Output vertex attributes (to fragment shader)
+varying vec3 fragPosition;
+
+void main()
+{
+ // Calculate fragment position based on model transformations
+ fragPosition = vertexPosition;
+
+ // Remove translation from the view matrix
+ mat4 rotView = mat4(mat3(matView));
+ vec4 clipPos = matProjection*rotView*vec4(vertexPosition, 1.0);
+
+ // Calculate final vertex position
+ gl_Position = clipPos;
+}
diff --git a/raylib/examples/models/resources/shaders/glsl330/cubemap.fs b/raylib/examples/models/resources/shaders/glsl330/cubemap.fs
new file mode 100644
index 0000000..f59003f
--- /dev/null
+++ b/raylib/examples/models/resources/shaders/glsl330/cubemap.fs
@@ -0,0 +1,30 @@
+#version 330
+
+// Input vertex attributes (from vertex shader)
+in vec3 fragPosition;
+
+// Input uniform values
+uniform sampler2D equirectangularMap;
+
+// Output fragment color
+out vec4 finalColor;
+
+vec2 SampleSphericalMap(vec3 v)
+{
+ vec2 uv = vec2(atan(v.z, v.x), asin(v.y));
+ uv *= vec2(0.1591, 0.3183);
+ uv += 0.5;
+ return uv;
+}
+
+void main()
+{
+ // Normalize local position
+ vec2 uv = SampleSphericalMap(normalize(fragPosition));
+
+ // Fetch color from texture map
+ vec3 color = texture(equirectangularMap, uv).rgb;
+
+ // Calculate final fragment color
+ finalColor = vec4(color, 1.0);
+}
diff --git a/raylib/examples/models/resources/shaders/glsl330/cubemap.vs b/raylib/examples/models/resources/shaders/glsl330/cubemap.vs
new file mode 100644
index 0000000..d71f808
--- /dev/null
+++ b/raylib/examples/models/resources/shaders/glsl330/cubemap.vs
@@ -0,0 +1,20 @@
+#version 330
+
+// Input vertex attributes
+in vec3 vertexPosition;
+
+// Input uniform values
+uniform mat4 matProjection;
+uniform mat4 matView;
+
+// Output vertex attributes (to fragment shader)
+out vec3 fragPosition;
+
+void main()
+{
+ // Calculate fragment position based on model transformations
+ fragPosition = vertexPosition;
+
+ // Calculate final vertex position
+ gl_Position = matProjection*matView*vec4(vertexPosition, 1.0);
+}
diff --git a/raylib/examples/models/resources/shaders/glsl330/skybox.fs b/raylib/examples/models/resources/shaders/glsl330/skybox.fs
new file mode 100644
index 0000000..d71fef0
--- /dev/null
+++ b/raylib/examples/models/resources/shaders/glsl330/skybox.fs
@@ -0,0 +1,30 @@
+#version 330
+
+// Input vertex attributes (from vertex shader)
+in vec3 fragPosition;
+
+// Input uniform values
+uniform samplerCube environmentMap;
+uniform bool vflipped;
+uniform bool doGamma;
+
+// Output fragment color
+out vec4 finalColor;
+
+void main()
+{
+ // Fetch color from texture map
+ vec3 color = vec3(0.0);
+
+ if (vflipped) color = texture(environmentMap, vec3(fragPosition.x, -fragPosition.y, fragPosition.z)).rgb;
+ else color = texture(environmentMap, fragPosition).rgb;
+
+ if (doGamma)// Apply gamma correction
+ {
+ color = color/(color + vec3(1.0));
+ color = pow(color, vec3(1.0/2.2));
+ }
+
+ // Calculate final fragment color
+ finalColor = vec4(color, 1.0);
+}
diff --git a/raylib/examples/models/resources/shaders/glsl330/skybox.vs b/raylib/examples/models/resources/shaders/glsl330/skybox.vs
new file mode 100644
index 0000000..f41d469
--- /dev/null
+++ b/raylib/examples/models/resources/shaders/glsl330/skybox.vs
@@ -0,0 +1,24 @@
+#version 330
+
+// Input vertex attributes
+in vec3 vertexPosition;
+
+// Input uniform values
+uniform mat4 matProjection;
+uniform mat4 matView;
+
+// Output vertex attributes (to fragment shader)
+out vec3 fragPosition;
+
+void main()
+{
+ // Calculate fragment position based on model transformations
+ fragPosition = vertexPosition;
+
+ // Remove translation from the view matrix
+ mat4 rotView = mat4(mat3(matView));
+ vec4 clipPos = matProjection*rotView*vec4(vertexPosition, 1.0);
+
+ // Calculate final vertex position
+ gl_Position = clipPos;
+}
diff --git a/raylib/examples/models/resources/skybox.png b/raylib/examples/models/resources/skybox.png
new file mode 100644
index 0000000..36a79b2
--- /dev/null
+++ b/raylib/examples/models/resources/skybox.png
Binary files differ