Правильное использование SetDeviceGammaRamp
Я хотел бы добавить возможность настройки гаммы экрана при запуске приложения и сбросить его при выходе. Хотя это спорно, следует ли вообще вмешиваться в гамму (лично я считаю это бесполезным и вредным), но эй, некоторые люди ожидают, что смогут делать такие вещи.
это всего лишь один простой вызов API, так что все просто, верно?
MSDN говорит:"гамма-рампа задается в трех массивах по 256 слов в каждом [...] значения должны храниться в наиболее значительные биты каждого слова для повышения независимости DAC.". Это означает, в моем понимании, что-то вроде word_value = byte_value<<8
, Что звучит довольно странно, но так я это читаю.
исходный код Doom3 содержит функцию, которая принимает три массива char
значения и преобразует их в массив uint16_t
значения, имеющие одинаковое значение байта и в верхней и нижней половине. Другими словами что-то вроде word_value = (byte_value<<8)|byte_value
. Это так же странно, но что хуже это не то же, что и выше.
также существует несколько фрагментов кода в интернете на различных сайтах программистов хобби (по-видимому, один украден из другого, потому что они идентичны букве), которые делают некоторую неясную математику, умножая линейный индекс на значение, смещение со 128 и зажим до 65535. Я не совсем уверен, о чем это, но для меня это выглядит полной бессмыслицей, и снова это не то же самое, что и любой из вышеперечисленных два.
что это дает? Это должно быть четко определено - без догадок - как должны выглядеть данные, которые вы предоставляете? В конце концов, что нужно сделать, это прочитать исходные значения и позволить пользователю настроить некоторые ползунки в любом случае (и, возможно, сохранить этот blob на диск с конфигурацией пользователя), но все же... чтобы изменить эти значения, нужно знать, каковы они и что ожидается.
кто-нибудь сделал (и протестирован!) это раньше и знает, какой из них прав?
2 ответов
исследуя возможность программного изменения яркости экрана, я наткнулся на эту статью изменение яркости экрана programmingly - с помощью Гама пандус для API.
используя отладчик, я взглянул на значения, предусмотренных
Я не тестировал это, но если бы мне пришлось угадать, ранние видеокарты были нестандартными в их реализации SetDeviceGammaRamp (), когда Doom был написан и иногда использовал ЛОБАЙТ, а иногда использовал ГИБАЙТ значения слова. Консенсус перешел только к использованию HIBYTE, следовательно,word_value = byte_value<<8
.
вот еще одна точка данных из библиотеки PsychoPy (в python), которая просто обменивает ЛОБАЙТ и ГИБАЙТ:
"""Sets the hardware look-up table, using platform-specific ctypes functions.
For use with pyglet windows only (pygame has its own routines for this).
Ramp should be provided as 3x256 or 3x1024 array in range 0:1.0
"""
if sys.platform=='win32':
newRamp= (255*newRamp).astype(numpy.uint16)
newRamp.byteswap(True)#necessary, according to pyglet post from Martin Spacek
success = windll.gdi32.SetDeviceGammaRamp(pygletWindow._dc, newRamp.ctypes)
if not success: raise AssertionError, 'SetDeviceGammaRamp failed'
также кажется, что Windows не разрешить все настройки гаммы, см.: http://jonls.dk/2010/09/windows-gamma-adjustments/
обновление:
первыми API-интерфейсами Windows, предлагающими gamma control, являются SetDeviceGammaRamp и GetDeviceGammaRamp интерфейса графического устройства Windows (GDI). Эти API работают с тремя 256-входными массивами слов, с каждым словом, кодирующим от нуля до одного, представленными значениями слов 0 и 65535. Дополнительная точность слова обычно недоступна в фактические таблицы аппаратного поиска, но эти API должны были быть гибкими. Эти API, в отличие от других, описанных далее в этом разделе, допускают только небольшое отклонение от функции идентификации. Фактически, любая запись в рампе должна находиться в пределах 32768 от значения идентификатора. Это ограничение означает, что ни одно приложение не может превратить дисплей полностью черный или какой-либо другой нечитаемый цвет.
http://msdn.microsoft.com/en-us/library/windows/desktop/jj635732(v=vs. 85).aspx