summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorraysan5 <[email protected]>2017-07-19 10:09:34 +0200
committerraysan5 <[email protected]>2017-07-19 10:09:34 +0200
commitd368403a131522a53c0dedd1ae4f24301898e96e (patch)
treea2b92ba988d4d3c6d7cc8d489b94632b449d578e
parent8f569e59b177e879fe350027a706c6f731f86c4a (diff)
downloadraylib-d368403a131522a53c0dedd1ae4f24301898e96e.tar.gz
raylib-d368403a131522a53c0dedd1ae4f24301898e96e.zip
Working on PBR materials, renamed some data
-rw-r--r--examples/models/models_cubicmap.c2
-rw-r--r--examples/models/models_material_pbr.c20
-rw-r--r--examples/models/models_skybox.c6
-rw-r--r--src/core.c2
-rw-r--r--src/models.c127
-rw-r--r--src/raylib.h110
-rw-r--r--src/rlgl.c947
-rw-r--r--src/rlgl.h84
8 files changed, 658 insertions, 640 deletions
diff --git a/examples/models/models_cubicmap.c b/examples/models/models_cubicmap.c
index 8abc7d48..177cf890 100644
--- a/examples/models/models_cubicmap.c
+++ b/examples/models/models_cubicmap.c
@@ -31,7 +31,7 @@ int main()
// NOTE: By default each cube is mapped to one part of texture atlas
Texture2D texture = LoadTexture("resources/cubicmap_atlas.png"); // Load map texture
- model.material.maps[TEXMAP_DIFFUSE].tex = texture; // Set map diffuse texture
+ model.material.maps[MAP_DIFFUSE].texture = texture; // Set map diffuse texture
Vector3 mapPosition = { -16.0f, 0.0f, -8.0f }; // Set model position
diff --git a/examples/models/models_material_pbr.c b/examples/models/models_material_pbr.c
index 9380bd91..5761b2af 100644
--- a/examples/models/models_material_pbr.c
+++ b/examples/models/models_material_pbr.c
@@ -58,18 +58,18 @@ int main()
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"));
+ SetMaterialTexture(&model.material, MAP_ALBEDO, LoadTexture("resources/pbr/trooper_albedo.png"));
+ SetMaterialTexture(&model.material, MAP_NORMAL, LoadTexture("resources/pbr/trooper_normals.png"));
+ SetMaterialTexture(&model.material, MAP_METALNESS, LoadTexture("resources/pbr/trooper_metalness.png"));
+ SetMaterialTexture(&model.material, MAP_ROUGHNESS, LoadTexture("resources/pbr/trooper_roughness.png"));
+ SetMaterialTexture(&model.material, MAP_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);
+ SetTextureFilter(model.material.maps[MAP_ALBEDO].texture, FILTER_BILINEAR);
+ SetTextureFilter(model.material.maps[MAP_NORMAL].texture, FILTER_BILINEAR);
+ SetTextureFilter(model.material.maps[MAP_METALNESS].texture, FILTER_BILINEAR);
+ SetTextureFilter(model.material.maps[MAP_ROUGHNESS].texture, FILTER_BILINEAR);
+ SetTextureFilter(model.material.maps[MAP_OCCLUSION].texture, FILTER_BILINEAR);
int renderModeLoc = GetShaderLocation(model.material.shader, "renderMode");
SetShaderValuei(model.material.shader, renderModeLoc, (int[1]){ 0 }, 1);
diff --git a/examples/models/models_skybox.c b/examples/models/models_skybox.c
index 8b302b1c..d347854f 100644
--- a/examples/models/models_skybox.c
+++ b/examples/models/models_skybox.c
@@ -30,8 +30,8 @@ int main()
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);
+ skybox.material.maps[MAP_CUBEMAP].texture = GenTextureCubemap(texHDR, 512);
+ SetShaderValuei(skybox.material.shader, GetShaderLocation(skybox.material.shader, "environmentMap"), (int[1]){ MAP_CUBEMAP }, 1);
// Get skybox shader locations
skybox.material.shader.locs[LOC_MATRIX_PROJECTION] = GetShaderLocation(skybox.material.shader, "projection");
@@ -66,7 +66,7 @@ int main()
Begin3dMode(camera);
- DrawModel(skybox, VectorZero(), 1.0f, RED);
+ DrawModel(skybox, VectorZero(), 1.0f, WHITE);
DrawGrid(10, 1.0f);
diff --git a/src/core.c b/src/core.c
index ad905d4e..5cdd8e6b 100644
--- a/src/core.c
+++ b/src/core.c
@@ -1878,7 +1878,7 @@ static void InitGraphicsDevice(int width, int height)
#if defined(PLATFORM_DESKTOP)
// Load OpenGL 3.3 extensions
// NOTE: GLFW loader function is passed as parameter
- rlglLoadExtensions(glfwGetProcAddress);
+ rlLoadExtensions(glfwGetProcAddress);
#endif
// Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS)
diff --git a/src/models.c b/src/models.c
index 0865e8d7..660ecc79 100644
--- a/src/models.c
+++ b/src/models.c
@@ -1281,12 +1281,12 @@ 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[MAP_DIFFUSE].texture = GetTextureDefault(); // White texture (1x1 pixel)
+ //material.maps[MAP_NORMAL].tex; // NOTE: By default, not set
+ //material.maps[MAP_SPECULAR].tex; // NOTE: By default, not set
- material.maps[TEXMAP_DIFFUSE].color = WHITE; // Diffuse color
- material.maps[TEXMAP_SPECULAR].color = WHITE; // Specular color
+ material.maps[MAP_DIFFUSE].color = WHITE; // Diffuse color
+ material.maps[MAP_SPECULAR].color = WHITE; // Specular color
return material;
}
@@ -1294,7 +1294,7 @@ Material LoadMaterialDefault(void)
// 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 };
+ Material mat = { 0 }; // NOTE: All maps textures are set to { 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
@@ -1303,16 +1303,16 @@ Material LoadMaterialPBR(Texture2D hdr, Color albedo, float metalness, float rou
// 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");
+ mat.shader.locs[LOC_MAP_ALBEDO] = GetShaderLocation(mat.shader, "albedo.sampler");
+ mat.shader.locs[LOC_MAP_METALNESS] = GetShaderLocation(mat.shader, "metalness.sampler");
+ mat.shader.locs[LOC_MAP_NORMAL] = GetShaderLocation(mat.shader, "normals.sampler");
+ mat.shader.locs[LOC_MAP_ROUGHNESS] = GetShaderLocation(mat.shader, "roughness.sampler");
+ mat.shader.locs[LOC_MAP_OCCUSION] = GetShaderLocation(mat.shader, "occlusion.sampler");
+ mat.shader.locs[LOC_MAP_EMISSION] = GetShaderLocation(mat.shader, "emission.sampler");
+ mat.shader.locs[LOC_MAP_HEIGHT] = GetShaderLocation(mat.shader, "height.sampler");
+ mat.shader.locs[LOC_MAP_IRRADIANCE] = GetShaderLocation(mat.shader, "irradianceMap");
+ mat.shader.locs[LOC_MAP_PREFILTER] = GetShaderLocation(mat.shader, "prefilterMap");
+ mat.shader.locs[LOC_MAP_BRDF] = GetShaderLocation(mat.shader, "brdfLUT");
// Set view matrix location
mat.shader.locs[LOC_MATRIX_MODEL] = GetShaderLocation(mat.shader, "mMatrix");
@@ -1320,30 +1320,25 @@ Material LoadMaterialPBR(Texture2D hdr, Color albedo, float metalness, float rou
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;
+ mat.maps[MAP_ALBEDO].color = albedo;
+ mat.maps[MAP_NORMAL].color = (Color){ 128, 128, 255, 255 };
+ mat.maps[MAP_METALNESS].value = metalness;
+ mat.maps[MAP_ROUGHNESS].value = roughness;
+ mat.maps[MAP_OCCLUSION].value = 1.0f;
+ mat.maps[MAP_EMISSION].value = 0.0f;
+ mat.maps[MAP_HEIGHT].value = 0.0f;
- #define CUBEMAP_SIZE 1024 // Cubemap texture size
+ #define CUBEMAP_SIZE 512 // 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);
+ Texture2D cubemap = GenTextureCubemap(hdr, CUBEMAP_SIZE);
+ mat.maps[MAP_IRRADIANCE].texture = GenTextureIrradiance(cubemap, IRRADIANCE_SIZE);
+ mat.maps[MAP_PREFILTER].texture = GenTexturePrefilter(cubemap, PREFILTERED_SIZE);
+ mat.maps[MAP_BRDF].texture = GenTextureBRDF(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;
}
@@ -1355,53 +1350,53 @@ void UnloadMaterial(Material material)
UnloadShader(material.shader);
// Unload loaded texture maps
- for (int i = 0; i < MAX_MATERIAL_TEXTURE_MAPS; i++)
+ for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
{
// NOTE: We already check for (tex.id > 0) inside function
- rlDeleteTextures(material.maps[i].tex.id);
+ rlDeleteTextures(material.maps[i].texture.id);
}
}
// Set material texture
void SetMaterialTexture(Material *mat, int texmapType, Texture2D texture)
{
- mat->maps[texmapType].tex = texture;
+ mat->maps[texmapType].texture = texture;
// Update MaterialProperty use sampler state to use texture fetch instead of color attribute
int location = -1;
switch (texmapType)
{
- case TEXMAP_ALBEDO:
+ case MAP_ALBEDO:
{
location = GetShaderLocation(mat->shader, "albedo.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
} break;
- case TEXMAP_NORMAL:
+ case MAP_NORMAL:
{
location = GetShaderLocation(mat->shader, "normals.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
} break;
- case TEXMAP_METALNESS:
+ case MAP_METALNESS:
{
location = GetShaderLocation(mat->shader, "metalness.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
} break;
- case TEXMAP_ROUGHNESS:
+ case MAP_ROUGHNESS:
{
location = GetShaderLocation(mat->shader, "roughness.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
} break;
- case TEXMAP_OCCLUSION:
+ case MAP_OCCLUSION:
{
location = GetShaderLocation(mat->shader, "occlusion.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
} break;
- case TEXMAP_EMISSION:
+ case MAP_EMISSION:
{
location = GetShaderLocation(mat->shader, "emission.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
} break;
- case TEXMAP_HEIGHT:
+ case MAP_HEIGHT:
{
location = GetShaderLocation(mat->shader, "height.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
@@ -1412,44 +1407,44 @@ void SetMaterialTexture(Material *mat, int texmapType, Texture2D texture)
// 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 };
+ UnloadTexture(mat->maps[texmapType].texture);
+ mat->maps[texmapType].texture = (Texture2D){ 0 };
// Update MaterialProperty use sampler state to use texture fetch instead of color attribute
int location = -1;
switch (texmapType)
{
- case TEXMAP_ALBEDO:
+ case MAP_ALBEDO:
{
location = GetShaderLocation(mat->shader, "albedo.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
} break;
- case TEXMAP_NORMAL:
+ case MAP_NORMAL:
{
location = GetShaderLocation(mat->shader, "normals.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
} break;
- case TEXMAP_METALNESS:
+ case MAP_METALNESS:
{
location = GetShaderLocation(mat->shader, "metalness.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
} break;
- case TEXMAP_ROUGHNESS:
+ case MAP_ROUGHNESS:
{
location = GetShaderLocation(mat->shader, "roughness.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
} break;
- case TEXMAP_OCCLUSION:
+ case MAP_OCCLUSION:
{
location = GetShaderLocation(mat->shader, "occlusion.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
} break;
- case TEXMAP_EMISSION:
+ case MAP_EMISSION:
{
location = GetShaderLocation(mat->shader, "emission.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
} break;
- case TEXMAP_HEIGHT:
+ case MAP_HEIGHT:
{
location = GetShaderLocation(mat->shader, "height.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
@@ -1481,7 +1476,7 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
//Matrix matModel = MatrixMultiply(model.transform, matTransform); // Transform to world-space coordinates
model.transform = MatrixMultiply(model.transform, matTransform);
- model.material.maps[TEXMAP_DIFFUSE].color = tint; // TODO: Multiply tint color by diffuse color?
+ model.material.maps[MAP_DIFFUSE].color = tint; // TODO: Multiply tint color by diffuse color?
rlDrawMesh(model.mesh, model.material, model.transform);
}
@@ -2244,16 +2239,16 @@ static Material LoadMTL(const char *fileName)
case 'd': // Kd float float float Diffuse color (RGB)
{
sscanf(buffer, "Kd %f %f %f", &color.x, &color.y, &color.z);
- 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);
+ material.maps[MAP_DIFFUSE].color.r = (unsigned char)(color.x*255);
+ material.maps[MAP_DIFFUSE].color.g = (unsigned char)(color.y*255);
+ material.maps[MAP_DIFFUSE].color.b = (unsigned char)(color.z*255);
} break;
case 's': // Ks float float float Specular color (RGB)
{
sscanf(buffer, "Ks %f %f %f", &color.x, &color.y, &color.z);
- 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);
+ material.maps[MAP_SPECULAR].color.r = (unsigned char)(color.x*255);
+ material.maps[MAP_SPECULAR].color.g = (unsigned char)(color.y*255);
+ material.maps[MAP_SPECULAR].color.b = (unsigned char)(color.z*255);
} break;
case 'e': // Ke float float float Emmisive color (RGB)
{
@@ -2285,12 +2280,12 @@ static Material LoadMTL(const char *fileName)
if (buffer[5] == 'd') // map_Kd string Diffuse color texture map.
{
result = sscanf(buffer, "map_Kd %s", mapFileName);
- if (result != EOF) material.maps[TEXMAP_DIFFUSE].tex = LoadTexture(mapFileName);
+ if (result != EOF) material.maps[MAP_DIFFUSE].texture = LoadTexture(mapFileName);
}
else if (buffer[5] == 's') // map_Ks string Specular color texture map.
{
result = sscanf(buffer, "map_Ks %s", mapFileName);
- if (result != EOF) material.maps[TEXMAP_SPECULAR].tex = LoadTexture(mapFileName);
+ if (result != EOF) material.maps[MAP_SPECULAR].texture = LoadTexture(mapFileName);
}
else if (buffer[5] == 'a') // map_Ka string Ambient color texture map.
{
@@ -2300,12 +2295,12 @@ static Material LoadMTL(const char *fileName)
case 'B': // map_Bump string Bump texture map.
{
result = sscanf(buffer, "map_Bump %s", mapFileName);
- if (result != EOF) material.maps[TEXMAP_NORMAL].tex = LoadTexture(mapFileName);
+ if (result != EOF) material.maps[MAP_NORMAL].texture = LoadTexture(mapFileName);
} break;
case 'b': // map_bump string Bump texture map.
{
result = sscanf(buffer, "map_bump %s", mapFileName);
- if (result != EOF) material.maps[TEXMAP_NORMAL].tex = LoadTexture(mapFileName);
+ if (result != EOF) material.maps[MAP_NORMAL].texture = LoadTexture(mapFileName);
} break;
case 'd': // map_d string Opacity texture map.
{
@@ -2320,7 +2315,7 @@ static Material LoadMTL(const char *fileName)
{
float alpha = 1.0f;
sscanf(buffer, "d %f", &alpha);
- material.maps[TEXMAP_DIFFUSE].color.a = (unsigned char)(alpha*255);
+ material.maps[MAP_DIFFUSE].color.a = (unsigned char)(alpha*255);
}
else if (buffer[1] == 'i') // disp string Displacement map
{
@@ -2330,13 +2325,13 @@ static Material LoadMTL(const char *fileName)
case 'b': // bump string Bump texture map
{
result = sscanf(buffer, "bump %s", mapFileName);
- if (result != EOF) material.maps[TEXMAP_NORMAL].tex = LoadTexture(mapFileName);
+ if (result != EOF) material.maps[MAP_NORMAL].texture = LoadTexture(mapFileName);
} break;
case 'T': // Tr float Transparency Tr (alpha). Tr is inverse of d
{
float ialpha = 0.0f;
sscanf(buffer, "Tr %f", &ialpha);
- material.maps[TEXMAP_DIFFUSE].color.a = (unsigned char)((1.0f - ialpha)*255);
+ material.maps[MAP_DIFFUSE].color.a = (unsigned char)((1.0f - ialpha)*255);
} break;
case 'r': // refl string Reflection texture map
diff --git a/src/raylib.h b/src/raylib.h
index c84d6ce4..8d93a214 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -292,9 +292,8 @@
#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
+#define MAX_SHADER_LOCATIONS 32 // Maximum number of predefined locations stored in shader struct
+#define MAX_MATERIAL_MAPS 12 // Maximum number of texture maps stored in shader struct
//----------------------------------------------------------------------------------
// Structures Definition
@@ -405,21 +404,22 @@ typedef struct Camera2D {
// Bounding box type
typedef struct BoundingBox {
- Vector3 min; // minimum vertex box-corner
- Vector3 max; // maximum vertex box-corner
+ Vector3 min; // Minimum vertex box-corner
+ Vector3 max; // Maximum vertex box-corner
} BoundingBox;
// Vertex data definning a mesh
typedef struct Mesh {
- int vertexCount; // number of vertices stored in arrays
- int triangleCount; // number of triangles stored (indexed or not)
- float *vertices; // vertex position (XYZ - 3 components per vertex) (shader-location = 0)
- float *texcoords; // vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
- float *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
- float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
- float *tangents; // vertex tangents (XYZ - 3 components per vertex) (shader-location = 4)
- unsigned char *colors; // vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
- unsigned short *indices;// vertex indices (in case vertex data comes indexed)
+ int vertexCount; // Number of vertices stored in arrays
+ int triangleCount; // Number of triangles stored (indexed or not)
+
+ float *vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0)
+ float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
+ float *texcoords2; // Vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
+ float *normals; // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
+ float *tangents; // Vertex tangents (XYZ - 3 components per vertex) (shader-location = 4)
+ unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
+ unsigned short *indices;// Vertex indices (in case vertex data comes indexed)
unsigned int vaoId; // OpenGL Vertex Array Object id
unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
@@ -427,22 +427,22 @@ typedef struct Mesh {
// Shader type (generic)
typedef struct Shader {
- unsigned int id; // Shader program id
- int locs[MAX_SHADER_LOCATIONS]; // Initialized on LoadShader(), set to MAX_SHADER_LOCATIONS
+ unsigned int id; // Shader program id
+ int locs[MAX_SHADER_LOCATIONS]; // Shader locations array
} Shader;
// Material texture map
-typedef struct TextureMap {
- Texture2D tex;
- Color color;
- float value;
-} TextureMap;
+typedef struct MaterialMap {
+ Texture2D texture; // Material map texture
+ Color color; // Material map color
+ float value; // Material map value
+} MaterialMap;
// 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
+ Shader shader; // Material shader
+ MaterialMap maps[MAX_MATERIAL_MAPS]; // Material maps
+ float *params; // Material generic parameters (if required)
} Material;
// Model type
@@ -526,6 +526,7 @@ typedef enum {
LOG_OTHER
} LogType;
+// Shader location point type
typedef enum {
LOC_VERTEX_POSITION = 0,
LOC_VERTEX_TEXCOORD01,
@@ -541,38 +542,39 @@ typedef enum {
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
+ LOC_MAP_ALBEDO, // LOC_MAP_DIFFUSE
+ LOC_MAP_METALNESS, // LOC_MAP_SPECULAR
+ LOC_MAP_NORMAL,
+ LOC_MAP_ROUGHNESS,
+ LOC_MAP_OCCUSION,
+ LOC_MAP_EMISSION,
+ LOC_MAP_HEIGHT,
+ LOC_MAP_CUBEMAP,
+ LOC_MAP_IRRADIANCE,
+ LOC_MAP_PREFILTER,
+ LOC_MAP_BRDF
} ShaderLocationIndex;
-#define LOC_TEXMAP_DIFFUSE LOC_TEXMAP_ALBEDO
-#define LOC_TEXMAP_SPECULAR LOC_TEXMAP_METALNESS
+#define LOC_MAP_DIFFUSE LOC_MAP_ALBEDO
+#define LOC_MAP_SPECULAR LOC_MAP_METALNESS
+// Material map type
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
+ MAP_ALBEDO = 0, // MAP_DIFFUSE
+ MAP_METALNESS = 1, // MAP_SPECULAR
+ MAP_NORMAL = 2,
+ MAP_ROUGHNESS = 3,
+ MAP_OCCLUSION,
+ MAP_EMISSION,
+ MAP_HEIGHT,
+ MAP_CUBEMAP, // NOTE: Uses GL_TEXTURE_CUBE_MAP
+ MAP_IRRADIANCE, // NOTE: Uses GL_TEXTURE_CUBE_MAP
+ MAP_PREFILTER, // NOTE: Uses GL_TEXTURE_CUBE_MAP
+ MAP_BRDF
} TexmapIndex;
-#define TEXMAP_DIFFUSE TEXMAP_ALBEDO
-#define TEXMAP_SPECULAR TEXMAP_METALNESS
+#define MAP_DIFFUSE MAP_ALBEDO
+#define MAP_SPECULAR MAP_METALNESS
// Texture formats
// NOTE: Support depends on OpenGL version and platform
@@ -1037,8 +1039,6 @@ RLAPI void UnloadShader(Shader shader); // Unl
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
RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
RLAPI void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
@@ -1047,6 +1047,12 @@ RLAPI void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat);
RLAPI void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
RLAPI void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
+// Texture maps generation (PBR)
+RLAPI Texture2D GenTextureCubemap(Texture2D skyHDR, int size); // Generate cubemap texture from HDR texture
+RLAPI Texture2D GenTextureIrradiance(Texture2D cubemap, int size); // Generate irradiance texture using cubemap data
+RLAPI Texture2D GenTexturePrefilter(Texture2D cubemap, int size); // Generate prefilter texture using cubemap data
+RLAPI Texture2D GenTextureBRDF(Texture2D cubemap, int size); // Generate BRDF texture using cubemap data
+
// Shading begin/end functions
RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing
RLAPI void EndShaderMode(void); // End custom shader drawing (use default shader)
diff --git a/src/rlgl.c b/src/rlgl.c
index 742b0ed5..b9576b9b 100644
--- a/src/rlgl.c
+++ b/src/rlgl.c
@@ -340,13 +340,13 @@ static Shader LoadShaderDefault(void); // Load default shader (just vertex
static void SetShaderDefaultLocations(Shader *shader); // Bind default shader locations (attributes and uniforms)
static void UnloadShaderDefault(void); // Unload default shader
-static void LoadDefaultBuffers(void); // Load default internal buffers (lines, triangles, quads)
-static void UpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data
-static void DrawDefaultBuffers(void); // Draw default internal buffers vertex data
-static void UnloadDefaultBuffers(void); // Unload default internal buffers vertex data from CPU and GPU
+static void LoadBuffersDefault(void); // Load default internal buffers (lines, triangles, quads)
+static void UpdateBuffersDefault(void); // Update default internal buffers (VAOs/VBOs) with vertex data
+static void DrawBuffersDefault(void); // Draw default internal buffers vertex data
+static void UnloadBuffersDefault(void); // Unload default internal buffers vertex data from CPU and GPU
-static void RenderCube(void);
-static void RenderQuad(void);
+static void GenDrawCube(void); // Generate and draw cube
+static void GenDrawQuad(void); // Generate and draw quad
#if defined(SUPPORT_VR_SIMULATOR)
static void SetStereoConfig(VrDeviceInfo info); // Configure stereo rendering (including distortion shader) with HMD device parameters
@@ -1219,7 +1219,7 @@ void rlglInit(int width, int height)
currentShader = defaultShader;
// Init default vertex arrays buffers (lines, triangles, quads)
- LoadDefaultBuffers();
+ LoadBuffersDefault();
// Init temp vertex buffer, used when transformation required (translate, rotate, scale)
tempBuffer = (Vector3 *)malloc(sizeof(Vector3)*TEMP_VERTEX_BUFFER_SIZE);
@@ -1288,7 +1288,7 @@ void rlglClose(void)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
UnloadShaderDefault();
- UnloadDefaultBuffers();
+ UnloadBuffersDefault();
// Delete default white texture
glDeleteTextures(1, &whiteTexture);
@@ -1306,14 +1306,14 @@ void rlglDraw(void)
//for (int i = 0; i < modelsCount; i++) rlDrawMesh(models[i]->mesh, models[i]->material, models[i]->transform);
// NOTE: Default buffers upload and draw
- UpdateDefaultBuffers();
- DrawDefaultBuffers(); // NOTE: Stereo rendering is checked inside
+ UpdateBuffersDefault();
+ DrawBuffersDefault(); // NOTE: Stereo rendering is checked inside
#endif
}
// Load OpenGL extensions
// NOTE: External loader function could be passed as a pointer
-void rlglLoadExtensions(void *loader)
+void rlLoadExtensions(void *loader)
{
#if defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_33)
// NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions)
@@ -1718,422 +1718,6 @@ void rlGenerateMipmaps(Texture2D *texture)
glBindTexture(GL_TEXTURE_2D, 0);
}
-// Generated cubemap texture
-Texture2D rlGenMapCubemap(Texture2D skyHDR, int size)
-{
- Texture2D cubemap = { 0 };
-
- #define PATH_CUBEMAP_VS "resources/shaders/cubemap.vs" // Path to equirectangular to cubemap vertex shader
- #define PATH_CUBEMAP_FS "resources/shaders/cubemap.fs" // Path to equirectangular to cubemap fragment shader
-
- Shader shader = LoadShader(PATH_CUBEMAP_VS, PATH_CUBEMAP_FS);
-
- // Get cubemap shader locations
- int projectionLoc = GetShaderLocation(shader, "projection");
- int viewLoc = GetShaderLocation(shader, "view");
- int texmapLoc = GetShaderLocation(shader, "equirectangularMap");
-
- SetShaderValuei(shader, texmapLoc, (int[1]){ 0 }, 1); // Set default active texture to 0
-
- // Set up depth face culling and cubemap seamless
- glDisable(GL_CULL_FACE);
- glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
-
- // Setup framebuffer
- unsigned int fbo, rbo;
- glGenFramebuffers(1, &fbo);
- glGenRenderbuffers(1, &rbo);
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- glBindRenderbuffer(GL_RENDERBUFFER, rbo);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size, size);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
-
- // Set up cubemap to render and attach to framebuffer
- // NOTE: faces are stored with 16 bit floating point values
- glGenTextures(1, &cubemap.id);
- glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap.id);
- for (unsigned int i = 0; i < 6; i++)
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, size, size, 0, GL_RGB, GL_FLOAT, NULL);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- // Create projection (transposed) and different views for each face
- Matrix fboProjection = MatrixPerspective(90.0, 1.0, 0.01, 1000.0);
- MatrixTranspose(&fboProjection);
- Matrix fboViews[6] = {
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ -1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }),
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }),
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f })
- };
-
- // Convert HDR equirectangular environment map to cubemap equivalent
- glUseProgram(shader.id);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, skyHDR.id);
- SetShaderValueMatrix(shader, projectionLoc, fboProjection);
-
- // Note: don't forget to configure the viewport to the capture dimensions
- glViewport(0, 0, size, size);
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-
- for (unsigned int i = 0; i < 6; i++)
- {
- SetShaderValueMatrix(shader, viewLoc, fboViews[i]);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cubemap.id, 0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- RenderCube();
- }
-
- // Unbind framebuffer and textures
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
- UnloadShader(shader);
-
- cubemap.width = size;
- cubemap.height = size;
-
- // Reset viewport dimensions to default
- glViewport(0, 0, GetScreenWidth(), GetScreenHeight());
- //glEnable(GL_CULL_FACE);
-
- return cubemap;
-}
-
-Texture2D rlGenMapIrradiance(Texture2D cubemap, int size)
-{
- Texture2D irradiance = { 0 };
-
- #define PATH_SKYBOX_VS "resources/shaders/skybox.vs" // Path to skybox vertex shader
- #define PATH_IRRADIANCE_FS "resources/shaders/irradiance.fs" // Path to irradiance (GI) calculation fragment shader
-
- Shader shader = LoadShader(PATH_SKYBOX_VS, PATH_IRRADIANCE_FS);
-
- // Get irradiance shader locations
- int projectionLoc = GetShaderLocation(shader, "projection");
- int viewLoc = GetShaderLocation(shader, "view");
- int texmapLoc = GetShaderLocation(shader, "environmentMap");
-
- // Set up shaders constant values
- SetShaderValuei(shader, texmapLoc, (int[1]){ 0 }, 1);
-
- // Setup framebuffer
- unsigned int fbo, rbo;
- glGenFramebuffers(1, &fbo);
- glGenRenderbuffers(1, &rbo);
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- glBindRenderbuffer(GL_RENDERBUFFER, rbo);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size, size);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
-
- // Create an irradiance cubemap, and re-scale capture FBO to irradiance scale
- glGenTextures(1, &irradiance.id);
- glBindTexture(GL_TEXTURE_CUBE_MAP, irradiance.id);
- for (unsigned int i = 0; i < 6; i++)
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, size, size, 0, GL_RGB, GL_FLOAT, NULL);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- // Create projection (transposed) and different views for each face
- Matrix fboProjection = MatrixPerspective(90.0, 1.0, 0.01, 1000.0);
- MatrixTranspose(&fboProjection);
- Matrix fboViews[6] = {
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ -1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }),
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }),
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f })
- };
-
- // Solve diffuse integral by convolution to create an irradiance cubemap
- glUseProgram(shader.id);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap.id);
- SetShaderValueMatrix(shader, projectionLoc, fboProjection);
-
- // Note: don't forget to configure the viewport to the capture dimensions
- glViewport(0, 0, size, size);
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-
- for (unsigned int i = 0; i < 6; i++)
- {
- SetShaderValueMatrix(shader, viewLoc, fboViews[i]);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, irradiance.id, 0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- RenderCube();
- }
-
- // Unbind framebuffer and textures
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
- UnloadShader(shader);
-
- irradiance.width = size;
- irradiance.height = size;
-
- return irradiance;
-}
-
-Texture2D rlGenMapPrefilter(Texture2D cubemap, int size)
-{
- Texture2D prefilter = { 0 };
-
- #define PATH_SKYBOX_VS "resources/shaders/skybox.vs" // Path to skybox vertex shader
- #define PATH_PREFILTER_FS "resources/shaders/prefilter.fs" // Path to reflection prefilter calculation fragment shader
-
- Shader shader = LoadShader(PATH_SKYBOX_VS, PATH_PREFILTER_FS);
-
- // Get prefilter shader locations
- int projectionLoc = GetShaderLocation(shader, "projection");
- int viewLoc = GetShaderLocation(shader, "view");
- int roughnessLoc = GetShaderLocation(shader, "roughness");
- int texmapLoc = GetShaderLocation(shader, "environmentMap");
-
- SetShaderValuei(shader, texmapLoc, (int[1]){ 0 }, 1);
-
- // Setup framebuffer
- unsigned int fbo, rbo;
- glGenFramebuffers(1, &fbo);
- glGenRenderbuffers(1, &rbo);
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- glBindRenderbuffer(GL_RENDERBUFFER, rbo);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size, size);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
-
- // Create a prefiltered HDR environment map
- glGenTextures(1, &prefilter.id);
- glBindTexture(GL_TEXTURE_CUBE_MAP, prefilter.id);
- for (unsigned int i = 0; i < 6; i++)
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, size, size, 0, GL_RGB, GL_FLOAT, NULL);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- // Generate mipmaps for the prefiltered HDR texture
- glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
-
- // Create projection (transposed) and different views for each face
- Matrix fboProjection = MatrixPerspective(90.0, 1.0, 0.01, 1000.0);
- MatrixTranspose(&fboProjection);
- Matrix fboViews[6] = {
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ -1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }),
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }),
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
- MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f })
- };
-
- // Prefilter HDR and store data into mipmap levels
- glUseProgram(shader.id);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap.id);
- SetShaderValueMatrix(shader, projectionLoc, fboProjection);
-
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-
- #define MAX_MIPMAP_LEVELS 5 // Max number of prefilter texture mipmaps
-
- for (unsigned int mip = 0; mip < MAX_MIPMAP_LEVELS; mip++)
- {
- // Resize framebuffer according to mip-level size.
- unsigned int mipWidth = size*powf(0.5f, mip);
- unsigned int mipHeight = size*powf(0.5f, mip);
-
- glBindRenderbuffer(GL_RENDERBUFFER, rbo);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mipWidth, mipHeight);
- glViewport(0, 0, mipWidth, mipHeight);
-
- float roughness = (float)mip/(float)(MAX_MIPMAP_LEVELS - 1);
- glUniform1f(roughnessLoc, roughness);
-
- for (unsigned int i = 0; i < 6; ++i)
- {
- SetShaderValueMatrix(shader, viewLoc, fboViews[i]);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, prefilter.id, mip);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- RenderCube();
- }
- }
-
- // Unbind framebuffer and textures
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
- UnloadShader(shader);
-
- prefilter.width = size;
- prefilter.height = size;
-
- return prefilter;
-}
-
-Texture2D rlGenMapBRDF(Texture2D cubemap, int size)
-{
- Texture2D brdf = { 0 };
-
- #define PATH_BRDF_VS "resources/shaders/brdf.vs" // Path to bidirectional reflectance distribution function vertex shader
- #define PATH_BRDF_FS "resources/shaders/brdf.fs" // Path to bidirectional reflectance distribution function fragment shader
-
- Shader shader = LoadShader(PATH_BRDF_VS, PATH_BRDF_FS);
-
- // Generate BRDF convolution texture
- glGenTextures(1, &brdf.id);
- glBindTexture(GL_TEXTURE_2D, brdf.id);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16F, size, size, 0, GL_RG, GL_FLOAT, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- // Render BRDF LUT into a quad using FBO
- unsigned int fbo, rbo;
- glGenFramebuffers(1, &fbo);
- glGenRenderbuffers(1, &rbo);
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- glBindRenderbuffer(GL_RENDERBUFFER, rbo);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size, size);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, brdf.id, 0);
-
- rlViewport(0, 0, size, size);
- glUseProgram(shader.id);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- RenderQuad();
-
- // Unbind framebuffer and textures
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
- UnloadShader(shader);
-
- brdf.width = size;
- brdf.height = size;
-
- return brdf;
-}
-
-// Renders a 1x1 3D cube in NDC
-GLuint cubeVAO = 0;
-GLuint cubeVBO = 0;
-static void RenderCube(void)
-{
- // Initialize if it is not yet
- if (cubeVAO == 0)
- {
- GLfloat 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
- };
-
- // Set up cube VAO
- glGenVertexArrays(1, &cubeVAO);
- glGenBuffers(1, &cubeVBO);
-
- // Fill buffer
- glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
-
- // Link vertex attributes
- glBindVertexArray(cubeVAO);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (GLvoid*)0);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (GLvoid*)(3*sizeof(GLfloat)));
- glEnableVertexAttribArray(2);
- glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (GLvoid*)(6*sizeof(GLfloat)));
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindVertexArray(0);
- }
-
- // Render cube
- glBindVertexArray(cubeVAO);
- glDrawArrays(GL_TRIANGLES, 0, 36);
- glBindVertexArray(0);
-}
-
-// Renders a 1x1 XY quad in NDC
-GLuint quadVAO = 0;
-GLuint quadVBO;
-static void RenderQuad(void)
-{
- // Initialize if it is not yet
- if (quadVAO == 0)
- {
- GLfloat quadVertices[] = {
- // Positions // Texture Coords
- -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
- -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
- 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
- 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
- };
-
- // Set up plane VAO
- glGenVertexArrays(1, &quadVAO);
- glGenBuffers(1, &quadVBO);
- glBindVertexArray(quadVAO);
-
- // Fill buffer
- glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
-
- // Link vertex attributes
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (GLvoid*)0);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (GLvoid*)(3*sizeof(GLfloat)));
- }
-
- // Render quad
- glBindVertexArray(quadVAO);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- glBindVertexArray(0);
-}
-
-
-
// Upload vertex data into a VAO (if supported) and VBO
// TODO: Check if mesh has already been loaded in GPU
void rlLoadMesh(Mesh *mesh, bool dynamic)
@@ -2339,7 +1923,7 @@ void rlDrawMesh(Mesh mesh, Material material, Matrix transform)
{
#if defined(GRAPHICS_API_OPENGL_11)
glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, material.maps[TEXMAP_DIFFUSE].tex.id);
+ glBindTexture(GL_TEXTURE_2D, material.maps[MAP_DIFFUSE].tex.id);
// NOTE: On OpenGL 1.1 we use Vertex Arrays to draw model
glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex array
@@ -2381,17 +1965,17 @@ void rlDrawMesh(Mesh mesh, Material material, Matrix transform)
SetShaderValueMatrix(material.shader, material.shader.locs[LOC_MATRIX_MODEL], transform);
// Upload to shader material.colDiffuse
- glUniform4f(material.shader.locs[LOC_COLOR_DIFFUSE], (float)material.maps[TEXMAP_DIFFUSE].color.r/255,
- (float)material.maps[TEXMAP_DIFFUSE].color.g/255,
- (float)material.maps[TEXMAP_DIFFUSE].color.b/255,
- (float)material.maps[TEXMAP_DIFFUSE].color.a/255);
+ glUniform4f(material.shader.locs[LOC_COLOR_DIFFUSE], (float)material.maps[MAP_DIFFUSE].color.r/255,
+ (float)material.maps[MAP_DIFFUSE].color.g/255,
+ (float)material.maps[MAP_DIFFUSE].color.b/255,
+ (float)material.maps[MAP_DIFFUSE].color.a/255);
// Upload to shader material.colSpecular (if available)
if (material.shader.locs[LOC_COLOR_SPECULAR] != -1)
- glUniform4f(material.shader.locs[LOC_COLOR_SPECULAR], (float)material.maps[TEXMAP_SPECULAR].color.r/255,
- (float)material.maps[TEXMAP_SPECULAR].color.g/255,
- (float)material.maps[TEXMAP_SPECULAR].color.b/255,
- (float)material.maps[TEXMAP_SPECULAR].color.a/255);
+ glUniform4f(material.shader.locs[LOC_COLOR_SPECULAR], (float)material.maps[MAP_SPECULAR].color.r/255,
+ (float)material.maps[MAP_SPECULAR].color.g/255,
+ (float)material.maps[MAP_SPECULAR].color.b/255,
+ (float)material.maps[MAP_SPECULAR].color.a/255);
// At this point the modelview matrix just contains the view matrix (camera)
// That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix()
@@ -2403,15 +1987,15 @@ void rlDrawMesh(Mesh mesh, Material material, Matrix transform)
//-----------------------------------------------------
// Bind active texture maps (if available)
- for (int i = 0; i < MAX_MATERIAL_TEXTURE_MAPS; i++)
+ for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
{
- if (material.maps[i].tex.id > 0)
+ if (material.maps[i].texture.id > 0)
{
glActiveTexture(GL_TEXTURE0 + i);
- if ((i == TEXMAP_IRRADIANCE) || (i == TEXMAP_PREFILTER) || (i == TEXMAP_CUBEMAP)) glBindTexture(GL_TEXTURE_CUBE_MAP, material.maps[i].tex.id);
- else glBindTexture(GL_TEXTURE_2D, material.maps[i].tex.id);
+ if ((i == MAP_IRRADIANCE) || (i == MAP_PREFILTER) || (i == MAP_CUBEMAP)) glBindTexture(GL_TEXTURE_CUBE_MAP, material.maps[i].texture.id);
+ else glBindTexture(GL_TEXTURE_2D, material.maps[i].texture.id);
- glUniform1i(material.shader.locs[LOC_TEXMAP_DIFFUSE + i], i);
+ glUniform1i(material.shader.locs[LOC_MAP_DIFFUSE + i], i);
}
}
@@ -2500,10 +2084,10 @@ void rlDrawMesh(Mesh mesh, Material material, Matrix transform)
}
// Unbind all binded texture maps
- for (int i = 0; i < MAX_MATERIAL_TEXTURE_MAPS; i++)
+ for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
{
glActiveTexture(GL_TEXTURE0 + i); // Set shader active texture
- if ((i == TEXMAP_IRRADIANCE) || (i == TEXMAP_PREFILTER) || (i == TEXMAP_CUBEMAP)) glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
+ if ((i == MAP_IRRADIANCE) || (i == MAP_PREFILTER) || (i == MAP_CUBEMAP)) glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
else glBindTexture(GL_TEXTURE_2D, 0); // Unbind current active texture
}
@@ -2738,6 +2322,17 @@ Texture2D GetTextureDefault(void)
return texture;
}
+// Get default shader
+Shader GetShaderDefault(void)
+{
+#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
+ return defaultShader;
+#else
+ Shader shader = { 0 };
+ return shader;
+#endif
+}
+
// Load text data from file
// NOTE: text chars array should be freed manually
char *LoadText(const char *fileName)
@@ -2860,17 +2455,6 @@ void EndShaderMode(void)
#endif
}
-// Get default shader
-Shader GetShaderDefault(void)
-{
-#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- return defaultShader;
-#else
- Shader shader = { 0 };
- return shader;
-#endif
-}
-
// Get shader uniform location
int GetShaderLocation(Shader shader, const char *uniformName)
{
@@ -2944,6 +2528,321 @@ void SetMatrixModelview(Matrix view)
#endif
}
+// Generate cubemap texture from HDR texture
+Texture2D GenTextureCubemap(Texture2D skyHDR, int size)
+{
+ Texture2D cubemap = { 0 };
+
+ #define PATH_CUBEMAP_VS "resources/shaders/cubemap.vs" // Path to equirectangular to cubemap vertex shader
+ #define PATH_CUBEMAP_FS "resources/shaders/cubemap.fs" // Path to equirectangular to cubemap fragment shader
+
+ Shader shader = LoadShader(PATH_CUBEMAP_VS, PATH_CUBEMAP_FS);
+
+ // Get cubemap shader locations
+ int projectionLoc = GetShaderLocation(shader, "projection");
+ int viewLoc = GetShaderLocation(shader, "view");
+ int texmapLoc = GetShaderLocation(shader, "equirectangularMap");
+
+ SetShaderValuei(shader, texmapLoc, (int[1]){ 0 }, 1); // Set default active texture to 0
+
+ // Set up depth face culling and cubemap seamless
+ glDisable(GL_CULL_FACE);
+ glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
+
+ // Setup framebuffer
+ unsigned int fbo, rbo;
+ glGenFramebuffers(1, &fbo);
+ glGenRenderbuffers(1, &rbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glBindRenderbuffer(GL_RENDERBUFFER, rbo);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size, size);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
+
+ // Set up cubemap to render and attach to framebuffer
+ // NOTE: faces are stored with 16 bit floating point values
+ glGenTextures(1, &cubemap.id);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap.id);
+ for (unsigned int i = 0; i < 6; i++)
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, size, size, 0, GL_RGB, GL_FLOAT, NULL);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ // Create projection (transposed) and different views for each face
+ Matrix fboProjection = MatrixPerspective(90.0, 1.0, 0.01, 1000.0);
+ MatrixTranspose(&fboProjection);
+ Matrix fboViews[6] = {
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ -1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f })
+ };
+
+ // Convert HDR equirectangular environment map to cubemap equivalent
+ glUseProgram(shader.id);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, skyHDR.id);
+ SetShaderValueMatrix(shader, projectionLoc, fboProjection);
+
+ // Note: don't forget to configure the viewport to the capture dimensions
+ glViewport(0, 0, size, size);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ for (unsigned int i = 0; i < 6; i++)
+ {
+ SetShaderValueMatrix(shader, viewLoc, fboViews[i]);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cubemap.id, 0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ GenDrawCube();
+ }
+
+ // Unbind framebuffer and textures
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ // Reset viewport dimensions to default
+ glViewport(0, 0, GetScreenWidth(), GetScreenHeight());
+ //glEnable(GL_CULL_FACE);
+
+ UnloadShader(shader);
+
+ cubemap.width = size;
+ cubemap.height = size;
+
+ return cubemap;
+}
+
+// Generate irradiance texture using cubemap data
+Texture2D GenTextureIrradiance(Texture2D cubemap, int size)
+{
+ Texture2D irradiance = { 0 };
+
+ #define PATH_SKYBOX_VS "resources/shaders/skybox.vs" // Path to skybox vertex shader
+ #define PATH_IRRADIANCE_FS "resources/shaders/irradiance.fs" // Path to irradiance (GI) calculation fragment shader
+
+ Shader shader = LoadShader(PATH_SKYBOX_VS, PATH_IRRADIANCE_FS);
+
+ // Get irradiance shader locations
+ int projectionLoc = GetShaderLocation(shader, "projection");
+ int viewLoc = GetShaderLocation(shader, "view");
+ int texmapLoc = GetShaderLocation(shader, "environmentMap");
+
+ // Set up shaders constant values
+ SetShaderValuei(shader, texmapLoc, (int[1]){ 0 }, 1);
+
+ // Setup framebuffer
+ unsigned int fbo, rbo;
+ glGenFramebuffers(1, &fbo);
+ glGenRenderbuffers(1, &rbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glBindRenderbuffer(GL_RENDERBUFFER, rbo);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size, size);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
+
+ // Create an irradiance cubemap, and re-scale capture FBO to irradiance scale
+ glGenTextures(1, &irradiance.id);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, irradiance.id);
+ for (unsigned int i = 0; i < 6; i++)
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, size, size, 0, GL_RGB, GL_FLOAT, NULL);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ // Create projection (transposed) and different views for each face
+ Matrix fboProjection = MatrixPerspective(90.0, 1.0, 0.01, 1000.0);
+ MatrixTranspose(&fboProjection);
+ Matrix fboViews[6] = {
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ -1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f })
+ };
+
+ // Solve diffuse integral by convolution to create an irradiance cubemap
+ glUseProgram(shader.id);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap.id);
+ SetShaderValueMatrix(shader, projectionLoc, fboProjection);
+
+ // Note: don't forget to configure the viewport to the capture dimensions
+ glViewport(0, 0, size, size);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ for (unsigned int i = 0; i < 6; i++)
+ {
+ SetShaderValueMatrix(shader, viewLoc, fboViews[i]);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, irradiance.id, 0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ GenDrawCube();
+ }
+
+ // Unbind framebuffer and textures
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ // Reset viewport dimensions to default
+ glViewport(0, 0, GetScreenWidth(), GetScreenHeight());
+
+ UnloadShader(shader);
+
+ irradiance.width = size;
+ irradiance.height = size;
+
+ return irradiance;
+}
+
+// Generate prefilter texture using cubemap data
+Texture2D GenTexturePrefilter(Texture2D cubemap, int size)
+{
+ Texture2D prefilter = { 0 };
+
+ #define PATH_SKYBOX_VS "resources/shaders/skybox.vs" // Path to skybox vertex shader
+ #define PATH_PREFILTER_FS "resources/shaders/prefilter.fs" // Path to reflection prefilter calculation fragment shader
+
+ Shader shader = LoadShader(PATH_SKYBOX_VS, PATH_PREFILTER_FS);
+
+ // Get prefilter shader locations
+ int projectionLoc = GetShaderLocation(shader, "projection");
+ int viewLoc = GetShaderLocation(shader, "view");
+ int roughnessLoc = GetShaderLocation(shader, "roughness");
+ int texmapLoc = GetShaderLocation(shader, "environmentMap");
+
+ SetShaderValuei(shader, texmapLoc, (int[1]){ 0 }, 1);
+
+ // Setup framebuffer
+ unsigned int fbo, rbo;
+ glGenFramebuffers(1, &fbo);
+ glGenRenderbuffers(1, &rbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glBindRenderbuffer(GL_RENDERBUFFER, rbo);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size, size);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
+
+ // Create a prefiltered HDR environment map
+ glGenTextures(1, &prefilter.id);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, prefilter.id);
+ for (unsigned int i = 0; i < 6; i++)
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, size, size, 0, GL_RGB, GL_FLOAT, NULL);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ // Generate mipmaps for the prefiltered HDR texture
+ glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
+
+ // Create projection (transposed) and different views for each face
+ Matrix fboProjection = MatrixPerspective(90.0, 1.0, 0.01, 1000.0);
+ MatrixTranspose(&fboProjection);
+ Matrix fboViews[6] = {
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ -1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
+ MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f })
+ };
+
+ // Prefilter HDR and store data into mipmap levels
+ glUseProgram(shader.id);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap.id);
+ SetShaderValueMatrix(shader, projectionLoc, fboProjection);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ #define MAX_MIPMAP_LEVELS 5 // Max number of prefilter texture mipmaps
+
+ for (unsigned int mip = 0; mip < MAX_MIPMAP_LEVELS; mip++)
+ {
+ // Resize framebuffer according to mip-level size.
+ unsigned int mipWidth = size*powf(0.5f, mip);
+ unsigned int mipHeight = size*powf(0.5f, mip);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, rbo);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mipWidth, mipHeight);
+ glViewport(0, 0, mipWidth, mipHeight);
+
+ float roughness = (float)mip/(float)(MAX_MIPMAP_LEVELS - 1);
+ glUniform1f(roughnessLoc, roughness);
+
+ for (unsigned int i = 0; i < 6; ++i)
+ {
+ SetShaderValueMatrix(shader, viewLoc, fboViews[i]);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, prefilter.id, mip);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ GenDrawCube();
+ }
+ }
+
+ // Unbind framebuffer and textures
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ // Reset viewport dimensions to default
+ glViewport(0, 0, GetScreenWidth(), GetScreenHeight());
+
+ UnloadShader(shader);
+
+ prefilter.width = size;
+ prefilter.height = size;
+
+ return prefilter;
+}
+
+// Generate BRDF texture using cubemap data
+Texture2D GenTextureBRDF(Texture2D cubemap, int size)
+{
+ Texture2D brdf = { 0 };
+
+ #define PATH_BRDF_VS "resources/shaders/brdf.vs" // Path to bidirectional reflectance distribution function vertex shader
+ #define PATH_BRDF_FS "resources/shaders/brdf.fs" // Path to bidirectional reflectance distribution function fragment shader
+
+ Shader shader = LoadShader(PATH_BRDF_VS, PATH_BRDF_FS);
+
+ // Generate BRDF convolution texture
+ glGenTextures(1, &brdf.id);
+ glBindTexture(GL_TEXTURE_2D, brdf.id);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16F, size, size, 0, GL_RG, GL_FLOAT, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ // Render BRDF LUT into a quad using FBO
+ unsigned int fbo, rbo;
+ glGenFramebuffers(1, &fbo);
+ glGenRenderbuffers(1, &rbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glBindRenderbuffer(GL_RENDERBUFFER, rbo);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size, size);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, brdf.id, 0);
+
+ glViewport(0, 0, size, size);
+ glUseProgram(shader.id);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ GenDrawQuad();
+
+ // Unbind framebuffer and textures
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ // Reset viewport dimensions to default
+ glViewport(0, 0, GetScreenWidth(), GetScreenHeight());
+
+ UnloadShader(shader);
+
+ brdf.width = size;
+ brdf.height = size;
+
+ return brdf;
+}
+
// Begin blending mode (alpha, additive, multiplied)
// NOTE: Only 3 blending modes supported, default blend mode is alpha
void BeginBlendMode(int mode)
@@ -3182,8 +3081,8 @@ void EndVrDrawing(void)
rlDisableTexture();
// Update and draw render texture fbo with distortion to backbuffer
- UpdateDefaultBuffers();
- DrawDefaultBuffers();
+ UpdateBuffersDefault();
+ DrawBuffersDefault();
// Restore defaultShader
currentShader = defaultShader;
@@ -3452,7 +3351,7 @@ static Shader LoadShaderDefault(void)
// Get handles to GLSL uniform locations
shader.locs[LOC_MATRIX_MVP] = glGetUniformLocation(shader.id, "mvpMatrix");
shader.locs[LOC_COLOR_DIFFUSE] = glGetUniformLocation(shader.id, "colDiffuse");
- shader.locs[LOC_TEXMAP_DIFFUSE] = glGetUniformLocation(shader.id, "texture0");
+ shader.locs[LOC_MAP_DIFFUSE] = glGetUniformLocation(shader.id, "texture0");
}
else TraceLog(LOG_WARNING, "[SHDR ID %i] Default shader could not be loaded", shader.id);
@@ -3484,9 +3383,9 @@ static void SetShaderDefaultLocations(Shader *shader)
// Get handles to GLSL uniform locations (fragment shader)
shader->locs[LOC_COLOR_DIFFUSE] = glGetUniformLocation(shader->id, "colDiffuse");
- shader->locs[LOC_TEXMAP_DIFFUSE] = glGetUniformLocation(shader->id, "texture0");
- shader->locs[LOC_TEXMAP_NORMAL] = glGetUniformLocation(shader->id, "texture1");
- shader->locs[LOC_TEXMAP_SPECULAR] = glGetUniformLocation(shader->id, "texture2");
+ shader->locs[LOC_MAP_DIFFUSE] = glGetUniformLocation(shader->id, "texture0");
+ shader->locs[LOC_MAP_NORMAL] = glGetUniformLocation(shader->id, "texture1");
+ shader->locs[LOC_MAP_SPECULAR] = glGetUniformLocation(shader->id, "texture2");
// TODO: Try to find all expected/recognized shader locations (predefined names, must be documented)
}
@@ -3504,7 +3403,7 @@ static void UnloadShaderDefault(void)
}
// Load default internal buffers (lines, triangles, quads)
-static void LoadDefaultBuffers(void)
+static void LoadBuffersDefault(void)
{
// [CPU] Allocate and initialize float array buffers to store vertex data (lines, triangles, quads)
//--------------------------------------------------------------------------------------------
@@ -3677,7 +3576,7 @@ static void LoadDefaultBuffers(void)
// Update default internal buffers (VAOs/VBOs) with vertex array data
// NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0)
// TODO: If no data changed on the CPU arrays --> No need to re-update GPU arrays (change flag required)
-static void UpdateDefaultBuffers(void)
+static void UpdateBuffersDefault(void)
{
// Update lines vertex buffers
if (lines.vCounter > 0)
@@ -3747,7 +3646,7 @@ static void UpdateDefaultBuffers(void)
// Draw default internal buffers vertex data
// NOTE: We draw in this order: lines, triangles, quads
-static void DrawDefaultBuffers()
+static void DrawBuffersDefault()
{
Matrix matProjection = projection;
Matrix matModelView = modelview;
@@ -3773,7 +3672,7 @@ static void DrawDefaultBuffers()
glUniformMatrix4fv(currentShader.locs[LOC_MATRIX_MVP], 1, false, MatrixToFloat(matMVP));
glUniform4f(currentShader.locs[LOC_COLOR_DIFFUSE], 1.0f, 1.0f, 1.0f, 1.0f);
- glUniform1i(currentShader.locs[LOC_TEXMAP_DIFFUSE], 0);
+ glUniform1i(currentShader.locs[LOC_MAP_DIFFUSE], 0);
// NOTE: Additional map textures not considered for default buffers drawing
}
@@ -3897,10 +3796,10 @@ static void DrawDefaultBuffers()
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
- glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures
+ glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures
}
- if (vaoSupported) glBindVertexArray(0); // Unbind VAO
+ if (vaoSupported) glBindVertexArray(0); // Unbind VAO
glUseProgram(0); // Unbind shader program
}
@@ -3928,7 +3827,7 @@ static void DrawDefaultBuffers()
}
// Unload default internal buffers vertex data from CPU and GPU
-static void UnloadDefaultBuffers(void)
+static void UnloadBuffersDefault(void)
{
// Unbind everything
if (vaoSupported) glBindVertexArray(0);
@@ -3970,6 +3869,120 @@ static void UnloadDefaultBuffers(void)
free(quads.indices);
}
+// Renders a 1x1 XY quad in NDC
+static void GenDrawQuad(void)
+{
+ unsigned int quadVAO = 0;
+ unsigned int quadVBO = 0;
+
+ float vertices[] = {
+ // Positions // Texture Coords
+ -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
+ -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
+ };
+
+ // Set up plane VAO
+ glGenVertexArrays(1, &quadVAO);
+ glGenBuffers(1, &quadVBO);
+ glBindVertexArray(quadVAO);
+
+ // Fill buffer
+ glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_STATIC_DRAW);
+
+ // Link vertex attributes
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (GLvoid*)0);
+ glEnableVertexAttribArray(1);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (GLvoid*)(3*sizeof(GLfloat)));
+
+ // Draw quad
+ glBindVertexArray(quadVAO);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ glBindVertexArray(0);
+
+ glDeleteBuffers(1, &quadVBO);
+ glDeleteVertexArrays(1, &quadVAO);
+}
+
+// Renders a 1x1 3D cube in NDC
+GLuint cubeVAO = 0;
+GLuint cubeVBO = 0;
+static void GenDrawCube(void)
+{
+ // Lazy initialization
+ if (cubeVAO == 0)
+ {
+ GLfloat 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
+ };
+
+ // Set up cube VAO
+ glGenVertexArrays(1, &cubeVAO);
+ glGenBuffers(1, &cubeVBO);
+
+ // Fill buffer
+ glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
+
+ // Link vertex attributes
+ glBindVertexArray(cubeVAO);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (GLvoid*)0);
+ glEnableVertexAttribArray(1);
+ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (GLvoid*)(3*sizeof(GLfloat)));
+ glEnableVertexAttribArray(2);
+ glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (GLvoid*)(6*sizeof(GLfloat)));
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindVertexArray(0);
+ }
+
+ // Draw cube
+ glBindVertexArray(cubeVAO);
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+ glBindVertexArray(0);
+
+ //glDeleteBuffers(1, &cubeVBO);
+ //glDeleteVertexArrays(1, &cubeVAO);
+}
+
#if defined(SUPPORT_VR_SIMULATOR)
// Configure stereo rendering (including distortion shader) with HMD device parameters
static void SetStereoConfig(VrDeviceInfo hmd)
diff --git a/src/rlgl.h b/src/rlgl.h
index 3adf81a5..a509068e 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -146,6 +146,7 @@ typedef unsigned char byte;
typedef enum { false, true } bool;
#endif
+ // Shader location point type
typedef enum {
LOC_VERTEX_POSITION = 0,
LOC_VERTEX_TEXCOORD01,
@@ -161,38 +162,39 @@ typedef unsigned char byte;
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
+ LOC_MAP_ALBEDO, // LOC_MAP_DIFFUSE
+ LOC_MAP_METALNESS, // LOC_MAP_SPECULAR
+ LOC_MAP_NORMAL,
+ LOC_MAP_ROUGHNESS,
+ LOC_MAP_OCCUSION,
+ LOC_MAP_EMISSION,
+ LOC_MAP_HEIGHT,
+ LOC_MAP_CUBEMAP,
+ LOC_MAP_IRRADIANCE,
+ LOC_MAP_PREFILTER,
+ LOC_MAP_BRDF
} ShaderLocationIndex;
- #define LOC_TEXMAP_DIFFUSE LOC_TEXMAP_ALBEDO
- #define LOC_TEXMAP_SPECULAR LOC_TEXMAP_METALNESS
+ #define LOC_MAP_DIFFUSE LOC_MAP_ALBEDO
+ #define LOC_MAP_SPECULAR LOC_MAP_METALNESS
+ // Material map type
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
+ MAP_ALBEDO = 0, // MAP_DIFFUSE
+ MAP_METALNESS = 1, // MAP_SPECULAR
+ MAP_NORMAL = 2,
+ MAP_ROUGHNESS = 3,
+ MAP_OCCLUSION,
+ MAP_EMISSION,
+ MAP_HEIGHT,
+ MAP_CUBEMAP, // NOTE: Uses GL_TEXTURE_CUBE_MAP
+ MAP_IRRADIANCE, // NOTE: Uses GL_TEXTURE_CUBE_MAP
+ MAP_PREFILTER, // NOTE: Uses GL_TEXTURE_CUBE_MAP
+ MAP_BRDF
} TexmapIndex;
- #define TEXMAP_DIFFUSE TEXMAP_ALBEDO
- #define TEXMAP_SPECULAR TEXMAP_METALNESS
+ #define MAP_DIFFUSE MAP_ALBEDO
+ #define MAP_SPECULAR MAP_METALNESS
// Color type, RGBA (32bit)
typedef struct Color {
@@ -237,8 +239,7 @@ typedef unsigned char byte;
// Shader and material limits
#define MAX_SHADER_LOCATIONS 32
- #define MAX_MATERIAL_TEXTURE_MAPS 12
- #define MAX_MATERIAL_PARAMS 8
+ #define MAX_MATERIAL_MAPS 12
// Shader type (generic)
typedef struct Shader {
@@ -247,16 +248,16 @@ typedef unsigned char byte;
} Shader;
// Material texture map
- typedef struct TextureMap {
+ typedef struct MaterialMap {
Texture2D tex;
Color color;
float value;
- } TextureMap;
+ } MaterialMap;
// Material type (generic)
typedef struct Material {
Shader shader;
- TextureMap maps[MAX_TEXTURE_MAPS]; // Initialized on LoadMaterial*(), set to MAX_TEXTURE_MAPS
+ MaterialMap maps[MAX_TEXTURE_MAPS]; // Initialized on LoadMaterial*(), set to MAX_TEXTURE_MAPS
float *params; // Initialized on LoadMaterial*(), set to MAX_MATERIAL_PARAMS
} Material;
@@ -400,9 +401,10 @@ Vector3 rlUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coo
// Functions Declaration - rlgl functionality
//------------------------------------------------------------------------------------
void rlglInit(int width, int height); // Initialize rlgl (buffers, shaders, textures, states)
-void rlglClose(void); // De-init rlgl
-void rlglDraw(void); // Draw VAO/VBO
-void rlglLoadExtensions(void *loader); // Load OpenGL extensions
+void rlglClose(void); // De-inititialize rlgl (buffers, shaders, textures)
+void rlglDraw(void); // Update and Draw default buffers (lines, triangles, quads)
+
+void rlLoadExtensions(void *loader); // Load OpenGL extensions
// Textures data management
unsigned int rlLoadTexture(void *data, int width, int height, int format, int mipmapCount); // Load texture in GPU
@@ -419,12 +421,6 @@ void rlUpdateMesh(Mesh mesh, int buffer, int numVertex); // Update ve
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,
// to avoid creating function wrappers through core module, they have been directly declared in raylib.h
@@ -447,11 +443,19 @@ void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // S
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)
+// Texture maps generation (PBR)
+Texture2D GenTextureCubemap(Texture2D skyHDR, int size); // Generate cubemap texture map from HDR texture
+Texture2D GenTextureIrradiance(Texture2D cubemap, int size); // Generate irradiance texture map
+Texture2D GenTexturePrefilter(Texture2D cubemap, int size); // Generate prefilter texture map
+Texture2D GenTextureBRDF(Texture2D cubemap, int size); // Generate BRDF texture map
+
+// Shading and 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)
+// VR simulator functionality
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