Browse Source

Manual integration of material-pbr into develop

Ray 8 years ago
parent
commit
6546474fa4

+ 6 - 4
examples/models/models_cubicmap.c

@@ -25,11 +25,13 @@ int main()
 
 
     Image image = LoadImage("resources/cubicmap.png");      // Load cubicmap image (RAM)
     Image image = LoadImage("resources/cubicmap.png");      // Load cubicmap image (RAM)
     Texture2D cubicmap = LoadTextureFromImage(image);       // Convert image to texture to display (VRAM)
     Texture2D cubicmap = LoadTextureFromImage(image);       // Convert image to texture to display (VRAM)
-    Model map = LoadCubicmap(image);                        // Load cubicmap model (generate model from image)
+    
+    Mesh mesh = GenMeshCubicmap(image, VectorOne());
+    Model model = LoadModelFromMesh(mesh, false);
     
     
     // NOTE: By default each cube is mapped to one part of texture atlas
     // NOTE: By default each cube is mapped to one part of texture atlas
     Texture2D texture = LoadTexture("resources/cubicmap_atlas.png");    // Load map texture
     Texture2D texture = LoadTexture("resources/cubicmap_atlas.png");    // Load map texture
-    map.material.texDiffuse = texture;                      // Set map diffuse texture
+    model.material.maps[TEXMAP_DIFFUSE].tex = texture;                  // Set map diffuse texture
     
     
     Vector3 mapPosition = { -16.0f, 0.0f, -8.0f };          // Set model position
     Vector3 mapPosition = { -16.0f, 0.0f, -8.0f };          // Set model position
 
 
@@ -56,7 +58,7 @@ int main()
 
 
             Begin3dMode(camera);
             Begin3dMode(camera);
 
 
-                DrawModel(map, mapPosition, 1.0f, WHITE);
+                DrawModel(model, mapPosition, 1.0f, WHITE);
 
 
             End3dMode();
             End3dMode();
             
             
@@ -76,7 +78,7 @@ int main()
     //--------------------------------------------------------------------------------------
     //--------------------------------------------------------------------------------------
     UnloadTexture(cubicmap);    // Unload cubicmap texture
     UnloadTexture(cubicmap);    // Unload cubicmap texture
     UnloadTexture(texture);     // Unload map texture
     UnloadTexture(texture);     // Unload map texture
-    UnloadModel(map);           // Unload map model
+    UnloadModel(model);         // Unload map model
 
 
     CloseWindow();              // Close window and OpenGL context
     CloseWindow();              // Close window and OpenGL context
     //--------------------------------------------------------------------------------------
     //--------------------------------------------------------------------------------------

+ 185 - 0
examples/models/models_material_pbr.c

