@@ -2229,6 +2229,48 @@ video::ITexture* TextureSource::getNormalTexture(const std::string &name)
2229
2229
return NULL ;
2230
2230
}
2231
2231
2232
+ namespace {
2233
+ // For more colourspace transformations, see for example
2234
+ // https://github.com/tobspr/GLSL-Color-Spaces/blob/master/ColorSpaces.inc.glsl
2235
+
2236
+ inline float linear_to_srgb_component (float v)
2237
+ {
2238
+ if (v > 0 .0031308f )
2239
+ return 1 .055f * powf (v, 1 .0f / 2 .4f ) - 0 .055f ;
2240
+ return 12 .92f * v;
2241
+ }
2242
+ inline float srgb_to_linear_component (float v)
2243
+ {
2244
+ if (v > 0 .04045f )
2245
+ return powf ((v + 0 .055f ) / 1 .055f , 2 .4f );
2246
+ return v / 12 .92f ;
2247
+ }
2248
+
2249
+ v3f srgb_to_linear (const video::SColor &col_srgb)
2250
+ {
2251
+ v3f col (col_srgb.getRed (), col_srgb.getGreen (), col_srgb.getBlue ());
2252
+ col /= 255 .0f ;
2253
+ col.X = srgb_to_linear_component (col.X );
2254
+ col.Y = srgb_to_linear_component (col.Y );
2255
+ col.Z = srgb_to_linear_component (col.Z );
2256
+ return col;
2257
+ }
2258
+
2259
+ video::SColor linear_to_srgb (const v3f &col_linear)
2260
+ {
2261
+ v3f col;
2262
+ col.X = linear_to_srgb_component (col_linear.X );
2263
+ col.Y = linear_to_srgb_component (col_linear.Y );
2264
+ col.Z = linear_to_srgb_component (col_linear.Z );
2265
+ col *= 255 .0f ;
2266
+ col.X = core::clamp<float >(col.X , 0 .0f , 255 .0f );
2267
+ col.Y = core::clamp<float >(col.Y , 0 .0f , 255 .0f );
2268
+ col.Z = core::clamp<float >(col.Z , 0 .0f , 255 .0f );
2269
+ return video::SColor (0xff , myround (col.X ), myround (col.Y ),
2270
+ myround (col.Z ));
2271
+ }
2272
+ }
2273
+
2232
2274
video::SColor TextureSource::getTextureAverageColor (const std::string &name)
2233
2275
{
2234
2276
video::IVideoDriver *driver = RenderingEngine::get_video_driver ();
@@ -2243,9 +2285,7 @@ video::SColor TextureSource::getTextureAverageColor(const std::string &name)
2243
2285
return c;
2244
2286
2245
2287
u32 total = 0 ;
2246
- u32 tR = 0 ;
2247
- u32 tG = 0 ;
2248
- u32 tB = 0 ;
2288
+ v3f col_acc (0 , 0 , 0 );
2249
2289
core::dimension2d<u32> dim = image->getDimension ();
2250
2290
u16 step = 1 ;
2251
2291
if (dim.Width > 16 )
@@ -2255,17 +2295,14 @@ video::SColor TextureSource::getTextureAverageColor(const std::string &name)
2255
2295
c = image->getPixel (x,y);
2256
2296
if (c.getAlpha () > 0 ) {
2257
2297
total++;
2258
- tR += c.getRed ();
2259
- tG += c.getGreen ();
2260
- tB += c.getBlue ();
2298
+ col_acc += srgb_to_linear (c);
2261
2299
}
2262
2300
}
2263
2301
}
2264
2302
image->drop ();
2265
2303
if (total > 0 ) {
2266
- c.setRed (tR / total);
2267
- c.setGreen (tG / total);
2268
- c.setBlue (tB / total);
2304
+ col_acc /= total;
2305
+ c = linear_to_srgb (col_acc);
2269
2306
}
2270
2307
c.setAlpha (255 );
2271
2308
return c;
0 commit comments