diff --git a/bind/v4k.lua b/bind/v4k.lua index 969a313..6421779 100644 --- a/bind/v4k.lua +++ b/bind/v4k.lua @@ -1270,7 +1270,7 @@ enum MATERIAL_ENUMS { MATERIAL_CHANNEL_AO, MATERIAL_CHANNEL_AMBIENT, MATERIAL_CHANNEL_EMISSIVE, - MAX_CHANNELS_PER_MATERIAL = MATERIAL_CHANNEL_EMISSIVE + MAX_CHANNELS_PER_MATERIAL }; typedef struct material_layer_t { char texname[32]; diff --git a/demos/06-material.c b/demos/06-material.c index 48f0466..9eb4a6f 100644 --- a/demos/06-material.c +++ b/demos/06-material.c @@ -32,8 +32,8 @@ int main() { // load video, RGB texture, no audio video_t *v = video( "pexels-pachon-in-motion-17486489.mp4", VIDEO_RGB | VIDEO_NO_AUDIO | VIDEO_LOOP ); video_seek(v, 30); // load texture - texture_t t1 = texture("kgirl/g01_texture.png", TEXTURE_RGB); - texture_t t2 = texture("matcaps/material3", 0); + texture_t t1 = texture("kgirl/g01_texture.png", TEXTURE_SRGB); + texture_t t2 = texture("matcaps/material3", TEXTURE_SRGB); // load model model_t m1 = model("suzanne.obj", MODEL_NO_ANIMATIONS); model_t m2 = model("suzanne.obj", MODEL_NO_ANIMATIONS|MODEL_MATCAPS); diff --git a/demos/06-scene.c b/demos/06-scene.c index 8bcd5a4..32467f7 100644 --- a/demos/06-scene.c +++ b/demos/06-scene.c @@ -51,7 +51,7 @@ int main() { // manual spawn & loading model_t m1 = model("kgirl/kgirls01.fbx", 0); //MODEL_NO_ANIMS); - texture_t t1 = texture("kgirl/g01_texture.png", TEXTURE_RGB); + texture_t t1 = texture("kgirl/g01_texture.png", TEXTURE_SRGB); object_t* obj3 = scene_spawn(); object_model(obj3, m1); object_diffuse(obj3, t1); diff --git a/demos/08-video.c b/demos/08-video.c index aa7e933..2b96167 100644 --- a/demos/08-video.c +++ b/demos/08-video.c @@ -20,7 +20,7 @@ int main() { // present decoded textures as a fullscreen composed quad profile( "Video quad" ) { - if(is_rgb) fullscreen_quad_rgb( textures[0], 1.3f ); + if(is_rgb) fullscreen_quad_rgb( textures[0], 2.2f ); else fullscreen_quad_ycbcr( textures, 1.3f ); } diff --git a/engine/art/shaders/fs_32_4_model.glsl b/engine/art/shaders/fs_32_4_model.glsl index f2f1604..391f6b0 100644 --- a/engine/art/shaders/fs_32_4_model.glsl +++ b/engine/art/shaders/fs_32_4_model.glsl @@ -447,6 +447,8 @@ void main() { vec3 col = u_rimcolor*(pow(smoothstep(1.0-u_rimrange.x,u_rimrange.y,rim), u_rimrange.z)); fragcolor += vec4(col, 1.0);} #endif + + fragcolor.rgb = pow( fragcolor.rgb, vec3(1. / 2.2) ); } #endif #ifdef SHADING_PBR @@ -691,7 +693,7 @@ void main(void) color = (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06); // gamma correction // color = pow( color, vec3(1. / 2.2) ); -#elif 1 +#elif 0 // aces film (CC0, src: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/) vec3 x = color; float a = 2.51f; @@ -703,6 +705,7 @@ void main(void) // gamma correction color = pow( color, vec3(1. / 2.2) ); #endif + color = pow( color, vec3(1. / 2.2) ); // Technically this alpha may be too transparent, if there is a lot of reflected light we wouldn't // see the background, maybe we can approximate it well enough by adding a fresnel term diff --git a/engine/art/shaders/fs_3_4_skybox.glsl b/engine/art/shaders/fs_3_4_skybox.glsl index 340562c..ad27e6d 100644 --- a/engine/art/shaders/fs_3_4_skybox.glsl +++ b/engine/art/shaders/fs_3_4_skybox.glsl @@ -1,10 +1,11 @@ -uniform samplerCube u_cubemap; - - -in vec3 v_direction; -out vec4 fragcolor; - - -void main() { - fragcolor = vec4(texture(u_cubemap, v_direction).rgb, 1.0); +uniform samplerCube u_cubemap; + + +in vec3 v_direction; +out vec4 fragcolor; + + +void main() { + fragcolor = vec4(texture(u_cubemap, v_direction).rgb, 1.0); + fragcolor.rgb = pow(fragcolor.rgb, vec3(1.0/2.2)); } \ No newline at end of file diff --git a/engine/art/shaders/fs_3_4_skybox_rayleigh.glsl b/engine/art/shaders/fs_3_4_skybox_rayleigh.glsl index 8f09732..4dd4210 100644 --- a/engine/art/shaders/fs_3_4_skybox_rayleigh.glsl +++ b/engine/art/shaders/fs_3_4_skybox_rayleigh.glsl @@ -1,154 +1,154 @@ -uniform vec3 uSunPos; -uniform vec3 uRayOrigin; -uniform float uSunIntensity; -uniform float uPlanetRadius; -uniform float uAtmosphereRadius; -uniform vec3 uRayleighScattering; -uniform float uMieScattering; -uniform float uRayleighScaleHeight; -uniform float uMieScaleHeight; -uniform float uMiePreferredDirection; - - -in vec3 v_direction; -out vec4 fragcolor; - - -vec3 atmosphere(vec3 r, vec3 r0, vec3 pSun, float iSun, float rPlanet, float rAtmos, vec3 kRlh, float kMie, float shRlh, float shMie, float g); - - -void main() { - vec3 color = atmosphere( - normalize(v_direction), // normalized ray direction - uRayOrigin, // ray origin - uSunPos, // position of the sun - uSunIntensity, // intensity of the sun - uPlanetRadius, // radius of the planet in meters - uAtmosphereRadius, // radius of the atmosphere in meters - uRayleighScattering, // Rayleigh scattering coefficient - uMieScattering, // Mie scattering coefficient - uRayleighScaleHeight, // Rayleigh scale height - uMieScaleHeight, // Mie scale height - uMiePreferredDirection // Mie preferred scattering direction - ); - - // Apply exposure. - color = 1.0 - exp(-1.0 * color); - - fragcolor = vec4(color, 1); -} - - -// [src] https://github.com/wwwtyro/glsl-atmosphere by wwwtyro (Unlicensed) -// For more information, please refer to - - -#define PI 3.141592 -#define iSteps 16 -#define jSteps 8 - - -vec2 rsi(vec3 r0, vec3 rd, float sr) { - // ray-sphere intersection that assumes - // the sphere is centered at the origin. - // No intersection when result.x > result.y - float a = dot(rd, rd); - float b = 2.0 * dot(rd, r0); - float c = dot(r0, r0) - (sr * sr); - float d = (b*b) - 4.0*a*c; - if (d < 0.0) return vec2(1e5,-1e5); - return vec2( - (-b - sqrt(d))/(2.0*a), - (-b + sqrt(d))/(2.0*a) - ); -} - - -vec3 atmosphere(vec3 r, vec3 r0, vec3 pSun, float iSun, float rPlanet, float rAtmos, vec3 kRlh, float kMie, float shRlh, float shMie, float g) { - // Normalize the sun and view directions. - pSun = normalize(pSun); - r = normalize(r); - - // Calculate the step size of the primary ray. - vec2 p = rsi(r0, r, rAtmos); - if (p.x > p.y) return vec3(0,0,0); - p.y = min(p.y, rsi(r0, r, rPlanet).x); - float iStepSize = (p.y - p.x) / float(iSteps); - - // Initialize the primary ray time. - float iTime = 0.0; - - // Initialize accumulators for Rayleigh and Mie scattering. - vec3 totalRlh = vec3(0,0,0); - vec3 totalMie = vec3(0,0,0); - - // Initialize optical depth accumulators for the primary ray. - float iOdRlh = 0.0; - float iOdMie = 0.0; - - // Calculate the Rayleigh and Mie phases. - float mu = dot(r, pSun); - float mumu = mu * mu; - float gg = g * g; - float pRlh = 3.0 / (16.0 * PI) * (1.0 + mumu); - float pMie = 3.0 / (8.0 * PI) * ((1.0 - gg) * (mumu + 1.0)) / (pow(1.0 + gg - 2.0 * mu * g, 1.5) * (2.0 + gg)); - - // Sample the primary ray. - for (int i = 0; i < iSteps; i++) { - - // Calculate the primary ray sample position. - vec3 iPos = r0 + r * (iTime + iStepSize * 0.5); - - // Calculate the height of the sample. - float iHeight = length(iPos) - rPlanet; - - // Calculate the optical depth of the Rayleigh and Mie scattering for this step. - float odStepRlh = exp(-iHeight / shRlh) * iStepSize; - float odStepMie = exp(-iHeight / shMie) * iStepSize; - - // Accumulate optical depth. - iOdRlh += odStepRlh; - iOdMie += odStepMie; - - // Calculate the step size of the secondary ray. - float jStepSize = rsi(iPos, pSun, rAtmos).y / float(jSteps); - - // Initialize the secondary ray time. - float jTime = 0.0; - - // Initialize optical depth accumulators for the secondary ray. - float jOdRlh = 0.0; - float jOdMie = 0.0; - - // Sample the secondary ray. - for (int j = 0; j < jSteps; j++) { - - // Calculate the secondary ray sample position. - vec3 jPos = iPos + pSun * (jTime + jStepSize * 0.5); - - // Calculate the height of the sample. - float jHeight = length(jPos) - rPlanet; - - // Accumulate the optical depth. - jOdRlh += exp(-jHeight / shRlh) * jStepSize; - jOdMie += exp(-jHeight / shMie) * jStepSize; - - // Increment the secondary ray time. - jTime += jStepSize; - } - - // Calculate attenuation. - vec3 attn = exp(-(kMie * (iOdMie + jOdMie) + kRlh * (iOdRlh + jOdRlh))); - - // Accumulate scattering. - totalRlh += odStepRlh * attn; - totalMie += odStepMie * attn; - - // Increment the primary ray time. - iTime += iStepSize; - - } - - // Calculate and return the final color. - return iSun * (pRlh * kRlh * totalRlh + pMie * kMie * totalMie); +uniform vec3 uSunPos; +uniform vec3 uRayOrigin; +uniform float uSunIntensity; +uniform float uPlanetRadius; +uniform float uAtmosphereRadius; +uniform vec3 uRayleighScattering; +uniform float uMieScattering; +uniform float uRayleighScaleHeight; +uniform float uMieScaleHeight; +uniform float uMiePreferredDirection; + + +in vec3 v_direction; +out vec4 fragcolor; + + +vec3 atmosphere(vec3 r, vec3 r0, vec3 pSun, float iSun, float rPlanet, float rAtmos, vec3 kRlh, float kMie, float shRlh, float shMie, float g); + + +void main() { + vec3 color = atmosphere( + normalize(v_direction), // normalized ray direction + uRayOrigin, // ray origin + uSunPos, // position of the sun + uSunIntensity, // intensity of the sun + uPlanetRadius, // radius of the planet in meters + uAtmosphereRadius, // radius of the atmosphere in meters + uRayleighScattering, // Rayleigh scattering coefficient + uMieScattering, // Mie scattering coefficient + uRayleighScaleHeight, // Rayleigh scale height + uMieScaleHeight, // Mie scale height + uMiePreferredDirection // Mie preferred scattering direction + ); + + // Apply exposure. + color = 1.0 - exp(-1.0 * color); + + fragcolor = vec4(color, 1); +} + + +// [src] https://github.com/wwwtyro/glsl-atmosphere by wwwtyro (Unlicensed) +// For more information, please refer to + + +#define PI 3.141592 +#define iSteps 16 +#define jSteps 8 + + +vec2 rsi(vec3 r0, vec3 rd, float sr) { + // ray-sphere intersection that assumes + // the sphere is centered at the origin. + // No intersection when result.x > result.y + float a = dot(rd, rd); + float b = 2.0 * dot(rd, r0); + float c = dot(r0, r0) - (sr * sr); + float d = (b*b) - 4.0*a*c; + if (d < 0.0) return vec2(1e5,-1e5); + return vec2( + (-b - sqrt(d))/(2.0*a), + (-b + sqrt(d))/(2.0*a) + ); +} + + +vec3 atmosphere(vec3 r, vec3 r0, vec3 pSun, float iSun, float rPlanet, float rAtmos, vec3 kRlh, float kMie, float shRlh, float shMie, float g) { + // Normalize the sun and view directions. + pSun = normalize(pSun); + r = normalize(r); + + // Calculate the step size of the primary ray. + vec2 p = rsi(r0, r, rAtmos); + if (p.x > p.y) return vec3(0,0,0); + p.y = min(p.y, rsi(r0, r, rPlanet).x); + float iStepSize = (p.y - p.x) / float(iSteps); + + // Initialize the primary ray time. + float iTime = 0.0; + + // Initialize accumulators for Rayleigh and Mie scattering. + vec3 totalRlh = vec3(0,0,0); + vec3 totalMie = vec3(0,0,0); + + // Initialize optical depth accumulators for the primary ray. + float iOdRlh = 0.0; + float iOdMie = 0.0; + + // Calculate the Rayleigh and Mie phases. + float mu = dot(r, pSun); + float mumu = mu * mu; + float gg = g * g; + float pRlh = 3.0 / (16.0 * PI) * (1.0 + mumu); + float pMie = 3.0 / (8.0 * PI) * ((1.0 - gg) * (mumu + 1.0)) / (pow(1.0 + gg - 2.0 * mu * g, 1.5) * (2.0 + gg)); + + // Sample the primary ray. + for (int i = 0; i < iSteps; i++) { + + // Calculate the primary ray sample position. + vec3 iPos = r0 + r * (iTime + iStepSize * 0.5); + + // Calculate the height of the sample. + float iHeight = length(iPos) - rPlanet; + + // Calculate the optical depth of the Rayleigh and Mie scattering for this step. + float odStepRlh = exp(-iHeight / shRlh) * iStepSize; + float odStepMie = exp(-iHeight / shMie) * iStepSize; + + // Accumulate optical depth. + iOdRlh += odStepRlh; + iOdMie += odStepMie; + + // Calculate the step size of the secondary ray. + float jStepSize = rsi(iPos, pSun, rAtmos).y / float(jSteps); + + // Initialize the secondary ray time. + float jTime = 0.0; + + // Initialize optical depth accumulators for the secondary ray. + float jOdRlh = 0.0; + float jOdMie = 0.0; + + // Sample the secondary ray. + for (int j = 0; j < jSteps; j++) { + + // Calculate the secondary ray sample position. + vec3 jPos = iPos + pSun * (jTime + jStepSize * 0.5); + + // Calculate the height of the sample. + float jHeight = length(jPos) - rPlanet; + + // Accumulate the optical depth. + jOdRlh += exp(-jHeight / shRlh) * jStepSize; + jOdMie += exp(-jHeight / shMie) * jStepSize; + + // Increment the secondary ray time. + jTime += jStepSize; + } + + // Calculate attenuation. + vec3 attn = exp(-(kMie * (iOdMie + jOdMie) + kRlh * (iOdRlh + jOdRlh))); + + // Accumulate scattering. + totalRlh += odStepRlh * attn; + totalMie += odStepMie * attn; + + // Increment the primary ray time. + iTime += iStepSize; + + } + + // Calculate and return the final color. + return iSun * (pRlh * kRlh * totalRlh + pMie * kMie * totalMie); } \ No newline at end of file diff --git a/engine/joint/v4k.h b/engine/joint/v4k.h index d56a723..b371ff1 100644 --- a/engine/joint/v4k.h +++ b/engine/joint/v4k.h @@ -17476,7 +17476,8 @@ enum MATERIAL_ENUMS { MATERIAL_CHANNEL_AO, MATERIAL_CHANNEL_AMBIENT, MATERIAL_CHANNEL_EMISSIVE, - MAX_CHANNELS_PER_MATERIAL = MATERIAL_CHANNEL_EMISSIVE + + MAX_CHANNELS_PER_MATERIAL }; typedef struct material_layer_t { @@ -363360,7 +363361,7 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len, glEnableVertexAttribArray(1); glVertexAttribPointer(1,4,GL_FLOAT,GL_FALSE,0,(void*)0); glVertexAttribDivisor(1, 1); - //glEnable(GL_FRAMEBUFFER_SRGB); + // glEnable(GL_FRAMEBUFFER_SRGB); // setup and upload font bitmap texture glGenTextures(1, &f->texture_fontdata); @@ -371571,7 +371572,7 @@ cubemap_t cubemap6( const image_t images[6], int flags ) { for (int i = 0; i < 6; i++) { image_t img = images[i]; //image(textures[i], IMAGE_RGB); - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, img.w, img.h, 0, img.n == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, img.pixels); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_SRGB, img.w, img.h, 0, img.n == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, img.pixels); // calculate SH coefficients (@ands) const vec3 skyDir[] = {{ 1, 0, 0},{-1, 0, 0},{ 0, 1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1}}; @@ -371663,7 +371664,7 @@ skybox_t skybox(const char *asset, int flags) { if( asset ) { int is_panorama = vfs_size( asset ); if( is_panorama ) { // is file - stbi_hdr_to_ldr_gamma(1.2f); + // stbi_hdr_to_ldr_gamma(1.2f); image_t panorama = image( asset, IMAGE_RGBA ); sky.cubemap = cubemap( panorama, 0 ); // RGBA required image_destroy(&panorama); @@ -373335,7 +373336,7 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model, if( reused ) continue; // decode texture+material - int flags = TEXTURE_MIPMAPS|TEXTURE_REPEAT|TEXTURE_ANISOTROPY; // LINEAR, NEAREST + int flags = TEXTURE_MIPMAPS|TEXTURE_REPEAT|TEXTURE_ANISOTROPY|TEXTURE_SRGB; // LINEAR, NEAREST if (!(_flags & MODEL_NO_FILTERING)) flags |= TEXTURE_LINEAR; int invalid = texture_checker().id; @@ -375414,7 +375415,7 @@ int scene_merge(const char *source) { //char *a = archive_read(animation_file); object_t *o = scene_spawn(); object_model(o, m); - if( texture_file[0] ) object_diffuse(o, texture_from_mem(vfs_read(texture_file), vfs_size(texture_file), opt_flip_uv ? IMAGE_FLIP : 0) ); + if( texture_file[0] ) object_diffuse(o, texture_from_mem(vfs_read(texture_file), vfs_size(texture_file), TEXTURE_SRGB|(opt_flip_uv ? IMAGE_FLIP : 0)) ); object_scale(o, scale); object_teleport(o, position); object_pivot(o, rotation); // object_rotate(o, rotation); diff --git a/engine/split/v4k_font.c b/engine/split/v4k_font.c index 0b6f9f8..0b952af 100644 --- a/engine/split/v4k_font.c +++ b/engine/split/v4k_font.c @@ -1816,7 +1816,7 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len, glEnableVertexAttribArray(1); glVertexAttribPointer(1,4,GL_FLOAT,GL_FALSE,0,(void*)0); glVertexAttribDivisor(1, 1); - //glEnable(GL_FRAMEBUFFER_SRGB); + // glEnable(GL_FRAMEBUFFER_SRGB); // setup and upload font bitmap texture glGenTextures(1, &f->texture_fontdata); diff --git a/engine/split/v4k_render.c b/engine/split/v4k_render.c index 1485b3d..fb7cdf5 100644 --- a/engine/split/v4k_render.c +++ b/engine/split/v4k_render.c @@ -1555,7 +1555,7 @@ cubemap_t cubemap6( const image_t images[6], int flags ) { for (int i = 0; i < 6; i++) { image_t img = images[i]; //image(textures[i], IMAGE_RGB); - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, img.w, img.h, 0, img.n == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, img.pixels); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_SRGB, img.w, img.h, 0, img.n == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, img.pixels); // calculate SH coefficients (@ands) const vec3 skyDir[] = {{ 1, 0, 0},{-1, 0, 0},{ 0, 1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1}}; @@ -1647,7 +1647,7 @@ skybox_t skybox(const char *asset, int flags) { if( asset ) { int is_panorama = vfs_size( asset ); if( is_panorama ) { // is file - stbi_hdr_to_ldr_gamma(1.2f); + // stbi_hdr_to_ldr_gamma(1.2f); image_t panorama = image( asset, IMAGE_RGBA ); sky.cubemap = cubemap( panorama, 0 ); // RGBA required image_destroy(&panorama); @@ -3319,7 +3319,7 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model, if( reused ) continue; // decode texture+material - int flags = TEXTURE_MIPMAPS|TEXTURE_REPEAT|TEXTURE_ANISOTROPY; // LINEAR, NEAREST + int flags = TEXTURE_MIPMAPS|TEXTURE_REPEAT|TEXTURE_ANISOTROPY|TEXTURE_SRGB; // LINEAR, NEAREST if (!(_flags & MODEL_NO_FILTERING)) flags |= TEXTURE_LINEAR; int invalid = texture_checker().id; diff --git a/engine/split/v4k_render.h b/engine/split/v4k_render.h index 2512629..29f341e 100644 --- a/engine/split/v4k_render.h +++ b/engine/split/v4k_render.h @@ -454,7 +454,8 @@ enum MATERIAL_ENUMS { MATERIAL_CHANNEL_AO, MATERIAL_CHANNEL_AMBIENT, MATERIAL_CHANNEL_EMISSIVE, - MAX_CHANNELS_PER_MATERIAL = MATERIAL_CHANNEL_EMISSIVE + + MAX_CHANNELS_PER_MATERIAL }; typedef struct material_layer_t { diff --git a/engine/split/v4k_scene.c b/engine/split/v4k_scene.c index 8dd9029..0a63c51 100644 --- a/engine/split/v4k_scene.c +++ b/engine/split/v4k_scene.c @@ -440,7 +440,7 @@ int scene_merge(const char *source) { //char *a = archive_read(animation_file); object_t *o = scene_spawn(); object_model(o, m); - if( texture_file[0] ) object_diffuse(o, texture_from_mem(vfs_read(texture_file), vfs_size(texture_file), opt_flip_uv ? IMAGE_FLIP : 0) ); + if( texture_file[0] ) object_diffuse(o, texture_from_mem(vfs_read(texture_file), vfs_size(texture_file), TEXTURE_SRGB|(opt_flip_uv ? IMAGE_FLIP : 0)) ); object_scale(o, scale); object_teleport(o, position); object_pivot(o, rotation); // object_rotate(o, rotation); diff --git a/engine/v4k.c b/engine/v4k.c index 55c4443..33d2579 100644 --- a/engine/v4k.c +++ b/engine/v4k.c @@ -10518,7 +10518,7 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len, glEnableVertexAttribArray(1); glVertexAttribPointer(1,4,GL_FLOAT,GL_FALSE,0,(void*)0); glVertexAttribDivisor(1, 1); - //glEnable(GL_FRAMEBUFFER_SRGB); + // glEnable(GL_FRAMEBUFFER_SRGB); // setup and upload font bitmap texture glGenTextures(1, &f->texture_fontdata); @@ -18729,7 +18729,7 @@ cubemap_t cubemap6( const image_t images[6], int flags ) { for (int i = 0; i < 6; i++) { image_t img = images[i]; //image(textures[i], IMAGE_RGB); - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, img.w, img.h, 0, img.n == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, img.pixels); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_SRGB, img.w, img.h, 0, img.n == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, img.pixels); // calculate SH coefficients (@ands) const vec3 skyDir[] = {{ 1, 0, 0},{-1, 0, 0},{ 0, 1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1}}; @@ -18821,7 +18821,7 @@ skybox_t skybox(const char *asset, int flags) { if( asset ) { int is_panorama = vfs_size( asset ); if( is_panorama ) { // is file - stbi_hdr_to_ldr_gamma(1.2f); + // stbi_hdr_to_ldr_gamma(1.2f); image_t panorama = image( asset, IMAGE_RGBA ); sky.cubemap = cubemap( panorama, 0 ); // RGBA required image_destroy(&panorama); @@ -20493,7 +20493,7 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model, if( reused ) continue; // decode texture+material - int flags = TEXTURE_MIPMAPS|TEXTURE_REPEAT|TEXTURE_ANISOTROPY; // LINEAR, NEAREST + int flags = TEXTURE_MIPMAPS|TEXTURE_REPEAT|TEXTURE_ANISOTROPY|TEXTURE_SRGB; // LINEAR, NEAREST if (!(_flags & MODEL_NO_FILTERING)) flags |= TEXTURE_LINEAR; int invalid = texture_checker().id; @@ -22572,7 +22572,7 @@ int scene_merge(const char *source) { //char *a = archive_read(animation_file); object_t *o = scene_spawn(); object_model(o, m); - if( texture_file[0] ) object_diffuse(o, texture_from_mem(vfs_read(texture_file), vfs_size(texture_file), opt_flip_uv ? IMAGE_FLIP : 0) ); + if( texture_file[0] ) object_diffuse(o, texture_from_mem(vfs_read(texture_file), vfs_size(texture_file), TEXTURE_SRGB|(opt_flip_uv ? IMAGE_FLIP : 0)) ); object_scale(o, scale); object_teleport(o, position); object_pivot(o, rotation); // object_rotate(o, rotation); diff --git a/engine/v4k.h b/engine/v4k.h index 2906179..57d7ba6 100644 --- a/engine/v4k.h +++ b/engine/v4k.h @@ -3543,7 +3543,8 @@ enum MATERIAL_ENUMS { MATERIAL_CHANNEL_AO, MATERIAL_CHANNEL_AMBIENT, MATERIAL_CHANNEL_EMISSIVE, - MAX_CHANNELS_PER_MATERIAL = MATERIAL_CHANNEL_EMISSIVE + + MAX_CHANNELS_PER_MATERIAL }; typedef struct material_layer_t {