@@ -0,0 +1,185 @@
+/*******************************************************************************************
+*
+*   raylib [models] example - PBR material
+*
+*   This example has been created using raylib 1.8 (www.raylib.com)
+*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+*   Copyright (c) 2017 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+#include "raymath.h"
+
+#define         MAX_LIGHTS            4         // Max lights supported by shader
+#define         LIGHT_DISTANCE        3.5f      // Light distance from world center
+#define         LIGHT_HEIGHT          1.0f      // Light height position
+
+typedef enum {
+    LIGHT_DIRECTIONAL,
+    LIGHT_POINT
+} LightType;
+
+typedef struct {
+    bool enabled;
+    LightType type;
+    Vector3 position;
+    Vector3 target;
+    Color color;
+    int enabledLoc;
+    int typeLoc;
+    int posLoc;
+    int targetLoc;
+    int colorLoc;
+} Light;
+
+int lightsCount = 0;                     // Current amount of created lights
+
+Light CreateLight(int type, Vector3 pos, Vector3 targ, Color color, Shader shader);         // Defines a light and get locations from PBR shader
+void UpdateLightValues(Shader shader, Light light);                                         // Send to PBR shader light values
+
+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 [models] example - pbr material");
+
+    // Define the camera to look into our 3d world
+    Camera camera = {{ 4.0f, 4.0f, 4.0f }, { 0.0f, 0.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
+
+    // Load model and PBR material
+    Model model = LoadModel("resources/pbr/trooper.obj");
+    
+    Texture2D texHDR = LoadTexture("resources/pinetree.hdr");
+    model.material = LoadMaterialPBR(texHDR, (Color){ 255, 255, 255, 255 }, 1.0f, 1.0f);
+    
+    SetMaterialTexture(&model.material, TEXMAP_ALBEDO, LoadTexture("resources/pbr/trooper_albedo.png"));
+    SetMaterialTexture(&model.material, TEXMAP_NORMAL, LoadTexture("resources/pbr/trooper_normals.png"));
+    SetMaterialTexture(&model.material, TEXMAP_METALNESS, LoadTexture("resources/pbr/trooper_metalness.png"));
+    SetMaterialTexture(&model.material, TEXMAP_ROUGHNESS, LoadTexture("resources/pbr/trooper_roughness.png"));
+    SetMaterialTexture(&model.material, TEXMAP_OCCLUSION, LoadTexture("resources/pbr/trooper_ao.png"));
+    
+    // Set textures filtering for better quality
+    SetTextureFilter(model.material.maps[TEXMAP_ALBEDO].tex, FILTER_BILINEAR);
+    SetTextureFilter(model.material.maps[TEXMAP_NORMAL].tex, FILTER_BILINEAR);
+    SetTextureFilter(model.material.maps[TEXMAP_METALNESS].tex, FILTER_BILINEAR);
+    SetTextureFilter(model.material.maps[TEXMAP_ROUGHNESS].tex, FILTER_BILINEAR);
+    SetTextureFilter(model.material.maps[TEXMAP_OCCLUSION].tex, FILTER_BILINEAR);
+    
+    int renderModeLoc = GetShaderLocation(model.material.shader, "renderMode");
+    SetShaderValuei(model.material.shader, renderModeLoc, (int[1]){ 0 }, 1);
+
+    SetCameraMode(camera, CAMERA_ORBITAL);  // Set an orbital camera mode
+    
+    // Define lights attributes
+    Light lights[MAX_LIGHTS] = { CreateLight(LIGHT_POINT, (Vector3){ LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 0, 255 }, model.material.shader),
+    CreateLight(LIGHT_POINT, (Vector3){ 0.0f, LIGHT_HEIGHT, LIGHT_DISTANCE }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 0, 255, 0, 255 }, model.material.shader),
+    CreateLight(LIGHT_POINT, (Vector3){ -LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 0, 0, 255, 255 }, model.material.shader),
+    CreateLight(LIGHT_DIRECTIONAL, (Vector3){ 0.0f, LIGHT_HEIGHT*2.0f, -LIGHT_DISTANCE }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 255, 255 }, model.material.shader) };
+
+    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
+        
+        // Send to material PBR shader camera view position
+        float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z };
+        SetShaderValue(model.material.shader, model.material.shader.locs[LOC_VECTOR_VIEW], cameraPos, 3);
+        //----------------------------------------------------------------------------------
+
+        // Draw
+        //----------------------------------------------------------------------------------
+        BeginDrawing();
+
+            ClearBackground(RAYWHITE);
+
+            Begin3dMode(camera);
+
+                DrawModel(model, VectorZero(), 1.0f, WHITE);
+                
+                DrawGrid(10, 1.0f);
+
+            End3dMode();
+
+            DrawFPS(10, 10);
+
+        EndDrawing();
+        //----------------------------------------------------------------------------------
+    }
+
+    // De-Initialization
+    //--------------------------------------------------------------------------------------
+    UnloadModel(model);         // Unload skybox model
+
+    CloseWindow();              // Close window and OpenGL context
+    //--------------------------------------------------------------------------------------
+
+    return 0;
+}
+
+// Defines a light and get locations from PBR shader
+Light CreateLight(int type, Vector3 pos, Vector3 targ, Color color, Shader shader)
+{
+    Light light = { 0 };
+
+    if (lightsCount < MAX_LIGHTS)
+    {
+        light.enabled = true;
+        light.type = type;
+        light.position = pos;
+        light.target = targ;
+        light.color = color;
+
+        char enabledName[32] = "lights[x].enabled\0";
+        char typeName[32] = "lights[x].type\0";
+        char posName[32] = "lights[x].position\0";
+        char targetName[32] = "lights[x].target\0";
+        char colorName[32] = "lights[x].color\0";
+        enabledName[7] = '0' + lightsCount;
+        typeName[7] = '0' + lightsCount;
+        posName[7] = '0' + lightsCount;
+        targetName[7] = '0' + lightsCount;
+        colorName[7] = '0' + lightsCount;
+
+        light.enabledLoc = GetShaderLocation(shader, enabledName);
+        light.typeLoc = GetShaderLocation(shader, typeName);
+        light.posLoc = GetShaderLocation(shader, posName);
+        light.targetLoc = GetShaderLocation(shader, targetName);
+        light.colorLoc = GetShaderLocation(shader, colorName);
+
+        UpdateLightValues(shader, light);
+        lightsCount++;
+    }
+
+    return light;
+}
+
+// Send to PBR shader light values
+void UpdateLightValues(Shader shader, Light light)
+{
+    // Send to shader light enabled state and type
+    SetShaderValuei(shader, light.enabledLoc, (int[1]){ light.enabled }, 1);
+    SetShaderValuei(shader, light.typeLoc, (int[1]){ light.type }, 1);
+
+    // Send to shader light position values
+    float position[3] = { light.position.x, light.position.y, light.position.z };
+    SetShaderValue(shader, light.posLoc, position, 3);
+
+    // Send to shader light target position values
+    float target[3] = { light.target.x, light.target.y, light.target.z };
+    SetShaderValue(shader, light.targetLoc, target, 3);
+
+    // Send to shader light color values
+    float diff[4] = { (float)light.color.r/(float)255, (float)light.color.g/(float)255, (float)light.color.b/(float)255, (float)light.color.a/(float)255 };
+    SetShaderValue(shader, light.colorLoc, diff, 4);
+}

BIN
examples/models/models_material_pbr.png


+ 89 - 0
examples/models/models_skybox.c

@@ -0,0 +1,89 @@
+/*******************************************************************************************
+*
+*   raylib [models] example - Skybox loading and drawing
+*
+*   This example has been created using raylib 1.8 (www.raylib.com)
+*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+*   Copyright (c) 2017 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+#include "raymath.h"
+
+int main()
+{
+    // Initialization
+    //--------------------------------------------------------------------------------------
+    int screenWidth = 800;
+    int screenHeight = 450;
+
+    InitWindow(screenWidth, screenHeight, "raylib [models] example - skybox loading and drawing");
+
+    // Define the camera to look into our 3d world
+    Camera camera = {{ 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
+
+    // Load skybox model and shader    
+    Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f);
+    Model skybox = LoadModelFromMesh(cube, false);
+    skybox.material.shader = LoadShader("resources/shaders/skybox.vs", "resources/shaders/skybox.fs");
+
+    Texture2D texHDR = LoadTexture("resources/pinetree.hdr");
+    skybox.material.maps[TEXMAP_CUBEMAP].tex = rlGenMapCubemap(texHDR, 512);
+    SetShaderValuei(skybox.material.shader, GetShaderLocation(skybox.material.shader, "environmentMap"), (int[1]){ TEXMAP_CUBEMAP }, 1);
+
+    // Get skybox shader locations
+    skybox.material.shader.locs[LOC_MATRIX_PROJECTION] = GetShaderLocation(skybox.material.shader, "projection");
+    skybox.material.shader.locs[LOC_MATRIX_VIEW] = GetShaderLocation(skybox.material.shader, "view");
+
+    // Then before rendering, configure the viewport to the actual screen dimensions
+    Matrix proj = MatrixPerspective(60.0, (double)GetScreenWidth()/(double)GetScreenHeight(), 0.01, 1000.0);
+    MatrixTranspose(&proj);
+    SetShaderValueMatrix(skybox.material.shader, skybox.material.shader.locs[LOC_MATRIX_PROJECTION], proj);
+
+    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
+        
+        Matrix view = MatrixLookAt(camera.position, camera.target, camera.up);
+        SetShaderValueMatrix(skybox.material.shader, skybox.material.shader.locs[LOC_MATRIX_VIEW], view);
+        //----------------------------------------------------------------------------------
+
+        // Draw
+        //----------------------------------------------------------------------------------
+        BeginDrawing();
+
+            ClearBackground(RAYWHITE);
+
+            Begin3dMode(camera);
+
+                DrawModel(skybox, VectorZero(), 1.0f, RED);
+                
+                DrawGrid(10, 1.0f);
+
+            End3dMode();
+
+            DrawFPS(10, 10);
+
+        EndDrawing();
+        //----------------------------------------------------------------------------------
+    }
+
+    // De-Initialization
+    //--------------------------------------------------------------------------------------
+    UnloadModel(skybox);        // Unload skybox model
+
+    CloseWindow();              // Close window and OpenGL context
+    //--------------------------------------------------------------------------------------
+
+    return 0;
+}

BIN
examples/models/models_skybox.png


+ 1 - 1
examples/shaders/shaders_model_shader.c

@@ -38,7 +38,7 @@ int main()
                                "resources/shaders/glsl330/grayscale.fs");   // Load model shader
                                "resources/shaders/glsl330/grayscale.fs");   // Load model shader
 
 
     dwarf.material.shader = shader;             // Set shader effect to 3d model
     dwarf.material.shader = shader;             // Set shader effect to 3d model
-    dwarf.material.texDiffuse = texture;        // Bind texture to model
+    dwarf.material.maps[TEXMAP_DIFFUSE].tex = texture;        // Bind texture to model
     
     
     Vector3 position = { 0.0f, 0.0f, 0.0f };    // Set model position
     Vector3 position = { 0.0f, 0.0f, 0.0f };    // Set model position
     
     

+ 5 - 5
src/core.c

@@ -809,7 +809,7 @@ void EndDrawing(void)
         {
         {
             // Get image data for the current frame (from backbuffer)
             // Get image data for the current frame (from backbuffer)
             // NOTE: This process is very slow... :(
             // NOTE: This process is very slow... :(
-            unsigned char *screenData = rlglReadScreenPixels(screenWidth, screenHeight);
+            unsigned char *screenData = rlReadScreenPixels(screenWidth, screenHeight);
             GifWriteFrame(screenData, screenWidth, screenHeight, 10, 8, false);
             GifWriteFrame(screenData, screenWidth, screenHeight, 10, 8, false);
             
             
             free(screenData);   // Free image data
             free(screenData);   // Free image data
@@ -994,10 +994,10 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera)
     MatrixTranspose(&matView);
     MatrixTranspose(&matView);
 
 
 //#define USE_RLGL_UNPROJECT
 //#define USE_RLGL_UNPROJECT
-#if defined(USE_RLGL_UNPROJECT)     // OPTION 1: Use rlglUnproject()
+#if defined(USE_RLGL_UNPROJECT)     // OPTION 1: Use rlUnproject()
 
 
-    Vector3 nearPoint = rlglUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 0.0f }, matProj, matView);
-    Vector3 farPoint = rlglUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 1.0f }, matProj, matView);
+    Vector3 nearPoint = rlUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 0.0f }, matProj, matView);
+    Vector3 farPoint = rlUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 1.0f }, matProj, matView);
 
 
 #else   // OPTION 2: Compute unprojection directly here
 #else   // OPTION 2: Compute unprojection directly here
 
 
@@ -1201,7 +1201,7 @@ void SetConfigFlags(char flags)
 void TakeScreenshot(const char *fileName)
 void TakeScreenshot(const char *fileName)
 {
 {
 #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
 #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
-    unsigned char *imgData = rlglReadScreenPixels(renderWidth, renderHeight);
+    unsigned char *imgData = rlReadScreenPixels(renderWidth, renderHeight);
     SavePNG(fileName, imgData, renderWidth, renderHeight, 4); // Save image as PNG
     SavePNG(fileName, imgData, renderWidth, renderHeight, 4); // Save image as PNG
     free(imgData);
     free(imgData);
 
 

+ 396 - 139
src/models.c

@@ -76,9 +76,6 @@ static Mesh LoadOBJ(const char *fileName);      // Load OBJ mesh data
 static Material LoadMTL(const char *fileName);  // Load MTL material data
 static Material LoadMTL(const char *fileName);  // Load MTL material data
 #endif
 #endif
 
 
-static Mesh GenMeshHeightmap(Image image, Vector3 size);
-static Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);
-
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 // Module Functions Definition
 // Module Functions Definition
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
@@ -587,110 +584,32 @@ void DrawGizmo(Vector3 position)
     rlPopMatrix();
     rlPopMatrix();
 }
 }
 
 
-// Load mesh from file
-Mesh LoadMesh(const char *fileName)
-{
-    Mesh mesh = { 0 };
-
-#if defined(SUPPORT_FILEFORMAT_OBJ)
-    if (IsFileExtension(fileName, ".obj")) mesh = LoadOBJ(fileName);
-#else
-    TraceLog(LOG_WARNING, "[%s] Mesh fileformat not supported, it can't be loaded", fileName);
-#endif
-
-    if (mesh.vertexCount == 0) TraceLog(LOG_WARNING, "Mesh could not be loaded");
-    else rlglLoadMesh(&mesh, false);  // Upload vertex data to GPU (static mesh)
-
-    // TODO: Initialize default mesh data in case loading fails, maybe a cube?
-
-    return mesh;
-}
-
-// Load mesh from vertex data
-// NOTE: All vertex data arrays must be same size: vertexCount
-Mesh LoadMeshEx(int vertexCount, float *vData, float *vtData, float *vnData, Color *cData)
-{
-    Mesh mesh = { 0 };
-
-    mesh.vertexCount = vertexCount;
-    mesh.triangleCount = vertexCount/3;
-    mesh.vertices = vData;
-    mesh.texcoords = vtData;
-    mesh.texcoords2 = NULL;
-    mesh.normals = vnData;
-    mesh.tangents = NULL;
-    mesh.colors = (unsigned char *)cData;
-    mesh.indices = NULL;
-
-    rlglLoadMesh(&mesh, false);     // Upload vertex data to GPU (static mesh)
-
-    return mesh;
-}
-
-// Load model from file
+// Load model from files (mesh and material)
 Model LoadModel(const char *fileName)
 Model LoadModel(const char *fileName)
 {
 {
     Model model = { 0 };
     Model model = { 0 };
 
 
     model.mesh = LoadMesh(fileName);
     model.mesh = LoadMesh(fileName);
     model.transform = MatrixIdentity();
     model.transform = MatrixIdentity();
-    model.material = LoadDefaultMaterial();
-
-    return model;
-}
-
-// Load model from mesh data
-Model LoadModelFromMesh(Mesh data, bool dynamic)
-{
-    Model model = { 0 };
-
-    model.mesh = data;
-
-    rlglLoadMesh(&model.mesh, dynamic);  // Upload vertex data to GPU
-
-    model.transform = MatrixIdentity();
-    model.material = LoadDefaultMaterial();
+    model.material = LoadMaterialDefault();
 
 
     return model;
     return model;
 }
 }
 
 
-// Load heightmap model from image data
-// NOTE: model map size is defined in generic units
-Model LoadHeightmap(Image heightmap, Vector3 size)
+// Load model from generated mesh
+Model LoadModelFromMesh(Mesh mesh, bool dynamic)
 {
 {
     Model model = { 0 };
     Model model = { 0 };
-
-    model.mesh = GenMeshHeightmap(heightmap, size);
-
-    rlglLoadMesh(&model.mesh, false);  // Upload vertex data to GPU (static model)
-
-    model.transform = MatrixIdentity();
-    model.material = LoadDefaultMaterial();
-
-    return model;
-}
-
-// Load cubes-based map model from image data
-Model LoadCubicmap(Image cubicmap)
-{
-    Model model = { 0 };
-
-    model.mesh = GenMeshCubicmap(cubicmap, (Vector3){ 1.0f, 1.5f, 1.0f });
-
-    rlglLoadMesh(&model.mesh, false);  // Upload vertex data to GPU (static model)
-
+    
+    rlLoadMesh(&mesh, dynamic);
+    
+    model.mesh = mesh;
     model.transform = MatrixIdentity();
     model.transform = MatrixIdentity();
-    model.material = LoadDefaultMaterial();
+    model.material = LoadMaterialDefault();
 
 
     return model;
     return model;
 }
 }
 
 
-// Unload mesh from memory (RAM and/or VRAM)
-void UnloadMesh(Mesh *mesh)
-{
-    rlglUnloadMesh(mesh);
-}
-
 // Unload model from memory (RAM and/or VRAM)
 // Unload model from memory (RAM and/or VRAM)
 void UnloadModel(Model model)
 void UnloadModel(Model model)
 {
 {
@@ -700,49 +619,190 @@ void UnloadModel(Model model)
     TraceLog(LOG_INFO, "Unloaded model data (mesh and material) from RAM and VRAM");
     TraceLog(LOG_INFO, "Unloaded model data (mesh and material) from RAM and VRAM");
 }
 }
 
 
-// Load material data (from file)
-Material LoadMaterial(const char *fileName)
+// Load mesh from file
+Mesh LoadMesh(const char *fileName)
 {
 {
-    Material material = { 0 };
+    Mesh mesh = { 0 };
 
 
-#if defined(SUPPORT_FILEFORMAT_MTL)
-    if (IsFileExtension(fileName, ".mtl")) material = LoadMTL(fileName);
+#if defined(SUPPORT_FILEFORMAT_OBJ)
+    if (IsFileExtension(fileName, ".obj")) mesh = LoadOBJ(fileName);
 #else
 #else
-    TraceLog(LOG_WARNING, "[%s] Material fileformat not supported, it can't be loaded", fileName);
+    TraceLog(WARNING, "[%s] Mesh fileformat not supported, it can't be loaded", fileName);
 #endif
 #endif
 
 
-    return material;
-}
-
-// Load default material (uses default models shader)
-Material LoadDefaultMaterial(void)
-{
-    Material material = { 0 };
+    if (mesh.vertexCount == 0) TraceLog(WARNING, "Mesh could not be loaded");
+    else rlLoadMesh(&mesh, false);  // Upload vertex data to GPU (static mesh)
 
 
-    material.shader = GetDefaultShader();
-    material.texDiffuse = GetDefaultTexture();      // White texture (1x1 pixel)
-    //material.texNormal;           // NOTE: By default, not set
-    //material.texSpecular;         // NOTE: By default, not set
-
-    material.colDiffuse = WHITE;    // Diffuse color
-    material.colAmbient = WHITE;    // Ambient color
-    material.colSpecular = WHITE;   // Specular color
+    // TODO: Initialize default mesh data in case loading fails, maybe a cube?
 
 
-    material.glossiness = 100.0f;   // Glossiness level
+    return mesh;
+}
 
 
-    return material;
+// Unload mesh from memory (RAM and/or VRAM)
+void UnloadMesh(Mesh *mesh)
+{
+    rlUnloadMesh(mesh);
 }
 }
 
 
-// Unload material from memory
-void UnloadMaterial(Material material)
+// Generated cuboid mesh
+Mesh GenMeshCube(float width, float height, float length)
 {
 {
-    rlDeleteTextures(material.texDiffuse.id);
-    rlDeleteTextures(material.texNormal.id);
-    rlDeleteTextures(material.texSpecular.id);
+    Mesh mesh = { 0 };
+    /*
+    float vertices[] = {
+            -1.0f, -1.0f, -1.0f,  0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
+            1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
+            1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
+            1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
+            -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
+            -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
+            -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
+            1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
+            1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
+            1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
+            -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
+            -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
+            -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
+            -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
+            -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+            -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+            -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+            -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
+            1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
+            1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+            1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
+            1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+            1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
+            1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+            -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
+            1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
+            1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
+            1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
+            -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
+            -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
+            -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
+            1.0f, 1.0f , 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
+            1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+            1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
+            -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
+            -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f
+        };
+    */
+    float vertices[] = {
+        -width/2, -height/2, length/2,
+        width/2, -height/2, length/2,
+        width/2, height/2, length/2,
+        -width/2, height/2, length/2,
+        -width/2, -height/2, -length/2,
+        -width/2, height/2, -length/2,
+        width/2, height/2, -length/2,
+        width/2, -height/2, -length/2,
+        -width/2, height/2, -length/2,
+        -width/2, height/2, length/2,
+        width/2, height/2, length/2,
+        width/2, height/2, -length/2,
+        -width/2, -height/2, -length/2,
+        width/2, -height/2, -length/2,
+        width/2, -height/2, length/2,
+        -width/2, -height/2, length/2,
+        width/2, -height/2, -length/2,
+        width/2, height/2, -length/2,
+        width/2, height/2, length/2,
+        width/2, -height/2, length/2,
+        -width/2, -height/2, -length/2,
+        -width/2, -height/2, length/2,
+        -width/2, height/2, length/2,
+        -width/2, height/2, -length/2
+    };
+    
+    float texcoords[] = {
+        0.0f, 0.0f,
+        1.0f, 0.0f,
+        1.0f, 1.0f,
+        0.0f, 1.0f,
+        1.0f, 0.0f,
+        1.0f, 1.0f,
+        0.0f, 1.0f,
+        0.0f, 0.0f,
+        0.0f, 1.0f,
+        0.0f, 0.0f,
+        1.0f, 0.0f,
+        1.0f, 1.0f,
+        1.0f, 1.0f,
+        0.0f, 1.0f,
+        0.0f, 0.0f,
+        1.0f, 0.0f,
+        1.0f, 0.0f,
+        1.0f, 1.0f,
+        0.0f, 1.0f,
+        0.0f, 0.0f,
+        0.0f, 0.0f,
+        1.0f, 0.0f,
+        1.0f, 1.0f,
+        0.0f, 1.0f
+    };
+    
+    float normals[] = {
+        0.0f, 0.0f, 1.0f,
+        0.0f, 0.0f, 1.0f,
+        0.0f, 0.0f, 1.0f,
+        0.0f, 0.0f, 1.0f,
+        0.0f, 0.0f,-1.0f,
+        0.0f, 0.0f,-1.0f,
+        0.0f, 0.0f,-1.0f,
+        0.0f, 0.0f,-1.0f,
+        0.0f, 1.0f, 0.0f,
+        0.0f, 1.0f, 0.0f,
+        0.0f, 1.0f, 0.0f,
+        0.0f, 1.0f, 0.0f,
+        0.0f,-1.0f, 0.0f,
+        0.0f,-1.0f, 0.0f,
+        0.0f,-1.0f, 0.0f,
+        0.0f,-1.0f, 0.0f,
+        1.0f, 0.0f, 0.0f,
+        1.0f, 0.0f, 0.0f,
+        1.0f, 0.0f, 0.0f,
+        1.0f, 0.0f, 0.0f,
+        -1.0f, 0.0f, 0.0f,
+        -1.0f, 0.0f, 0.0f,
+        -1.0f, 0.0f, 0.0f,
+        -1.0f, 0.0f, 0.0f
+    };
+
+    mesh.vertices = (float *)malloc(24*3*sizeof(float));
+    memcpy(mesh.vertices, vertices, 24*3*sizeof(float));
+    
+    mesh.texcoords = (float *)malloc(24*2*sizeof(float));
+    memcpy(mesh.texcoords, texcoords, 24*2*sizeof(float));
+    
+    mesh.normals = (float *)malloc(24*3*sizeof(float));
+    memcpy(mesh.normals, normals, 24*3*sizeof(float));
+    
+    mesh.indices = (unsigned short *)malloc(36*sizeof(unsigned short));
+    
+    int k = 0;
+
+    // Indices can be initialized right now
+    for (int i = 0; i < 36; i+=6)
+    {
+        mesh.indices[i] = 4*k;
+        mesh.indices[i+1] = 4*k+1;
+        mesh.indices[i+2] = 4*k+2;
+        mesh.indices[i+3] = 4*k;
+        mesh.indices[i+4] = 4*k+2;
+        mesh.indices[i+5] = 4*k+3;
+
+        k++;
+    }
+    
+    mesh.vertexCount = 24;
+    mesh.triangleCount = 12;
+
+    return mesh;
 }
 }
 
 
 // Generate a mesh from heightmap
 // Generate a mesh from heightmap
