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-small.jpg

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 the screen returned 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-small.jpg

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 from screen centre 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
-~----------~----~----~----~------~----~------~--~---

Reply via email to