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