-static Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
+Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
 {
 {
     #define GRAY_VALUE(c) ((c.r+c.g+c.b)/3)
     #define GRAY_VALUE(c) ((c.r+c.g+c.b)/3)
 
 
@@ -847,7 +907,7 @@ static Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
     return mesh;
     return mesh;
 }
 }
 
 
-static Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
+Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
 {
 {
     Mesh mesh = { 0 };
     Mesh mesh = { 0 };
 
 
@@ -1201,6 +1261,202 @@ static Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
     return mesh;
     return mesh;
 }
 }
 
 
+// Load material data (from file)
+Material LoadMaterial(const char *fileName)
+{
+    Material material = { 0 };
+
+#if defined(SUPPORT_FILEFORMAT_MTL)
+    if (IsFileExtension(fileName, ".mtl")) material = LoadMTL(fileName);
+#else
+    TraceLog(WARNING, "[%s] Material fileformat not supported, it can't be loaded", fileName);
+#endif
+
+    return material;
+}
+
+// Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
+Material LoadMaterialDefault(void)
+{
+    Material material = { 0 };
+
+    material.shader = GetShaderDefault();
+    material.maps[TEXMAP_DIFFUSE].tex = GetTextureDefault();   // White texture (1x1 pixel)
+    //material.maps[TEXMAP_NORMAL].tex;           // NOTE: By default, not set
+    //material.maps[TEXMAP_SPECULAR].tex;         // NOTE: By default, not set
+
+    material.maps[TEXMAP_DIFFUSE].color = WHITE;    // Diffuse color
+    material.maps[TEXMAP_SPECULAR].color = WHITE;   // Specular color
+
+    return material;
+}
+
+// Load PBR material (Supports: ALBEDO, NORMAL, METALNESS, ROUGHNESS, AO, EMMISIVE, HEIGHT maps)
+Material LoadMaterialPBR(Texture2D hdr, Color albedo, float metalness, float roughness)
+{
+    Material mat = { 0 };
+    
+    #define     PATH_PBR_VS     "resources/shaders/pbr.vs"              // Path to physically based rendering vertex shader
+    #define     PATH_PBR_FS     "resources/shaders/pbr.fs"              // Path to physically based rendering fragment shader
+   
+    mat.shader = LoadShader(PATH_PBR_VS, PATH_PBR_FS);
+    
+    // Get required locations points for PBR material
+    // NOTE: Those location names must be available and used in the shader code
+    mat.shader.locs[LOC_TEXMAP_ALBEDO] = GetShaderLocation(mat.shader, "albedo.sampler");
+    mat.shader.locs[LOC_TEXMAP_METALNESS] = GetShaderLocation(mat.shader, "metalness.sampler");
+    mat.shader.locs[LOC_TEXMAP_NORMAL] = GetShaderLocation(mat.shader, "normals.sampler");
+    mat.shader.locs[LOC_TEXMAP_ROUGHNESS] = GetShaderLocation(mat.shader, "roughness.sampler");
+    mat.shader.locs[LOC_TEXMAP_OCCUSION] = GetShaderLocation(mat.shader, "occlusion.sampler");
+    mat.shader.locs[LOC_TEXMAP_EMISSION] = GetShaderLocation(mat.shader, "emission.sampler");
+    mat.shader.locs[LOC_TEXMAP_HEIGHT] = GetShaderLocation(mat.shader, "height.sampler");
+    mat.shader.locs[LOC_TEXMAP_IRRADIANCE] = GetShaderLocation(mat.shader, "irradianceMap");
+    mat.shader.locs[LOC_TEXMAP_PREFILTER] = GetShaderLocation(mat.shader, "prefilterMap");
+    mat.shader.locs[LOC_TEXMAP_BRDF] = GetShaderLocation(mat.shader, "brdfLUT");
+
+    // Set view matrix location
+    mat.shader.locs[LOC_MATRIX_MODEL] = GetShaderLocation(mat.shader, "mMatrix");
+    mat.shader.locs[LOC_MATRIX_VIEW] = GetShaderLocation(mat.shader, "view");
+    mat.shader.locs[LOC_VECTOR_VIEW] = GetShaderLocation(mat.shader, "viewPos");
+
+    // Set up material properties color
+    mat.maps[TEXMAP_ALBEDO].color = albedo;
+    mat.maps[TEXMAP_NORMAL].color = (Color){ 128, 128, 255, 255 };
+    mat.maps[TEXMAP_METALNESS].value = metalness;
+    mat.maps[TEXMAP_ROUGHNESS].value = roughness;
+    mat.maps[TEXMAP_OCCLUSION].value = 1.0f;
+    mat.maps[TEXMAP_EMISSION].value = 0.0f;
+    mat.maps[TEXMAP_HEIGHT].value = 0.0f;
+    
+    #define CUBEMAP_SIZE        1024        // Cubemap texture size
+    #define IRRADIANCE_SIZE       32        // Irradiance map from cubemap texture size
+    #define PREFILTERED_SIZE     256        // Prefiltered HDR environment map texture size
+    #define BRDF_SIZE            512        // BRDF LUT texture map size
+
+    // Set up environment materials cubemap
+    Texture2D cubemap = rlGenMapCubemap(hdr, CUBEMAP_SIZE);
+    mat.maps[TEXMAP_IRRADIANCE].tex = rlGenMapIrradiance(cubemap, IRRADIANCE_SIZE);
+    mat.maps[TEXMAP_PREFILTER].tex = rlGenMapPrefilter(cubemap, PREFILTERED_SIZE);
+    mat.maps[TEXMAP_BRDF].tex = rlGenMapBRDF(cubemap, BRDF_SIZE);
+    UnloadTexture(cubemap);
+    
+    // NOTE: All maps textures are set to { 0 }
+    
+    // Reset viewport dimensions to default
+    rlViewport(0, 0, GetScreenWidth(), GetScreenHeight());
+
+    return mat;
+}
+
+// Unload material from memory
+void UnloadMaterial(Material material)
+{
+    // Unload material shader
+    UnloadShader(material.shader);
+
+    // Unload loaded texture maps
+    for (int i = 0; i < MAX_MATERIAL_TEXTURE_MAPS; i++)
+    {
+        // NOTE: We already check for (tex.id > 0) inside function
+        rlDeleteTextures(material.maps[i].tex.id); 
+    }
+}
+
+// Set material texture
+void SetMaterialTexture(Material *mat, int texmapType, Texture2D texture)
+{
+    mat->maps[texmapType].tex = texture;
+
+    // Update MaterialProperty use sampler state to use texture fetch instead of color attribute
+    int location = -1;
+    switch (texmapType)
+    {
+        case TEXMAP_ALBEDO:
+        {
+            location = GetShaderLocation(mat->shader, "albedo.useSampler");
+            SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
+        } break;
+        case TEXMAP_NORMAL:
+        {
+            location = GetShaderLocation(mat->shader, "normals.useSampler");
+            SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
+        } break;
+        case TEXMAP_METALNESS:
+        {
+            location = GetShaderLocation(mat->shader, "metalness.useSampler");
+            SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
+        } break;
+        case TEXMAP_ROUGHNESS:
+        {
+            location = GetShaderLocation(mat->shader, "roughness.useSampler");
+            SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
+        } break;
+        case TEXMAP_OCCLUSION:
+        {
+            location = GetShaderLocation(mat->shader, "occlusion.useSampler");
+            SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
+        } break;
+        case TEXMAP_EMISSION:
+        {
+            location = GetShaderLocation(mat->shader, "emission.useSampler");
+            SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
+        } break;
+        case TEXMAP_HEIGHT:
+        {
+            location = GetShaderLocation(mat->shader, "height.useSampler");
+            SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
+        } break;
+    }
+}
+
+// Unset texture from material and unload it from GPU
+void UnsetMaterialTexture(Material *mat, int texmapType)
+{
+    UnloadTexture(mat->maps[texmapType].tex);
+    mat->maps[texmapType].tex = (Texture2D){ 0 };
+
+    // Update MaterialProperty use sampler state to use texture fetch instead of color attribute
+    int location = -1;
+    switch (texmapType)
+    {
+        case TEXMAP_ALBEDO:
+        {
+            location = GetShaderLocation(mat->shader, "albedo.useSampler");
+            SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
+        } break;
+        case TEXMAP_NORMAL:
+        {
+            location = GetShaderLocation(mat->shader, "normals.useSampler");
+            SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
+        } break;
+        case TEXMAP_METALNESS:
+        {
+            location = GetShaderLocation(mat->shader, "metalness.useSampler");
+            SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
+        } break;
+        case TEXMAP_ROUGHNESS:
+        {
+            location = GetShaderLocation(mat->shader, "roughness.useSampler");
+            SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
+        } break;
+        case TEXMAP_OCCLUSION:
+        {
+            location = GetShaderLocation(mat->shader, "occlusion.useSampler");
+            SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
+        } break;
+        case TEXMAP_EMISSION:
+        {
+            location = GetShaderLocation(mat->shader, "emission.useSampler");
+            SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
+        } break;
+        case TEXMAP_HEIGHT:
+        {
+            location = GetShaderLocation(mat->shader, "height.useSampler");
+            SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
+        } break;
+    }
+}
+
 // Draw a model (with texture if set)
 // Draw a model (with texture if set)
 void DrawModel(Model model, Vector3 position, float scale, Color tint)
 void DrawModel(Model model, Vector3 position, float scale, Color tint)
 {
 {
@@ -1225,9 +1481,9 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
     //Matrix matModel = MatrixMultiply(model.transform, matTransform);    // Transform to world-space coordinates
     //Matrix matModel = MatrixMultiply(model.transform, matTransform);    // Transform to world-space coordinates
 
 
     model.transform = MatrixMultiply(model.transform, matTransform);
     model.transform = MatrixMultiply(model.transform, matTransform);
-    model.material.colDiffuse = tint;       // TODO: Multiply tint color by diffuse color?
+    model.material.maps[TEXMAP_DIFFUSE].color = tint;       // TODO: Multiply tint color by diffuse color?
 
 
-    rlglDrawMesh(model.mesh, model.material, model.transform);
+    rlDrawMesh(model.mesh, model.material, model.transform);
 }
 }
 
 
 // Draw a model wires (with texture if set)
 // Draw a model wires (with texture if set)
