When you say "pan" and "zoom", I understand you want to "translate" and
"scale".
But do you want to move the camera (GL_PROJECTION matrix) or the world
(GL_MODELVIEW matrix)?
To set up the camera. First use glViewport(0, 0, w, h) to define the
window limits,
then tell OpenGL you are going to modify the camera with
glMatrixMode(GL_PROJECTION).
Now there are two types of camera: isometric (glOrtho) or perspective
(gluPerspective).
This functions create a initial GL_PROJECTION matrix for you, but you
can apply other transformations by multipying.
Only a perspective camera lets you "zoom" (fov).
You are doing 2D, so probably you should start with isometric.
The code was to show you how a transformation matrix looks like. The
matrix is 4x4 = 16 GLdouble.
A matrix transforms the geometry. Let [V] be the geometry.
The identity matrix [I] has no effect:
| 1 0 0 0 |
| 0 1 0 0 | * [V] = [V]
| 0 0 1 0 |
| 0 0 0 1 |
When you call glLoadIdentity, you are setting [I] as the current
(GL_MODELVIEW or GL_PROJECTION) matrix.
You can multiply the matrix by other matrix to translate, then multiply
by other to rotate, and so on.
glMultMatrix([I]) obviously has no effect.
If now you want to translate the geometry to (tx, ty, tz), you need a
matrix like this [T]:
| 1 0 0 0 |
| 0 1 0 0 | * [V] = [T] * [V] = [V translated]
| 0 0 1 0 |
| tx ty tz 1 |
Thit is what glTranslate(tx, ty, tx) does, multiply the current matrix
by [T]: same as glMultMatrix([T])
glScale(sx, sy, sz) :
| sx 0 0 0 |
| 0 sy 0 0 | = [S]
| 0 0 sz 0 |
| 0 0 0 1 |
glRotate(0, 0, rz):
| cos(rz) -sin(rz) 0 0 |
| sin(rz) cos(rz) 0 0 | = [R]
| 0 0 1 1 |
| 0 0 0 1 |
One matrix [M]=[T]*[S]*[R] can apply translation, rotation and scale to
your geometry in one step (one multiplication).
Remember that [T]*[R] is not [R]*[T]
Try this:
# About OpenGL Projections
#---------------------------------
from pyglet import window,image
from pyglet.window import key
from pyglet.gl import *
def opengl_init():
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glDepthFunc(GL_LEQUAL)
def playground():
# Test your code here
glColor4f(1,1,1,1)
glBegin(GL_LINES)
glVertex3f(0,0,0)
glVertex3f(640,480,0)
glVertex3f(0,480,0)
glVertex3f(640,0,0)
glEnd()
class camera():
mode=1
x,y,z=0,0,512
rx,ry,rz=30,-45,0
w,h=640,480
far=8192
fov=60
def view(self,width,height):
self.w,self.h=width,height
glViewport(0, 0, width, height)
print "Viewport "+str(width)+"x"+str(height)
if self.mode==2: self.isometric()
elif self.mode==3: self.perspective()
else: self.default()
def default(self):
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, self.w, 0, self.h, -1, 1)
glMatrixMode(GL_MODELVIEW)
def isometric(self):
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(-self.w/2.,self.w/2.,-self.h/2.,self.h/2.,0,self.far)
glMatrixMode(GL_MODELVIEW)
def perspective(self):
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(self.fov, float(self.w)/self.h, 0.1, self.far)
glMatrixMode(GL_MODELVIEW)
def key(self, symbol, modifiers):
if symbol==key.F1:
self.mode=1
self.default()
print "Projection: Pyglet default"
elif symbol==key.F2:
print "Projection: 3D Isometric"
self.mode=2
self.isometric()
elif symbol==key.F3:
print "Projection: 3D Perspective"
self.mode=3
self.perspective()
elif self.mode==3 and symbol==key.NUM_SUBTRACT:
self.fov-=1
self.perspective()
elif self.mode==3 and symbol==key.NUM_ADD:
self.fov+=1
self.perspective()
else: print "KEY "+key.symbol_string(symbol)
def drag(self, x, y, dx, dy, button, modifiers):
if button==1:
self.x-=dx*2
self.y-=dy*2
elif button==2:
self.x-=dx*2
self.z-=dy*2
elif button==4:
self.ry+=dx/4.
self.rx-=dy/4.
def apply(self):
glLoadIdentity()
if self.mode==1: return
glTranslatef(-self.x,-self.y,-self.z)
glRotatef(self.rx,1,0,0)
glRotatef(self.ry,0,1,0)
glRotatef(self.rz,0,0,1)
def x_array(list):
return (GLfloat * len(list))(*list)
def axis(d=200):
vertices,colors=[],[]
#XZ RED
vertices.extend([-d, 0,-d, d, 0,-d, d, 0, d,-d, 0, d])
for i in range (0,4): colors.extend([1,0,0,0.5])
#YZ GREEN
vertices.extend([ 0,-d,-d, 0,-d, d, 0, d, d, 0, d,-d])
for i in range (0,4): colors.extend([0,1,0,0.5])
#XY BLUE
vertices.extend([-d,-d, 0, d,-d, 0, d, d, 0,-d, d, 0])
for i in range (0,4): colors.extend([0,0,1,0.5])
return x_array(vertices),x_array(colors)
AXIS_VERTICES,AXIS_COLORS=axis()
def draw_vertex_array(vertices,colors,mode=GL_LINES):
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_COLOR_ARRAY)
glColorPointer(4, GL_FLOAT, 0, colors)
glVertexPointer(3, GL_FLOAT, 0, vertices)
glDrawArrays(GL_QUADS, 0, len(vertices)/3)
glDisableClientState(GL_VERTEX_ARRAY)
glDisableClientState(GL_COLOR_ARRAY)
def draw_axis():
glEnable(GL_DEPTH_TEST)
draw_vertex_array(AXIS_VERTICES,AXIS_COLORS,GL_QUADS)
glDisable(GL_DEPTH_TEST)
print "OpenGL Projections"
print "---------------------------------"
print "Projection matrix -> F1, F2, F3"
print "Camera -> Drag LMB,CMB,RMB"
print ""
cam=camera()
win = window.Window(resizable=True)
win.on_resize=cam.view
win.on_key_press=cam.key
win.on_mouse_drag=cam.drag
opengl_init()
while not win.has_exit:
win.dispatch_events()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
cam.apply()
draw_axis()
playground()
win.flip()
Question:
El 27/07/2012 20:41, Derek S. escribió:
Thank you for the example Txema. I'm going to need to become a little
more educated to understand it.
Is A,C the x,y of the bottom left corner of the window, and B,D the
top right?
What kind of data type is the matrix, some sort of special double
precision tuple?
What do you use this bit of code for (zooming, panning, etc..)?
Txema Vicente wrote:
I have some code that may help you, the math is in there.
This is for a hierarchy of planes, and all matrices are calculated
"manually".
_tx, _ty, _tz : Translation
_scale: (XY axis)
_rotation: (Z axis)
RADIANS=-0.01745
class Plane(...):
def matrix_update(self):
a = self._scale*math.cos(RADIANS*self._rotation)
b = self._scale*math.sin(RADIANS*self._rotation)
if self.parent is None:
self.matrix=(gl.GLdouble * 16)(
a, -b, 0, 0,
b, a, 0, 0,
0, 0, 1, 0,
self._tx, self._ty, self._tz, 1)
else:
c, d = -b, a
origin=self.parent.matrix
A,C = origin[0], origin[1] #C=-B
B,D = origin[4], origin[5] #D=A
X,Y,Z = origin[12], origin[13], origin[14]
self.matrix=(gl.GLdouble * 16)(
A*a+B*c, C*a+D*c, 0, 0,
A*b+B*d, C*b+D*d, 0, 0,
0, 0, 1, 0,
X + A*self._tx + B*self._ty, Y + C*self._tx +
D*self._ty,
Z + self._tz, 1)
for plane in self.children: plane.matrix_update()
--
You received this message because you are subscribed to the Google
Groups "pyglet-users" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/pyglet-users/-/LGCPXGNx3EoJ.
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.
--
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.