Example #1
0
int main()
{
    // Initialization
    //--------------------------------------------------------------------------------------
    int screenWidth = 800;
    int screenHeight = 450;
    
    SetConfigFlags(FLAG_MSAA_4X_HINT);      // Enable Multi Sampling Anti Aliasing 4x (if available)

    InitWindow(screenWidth, screenHeight, "raylib [shaders] example - postprocessing shader");

    // Define the camera to look into our 3d world
    Camera camera = {{ 3.0, 3.0, 3.0 }, { 0.0, 1.5, 0.0 }, { 0.0, 1.0, 0.0 }};
    
    Model dwarf = LoadModel("resources/model/dwarf.obj");                   // Load OBJ model
    Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png");   // Load model texture
    SetModelTexture(&dwarf, texture);                                       // Bind texture to model

    Vector3 position = { 0.0, 0.0, 0.0 };                                   // Set model position
    
    Shader shader = LoadShader("resources/shaders/base.vs", 
                               "resources/shaders/bloom.fs");               // Load postpro shader

    SetPostproShader(shader);               // Set fullscreen postprocessing shader
    
    // Setup orbital camera
    SetCameraMode(CAMERA_ORBITAL);          // Set an orbital camera mode
    SetCameraPosition(camera.position);     // Set internal camera position to match our camera position
    SetCameraTarget(camera.target);         // Set internal camera target to match our camera target

    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);              // Update internal camera and our camera
        //----------------------------------------------------------------------------------

        // Draw
        //----------------------------------------------------------------------------------
        BeginDrawing();

            ClearBackground(RAYWHITE);

            Begin3dMode(camera);

                DrawModel(dwarf, position, 2.0f, WHITE);   // Draw 3d model with texture

                DrawGrid(10.0, 1.0);     // Draw a grid

            End3dMode();
            
            DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, BLACK);

            DrawFPS(10, 10);

        EndDrawing();
        //----------------------------------------------------------------------------------
    }

    // De-Initialization
    //--------------------------------------------------------------------------------------
    UnloadShader(shader);       // Unload shader
    UnloadTexture(texture);     // Unload texture
    UnloadModel(dwarf);         // Unload model

    CloseWindow();              // Close window and OpenGL context
    //--------------------------------------------------------------------------------------

    return 0;
}
Example #2
0
int main()
{
    // Initialization
    //--------------------------------------------------------------------------------------
    int screenWidth = 800;
    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 = {{ 18.0f, 16.0f, 18.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };

    Image image = LoadImage("resources/heightmap.png");         // Load heightmap image (RAM)
    Texture2D texture = LoadTextureFromImage(image);            // Convert image to texture (VRAM)
    Model map = LoadHeightmap(image, (Vector3) {
        16, 8, 16
    });   // Load heightmap model with defined size
    map.material.texDiffuse = texture;                          // Set map diffuse texture
    Vector3 mapPosition = { -8.0f, 0.0f, -8.0f };               // Set model position (depends on model scaling!)

    UnloadImage(image);                     // Unload heightmap image from RAM, already uploaded to VRAM

    SetCameraMode(camera, CAMERA_ORBITAL);  // Set an orbital camera mode

    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);              // Update camera
        //----------------------------------------------------------------------------------

        // Draw
        //----------------------------------------------------------------------------------
        BeginDrawing();

        ClearBackground(RAYWHITE);

        Begin3dMode(camera);

        // NOTE: Model is scaled to 1/4 of its original size (128x128 units)
        DrawModel(map, mapPosition, 1.0f, RED);

        DrawGrid(20, 1.0f);

        End3dMode();

        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(map);           // Unload model

    CloseWindow();              // Close window and OpenGL context
    //--------------------------------------------------------------------------------------

    return 0;
}
Example #3
0
int main()
{
    // Initialization
    //--------------------------------------------------------------------------------------
    int screenWidth = 800;
    int screenHeight = 450;

    InitWindow(screenWidth, screenHeight, "raylib [models] example - cubesmap loading and drawing");

    // Define the camera to look into our 3d world
    Camera camera = {{ 16.0f, 14.0f, 16.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };

    Image image = LoadImage("resources/cubicmap.png");      // Load cubicmap image (RAM)
    Texture2D cubicmap = LoadTextureFromImage(image);       // Convert image to texture to display (VRAM)
    Model map = LoadCubicmap(image);                        // Load cubicmap model (generate model from image)
    
    // NOTE: By default each cube is mapped to one part of texture atlas
    Texture2D texture = LoadTexture("resources/cubicmap_atlas.png");    // Load map texture
    map.material.texDiffuse = 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
    
    SetCameraMode(camera, CAMERA_ORBITAL);  // Set an orbital camera mode

    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);              // Update camera
        //----------------------------------------------------------------------------------

        // Draw
        //----------------------------------------------------------------------------------
        BeginDrawing();

            ClearBackground(RAYWHITE);

            Begin3dMode(camera);

                DrawModel(map, mapPosition, 1.0f, WHITE);

            End3dMode();
            
            DrawTextureEx(cubicmap, (Vector2){ screenWidth - cubicmap.width*4 - 20, 20 }, 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(map);           // Unload map model

    CloseWindow();              // Close window and OpenGL context
    //--------------------------------------------------------------------------------------

    return 0;
}
Example #4
0
//----------------------------------------------------------------------------------
// Main entry point
//----------------------------------------------------------------------------------
int main()
{
    // Initialization
    //--------------------------------------------------------------------------------------
    const char windowTitle[30] = "raylib functionality demo";
   
    //SetupFlags(FLAG_FULLSCREEN_MODE);
    InitWindow(screenWidth, screenHeight, windowTitle);
    
    InitAudioDevice();             // Initialize audio device

    // TITLE screen variables Initialization
    fontAlagard = LoadSpriteFont("resources/fonts/alagard.rbmf");        // rBMF font loading
    fontPixelplay = LoadSpriteFont("resources/fonts/pixelplay.rbmf");    // rBMF font loading
    fontMecha = LoadSpriteFont("resources/fonts/mecha.rbmf");            // rBMF font loading
    fontSetback = LoadSpriteFont("resources/fonts/setback.rbmf");        // rBMF font loading
    fontRomulus = LoadSpriteFont("resources/fonts/romulus.rbmf");        // rBMF font loading
    
    pongBallPosition = (Vector2){ screenWidth/2, screenHeight/2 + 20 };
    pongBallSpeed = (Vector2){ 6, 6 };
    pongPlayerRec = (Rectangle){ 20, screenHeight/2 - 50 + 40, 20, 100 };
    pongEnemyRec = (Rectangle){ screenWidth - 40, screenHeight/2 - 60, 20, 120 };

    // LOGO screen variables Initialization
    logoPositionX = screenWidth/2 - 128;
    logoPositionY = screenHeight/2 - 128;
    
    // MODULES screen variables Initialization
    raylibWindow = LoadTexture("resources/raylib_window.png");
    raylibWindow01 = LoadTexture("resources/raylib_window_01.png");
    raylibWindow02 = LoadTexture("resources/raylib_window_02.png");
    raylibWindow03 = LoadTexture("resources/raylib_window_03.png");
    platforms = LoadTexture("resources/platforms.png");
    raylibLogoB = LoadTexture("resources/raylib_logo128x128.png");
    lena = LoadTexture("resources/lena.png");
    mandrill = LoadTexture("resources/mandrill.png");
    texAlagard = LoadTexture("resources/fonts/custom_alagard.png");
    fontMechaC = LoadSpriteFont("resources/fonts/custom_mecha.png");
    fontAlagardC = LoadSpriteFont("resources/fonts/custom_alagard.png");
    fontJupiterC = LoadSpriteFont("resources/fonts/custom_jupiter_crash.png");
    
    ballPosition = (Vector2){ 520 + 656/2, 220 + 399/2 };
    
    camera = (Camera){{ 0.0, 12.0, 15.0 }, { 0.0, 3.0, 0.0 }, { 0.0, 1.0, 0.0 }};

    catTexture = LoadTexture("resources/catsham.png");   // Load model texture
    cat = LoadModel("resources/cat.obj");                 // Load OBJ model
    SetModelTexture(&cat, catTexture);
    
    fxWav = LoadSound("resources/audio/weird.wav");         // Load WAV audio file
    fxOgg = LoadSound("resources/audio/tanatana.ogg");      // Load OGG audio file
    
    for (int i = 0; i < MAX_BALLS; i++)
    {
        soundBallsPosition[i] = (Vector2){ 650 + 560/2 + GetRandomValue(-280, 280), 220 + 200 + GetRandomValue(-200, 200) };
        soundBallsColor[i] = (Color){ GetRandomValue(0, 255), GetRandomValue(0, 255), GetRandomValue(0, 255), 255 };
        soundBallsRadius[i] = GetRandomValue(2, 50);
        soundBallsAlpha[i] = 1.0f;
        
        soundBallsActive[i] = false;
    }
    
    // ENDING screen variables Initialization
    raylibLogoA = LoadTexture("resources/raylib_logo.png");

#ifndef PLATFORM_WEB
    SetTargetFPS(60);
#endif

#if defined(PLATFORM_WEB)
    emscripten_set_main_loop(UpdateDrawOneFrame, 0, 1);
#else
    //--------------------------------------------------------------------------------------
    
    // Main game loop
    while (!WindowShouldClose() && !closeWindow)    // Detect window close button or ESC key
    {
        UpdateDrawOneFrame();
    }
#endif

    // De-Initialization
    //--------------------------------------------------------------------------------------

    // Unload all loaded data (textures, fonts, audio)
    UnloadSpriteFont(fontAlagard);      // SpriteFont unloading
    UnloadSpriteFont(fontPixelplay);    // SpriteFont unloading
    UnloadSpriteFont(fontMecha);        // SpriteFont unloading
    UnloadSpriteFont(fontSetback);      // SpriteFont unloading
    UnloadSpriteFont(fontRomulus);      // SpriteFont unloading

    UnloadTexture(raylibWindow);
    UnloadTexture(raylibWindow01);
    UnloadTexture(raylibWindow02);
    UnloadTexture(raylibWindow03);
    UnloadTexture(platforms);
    UnloadTexture(raylibLogoA);
    UnloadTexture(raylibLogoB);
    UnloadTexture(lena);
    UnloadTexture(mandrill);
    UnloadTexture(texAlagard);

    UnloadSpriteFont(fontMechaC);
    UnloadSpriteFont(fontAlagardC);
    UnloadSpriteFont(fontJupiterC);

    UnloadTexture(catTexture);
    UnloadModel(cat);

    UnloadSound(fxWav);
    UnloadSound(fxOgg);

    CloseAudioDevice();
    
    CloseWindow();        // Close window and OpenGL context
    //--------------------------------------------------------------------------------------

    return 0;
}
Example #5
0
int main(void)
{
    // Initialization
    //--------------------------------------------------------------------------------------
    const int screenWidth = 800;
    const int screenHeight = 450;

    InitWindow(screenWidth, screenHeight, "raylib example - obj viewer");

    // Define the camera to look into our 3d world
    Camera camera = { { 30.0f, 30.0f, 30.0f }, { 0.0f, 10.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };

    Model model = LoadModel("resources/models/turret.obj");                     // Load default model obj
    Texture2D texture = LoadTexture("resources/models/turret_diffuse.png");     // Load default model texture
    model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Bind texture to model

    Vector3 position = { 0.0, 0.0, 0.0 };                   // Set model position
    BoundingBox bounds = MeshBoundingBox(model.meshes[0]);  // Set model bounds
    bool selected = false;                                  // Selected object flag

    SetCameraMode(camera, CAMERA_FREE);     // Set a free camera mode

    char objFilename[64] = "turret.obj";

    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 (IsFileDropped())
        {
            int count = 0;
            char **droppedFiles = GetDroppedFiles(&count);

            if (count == 1)
            {
                if (IsFileExtension(droppedFiles[0], ".obj"))
                {
                    for (int i = 0; i < model.meshCount; i++) UnloadMesh(&model.meshes[i]);
                    model.meshes = LoadMeshes(droppedFiles[0], &model.meshCount);
                    bounds = MeshBoundingBox(model.meshes[0]);
                }
                else if (IsFileExtension(droppedFiles[0], ".png"))
                {
                    UnloadTexture(texture);
                    texture = LoadTexture(droppedFiles[0]);
                    model.materials[0].maps[MAP_DIFFUSE].texture = texture;
                }

                strcpy(objFilename, GetFileName(droppedFiles[0]));
            }

            ClearDroppedFiles();    // Clear internal buffers
        }

        UpdateCamera(&camera);

        // Select model on mouse click
        if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
        {
            // Check collision between ray and box
            if (CheckCollisionRayBox(GetMouseRay(GetMousePosition(), camera), bounds)) selected = !selected;
            else selected = false;
        }
        //----------------------------------------------------------------------------------

        // Draw
        //----------------------------------------------------------------------------------
        BeginDrawing();

            ClearBackground(RAYWHITE);

            BeginMode3D(camera);

                DrawModel(model, position, 1.0f, WHITE);   // Draw 3d model with texture

                DrawGrid(20.0, 10.0);        // Draw a grid

                if (selected) DrawBoundingBox(bounds, GREEN);

            EndMode3D();

            DrawText("Free camera default controls:", 10, 20, 10, DARKGRAY);
            DrawText("- Mouse Wheel to Zoom in-out", 20, 40, 10, GRAY);
            DrawText("- Mouse Wheel Pressed to Pan", 20, 60, 10, GRAY);
            DrawText("- Alt + Mouse Wheel Pressed to Rotate", 20, 80, 10, GRAY);
            DrawText("- Alt + Ctrl + Mouse Wheel Pressed for Smooth Zoom", 20, 100, 10, GRAY);

            DrawText("Drag & drop .obj/.png to load mesh/texture.", 10, GetScreenHeight() - 20, 10, DARKGRAY);
            DrawText(FormatText("Current file: %s", objFilename), 250, GetScreenHeight() - 20, 10, GRAY);
            if (selected) DrawText("MODEL SELECTED", GetScreenWidth() - 110, 10, 10, GREEN);

            DrawText("(c) Turret 3D model by Alberto Cano", screenWidth - 200, screenHeight - 20, 10, GRAY);

        EndDrawing();
        //----------------------------------------------------------------------------------
    }

    // De-Initialization
    //--------------------------------------------------------------------------------------
    UnloadModel(model);         // Unload model

    ClearDroppedFiles();        // Clear internal buffers

    CloseWindow();              // Close window and OpenGL context
    //--------------------------------------------------------------------------------------

    return 0;
}
Example #6
0
int main()
{
    // Initialization
    //--------------------------------------------------------------------------------------
    const int screenWidth = 800;
    const int screenHeight = 450;
    
    SetConfigFlags(FLAG_MSAA_4X_HINT);
    InitWindow(screenWidth, screenHeight, "raylib [shaders] example - basic lighting");
    
    // Camera initialization
    Camera camera = {{ 8.0f, 8.0f, 8.0f }, { 0.0f, 3.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }};
    
    // Model initialization
    Vector3 position = { 0.0f, 0.0f, 0.0f };
    Model model = LoadModel("resources/model/dwarf.obj");
    Shader shader = LoadShader("resources/shaders/phong.vs", "resources/shaders/phong.fs");
    SetModelShader(&model, shader);
    
    // Shader locations initialization
    int lIntensityLoc = GetShaderLocation(shader, "light_intensity");
    int lAmbientLoc = GetShaderLocation(shader, "light_ambientColor");
    int lDiffuseLoc = GetShaderLocation(shader, "light_diffuseColor");
    int lSpecularLoc = GetShaderLocation(shader, "light_specularColor");
    int lSpecIntensityLoc = GetShaderLocation(shader, "light_specIntensity");
    
    int mAmbientLoc = GetShaderLocation(shader, "mat_ambientColor");
    int mSpecularLoc = GetShaderLocation(shader, "mat_specularColor");
    int mGlossLoc = GetShaderLocation(shader, "mat_glossiness");
    
    // Camera and light vectors shader locations
    int cameraLoc = GetShaderLocation(shader, "cameraPos");
    int lightLoc = GetShaderLocation(shader, "lightPos");
    
    // Model and View matrix locations (required for lighting)
    int modelLoc = GetShaderLocation(shader, "modelMatrix");
    //int viewLoc = GetShaderLocation(shader, "viewMatrix");        // Not used
    
    // Light and material definitions
    Light light;
    Material matBlinn;
    
    // Light initialization
    light.position = (Vector3){ 4.0f, 2.0f, 0.0f };
    light.direction = (Vector3){ 5.0f, 1.0f, 1.0f };
    light.intensity = 1.0f;
    light.diffuse = WHITE;
    light.ambient = (Color){ 150, 75, 0, 255 };
    light.specular = WHITE;
    light.specIntensity = 1.0f;
    
    // Material initialization
    matBlinn.colDiffuse = WHITE;
    matBlinn.colAmbient = (Color){ 50, 50, 50, 255 };
    matBlinn.colSpecular = WHITE;
    matBlinn.glossiness = 50.0f;
    
    // Setup camera
    SetCameraMode(CAMERA_FREE);             // Set camera mode
    SetCameraPosition(camera.position);     // Set internal camera position to match our camera position
    SetCameraTarget(camera.target);         // Set internal camera target to match our camera target
    
    SetTargetFPS(60);
    //--------------------------------------------------------------------------------------
    
    // Main game loop
    while (!WindowShouldClose())    // Detect window close button or ESC key
    {
        // Update
        //----------------------------------------------------------------------------------
        UpdateCamera(&camera);      // Update camera position
        
        // NOTE: Model transform can be set in model.transform or directly with params at draw... WATCH OUT!
        SetShaderValueMatrix(shader, modelLoc, model.transform);            // Send model matrix to shader
        //SetShaderValueMatrix(shader, viewLoc, GetCameraMatrix(camera));   // Not used
        
        // Glossiness input control
        if(IsKeyDown(KEY_UP)) matBlinn.glossiness += SHININESS_SPEED;
        else if(IsKeyDown(KEY_DOWN))
        {
            matBlinn.glossiness -= SHININESS_SPEED;
            if( matBlinn.glossiness < 0) matBlinn.glossiness = 0.0f;
        }
        
        // Light X movement
        if (IsKeyDown(KEY_D)) light.position.x += LIGHT_SPEED;
        else if(IsKeyDown(KEY_A)) light.position.x -= LIGHT_SPEED;
        
        // Light Y movement
        if (IsKeyDown(KEY_LEFT_SHIFT)) light.position.y += LIGHT_SPEED;
        else if (IsKeyDown(KEY_LEFT_CONTROL)) light.position.y -= LIGHT_SPEED;

        // Light Z movement
        if (IsKeyDown(KEY_S)) light.position.z += LIGHT_SPEED;
        else if (IsKeyDown(KEY_W)) light.position.z -= LIGHT_SPEED;
        
        // Send light values to shader
        SetShaderValue(shader, lIntensityLoc, &light.intensity, 1);
        SetShaderValue(shader, lAmbientLoc, ColorToFloat(light.ambient), 3);
        SetShaderValue(shader, lDiffuseLoc, ColorToFloat(light.diffuse), 3);
        SetShaderValue(shader, lSpecularLoc, ColorToFloat(light.specular), 3);
        SetShaderValue(shader, lSpecIntensityLoc, &light.specIntensity, 1);
        
        // Send material values to shader
        SetShaderValue(shader, mAmbientLoc, ColorToFloat(matBlinn.colAmbient), 3);
        SetShaderValue(shader, mSpecularLoc, ColorToFloat(matBlinn.colSpecular), 3);
        SetShaderValue(shader, mGlossLoc, &matBlinn.glossiness, 1);
        
        // Send camera and light transform values to shader
        SetShaderValue(shader, cameraLoc, VectorToFloat(camera.position), 3);
        SetShaderValue(shader, lightLoc, VectorToFloat(light.position), 3);
        //----------------------------------------------------------------------------------
        
        // Draw
        //----------------------------------------------------------------------------------
        BeginDrawing();
        
            ClearBackground(RAYWHITE);
            
            Begin3dMode(camera);
                
                DrawModel(model, position, 4.0f, matBlinn.colDiffuse);
                DrawSphere(light.position, 0.5f, GOLD);
                
                DrawGrid(20, 1.0f);
                
            End3dMode();
            
            DrawFPS(10, 10);                // Draw FPS
            
        EndDrawing();
        //----------------------------------------------------------------------------------
    }

    // De-Initialization
    //--------------------------------------------------------------------------------------
    UnloadShader(shader);
    UnloadModel(model);

    CloseWindow();        // Close window and OpenGL context
    //--------------------------------------------------------------------------------------
    
    return 0;
}
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.2f, 0.4f, 0.2f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };

    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[MAP_DIFFUSE].texture = texture;             // Set map diffuse texture

    // Get map image data to be used for collision detection
    Color *mapPixels = GetImageData(imMap);
    UnloadImage(imMap);             // Unload image from RAM

    Vector3 mapPosition = { -16.0f, 0.0f, -8.0f };  // Set model position
    Vector3 playerPosition = camera.position;       // Set player position

    SetCameraMode(camera, CAMERA_FIRST_PERSON);     // Set camera mode

    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);      // Update camera

        // 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
                //DrawCubeV(playerPosition, (Vector3){ 0.2f, 0.4f, 0.2f }, RED);  // Draw player

            EndMode3D();

            DrawTextureEx(cubicmap, (Vector2){ GetScreenWidth() - cubicmap.width*4 - 20, 20 }, 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
    //--------------------------------------------------------------------------------------
    free(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;
}