@@ -1980,23 +2236,24 @@ static Material LoadMTL(const char *fileName)
                     case 'a':   // Ka float float float    Ambient color (RGB)
                     case 'a':   // Ka float float float    Ambient color (RGB)
                     {
                     {
                         sscanf(buffer, "Ka %f %f %f", &color.x, &color.y, &color.z);
                         sscanf(buffer, "Ka %f %f %f", &color.x, &color.y, &color.z);
-                        material.colAmbient.r = (unsigned char)(color.x*255);
-                        material.colAmbient.g = (unsigned char)(color.y*255);
-                        material.colAmbient.b = (unsigned char)(color.z*255);
+                        // TODO: Support ambient color
+                        //material.colAmbient.r = (unsigned char)(color.x*255);
+                        //material.colAmbient.g = (unsigned char)(color.y*255);
+                        //material.colAmbient.b = (unsigned char)(color.z*255);
                     } break;
                     } break;
                     case 'd':   // Kd float float float     Diffuse color (RGB)
                     case 'd':   // Kd float float float     Diffuse color (RGB)
                     {
                     {
                         sscanf(buffer, "Kd %f %f %f", &color.x, &color.y, &color.z);
                         sscanf(buffer, "Kd %f %f %f", &color.x, &color.y, &color.z);
-                        material.colDiffuse.r = (unsigned char)(color.x*255);
-                        material.colDiffuse.g = (unsigned char)(color.y*255);
-                        material.colDiffuse.b = (unsigned char)(color.z*255);
+                        material.maps[TEXMAP_DIFFUSE].color.r = (unsigned char)(color.x*255);
+                        material.maps[TEXMAP_DIFFUSE].color.g = (unsigned char)(color.y*255);
+                        material.maps[TEXMAP_DIFFUSE].color.b = (unsigned char)(color.z*255);
                     } break;
                     } break;
                     case 's':   // Ks float float float     Specular color (RGB)
                     case 's':   // Ks float float float     Specular color (RGB)
                     {
                     {
                         sscanf(buffer, "Ks %f %f %f", &color.x, &color.y, &color.z);
                         sscanf(buffer, "Ks %f %f %f", &color.x, &color.y, &color.z);
-                        material.colSpecular.r = (unsigned char)(color.x*255);
-                        material.colSpecular.g = (unsigned char)(color.y*255);
-                        material.colSpecular.b = (unsigned char)(color.z*255);
+                        material.maps[TEXMAP_SPECULAR].color.r = (unsigned char)(color.x*255);
+                        material.maps[TEXMAP_SPECULAR].color.g = (unsigned char)(color.y*255);
+                        material.maps[TEXMAP_SPECULAR].color.b = (unsigned char)(color.z*255);
                     } break;
                     } break;
                     case 'e':   // Ke float float float     Emmisive color (RGB)
                     case 'e':   // Ke float float float     Emmisive color (RGB)
                     {
                     {
@@ -2012,7 +2269,7 @@ static Material LoadMTL(const char *fileName)
                     int shininess = 0;
                     int shininess = 0;
                     sscanf(buffer, "Ns %i", &shininess);
                     sscanf(buffer, "Ns %i", &shininess);
 
 
-                    material.glossiness = (float)shininess;
+                    //material.params[PARAM_GLOSSINES] = (float)shininess;
                 }
                 }
                 else if (buffer[1] == 'i')  // Ni int   Refraction index.
                 else if (buffer[1] == 'i')  // Ni int   Refraction index.
                 {
                 {
@@ -2028,12 +2285,12 @@ static Material LoadMTL(const char *fileName)
                         if (buffer[5] == 'd')       // map_Kd string    Diffuse color texture map.
                         if (buffer[5] == 'd')       // map_Kd string    Diffuse color texture map.
                         {
                         {
                             result = sscanf(buffer, "map_Kd %s", mapFileName);
                             result = sscanf(buffer, "map_Kd %s", mapFileName);
-                            if (result != EOF) material.texDiffuse = LoadTexture(mapFileName);
+                            if (result != EOF) material.maps[TEXMAP_DIFFUSE].tex = LoadTexture(mapFileName);
                         }
                         }
                         else if (buffer[5] == 's')  // map_Ks string    Specular color texture map.
                         else if (buffer[5] == 's')  // map_Ks string    Specular color texture map.
                         {
                         {
                             result = sscanf(buffer, "map_Ks %s", mapFileName);
                             result = sscanf(buffer, "map_Ks %s", mapFileName);
-                            if (result != EOF) material.texSpecular = LoadTexture(mapFileName);
+                            if (result != EOF) material.maps[TEXMAP_SPECULAR].tex = LoadTexture(mapFileName);
                         }
                         }
                         else if (buffer[5] == 'a')  // map_Ka string    Ambient color texture map.
                         else if (buffer[5] == 'a')  // map_Ka string    Ambient color texture map.
                         {
                         {
@@ -2043,12 +2300,12 @@ static Material LoadMTL(const char *fileName)
                     case 'B':       // map_Bump string      Bump texture map.
                     case 'B':       // map_Bump string      Bump texture map.
                     {
                     {
                         result = sscanf(buffer, "map_Bump %s", mapFileName);
                         result = sscanf(buffer, "map_Bump %s", mapFileName);
-                        if (result != EOF) material.texNormal = LoadTexture(mapFileName);
+                        if (result != EOF) material.maps[TEXMAP_NORMAL].tex = LoadTexture(mapFileName);
                     } break;
                     } break;
                     case 'b':       // map_bump string      Bump texture map.
                     case 'b':       // map_bump string      Bump texture map.
                     {
                     {
                         result = sscanf(buffer, "map_bump %s", mapFileName);
                         result = sscanf(buffer, "map_bump %s", mapFileName);
-                        if (result != EOF) material.texNormal = LoadTexture(mapFileName);
+                        if (result != EOF) material.maps[TEXMAP_NORMAL].tex = LoadTexture(mapFileName);
                     } break;
                     } break;
                     case 'd':       // map_d string         Opacity texture map.
                     case 'd':       // map_d string         Opacity texture map.
                     {
                     {
@@ -2063,7 +2320,7 @@ static Material LoadMTL(const char *fileName)
                 {
                 {
                     float alpha = 1.0f;
                     float alpha = 1.0f;
                     sscanf(buffer, "d %f", &alpha);
                     sscanf(buffer, "d %f", &alpha);
-                    material.colDiffuse.a = (unsigned char)(alpha*255);
+                    material.maps[TEXMAP_DIFFUSE].color.a = (unsigned char)(alpha*255);
                 }
                 }
                 else if (buffer[1] == 'i')  // disp string  Displacement map
                 else if (buffer[1] == 'i')  // disp string  Displacement map
                 {
                 {
@@ -2073,13 +2330,13 @@ static Material LoadMTL(const char *fileName)
             case 'b':   // bump string      Bump texture map
             case 'b':   // bump string      Bump texture map
             {
             {
                 result = sscanf(buffer, "bump %s", mapFileName);
                 result = sscanf(buffer, "bump %s", mapFileName);
-                if (result != EOF) material.texNormal = LoadTexture(mapFileName);
+                if (result != EOF) material.maps[TEXMAP_NORMAL].tex = LoadTexture(mapFileName);
             } break;
             } break;
             case 'T':   // Tr float         Transparency Tr (alpha). Tr is inverse of d
             case 'T':   // Tr float         Transparency Tr (alpha). Tr is inverse of d
             {
             {
                 float ialpha = 0.0f;
                 float ialpha = 0.0f;
                 sscanf(buffer, "Tr %f", &ialpha);
                 sscanf(buffer, "Tr %f", &ialpha);
-                material.colDiffuse.a = (unsigned char)((1.0f - ialpha)*255);
+                material.maps[TEXMAP_DIFFUSE].color.a = (unsigned char)((1.0f - ialpha)*255);
 
 
             } break;
             } break;
             case 'r':   // refl string      Reflection texture map
             case 'r':   // refl string      Reflection texture map

+ 84 - 41
src/raylib.h

@@ -291,6 +291,11 @@
 #define MAGENTA    CLITERAL{ 255, 0, 255, 255 }     // Magenta
 #define MAGENTA    CLITERAL{ 255, 0, 255, 255 }     // Magenta
 #define RAYWHITE   CLITERAL{ 245, 245, 245, 255 }   // My own White (raylib logo)
 #define RAYWHITE   CLITERAL{ 245, 245, 245, 255 }   // My own White (raylib logo)
 
 
+// Shader and material limits
+#define MAX_SHADER_LOCATIONS        32
+#define MAX_MATERIAL_TEXTURE_MAPS   12
+#define MAX_MATERIAL_PARAMS          8
+
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 // Structures Definition
 // Structures Definition
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
@@ -420,43 +425,24 @@ typedef struct Mesh {
     unsigned int vboId[7];  // OpenGL Vertex Buffer Objects id (7 types of vertex data)
     unsigned int vboId[7];  // OpenGL Vertex Buffer Objects id (7 types of vertex data)
 } Mesh;
 } Mesh;
 
 
-// Shader type (generic shader)
+// Shader type (generic)
 typedef struct Shader {
 typedef struct Shader {
     unsigned int id;        // Shader program id
     unsigned int id;        // Shader program id
-
-    // Vertex attributes locations (default locations)
-    int vertexLoc;          // Vertex attribute location point    (default-location = 0)
-    int texcoordLoc;        // Texcoord attribute location point  (default-location = 1)
-    int texcoord2Loc;       // Texcoord2 attribute location point (default-location = 5)
-    int normalLoc;          // Normal attribute location point    (default-location = 2)
-    int tangentLoc;         // Tangent attribute location point   (default-location = 4)
-    int colorLoc;           // Color attibute location point      (default-location = 3)
-
-    // Uniform locations
-    int mvpLoc;             // ModelView-Projection matrix uniform location point (vertex shader)
-    int colDiffuseLoc;      // Diffuse color uniform location point (fragment shader)
-    int colAmbientLoc;      // Ambient color uniform location point (fragment shader)
-    int colSpecularLoc;     // Specular color uniform location point (fragment shader)
-
-    // Texture map locations (generic for any kind of map)
-    int mapTexture0Loc;     // Map texture uniform location point (default-texture-unit = 0)
-    int mapTexture1Loc;     // Map texture uniform location point (default-texture-unit = 1)
-    int mapTexture2Loc;     // Map texture uniform location point (default-texture-unit = 2)
+    int locs[MAX_SHADER_LOCATIONS];             // Initialized on LoadShader(), set to MAX_SHADER_LOCATIONS
 } Shader;
 } Shader;
 
 
-// Material type
-typedef struct Material {
-    Shader shader;          // Standard shader (supports 3 map textures)
-
-    Texture2D texDiffuse;   // Diffuse texture  (binded to shader mapTexture0Loc)
-    Texture2D texNormal;    // Normal texture   (binded to shader mapTexture1Loc)
-    Texture2D texSpecular;  // Specular texture (binded to shader mapTexture2Loc)
+// Material texture map
+typedef struct TextureMap {
+    Texture2D tex;
+    Color color;
+    float value;
+} TextureMap;
 
 
-    Color colDiffuse;       // Diffuse color
-    Color colAmbient;       // Ambient color
-    Color colSpecular;      // Specular color
-
-    float glossiness;       // Glossiness level (Ranges from 0 to 1000)
+// Material type (generic)
+typedef struct Material {
+    Shader shader;
+    TextureMap maps[MAX_MATERIAL_TEXTURE_MAPS]; // Initialized on LoadMaterial*(), set to MAX_MATERIAL_TEXTURE_MAPS
+    float *params;          // Initialized on LoadMaterial*(), set to MAX_MATERIAL_PARAMS
 } Material;
 } Material;
 
 
 // Model type
 // Model type
@@ -540,6 +526,54 @@ typedef enum {
     LOG_OTHER 
     LOG_OTHER 
 } LogType;
 } LogType;
 
 
+typedef enum {
+    LOC_VERTEX_POSITION = 0,
+    LOC_VERTEX_TEXCOORD01,
+    LOC_VERTEX_TEXCOORD02,
+    LOC_VERTEX_NORMAL,
+    LOC_VERTEX_TANGENT,
+    LOC_VERTEX_COLOR,
+    LOC_MATRIX_MVP,
+    LOC_MATRIX_MODEL,
+    LOC_MATRIX_VIEW,
+    LOC_MATRIX_PROJECTION,
+    LOC_VECTOR_VIEW,
+    LOC_COLOR_DIFFUSE,
+    LOC_COLOR_SPECULAR,
+    LOC_COLOR_AMBIENT,
+    LOC_TEXMAP_ALBEDO,          // LOC_TEXMAP_DIFFUSE
+    LOC_TEXMAP_METALNESS,       // LOC_TEXMAP_SPECULAR
+    LOC_TEXMAP_NORMAL,
+    LOC_TEXMAP_ROUGHNESS,
+    LOC_TEXMAP_OCCUSION,
+    LOC_TEXMAP_EMISSION,
+    LOC_TEXMAP_HEIGHT,
+    LOC_TEXMAP_CUBEMAP,
+    LOC_TEXMAP_IRRADIANCE,
+    LOC_TEXMAP_PREFILTER,
+    LOC_TEXMAP_BRDF
+} ShaderLocationIndex;
+
+#define LOC_TEXMAP_DIFFUSE      LOC_TEXMAP_ALBEDO
+#define LOC_TEXMAP_SPECULAR     LOC_TEXMAP_METALNESS
+
+typedef enum {
+    TEXMAP_ALBEDO    = 0,       // TEXMAP_DIFFUSE
+    TEXMAP_METALNESS = 1,       // TEXMAP_SPECULAR
+    TEXMAP_NORMAL    = 2,
+    TEXMAP_ROUGHNESS = 3,
+    TEXMAP_OCCLUSION,
+    TEXMAP_EMISSION,
+    TEXMAP_HEIGHT,
+    TEXMAP_CUBEMAP,             // NOTE: Uses GL_TEXTURE_CUBE_MAP
+    TEXMAP_IRRADIANCE,          // NOTE: Uses GL_TEXTURE_CUBE_MAP
+    TEXMAP_PREFILTER,           // NOTE: Uses GL_TEXTURE_CUBE_MAP
+    TEXMAP_BRDF
+} TexmapIndex;
+
+#define TEXMAP_DIFFUSE      TEXMAP_ALBEDO
+#define TEXMAP_SPECULAR     TEXMAP_METALNESS
+
 // Texture formats
 // Texture formats
 // NOTE: Support depends on OpenGL version and platform
 // NOTE: Support depends on OpenGL version and platform
 typedef enum {
 typedef enum {
@@ -944,19 +978,26 @@ RLAPI void DrawGizmo(Vector3 position);
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
 
 
 // Model loading/unloading functions
 // Model loading/unloading functions
+RLAPI Model LoadModel(const char *fileName);                                                            // Load model from files (mesh and material)
+RLAPI Model LoadModelFromMesh(Mesh mesh, bool dynamic);                                                // Load model from generated mesh
+RLAPI void UnloadModel(Model model);                                                                    // Unload model from memory (RAM and/or VRAM)
+
+// Mesh loading/unloading functions
 RLAPI Mesh LoadMesh(const char *fileName);                                                              // Load mesh from file
 RLAPI Mesh LoadMesh(const char *fileName);                                                              // Load mesh from file
-RLAPI Mesh LoadMeshEx(int numVertex, float *vData, float *vtData, float *vnData, Color *cData);         // Load mesh from vertex data
-RLAPI Model LoadModel(const char *fileName);                                                            // Load model from file
-RLAPI Model LoadModelFromMesh(Mesh data, bool dynamic);                                                 // Load model from mesh data
-RLAPI Model LoadHeightmap(Image heightmap, Vector3 size);                                               // Load heightmap model from image data
-RLAPI Model LoadCubicmap(Image cubicmap);                                                               // Load cubes-based map model from image data
+//RLAPI void UpdateMesh(Mesh *mesh, int type, void *data);                                                // Update mesh data (CPU and GPU)
 RLAPI void UnloadMesh(Mesh *mesh);                                                                      // Unload mesh from memory (RAM and/or VRAM)
 RLAPI void UnloadMesh(Mesh *mesh);                                                                      // Unload mesh from memory (RAM and/or VRAM)
-RLAPI void UnloadModel(Model model);                                                                    // Unload model from memory (RAM and/or VRAM)
+
+RLAPI Mesh GenMeshCube(float width, float height, float length);                                        // Generate cuboid mesh
+RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size);                                             // Generate heightmap mesh from image data
+RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);                                           // Generate cubes-based map mesh from image data
 
 
 // Material loading/unloading functions
 // Material loading/unloading functions
 RLAPI Material LoadMaterial(const char *fileName);                                                      // Load material from file
 RLAPI Material LoadMaterial(const char *fileName);                                                      // Load material from file
-RLAPI Material LoadDefaultMaterial(void);                                                               // Load default material (uses default models shader)
+RLAPI Material LoadMaterialDefault(void);                                                               // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
+RLAPI Material LoadMaterialPBR(Texture2D cubemap, Color albedo, float metalness, float roughness);      // Load PBR material (Supports: ALBEDO, NORMAL, METALNESS, ROUGHNESS...)
 RLAPI void UnloadMaterial(Material material);                                                           // Unload material from GPU memory (VRAM)
 RLAPI void UnloadMaterial(Material material);                                                           // Unload material from GPU memory (VRAM)
+RLAPI void SetMaterialTexture(Material *mat, int texmapType, Texture2D texture);                        // Set material texture
+RLAPI void UnsetMaterialTexture(Material *mat, int texmapType);                                         // Unset texture from material and unload it from GPU
 
 
 // Model drawing functions
 // Model drawing functions
 RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint);                           // Draw a model (with texture if set)
 RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint);                           // Draw a model (with texture if set)
@@ -993,8 +1034,10 @@ RLAPI char *LoadText(const char *fileName);                               // Loa
 RLAPI Shader LoadShader(char *vsFileName, char *fsFileName);              // Load shader from files and bind default locations
 RLAPI Shader LoadShader(char *vsFileName, char *fsFileName);              // Load shader from files and bind default locations
 RLAPI void UnloadShader(Shader shader);                                   // Unload shader from GPU memory (VRAM)
 RLAPI void UnloadShader(Shader shader);                                   // Unload shader from GPU memory (VRAM)
 
 
-RLAPI Shader GetDefaultShader(void);                                      // Get default shader
-RLAPI Texture2D GetDefaultTexture(void);                                  // Get default texture
+RLAPI Shader GetShaderDefault(void);                                      // Get default shader
+RLAPI Texture2D GetTextureDefault(void);                                  // Get default texture
+
+RLAPI Texture2D rlGenMapCubemap(Texture2D skyHDR, int size);              // Generate cubemap texture map from HDR texture
 
 
 // Shader configuration functions
 // Shader configuration functions
 RLAPI int GetShaderLocation(Shader shader, const char *uniformName);              // Get shader uniform location
 RLAPI int GetShaderLocation(Shader shader, const char *uniformName);              // Get shader uniform location

File diff suppressed because it is too large
+ 589 - 192
src/rlgl.c


+ 121 - 84
src/rlgl.h

@@ -145,6 +145,54 @@ typedef unsigned char byte;
     // Boolean type
     // Boolean type
     typedef enum { false, true } bool;
     typedef enum { false, true } bool;
     #endif
     #endif
+    
+    typedef enum {
+        LOC_VERTEX_POSITION = 0,
+        LOC_VERTEX_TEXCOORD01,
+        LOC_VERTEX_TEXCOORD02,
+        LOC_VERTEX_NORMAL,
+        LOC_VERTEX_TANGENT,
+        LOC_VERTEX_COLOR,
+        LOC_MATRIX_MVP,
+        LOC_MATRIX_MODEL,
+        LOC_MATRIX_VIEW,
+        LOC_MATRIX_PROJECTION,
+        LOC_VECTOR_VIEW,
+        LOC_COLOR_DIFFUSE,
+        LOC_COLOR_SPECULAR,
+        LOC_COLOR_AMBIENT,
+        LOC_TEXMAP_ALBEDO,          // LOC_TEXMAP_DIFFUSE
+        LOC_TEXMAP_METALNESS,       // LOC_TEXMAP_SPECULAR
+        LOC_TEXMAP_NORMAL,
+        LOC_TEXMAP_ROUGHNESS,
+        LOC_TEXMAP_OCCUSION,
+        LOC_TEXMAP_EMISSION,
+        LOC_TEXMAP_HEIGHT,
+        LOC_TEXMAP_CUBEMAP,
+        LOC_TEXMAP_IRRADIANCE,
+        LOC_TEXMAP_PREFILTER,
+        LOC_TEXMAP_BRDF
+    } ShaderLocationIndex;
+
+    #define LOC_TEXMAP_DIFFUSE      LOC_TEXMAP_ALBEDO
+    #define LOC_TEXMAP_SPECULAR     LOC_TEXMAP_METALNESS
+
+    typedef enum {
+        TEXMAP_ALBEDO    = 0,       // TEXMAP_DIFFUSE
+        TEXMAP_METALNESS = 1,       // TEXMAP_SPECULAR
+        TEXMAP_NORMAL    = 2,
+        TEXMAP_ROUGHNESS = 3,
+        TEXMAP_OCCLUSION,
+        TEXMAP_EMISSION,
+        TEXMAP_HEIGHT,
+        TEXMAP_CUBEMAP,             // NOTE: Uses GL_TEXTURE_CUBE_MAP
+        TEXMAP_IRRADIANCE,          // NOTE: Uses GL_TEXTURE_CUBE_MAP
+        TEXMAP_PREFILTER,           // NOTE: Uses GL_TEXTURE_CUBE_MAP
+        TEXMAP_BRDF
+    } TexmapIndex;
+
+    #define TEXMAP_DIFFUSE      TEXMAP_ALBEDO
+    #define TEXMAP_SPECULAR     TEXMAP_METALNESS
 
 
     // Color type, RGBA (32bit)
     // Color type, RGBA (32bit)
     typedef struct Color {
     typedef struct Color {
@@ -186,44 +234,30 @@ typedef unsigned char byte;
         unsigned int vaoId;     // OpenGL Vertex Array Object id
         unsigned int vaoId;     // OpenGL Vertex Array Object id
         unsigned int vboId[7];  // OpenGL Vertex Buffer Objects id (7 types of vertex data)
         unsigned int vboId[7];  // OpenGL Vertex Buffer Objects id (7 types of vertex data)
     } Mesh;
     } Mesh;
-
-    // Shader type (generic shader)
+    
+    // Shader and material limits
+    #define MAX_SHADER_LOCATIONS        32
+    #define MAX_MATERIAL_TEXTURE_MAPS   12
+    #define MAX_MATERIAL_PARAMS          8
+    
+    // Shader type (generic)
     typedef struct Shader {
     typedef struct Shader {
         unsigned int id;        // Shader program id
         unsigned int id;        // Shader program id
-
-        // Vertex attributes locations (default locations)
-        int vertexLoc;          // Vertex attribute location point (default-location = 0)
-        int texcoordLoc;        // Texcoord attribute location point (default-location = 1)
-        int normalLoc;          // Normal attribute location point (default-location = 2)
-        int colorLoc;           // Color attibute location point (default-location = 3)
-        int tangentLoc;         // Tangent attribute location point (default-location = 4)
-        int texcoord2Loc;       // Texcoord2 attribute location point (default-location = 5)
-
-        // Uniform locations
-        int mvpLoc;             // ModelView-Projection matrix uniform location point (vertex shader)
-        int colDiffuseLoc;       // Color uniform location point (fragment shader)
-        int colAmbientLoc;      // Ambient color uniform location point (fragment shader)
-        int colSpecularLoc;     // Specular color uniform location point (fragment shader)
-
-        // Texture map locations (generic for any kind of map)
-        int mapTexture0Loc;     // Map texture uniform location point (default-texture-unit = 0)
-        int mapTexture1Loc;     // Map texture uniform location point (default-texture-unit = 1)
-        int mapTexture2Loc;     // Map texture uniform location point (default-texture-unit = 2)
+        int locs[MAX_SHADER_LOCATIONS];     // Initialized on LoadShader(), set to MAX_SHADER_LOCATIONS
     } Shader;
     } Shader;
 
 
-    // Material type
-    typedef struct Material {
-        Shader shader;          // Standard shader (supports 3 map types: diffuse, normal, specular)
-
-        Texture2D texDiffuse;   // Diffuse texture
-        Texture2D texNormal;    // Normal texture
-        Texture2D texSpecular;  // Specular texture
+    // Material texture map
+    typedef struct TextureMap {
+        Texture2D tex;
+        Color color;
+        float value;
+    } TextureMap;
 
 
-        Color colDiffuse;       // Diffuse color
-        Color colAmbient;       // Ambient color
-        Color colSpecular;      // Specular color
-
-        float glossiness;       // Glossiness level (Ranges from 0 to 1000)
+    // Material type (generic)
+    typedef struct Material {
+        Shader shader;
+        TextureMap maps[MAX_TEXTURE_MAPS];  // Initialized on LoadMaterial*(), set to MAX_TEXTURE_MAPS
+        float *params;          // Initialized on LoadMaterial*(), set to MAX_MATERIAL_PARAMS
     } Material;
     } Material;
 
 
     // Camera type, defines a camera position/orientation in 3d space
     // Camera type, defines a camera position/orientation in 3d space
@@ -343,23 +377,24 @@ void rlColor4f(float x, float y, float z, float w); // Define one vertex (color)
 // Functions Declaration - OpenGL equivalent functions (common to 1.1, 3.3+, ES2)
 // Functions Declaration - OpenGL equivalent functions (common to 1.1, 3.3+, ES2)
 // NOTE: This functions are used to completely abstract raylib code from OpenGL layer
 // NOTE: This functions are used to completely abstract raylib code from OpenGL layer
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
-void rlEnableTexture(unsigned int id);          // Enable texture usage
-void rlDisableTexture(void);                    // Disable texture usage
+void rlEnableTexture(unsigned int id);                  // Enable texture usage
+void rlDisableTexture(void);                            // Disable texture usage
 void rlTextureParameters(unsigned int id, int param, int value); // Set texture parameters (filter, wrap)
 void rlTextureParameters(unsigned int id, int param, int value); // Set texture parameters (filter, wrap)
-void rlEnableRenderTexture(unsigned int id);    // Enable render texture (fbo)
-void rlDisableRenderTexture(void);              // Disable render texture (fbo), return to default framebuffer
-void rlEnableDepthTest(void);                   // Enable depth test
-void rlDisableDepthTest(void);                  // Disable depth test
-void rlEnableWireMode(void);                    // Enable wire mode
-void rlDisableWireMode(void);                   // Disable wire mode
-void rlDeleteTextures(unsigned int id);         // Delete OpenGL texture from GPU
+void rlEnableRenderTexture(unsigned int id);            // Enable render texture (fbo)
+void rlDisableRenderTexture(void);                      // Disable render texture (fbo), return to default framebuffer
+void rlEnableDepthTest(void);                           // Enable depth test
+void rlDisableDepthTest(void);                          // Disable depth test
+void rlEnableWireMode(void);                            // Enable wire mode
+void rlDisableWireMode(void);                           // Disable wire mode
+void rlDeleteTextures(unsigned int id);                 // Delete OpenGL texture from GPU
 void rlDeleteRenderTextures(RenderTexture2D target);    // Delete render textures (fbo) from GPU
 void rlDeleteRenderTextures(RenderTexture2D target);    // Delete render textures (fbo) from GPU
-void rlDeleteShader(unsigned int id);           // Delete OpenGL shader program from GPU
-void rlDeleteVertexArrays(unsigned int id);     // Unload vertex data (VAO) from GPU memory
-void rlDeleteBuffers(unsigned int id);          // Unload vertex data (VBO) from GPU memory
-void rlClearColor(byte r, byte g, byte b, byte a);  // Clear color buffer with color
-void rlClearScreenBuffers(void);                // Clear used screen buffers (color and depth)
-int rlGetVersion(void);                         // Returns current OpenGL version
+void rlDeleteShader(unsigned int id);                   // Delete OpenGL shader program from GPU
+void rlDeleteVertexArrays(unsigned int id);             // Unload vertex data (VAO) from GPU memory
+void rlDeleteBuffers(unsigned int id);                  // Unload vertex data (VBO) from GPU memory
+void rlClearColor(byte r, byte g, byte b, byte a);      // Clear color buffer with color
+void rlClearScreenBuffers(void);                        // Clear used screen buffers (color and depth)
+int rlGetVersion(void);                                 // Returns current OpenGL version
+Vector3 rlUnproject(Vector3 source, Matrix proj, Matrix view);  // Get world coordinates from screen coordinates
 
 
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
 // Functions Declaration - rlgl functionality
 // Functions Declaration - rlgl functionality
@@ -369,24 +404,26 @@ void rlglClose(void);                           // De-init rlgl
 void rlglDraw(void);                            // Draw VAO/VBO
 void rlglDraw(void);                            // Draw VAO/VBO
 void rlglLoadExtensions(void *loader);          // Load OpenGL extensions
 void rlglLoadExtensions(void *loader);          // Load OpenGL extensions
 
 
-unsigned int rlglLoadTexture(void *data, int width, int height, int format, int mipmapCount);    // Load texture in GPU
-RenderTexture2D rlglLoadRenderTexture(int width, int height);   // Load a texture to be used for rendering (fbo with color and depth attachments)
-void rlglUpdateTexture(unsigned int id, int width, int height, int format, const void *data);         // Update GPU texture with new data
-void rlglGenerateMipmaps(Texture2D *texture);                       // Generate mipmap data for selected texture
-
-void rlglLoadMesh(Mesh *mesh, bool dynamic);                        // Upload vertex data into GPU and provided VAO/VBO ids
-void rlglUpdateMesh(Mesh mesh, int buffer, int numVertex);          // Update vertex data on GPU (upload new data to one buffer)
-void rlglDrawMesh(Mesh mesh, Material material, Matrix transform);  // Draw a 3d mesh with material and transform
-void rlglUnloadMesh(Mesh *mesh);                                    // Unload mesh data from CPU and GPU
-
-Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view);    // Get world coordinates from screen coordinates
-
-unsigned char *rlglReadScreenPixels(int width, int height);         // Read screen pixel data (color buffer)
-void *rlglReadTexturePixels(Texture2D texture);                     // Read texture pixel data
-
-// VR functions exposed to core module but not to raylib users
-void BeginVrDrawing(void);                  // Begin VR drawing configuration
-void EndVrDrawing(void);                    // End VR drawing process (and desktop mirror)
+// Textures data management
+unsigned int rlLoadTexture(void *data, int width, int height, int format, int mipmapCount);    // Load texture in GPU
+void rlUpdateTexture(unsigned int id, int width, int height, int format, const void *data);    // Update GPU texture with new data
+void rlUnloadTexture(unsigned int id);
+void rlGenerateMipmaps(Texture2D *texture);                         // Generate mipmap data for selected texture
+void *rlReadTexturePixels(Texture2D texture);                       // Read texture pixel data
+unsigned char *rlReadScreenPixels(int width, int height);           // Read screen pixel data (color buffer)
+RenderTexture2D rlLoadRenderTexture(int width, int height);         // Load a texture to be used for rendering (fbo with color and depth attachments)
+
+// Vertex data management
+void rlLoadMesh(Mesh *mesh, bool dynamic);                          // Upload vertex data into GPU and provided VAO/VBO ids
+void rlUpdateMesh(Mesh mesh, int buffer, int numVertex);            // Update vertex data on GPU (upload new data to one buffer)
+void rlDrawMesh(Mesh mesh, Material material, Matrix transform);    // Draw a 3d mesh with material and transform
+void rlUnloadMesh(Mesh *mesh);                                      // Unload mesh data from CPU and GPU
+
+// Texture maps generation (PBR)
+Texture2D rlGenMapCubemap(Texture2D skyHDR, int size);              // Generate cubemap texture map from HDR texture
+Texture2D rlGenMapIrradiance(Texture2D cubemap, int size);          // Generate irradiance texture map
+Texture2D rlGenMapPrefilter(Texture2D cubemap, int size);           // Generate prefilter texture map
+Texture2D rlGenMapBRDF(Texture2D cubemap, int size);                // Generate BRDF texture map
 
 
 // NOTE: There is a set of shader related functions that are available to end user,
 // NOTE: There is a set of shader related functions that are available to end user,
 // to avoid creating function wrappers through core module, they have been directly declared in raylib.h
 // to avoid creating function wrappers through core module, they have been directly declared in raylib.h
@@ -396,34 +433,34 @@ void EndVrDrawing(void);                    // End VR drawing process (and deskt
 // Shaders System Functions (Module: rlgl)
 // Shaders System Functions (Module: rlgl)
 // NOTE: This functions are useless when using OpenGL 1.1
 // NOTE: This functions are useless when using OpenGL 1.1
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
-Shader LoadShader(char *vsFileName, char *fsFileName);              // Load a custom shader and bind default locations
-void UnloadShader(Shader shader);                                   // Unload a custom shader from memory
+Shader LoadShader(char *vsFileName, char *fsFileName);  // Load a custom shader and bind default locations
+void UnloadShader(Shader shader);                       // Unload a custom shader from memory
 
 
-Shader GetDefaultShader(void);                                      // Get default shader
-Texture2D GetDefaultTexture(void);                                  // Get default texture
+Shader GetShaderDefault(void);                          // Get default shader
+Texture2D GetTextureDefault(void);                      // Get default texture
 
 
 int GetShaderLocation(Shader shader, const char *uniformName);              // Get shader uniform location
 int GetShaderLocation(Shader shader, const char *uniformName);              // Get shader uniform location
 void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
 void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
 void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size);  // Set shader uniform value (int)
 void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size);  // Set shader uniform value (int)
 void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat);       // Set shader uniform value (matrix 4x4)
 void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat);       // Set shader uniform value (matrix 4x4)
 
 
