Hey. I reduced the code to a minimal reproduce. Sorry I didn't do this
before posting the first time.
I eliminated PIL and all my opengl matrix operations. The code below
simply loads a png file and blits it to the screen.
Using screens[0] it works fine. On screens[1], if you switch focus to
another window, and then switch focus back, then the image appears
corrupted, as shows in the previously linked screenshot.
I've only tried this out on WindowsXP.
Thanks for any clues. I'm currently trying to work around by finding
ways to screengrab from the same screen that pyglet chooses by
default, instead of asking pyglet to open on a non-default screen.
from pyglet import app, image
from pyglet.window import get_platform, Window
def draw(image):
image.blit(0, 0)
def main():
desktop = image.load('testimage.png')
platform = get_platform()
display = platform.get_default_display()
screens = display.get_screens()
window = Window(
visible=True, fullscreen=True, screen=screens[1])
window.on_draw = lambda: draw(desktop)
app.run()
if __name__ == '__main__':
main()
On Sep 17, 11:40 am, Jonathan Hartley <[email protected]> wrote:
> I'm going to struggle to ask this question concisely. My apologies. I
> shall try.
>
> I'm grabbing an image of the desktop. For the moment, I use PIL to do
> this, which only works on Windows. The following returns a pyglet
> ImageData object which looks like the current desktop:
>
> import ImageGrab # PIL
> from pyglet.image import ImageData
> def grab_desktop():
> desktop = ImageGrab.grab()
> image = ImageData(
> desktop.size[0], desktop.size[1],
> 'RGB', desktop.tostring(),
> pitch=-desktop.size[0]* 3)
> return image
>
> Then I open a non-visible fullscreen pyglet window, set projection and
> modelview matrices, blit the grabbed desktop image to it, and finally
> make the window visible.
>
> def draw(image):
> image.blit(0, 0)
>
> image = grab_desktop()
> window = Window(visible=False, fullscreen=True)
> # set projection and modelview matrices here
> window.on_draw = lambda: on_draw(image)
> app.run()
>
> This works awesomely! The transition from real desktop to fullscreen
> pyglet window that looks like the desktop is totally seamless. I then
> mess around with the zoom and rotation to make the desktop image move
> around sickeningly. If you look carefully at this screengrab, you can
> see the image has started to tilt and zoom slightly. This is exactly
> the effect I am
> after:http://tartley.com/files/pyglet-users-deskzoom-corruption/normal-smal...
>
> My problem occurs when I have two monitors. As it happens PIL grabs
> the image from monitor 1, while pyglet opens its fullscreen window on
> monitor 2. I thought this could be easily rectified by opening
> pyglet's window on monitor 1 instead:
>
> platform = get_platform()
> display = platform.get_default_display()
> screens = display.get_screens()
>
> self.window = Window(
> visible=False, fullscreen=True,screen=screens[1])
>
> screen[0] is thescreenreturned by display.get_default_screen(), so
> here I use screens[1] instead.
>
> However, now the program works as normal, except the blitted image
> appears corrupt, or badly formatted in some
> way:http://tartley.com/files/pyglet-users-deskzoom-corruption/corrupt-sma...
>
> Using screens[0] in the Window constructor above reverts the program
> back to its original (non-corrupt, but wrong desktop) behaviour.
>
> Does anyone have any ideas what I'm doing wrong? My two monitors are
> both showing the same resolution and color depth.
>
> Full source is below. It requires pyglet, PIL and Windows.
>
> #!/usr/bin/python
>
> from __future__ import division
>
> from math import cos, pi, sin
> from random import uniform
>
> import ImageGrab # PIL
>
> from pyglet import app, clock
> from pyglet.event import EVENT_HANDLED
> from pyglet.image import ImageData
> from pyglet.window import get_platform, key, Window
> from pyglet.gl import (
> glClear, glClearColor, glLoadIdentity, glMatrixMode, gluLookAt,
> GL_COLOR_BUFFER_BIT, GL_MODELVIEW, GL_PROJECTION,
> )
> from pyglet.gl.glu import gluOrtho2D
>
> class Camera(object):
>
> def __init__(self, x, y, scale, angle=0.0):
> self.x = x
> self.y = y
> # scale is distance fromscreencentre to top or bottom, in
> world coords
> self.scale = scale
> self.angle = angle
>
> def set_modelview(self):
> glMatrixMode(GL_MODELVIEW)
> glLoadIdentity()
> gluLookAt(
> self.x, self.y, +1.0, # eye
> self.x, self.y, -1.0, # look at
> sin(self.angle), cos(self.angle), 0.0) # up
>
> def set_projection(self, aspect):
> glMatrixMode(GL_PROJECTION)
> glLoadIdentity()
> gluOrtho2D(
> -self.scale * aspect,
> +self.scale * aspect,
> -self.scale,
> +self.scale)
>
> class View(object):
>
> def __init__(self, model, camera):
> self.model = model
> self.camera = camera
>
> platform = get_platform()
> display = platform.get_default_display()
> screens = display.get_screens()
>
> self.window = Window(
> visible=False, fullscreen=True,screen=screens[1])
> self.window.on_resize = lambda _, __: EVENT_HANDLED
> self.window.on_draw = self.on_draw
>
> glClearColor(0, 0, 0, 0)
>
> def on_draw(self):
> glClear(GL_COLOR_BUFFER_BIT)
> aspect = self.window.width / self.window.height
> self.camera.set_projection(aspect)
> self.camera.set_modelview()
> self.model.draw()
> return EVENT_HANDLED
>
> def show(self, _):
> self.window.set_visible()
>
> class Model(object):
>
> def __init__(self, image):
> self.desktop = image
>
> def draw(self):
> self.desktop.blit(0, 0)
>
> class Zoomer(object):
>
> def __init__(self, width, height):
> self.width = width
> self.height = height
> self.zoomx = uniform(0, width)
> self.zoomy = uniform(0, height)
>
> def update_camera(self, age, camera):
> effect = age / 2 # effect starts at 0.0 and lasts 2 seconds
> camera.scale = self.height / 2 - effect ** 2 * 50
> # todo, set cam x and y
> camera.angle += sin(effect * pi / 2) * effect ** 2 / 1000
>
> class Control(object):
>
> def __init__(self, model, view, zoomer):
> self.age = 0.0
> self.model = model
> self.view = view
> self.zoomer = zoomer
>
> def update(self, dt):
> self.age += dt
> self.zoomer.update_camera(self.age, self.view.camera)
> if self.view.camera.scale < 0:
> self.view.window.close()
>
> def run(self):
> clock.schedule_once(self.view.show, 2/50)
> clock.schedule(self.update)
> app.run()
>
> def grab_desktop():
> desktop = ImageGrab.grab()
> image = ImageData(
> desktop.size[0], desktop.size[1],
> 'RGB', desktop.tostring(),
> pitch=-desktop.size[0]* 3)
> return image
>
> def main():
> image = grab_desktop()
> model = Model(image)
> camera = Camera(image.width / 2, image.height / 2, image.height /
> 2)
> view = View(model, camera)
> zoomer = Zoomer(image.width, image.height)
> control = Control(model, view, zoomer)
> control.run()
>
> if __name__ == '__main__':
> main()
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"pyglet-users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/pyglet-users?hl=en
-~----------~----~----~----~------~----~------~--~---