atom feed16 messages in com.googlegroups.pyglet-usersRe: setting gamma
FromSent OnAttachments
Martin SpacekDec 29, 2007 2:20 am 
Alex HolknerDec 29, 2007 3:55 pm 
Andrew StrawDec 29, 2007 9:06 pm 
Martin SpacekDec 29, 2007 11:48 pm 
Alex HolknerDec 30, 2007 1:09 am 
Martin SpacekJan 6, 2008 9:50 pm.py
Alex HolknerJan 7, 2008 1:14 am 
Martin SpacekJan 7, 2008 4:05 am.py
Andrew StrawJan 7, 2008 10:51 am 
Alex HolknerJan 7, 2008 1:59 pm 
Andrew StrawJan 7, 2008 9:10 pm 
Martin SpacekJan 7, 2008 9:34 pm 
Martin SpacekJan 7, 2008 9:47 pm 
Alex HolknerJan 7, 2008 11:01 pm 
JonFeb 2, 2008 8:26 am 
PhilipBoberFeb 2, 2008 11:16 pm 
Subject:Re: setting gamma
From:Martin Spacek (pyg@mspacek.mm.st)
Date:Jan 7, 2008 4:05:43 am
List:com.googlegroups.pyglet-users
Attachments:

Alex Holkner wrote:

The buffer needs to be 3 arrays of 256 words (you have only allocated the same number of bytes). So:

buf = ((c_uint16) * 256) * 3)()

where buf[0] is the red ramp, buf[1] is the green ramp, etc.

[GS]etDeviceGammaRamp needs a graphics device context, not an OpenGL context. So:

ret = windll.gdi32.GetDeviceGammaRamp(win._dc, buf) ret = windll.gdi32.SetDeviceGammaRamp(win._dc, buf)

(the byref is unnecessary; arrays are always passed as pointers in C).

Ah, thanks. I just figured both of those out the hard way. (I thought words were 8bit for some reason). It works great now. Here's the demo. I'm using numpy to create the gamma ramps.

Not sure if/how you want to incorporate this into pyglet. This is only the win32 call, linux and osx would have to be figured out too. Maybe a pyglet.window.Window.set_gamma(r, g, b) method, where you provide the 3 gamma values and it generates and sets the ramps for you? Or maybe make it a Screen method since setting gamma affects the whole screen?

Martin

"""Demo of how to set screen gamma in win32 using ctypes for a pyglet device context"""

from __future__ import division

import pyglet.window import numpy as np from ctypes import windll import time

gamma = 2.2

def invramp(gamma): """Inverted gamma ramp""" ramp = np.arange(256, dtype=np.uint16) / 255 # normalized linear ramp ramp = np.power(ramp, 1 / gamma) * 255 # unnormalized inverted gamma ramp return np.uint16(np.round(ramp)) # convert back to nearest ints

win = pyglet.window.Window() origramps = np.empty((3, 256), dtype=np.uint16) # init R, G, and B ramps

# try and get gamma ramp success = windll.gdi32.GetDeviceGammaRamp(win._dc, origramps.ctypes) if not success: raise AssertionError, 'GetDeviceGammaRamp failed'

ramp = invramp(gamma=gamma) ramps = np.asarray([ramp]*3) # identically inverted R, G, and B ramps ramps.byteswap(True) # seems CPU and GPU have different endianness?

# try and set gamma ramp success = windll.gdi32.SetDeviceGammaRamp(win._dc, ramps.ctypes) if not success: raise AssertionError, 'SetDeviceGammaRamp failed'

time.sleep(3) # marvel at gamma corrected screen

# reset to original gamma success = windll.gdi32.SetDeviceGammaRamp(win._dc, origramps.ctypes) if not success: raise AssertionError, 'SetDeviceGammaRamp failed'