-void SetMatrixProjection(Matrix proj);                              // Set a custom projection matrix (replaces internal projection matrix)
-void SetMatrixModelview(Matrix view);                               // Set a custom modelview matrix (replaces internal modelview matrix)
+void SetMatrixProjection(Matrix proj);                  // Set a custom projection matrix (replaces internal projection matrix)
+void SetMatrixModelview(Matrix view);                   // Set a custom modelview matrix (replaces internal modelview matrix)
 
 
-void BeginShaderMode(Shader shader);                                // Begin custom shader drawing
-void EndShaderMode(void);                                           // End custom shader drawing (use default shader)
-void BeginBlendMode(int mode);                                      // Begin blending mode (alpha, additive, multiplied)
-void EndBlendMode(void);                                            // End blending mode (reset to default: alpha blending)
+void BeginShaderMode(Shader shader);                    // Begin custom shader drawing
+void EndShaderMode(void);                               // End custom shader drawing (use default shader)
+void BeginBlendMode(int mode);                          // Begin blending mode (alpha, additive, multiplied)
+void EndBlendMode(void);                                // End blending mode (reset to default: alpha blending)
 
 
-void TraceLog(int msgType, const char *text, ...);                  // Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG)
-float *MatrixToFloat(Matrix mat);                                   // Get float array from Matrix data
+void InitVrSimulator(int vrDevice);                     // Init VR simulator for selected device
+void CloseVrSimulator(void);                            // Close VR simulator for current device
+void UpdateVrTracking(Camera *camera);                  // Update VR tracking (position and orientation) and camera
+void ToggleVrMode(void);                                // Enable/Disable VR experience (device or simulator)
+void BeginVrDrawing(void);                              // Begin VR stereo rendering
+void EndVrDrawing(void);                                // End VR stereo rendering
 
 
-void InitVrSimulator(int vrDevice);         // Init VR simulator for selected device
-void CloseVrSimulator(void);                // Close VR simulator for current device
-void UpdateVrTracking(Camera *camera);      // Update VR tracking (position and orientation) and camera
-void ToggleVrMode(void);                    // Enable/Disable VR experience (device or simulator)
-void BeginVrDrawing(void);                  // Begin VR stereo rendering
-void EndVrDrawing(void);                    // End VR stereo rendering
+void TraceLog(int msgType, const char *text, ...);      // Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG)
+float *MatrixToFloat(Matrix mat);                       // Converts Matrix to float array
 #endif
 #endif
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus

