Правильное использование 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