diff --git a/examples/models/models_material_pbr.c b/examples/models/models_material_pbr.c index adb4762b..d393a20d 100644 --- a/examples/models/models_material_pbr.c +++ b/examples/models/models_material_pbr.c @@ -38,7 +38,11 @@ int main() // Load model and PBR material Model model = LoadModel("resources/pbr/trooper.obj"); + + // Mesh tangents are generated... and uploaded to GPU + // NOTE: New VBO for tangents is generated at default location and also binded to mesh VAO MeshTangents(&model.meshes[0]); + model.materials[0] = LoadMaterialPBR((Color){ 255, 255, 255, 255 }, 1.0f, 1.0f); // Define lights attributes @@ -143,9 +147,13 @@ static Material LoadMaterialPBR(Color albedo, float metalness, float roughness) #define PATH_BRDF_FS "resources/shaders/brdf.fs" // Path to bidirectional reflectance distribution function fragment shader Shader shdrCubemap = LoadShader(PATH_CUBEMAP_VS, PATH_CUBEMAP_FS); + printf("Loaded shader: cubemap\n"); Shader shdrIrradiance = LoadShader(PATH_SKYBOX_VS, PATH_IRRADIANCE_FS); + printf("Loaded shader: irradiance\n"); Shader shdrPrefilter = LoadShader(PATH_SKYBOX_VS, PATH_PREFILTER_FS); + printf("Loaded shader: prefilter\n"); Shader shdrBRDF = LoadShader(PATH_BRDF_VS, PATH_BRDF_FS); + printf("Loaded shader: brdf\n"); // Setup required shader locations SetShaderValue(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, UNIFORM_INT); diff --git a/examples/models/resources/shaders/brdf.fs b/examples/models/resources/shaders/brdf.fs index 3e8777d2..d04bc661 100644 --- a/examples/models/resources/shaders/brdf.fs +++ b/examples/models/resources/shaders/brdf.fs @@ -10,13 +10,13 @@ #version 330 -#define MAX_SAMPLES 1024u // Input vertex attributes (from vertex shader) in vec2 fragTexCoord; // Constant values const float PI = 3.14159265359; +const uint MAX_SAMPLES = 1024u; // Output fragment color out vec4 finalColor; @@ -93,7 +93,7 @@ vec2 IntegrateBRDF(float NdotV, float roughness) vec3 V = vec3(sqrt(1.0 - NdotV*NdotV), 0.0, NdotV); vec3 N = vec3(0.0, 0.0, 1.0); - for (int i = 0; i < MAX_SAMPLES; i++) + for (uint i = 0u; i < MAX_SAMPLES; i++) { // Generate a sample vector that's biased towards the preferred alignment direction (importance sampling) diff --git a/examples/models/resources/shaders/irradiance.fs b/examples/models/resources/shaders/irradiance.fs index 87113673..b42d2143 100644 --- a/examples/models/resources/shaders/irradiance.fs +++ b/examples/models/resources/shaders/irradiance.fs @@ -9,7 +9,7 @@ #version 330 // Input vertex attributes (from vertex shader) -in vec3 fragPos; +in vec3 fragPosition; // Input uniform values uniform samplerCube environmentMap; @@ -23,7 +23,7 @@ out vec4 finalColor; void main() { // The sample direction equals the hemisphere's orientation - vec3 normal = normalize(fragPos); + vec3 normal = normalize(fragPosition); vec3 irradiance = vec3(0.0); diff --git a/examples/models/resources/shaders/prefilter.fs b/examples/models/resources/shaders/prefilter.fs index f5cf64be..9439810d 100644 --- a/examples/models/resources/shaders/prefilter.fs +++ b/examples/models/resources/shaders/prefilter.fs @@ -11,7 +11,7 @@ #define CUBEMAP_RESOLUTION 1024.0 // Input vertex attributes (from vertex shader) -in vec3 fragPos; +in vec3 fragPosition; // Input uniform values uniform samplerCube environmentMap; @@ -79,7 +79,7 @@ vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness) void main() { // Make the simplyfying assumption that V equals R equals the normal - vec3 N = normalize(fragPos); + vec3 N = normalize(fragPosition); vec3 R = N; vec3 V = R; diff --git a/src/models.c b/src/models.c index e437a0ab..7a9acdf7 100644 --- a/src/models.c +++ b/src/models.c @@ -2302,6 +2302,9 @@ void MeshTangents(Mesh *mesh) free(tan1); free(tan2); + + // Load a new tangent attributes buffer + mesh->vboId[LOC_VERTEX_TANGENT] = rlLoadAttribBuffer(mesh->vaoId, LOC_VERTEX_TANGENT, mesh->tangents, mesh->vertexCount*4*sizeof(float), false); TraceLog(LOG_INFO, "Tangents computed for mesh"); } diff --git a/src/rlgl.h b/src/rlgl.h index 3d433377..bf50ad0d 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -456,6 +456,7 @@ void rlDeleteBuffers(unsigned int id); // Unload vertex data (V 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) void rlUpdateBuffer(int bufferId, void *data, int dataSize); // Update GPU buffer with new data +unsigned int rlLoadAttribBuffer(unsigned int vaoId, int shaderLoc, void *buffer, int size, bool dynamic); // Load a new attributes buffer //------------------------------------------------------------------------------------ // Functions Declaration - rlgl functionality @@ -2532,6 +2533,29 @@ void rlLoadMesh(Mesh *mesh, bool dynamic) #endif } +// Load a new attributes buffer +unsigned int rlLoadAttribBuffer(unsigned int vaoId, int shaderLoc, void *buffer, int size, bool dynamic) +{ + unsigned int id = 0; + +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + int drawHint = GL_STATIC_DRAW; + if (dynamic) drawHint = GL_DYNAMIC_DRAW; + + if (vaoSupported) glBindVertexArray(vaoId); + + glGenBuffers(1, &id); + glBindBuffer(GL_ARRAY_BUFFER, id); + glBufferData(GL_ARRAY_BUFFER, size, buffer, drawHint); + glVertexAttribPointer(shaderLoc, 2, GL_FLOAT, 0, 0, 0); + glEnableVertexAttribArray(shaderLoc); + + if (vaoSupported) glBindVertexArray(0); +#endif + + return id; +} + // Update vertex data on GPU (upload new data to one buffer) void rlUpdateMesh(Mesh mesh, int buffer, int numVertex) {