+ 5 - 5
src/shapes.c

@@ -119,7 +119,7 @@ void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color)
     float d = sqrtf(dx*dx + dy*dy);
     float d = sqrtf(dx*dx + dy*dy);
     float angle = asinf(dy/d);
     float angle = asinf(dy/d);
     
     
-    rlEnableTexture(GetDefaultTexture().id);
+    rlEnableTexture(GetTextureDefault().id);
 
 
     rlPushMatrix();
     rlPushMatrix();
         rlTranslatef((float)startPos.x, (float)startPos.y, 0);
         rlTranslatef((float)startPos.x, (float)startPos.y, 0);
@@ -203,7 +203,7 @@ void DrawCircleV(Vector2 center, float radius, Color color)
     }
     }
     else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20))
     else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20))
     {
     {
-        rlEnableTexture(GetDefaultTexture().id); // Default white texture
+        rlEnableTexture(GetTextureDefault().id); // Default white texture
 
 
         rlBegin(RL_QUADS);
         rlBegin(RL_QUADS);
             for (int i = 0; i < 360; i += 20)
             for (int i = 0; i < 360; i += 20)
@@ -253,7 +253,7 @@ void DrawRectangleRec(Rectangle rec, Color color)
 
 
 void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color)
 void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color)
 {
 {
-    rlEnableTexture(GetDefaultTexture().id);
+    rlEnableTexture(GetTextureDefault().id);
 
 
     rlPushMatrix();
     rlPushMatrix();
         rlTranslatef((float)rec.x, (float)rec.y, 0);
         rlTranslatef((float)rec.x, (float)rec.y, 0);
@@ -309,7 +309,7 @@ void DrawRectangleV(Vector2 position, Vector2 size, Color color)
     }
     }
     else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20))
     else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20))
     {
     {
-        rlEnableTexture(GetDefaultTexture().id); // Default white texture
+        rlEnableTexture(GetTextureDefault().id); // Default white texture
 
 
         rlBegin(RL_QUADS);
         rlBegin(RL_QUADS);
             rlColor4ub(color.r, color.g, color.b, color.a);
             rlColor4ub(color.r, color.g, color.b, color.a);
@@ -376,7 +376,7 @@ void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
     }
     }
     else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20))
     else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20))
     {
     {
-        rlEnableTexture(GetDefaultTexture().id); // Default white texture
+        rlEnableTexture(GetTextureDefault().id); // Default white texture
 
 
         rlBegin(RL_QUADS);
         rlBegin(RL_QUADS);
             rlColor4ub(color.r, color.g, color.b, color.a);
             rlColor4ub(color.r, color.g, color.b, color.a);

+ 11 - 11
src/textures.c

@@ -63,8 +63,8 @@
 #include <string.h>             // Required for: strcmp(), strrchr(), strncmp()
 #include <string.h>             // Required for: strcmp(), strrchr(), strncmp()
 
 
 #include "rlgl.h"               // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2
 #include "rlgl.h"               // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2
-                                // Required for: rlglLoadTexture() rlDeleteTextures(),
-                                //      rlglGenerateMipmaps(), some funcs for DrawTexturePro()
+                                // Required for: rlLoadTexture() rlDeleteTextures(),
+                                //      rlGenerateMipmaps(), some funcs for DrawTexturePro()
 
 
 #include "utils.h"              // Required for: fopen() Android mapping
 #include "utils.h"              // Required for: fopen() Android mapping
 
 
@@ -384,7 +384,7 @@ Texture2D LoadTextureFromImage(Image image)
 {
 {
     Texture2D texture = { 0 };
     Texture2D texture = { 0 };
 
 
-    texture.id = rlglLoadTexture(image.data, image.width, image.height, image.format, image.mipmaps);
+    texture.id = rlLoadTexture(image.data, image.width, image.height, image.format, image.mipmaps);
 
 
     texture.width = image.width;
     texture.width = image.width;
     texture.height = image.height;
     texture.height = image.height;
@@ -399,7 +399,7 @@ Texture2D LoadTextureFromImage(Image image)
 // Load texture for rendering (framebuffer)
 // Load texture for rendering (framebuffer)
 RenderTexture2D LoadRenderTexture(int width, int height)
 RenderTexture2D LoadRenderTexture(int width, int height)
 {
 {
-    RenderTexture2D target = rlglLoadRenderTexture(width, height);
+    RenderTexture2D target = rlLoadRenderTexture(width, height);
 
 
     return target;
     return target;
 }
 }
@@ -416,7 +416,7 @@ void UnloadImage(Image image)
 // Unload texture from GPU memory (VRAM)
 // Unload texture from GPU memory (VRAM)
 void UnloadTexture(Texture2D texture)
 void UnloadTexture(Texture2D texture)
 {
 {
-    if (texture.id != 0)
+    if (texture.id > 0)
     {
     {
         rlDeleteTextures(texture.id);
         rlDeleteTextures(texture.id);
 
 
@@ -427,7 +427,7 @@ void UnloadTexture(Texture2D texture)
 // Unload render texture from GPU memory (VRAM)
 // Unload render texture from GPU memory (VRAM)
 void UnloadRenderTexture(RenderTexture2D target)
 void UnloadRenderTexture(RenderTexture2D target)
 {
 {
-    if (target.id != 0) rlDeleteRenderTextures(target);
+    if (target.id > 0) rlDeleteRenderTextures(target);
 }
 }
 
 
 // Get pixel data from image in the form of Color struct array
 // Get pixel data from image in the form of Color struct array
@@ -525,7 +525,7 @@ Image GetTextureData(Texture2D texture)
     
     
     if (texture.format < 8)
     if (texture.format < 8)
     {
     {
-        image.data = rlglReadTexturePixels(texture);
+        image.data = rlReadTexturePixels(texture);
 
 
         if (image.data != NULL)
         if (image.data != NULL)
         {
         {
@@ -553,7 +553,7 @@ Image GetTextureData(Texture2D texture)
 // NOTE: pixels data must match texture.format
 // NOTE: pixels data must match texture.format
 void UpdateTexture(Texture2D texture, const void *pixels)
 void UpdateTexture(Texture2D texture, const void *pixels)
 {
 {
-    rlglUpdateTexture(texture.id, texture.width, texture.height, texture.format, pixels);
+    rlUpdateTexture(texture.id, texture.width, texture.height, texture.format, pixels);
 }
 }
 
 
 // Save image to a PNG file
 // Save image to a PNG file
@@ -1660,9 +1660,9 @@ void GenTextureMipmaps(Texture2D *texture)
     {
     {
         TraceLog(LOG_WARNING, "Limited NPOT support, no mipmaps available for NPOT textures");
         TraceLog(LOG_WARNING, "Limited NPOT support, no mipmaps available for NPOT textures");
     }
     }
-    else rlglGenerateMipmaps(texture);
+    else rlGenerateMipmaps(texture);
 #else
 #else
-    rlglGenerateMipmaps(texture);
+    rlGenerateMipmaps(texture);
 #endif
 #endif
 }
 }
 
 
@@ -1792,7 +1792,7 @@ void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Co
 void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint)
 void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint)
 {
 {
     // Check if texture is valid
     // Check if texture is valid
-    if (texture.id != 0)
+    if (texture.id > 0)
     {
     {
         if (sourceRec.width < 0) sourceRec.x -= sourceRec.width;
         if (sourceRec.width < 0) sourceRec.x -= sourceRec.width;
         if (sourceRec.height < 0) sourceRec.y -= sourceRec.height;
         if (sourceRec.height < 0) sourceRec.y -= sourceRec.height;

Some files were not shown because too many files changed in this diff