From 0f10c44578c4500b770589e34cd8404bee4e8cba Mon Sep 17 00:00:00 2001 From: Jeffery Myers Date: Sun, 28 Feb 2021 14:31:25 -0800 Subject: [PATCH] Fixes gl state after HDR texture functions. (#1621) Updates skybox demo to show how to do both HDR and non HDR skyboxes Co-authored-by: Jeffery Myers --- examples/models/models_skybox.c | 71 +++++++++++++----- .../resources/shaders/glsl100/skybox.fs | 9 ++- .../resources/shaders/glsl330/skybox.fs | 9 ++- examples/models/resources/skybox.png | Bin 0 -> 10992 bytes src/rlgl.h | 6 +- 5 files changed, 67 insertions(+), 28 deletions(-) create mode 100644 examples/models/resources/skybox.png diff --git a/examples/models/models_skybox.c b/examples/models/models_skybox.c index f80fbf7a6..ad9c46c22 100644 --- a/examples/models/models_skybox.c +++ b/examples/models/models_skybox.c @@ -10,6 +10,9 @@ ********************************************************************************************/ #include "raylib.h" +#include "rlgl.h" + +bool useHDR = false; int main(void) { @@ -35,7 +38,8 @@ int main(void) skybox.materials[0].shader = LoadShader("resources/shaders/glsl100/skybox.vs", "resources/shaders/glsl100/skybox.fs"); #endif SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "environmentMap"), (int[1]){ MAP_CUBEMAP }, UNIFORM_INT); - SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "vflipped"), (int[1]){ 1 }, UNIFORM_INT); + SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "doGamma"), (int[1]) { useHDR ? 1 : 0 }, UNIFORM_INT); + SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "vflipped"), (int[1]){ useHDR ? 1 : 0 }, UNIFORM_INT); // Load cubemap shader and setup required shader locations #if defined(PLATFORM_DESKTOP) @@ -45,18 +49,29 @@ int main(void) #endif SetShaderValue(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, UNIFORM_INT); - // Load HDR panorama (sphere) texture - char panoFileName[256] = { 0 }; - TextCopy(panoFileName, "resources/dresden_square_2k.hdr"); - Texture2D panorama = LoadTexture(panoFileName); + char skyboxFileName[256] = { 0 }; - // Generate cubemap (texture with 6 quads-cube-mapping) from panorama HDR texture - // NOTE 1: New texture is generated rendering to texture, shader calculates the sphere->cube coordinates mapping - // NOTE 2: It seems on some Android devices WebGL, fbo does not properly support a FLOAT-based attachment, - // despite texture can be successfully created.. so using UNCOMPRESSED_R8G8B8A8 instead of UNCOMPRESSED_R32G32B32A32 - skybox.materials[0].maps[MAP_CUBEMAP].texture = GenTextureCubemap(shdrCubemap, panorama, 1024, UNCOMPRESSED_R8G8B8A8); + if (useHDR) + { + TextCopy(skyboxFileName, "resources/dresden_square_2k.hdr"); - UnloadTexture(panorama); // Texture not required anymore, cubemap already generated + // Load HDR panorama (sphere) texture + Texture2D panorama = panorama = LoadTexture(skyboxFileName); + + // Generate cubemap (texture with 6 quads-cube-mapping) from panorama HDR texture + // NOTE 1: New texture is generated rendering to texture, shader calculates the sphere->cube coordinates mapping + // NOTE 2: It seems on some Android devices WebGL, fbo does not properly support a FLOAT-based attachment, + // despite texture can be successfully created.. so using UNCOMPRESSED_R8G8B8A8 instead of UNCOMPRESSED_R32G32B32A32 + skybox.materials[0].maps[MAP_CUBEMAP].texture = GenTextureCubemap(shdrCubemap, panorama, 1024, UNCOMPRESSED_R8G8B8A8); + + UnloadTexture(panorama); // Texture not required anymore, cubemap already generated + } + else + { + Image img = LoadImage("resources/skybox.png"); + skybox.materials[0].maps[MAP_CUBEMAP].texture = LoadTextureCubemap(img, CUBEMAP_AUTO_DETECT); + UnloadImage(img); + } SetCameraMode(camera, CAMERA_FIRST_PERSON); // Set a first person camera mode @@ -82,12 +97,22 @@ int main(void) { // Unload current cubemap texture and load new one UnloadTexture(skybox.materials[0].maps[MAP_CUBEMAP].texture); - panorama = LoadTexture(droppedFiles[0]); - TextCopy(panoFileName, droppedFiles[0]); - - // Generate cubemap from panorama texture - skybox.materials[0].maps[MAP_CUBEMAP].texture = GenTextureCubemap(shdrCubemap, panorama, 1024, UNCOMPRESSED_R8G8B8A8); - UnloadTexture(panorama); + if (useHDR) + { + Texture2D panorama = LoadTexture(droppedFiles[0]); + + // Generate cubemap from panorama texture + skybox.materials[0].maps[MAP_CUBEMAP].texture = GenTextureCubemap(shdrCubemap, panorama, 1024, UNCOMPRESSED_R8G8B8A8); + UnloadTexture(panorama); + } + else + { + Image img = LoadImage(droppedFiles[0]); + skybox.materials[0].maps[MAP_CUBEMAP].texture = LoadTextureCubemap(img, CUBEMAP_AUTO_DETECT); + UnloadImage(img); + } + + TextCopy(skyboxFileName, droppedFiles[0]); } } @@ -102,11 +127,19 @@ int main(void) ClearBackground(RAYWHITE); BeginMode3D(camera); - DrawModel(skybox, (Vector3){0, 0, 0}, 1.0f, WHITE); + rlDisableBackfaceCulling(); + rlDisableDepthMask(); + DrawModel(skybox, (Vector3){0, 0, 0}, 1.0f, WHITE); + rlEnableBackfaceCulling(); + rlEnableDepthMask(); DrawGrid(10, 1.0f); EndMode3D(); - DrawText(TextFormat("Panorama image from hdrihaven.com: %s", GetFileName(panoFileName)), 10, GetScreenHeight() - 20, 10, BLACK); + if (useHDR) + DrawText(TextFormat("Panorama image from hdrihaven.com: %s", GetFileName(skyboxFileName)), 10, GetScreenHeight() - 20, 10, BLACK); + else + DrawText(TextFormat(": %s", GetFileName(skyboxFileName)), 10, GetScreenHeight() - 20, 10, BLACK); + DrawFPS(10, 10); EndDrawing(); diff --git a/examples/models/resources/shaders/glsl100/skybox.fs b/examples/models/resources/shaders/glsl100/skybox.fs index 1269a96d9..4aa4ec9c0 100644 --- a/examples/models/resources/shaders/glsl100/skybox.fs +++ b/examples/models/resources/shaders/glsl100/skybox.fs @@ -8,6 +8,7 @@ varying vec3 fragPosition; // Input uniform values uniform samplerCube environmentMap; uniform bool vflipped; +uniform bool doGamma; void main() { @@ -19,9 +20,11 @@ void main() vec3 color = vec3(texelColor.x, texelColor.y, texelColor.z); - // Apply gamma correction - color = color/(color + vec3(1.0)); - color = pow(color, vec3(1.0/2.2)); + if (doGamma)// Apply gamma correction + { + color = color/(color + vec3(1.0)); + color = pow(color, vec3(1.0/2.2)); + } // Calculate final fragment color gl_FragColor = vec4(color, 1.0); diff --git a/examples/models/resources/shaders/glsl330/skybox.fs b/examples/models/resources/shaders/glsl330/skybox.fs index dd8078e09..800c1c6fc 100644 --- a/examples/models/resources/shaders/glsl330/skybox.fs +++ b/examples/models/resources/shaders/glsl330/skybox.fs @@ -16,6 +16,7 @@ in vec3 fragPosition; // Input uniform values uniform samplerCube environmentMap; uniform bool vflipped; +uniform bool doGamma; // Output fragment color out vec4 finalColor; @@ -28,9 +29,11 @@ void main() if (vflipped) color = texture(environmentMap, vec3(fragPosition.x, -fragPosition.y, fragPosition.z)).rgb; else color = texture(environmentMap, fragPosition).rgb; - // Apply gamma correction - color = color/(color + vec3(1.0)); - color = pow(color, vec3(1.0/2.2)); + if (doGamma)// Apply gamma correction + { + color = color/(color + vec3(1.0)); + color = pow(color, vec3(1.0/2.2)); + } // Calculate final fragment color finalColor = vec4(color, 1.0); diff --git a/examples/models/resources/skybox.png b/examples/models/resources/skybox.png new file mode 100644 index 0000000000000000000000000000000000000000..36a79b2de5bee79b932730011d25e1e5f6209d48 GIT binary patch literal 10992 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