aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCraig Robbins <kde.psych@gmail.com>2014-12-14 21:28:08 +1000
committerCraig Robbins <kde.psych@gmail.com>2014-12-31 02:44:31 +1000
commit3d29be24e089b1c267409f05b897ce3f03e99a07 (patch)
tree56ecebfe323bf37536dcbf44c7a0668f725abc94 /src
parent2414580754734b62119369255b0e9c462381dc8a (diff)
downloadminetest-3d29be24e089b1c267409f05b897ce3f03e99a07.tar.gz
minetest-3d29be24e089b1c267409f05b897ce3f03e99a07.tar.bz2
minetest-3d29be24e089b1c267409f05b897ce3f03e99a07.zip
Add display_gamma option for client
Diffstat (limited to 'src')
-rw-r--r--src/clientmap.cpp1
-rw-r--r--src/defaultsettings.cpp1
-rw-r--r--src/game.cpp2
-rw-r--r--src/light.cpp98
-rw-r--r--src/light.h30
-rw-r--r--src/mapnode.h12
6 files changed, 103 insertions, 41 deletions
diff --git a/src/clientmap.cpp b/src/clientmap.cpp
index a5d364b73..0e53ab678 100644
--- a/src/clientmap.cpp
+++ b/src/clientmap.cpp
@@ -854,7 +854,6 @@ int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor,
ret = decode_light(n.getLightBlend(daylight_factor, ndef));
} else {
ret = oldvalue;
- //ret = blend_light(255, 0, daylight_factor);
}
} else {
/*float pre = (float)brightness_sum / (float)brightness_count;
diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp
index b660912f9..f46260dab 100644
--- a/src/defaultsettings.cpp
+++ b/src/defaultsettings.cpp
@@ -108,6 +108,7 @@ void set_default_settings(Settings *settings)
settings->setDefault("new_style_leaves", "true");
settings->setDefault("connected_glass", "false");
settings->setDefault("smooth_lighting", "true");
+ settings->setDefault("display_gamma", "1.8");
settings->setDefault("texture_path", "");
settings->setDefault("shader_path", "");
settings->setDefault("video_driver", "opengl");
diff --git a/src/game.cpp b/src/game.cpp
index 79dec17c6..5d44a7db5 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -1747,6 +1747,8 @@ void Game::run()
std::vector<aabb3f> highlight_boxes;
+ set_light_table(g_settings->getFloat("display_gamma"));
+
while (device->run() && !(*kill || g_gamecallback->shutdown_requested)) {
/* Must be called immediately after a device->run() call because it
diff --git a/src/light.cpp b/src/light.cpp
index 765c6303a..08380a180 100644
--- a/src/light.cpp
+++ b/src/light.cpp
@@ -18,31 +18,93 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include "light.h"
+#include <math.h>
+#include "util/numeric.h"
+
+#ifndef SERVER
-#if 1
-// Middle-raised variation of a_n+1 = a_n * 0.786
// Length of LIGHT_MAX+1 means LIGHT_MAX is the last value.
// LIGHT_SUN is read as LIGHT_MAX from here.
-u8 light_decode_table[LIGHT_MAX+1] =
+
+u8 light_LUT[LIGHT_MAX+1] =
{
-8,
-11+2,
-14+7,
-18+10,
-22+15,
-29+20,
-37+20,
-47+15,
-60+10,
-76+7,
-97+5,
-123+2,
-157,
-200,
-255,
+ /* Middle-raised variation of a_n+1 = a_n * 0.786
+ * Length of LIGHT_MAX+1 means LIGHT_MAX is the last value.
+ * LIGHT_SUN is read as LIGHT_MAX from here.
+ */
+ 8,
+ 11+2,
+ 14+7,
+ 18+10,
+ 22+15,
+ 29+20,
+ 37+20,
+ 47+15,
+ 60+10,
+ 76+7,
+ 97+5,
+ 123+2,
+ 157,
+ 200,
+ 255,
};
+
+const u8 *light_decode_table = light_LUT;
+
+/** Initialize or update the light value tables using the specified \p gamma.
+ * If \p gamma == 1.0 then the light table is linear. Typically values for
+ * gamma range between 1.8 and 2.2.
+ *
+ * @note The value for gamma will be restricted to the range 1.1 <= gamma <= 3.0.
+ *
+ * @note This function is not, currently, a simple linear to gamma encoding
+ * because adjustments are made so that a gamma of 1.8 gives the same
+ * results as those hardcoded for use by the server.
+ */
+void set_light_table(float gamma)
+{
+ static const float brightness_step = 255.0f / (LIGHT_MAX + 1);
+
+ /* These are adjustment values that are added to the calculated light value
+ * after gamma is applied. Currently they are used so that given a gamma
+ * of 1.8 the light values set by this function are the same as those
+ * hardcoded in the initalizer list for the declaration of light_LUT.
+ */
+ static const int adjustments[LIGHT_MAX + 1] = {
+ 7,
+ 7,
+ 7,
+ 5,
+ 2,
+ 0,
+ -7,
+ -20,
+ -31,
+ -39,
+ -43,
+ -45,
+ -40,
+ -25,
+ 0
+ };
+
+ gamma = rangelim(gamma, 1.1, 3.0);
+
+ float brightness = brightness_step;
+
+ for (size_t i = 0; i < LIGHT_MAX; i++) {
+ light_LUT[i] = (u8)(255 * powf(brightness / 255.0f, gamma));
+ light_LUT[i] = rangelim(light_LUT[i] + adjustments[i], 0, 255);
+ if (i > 1 && light_LUT[i] < light_LUT[i-1])
+ light_LUT[i] = light_LUT[i-1] + 1;
+ brightness += brightness_step;
+ }
+ light_LUT[LIGHT_MAX] = 255;
+}
#endif
+
+
#if 0
/*
Made using this and:
diff --git a/src/light.h b/src/light.h
index 769ca31ce..f49be4518 100644
--- a/src/light.h
+++ b/src/light.h
@@ -63,7 +63,21 @@ inline u8 undiminish_light(u8 light)
return light + 1;
}
-extern u8 light_decode_table[LIGHT_MAX+1];
+#ifndef SERVER
+
+/**
+ * \internal
+ *
+ * \warning DO NOT USE this directly; it is here simply so that decode_light()
+ * can be inlined.
+ *
+ * Array size is #LIGHTMAX+1
+ *
+ * The array is a lookup table to convert the internal representation of light
+ * (brightness) to the display brightness.
+ *
+ */
+extern const u8 *light_decode_table;
// 0 <= light <= LIGHT_SUN
// 0 <= return value <= 255
@@ -93,6 +107,10 @@ inline float decode_light_f(float light_f)
return f * v2 + (1.0 - f) * v1;
}
+void set_light_table(float gamma);
+
+#endif // ifndef SERVER
+
// 0 <= daylight_factor <= 1000
// 0 <= lightday, lightnight <= LIGHT_SUN
// 0 <= return value <= LIGHT_SUN
@@ -105,15 +123,5 @@ inline u8 blend_light(u32 daylight_factor, u8 lightday, u8 lightnight)
return l;
}
-// 0.0 <= daylight_factor <= 1.0
-// 0 <= lightday, lightnight <= LIGHT_SUN
-// 0 <= return value <= 255
-inline u8 blend_light_f1(float daylight_factor, u8 lightday, u8 lightnight)
-{
- u8 l = ((daylight_factor * decode_light(lightday) +
- (1.0-daylight_factor) * decode_light(lightnight)));
- return l;
-}
-
#endif
diff --git a/src/mapnode.h b/src/mapnode.h
index e67724ec1..da6e9bdea 100644
--- a/src/mapnode.h
+++ b/src/mapnode.h
@@ -209,7 +209,7 @@ struct MapNode
u8 getLightNoChecks(LightBank bank, const ContentFeatures *f);
bool getLightBanks(u8 &lightday, u8 &lightnight, INodeDefManager *nodemgr) const;
-
+
// 0 <= daylight_factor <= 1000
// 0 <= return value <= LIGHT_SUN
u8 getLightBlend(u32 daylight_factor, INodeDefManager *nodemgr) const
@@ -220,16 +220,6 @@ struct MapNode
return blend_light(daylight_factor, lightday, lightnight);
}
- // 0.0 <= daylight_factor <= 1.0
- // 0 <= return value <= LIGHT_SUN
- u8 getLightBlendF1(float daylight_factor, INodeDefManager *nodemgr) const
- {
- u8 lightday = 0;
- u8 lightnight = 0;
- getLightBanks(lightday, lightnight, nodemgr);
- return blend_light_f1(daylight_factor, lightday, lightnight);
- }
-
u8 getFaceDir(INodeDefManager *nodemgr) const;
u8 getWallMounted(INodeDefManager *nodemgr) const;
v3s16 getWallMountedDir(INodeDefManager *nodemgr) const;