Thanks for the replies,

Well, I forgot to mention step 4.5 :)

4.5 :  apply a projection on the sprites (pictures and labels) coordinates
so they get
closer to each other when you zoom out and farther when you zoom in.

I cannot provide the original code since there are too many dependancies
(it is a network mobility emulator) but I reproduced the behavior in the
example below :

The original code comes from http://tartley.com/?p=378 (second example: demo
camera)

I added the focus2 and map2scr functions. I also added the city names.
you can zoom in and zoom out using pgup/pgdown and you can pan and tilt
using arrow keys.
See how the labels follow the map but do not get scaled.

Enjoy !

#! python -O
"""
Demo2
Add a moveable/zoomable camera.
"""
from __future__ import division
from sys import stdout
from math import pi, sin, cos
from pyglet import app, clock
from pyglet.window import key, Window
from pyglet.window.key import symbol_string
from pyglet.gl import *
from pyglet import font

class Target(object):

    def __init__(self, camera):
        self.x, self.y = camera.x, camera.y
        self.scale = camera.scale
        self.angle = camera.angle

class Camera(object):

    def __init__(self, position=None, scale=None, angle=None):
        if position is None:
            position = (0, 0)
        self.x, self.y = position
        if scale is None:
            scale = 1
        self.scale = scale
        if angle is None:
            angle = 0
        self.angle = angle
        self.target = Target(self)
        self.desc_layer_scale = 512

    def zoom(self, factor):
        self.target.scale *= factor

    def pan(self, length, angle):
        self.target.x += length * sin(angle + self.angle)
        self.target.y += length * cos(angle + self.angle)

    def tilt(self, angle):
        self.target.angle += angle

    def update(self):
        self.x += (self.target.x - self.x) * 0.1
        self.y += (self.target.y - self.y) * 0.1
        self.scale += (self.target.scale - self.scale) * 0.1
        self.angle += (self.target.angle - self.angle) * 0.1

    def focus(self, width, height):
        "Set projection and modelview matrices ready for rendering"

        # Set projection matrix suitable for 2D rendering"
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        print width , height
        width / height
        aspect = width / height
        gluOrtho2D(
            -self.scale * aspect,
            +self.scale * aspect,
            -self.scale,
            +self.scale)

        # Set modelview matrix to move, scale & rotate to camera position"
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        gluLookAt(
            self.x, self.y, +1.0,
            self.x, self.y, -1.0,
            sin(self.angle), cos(self.angle), 0.0)

    def focus2(self, width, height):
        "Set projection and modelview matrices ready for rendering"

        # Set projection matrix suitable for 2D rendering"
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        print width , height
        width / height
        aspect = width / height
        gluOrtho2D(
                -self.desc_layer_scale * aspect ,
                +self.desc_layer_scale * aspect,
                -self.desc_layer_scale,
                +self.desc_layer_scale)

        # Set modelview matrix to move, scale & rotate to camera position"
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        diff = self.desc_layer_scale /self.scale
        gluLookAt(
            self.x * diff, self.y * diff, +1.0,
            self.x * diff, self.y * diff, -1.0,
            sin(self.angle), cos(self.angle), 0.0)

    def hud_mode(self, width, height):
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluOrtho2D(0, width, 0, height)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

win = Window(fullscreen=True, visible=False)
clockDisplay = clock.ClockDisplay()
glClearColor(0.4, 0.2, 0.3, 0)
camera = Camera((0, 0), 5)

verts = [
    ((255, 000, 000), (+10, +10)),
    ((000, 255, 000), (+10, -10)),
    ((000, 000, 255), (-10, +10)),
    ((255, 000, 000), (-10, -10)),
    ((000, 255, 000), (+10, -10)),
    ((000, 000, 255), (-10, +10)),
]

texts = [(font.Text(font.load('Arial', 30),'Paris'), (0, 2)),
         (font.Text(font.load('Arial', 30),'NewYork'), (-7, 2)),
         (font.Text(font.load('Arial', 30),'Tunis'), (1,0)),
         (font.Text(font.load('Arial', 30),'Bangkok'), (7,-2)),
        ]

def map2scr(xm, ym):
        xs = (xm)*camera.desc_layer_scale/camera.scale
        ys = (ym)*camera.desc_layer_scale/camera.scale
        return xs, ys

@win.event
def on_draw():
    glClear(GL_COLOR_BUFFER_BIT)
    camera.update()
    camera.focus(win.width, win.height)

    glBegin(GL_TRIANGLES)
    for color, position in verts:
        glColor3ub(*color)
        glVertex2f(*position)
    glEnd()
    camera.focus2(win.width, win.height)
    for t,pos in texts:
        x,y = map2scr(pos[0],pos[1])
        t.x, t.y = x,y
        t.draw()
    camera.hud_mode(win.width, win.height)
    clockDisplay.draw()


clock.schedule(lambda _: None)

key_handlers = {
    key.ESCAPE: lambda: win.close(),
    key.PAGEUP: lambda: camera.zoom(2),
    key.PAGEDOWN: lambda: camera.zoom(0.5),
    key.LEFT: lambda: camera.pan(camera.scale, -pi/2),
    key.RIGHT: lambda: camera.pan(camera.scale, +pi/2),
    key.DOWN: lambda: camera.pan(camera.scale, pi),
    key.UP: lambda: camera.pan(camera.scale, 0),
    key.COMMA: lambda: camera.tilt(-1),
    key.PERIOD: lambda: camera.tilt(+1),
}

@win.event
def on_key_press(symbol, modifiers):
    handler = key_handlers.get(symbol, lambda: None)
    handler()

print "keys to try:", [symbol_string(k) for k in key_handlers.keys()]
stdout.flush()
win.set_visible()
app.run()






On Sun, Feb 8, 2009 at 7:51 PM, Vincent Rioux <[email protected]>wrote:

>  Alex Holkner a écrit :
>
> On Sun, Feb 8, 2009 at 4:20 AM, Rayene Ben Rayana<[email protected]> 
> <[email protected]> wrote:
>
>
>  Ok, I've got it. I'll explain the trick in case someone encounters the same
> problem :
>
> 1. I had to call gluOrtho2D with scale = sc1 (sc1 depends on the zoom) and
> then call gluLookAt with x,y
> 2. draw the map
> 3. call gluOrtho2D with a fix  scale sc2 (does not depend on the zoom)
> 4 call gluLookAt again with coords = x*(sc2/sc1) , y*(sc2/sc1) , instead of
> x,y
> 5. draw the pictures and the labels.
>
> Now, when I zoom in and out,  the map is scaled but the labels keep the same
> size ;)
>
>
>  I'm not sure I understand how that works -- but well done if it does!
> I look forward to seeing it in action (and dissecting it ;-) ).
>
> Alex.
>
>
>
> I would be very interested too.
> Rayene, are you also interested to implement dnd features or stick to a map
> oriented project?
> i am actually looking for a simple way to implement a 2d zui interface to
> display pictures, some kind of zoomable contact sheet.
> i have been using tkzinc which is quite great especially for geometrical
> transformations (see
> http://www.tkzinc.org/Documentation/refman-3.3.4/index.html ) but i am
> very curious to know how one could implement it with pyglet.
>
> best regards,
> vincent
>
>
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
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