I'm guessing I can't just 'tilt' the 2D plane, whatever that means,
since the 2D sprites would disappear. However if it's easier to do that
with 3D sprites I'm open to that.
Here's what I'm doing so far:
* create a group to set OpenGL state for sprites
class CustomGroup(pyglet.graphics.Group):
def set_state(self):
glLoadIdentity()
glRotatef(0.0, 1.0, 0.0, 0.0)
glRotatef(0.0, 0.0, 1.0, 0.0)
glTranslatef(0.0, 0.0, 0.0)
def unset_state(self):
pass
(Though, if I try to rotate about a vector with glRotate, since the
sprites are just 2D the effect isn't what I want as expected).
* load images and make sprites, assigning to a batch and setting the
group to an instance of the class above
* in on_draw
def on_draw():
window.clear()
batch.draw()
I've tried giving the window a new on_resize, since as I understand it
the default is just a 2D projection (which I think I don't want, I'm not
sure), using this code from a nehe example:
def resize(width, height):
if height==0:
height=1
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45, 1.0*width/height, 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
I think this is basically what I want; from what I understand the
gluPerspective call sets the perspective angle at 45 degrees. However
setting this to the on_resize of the window then doesn't show my batch.
In the same example the code also translates to z = -5.0, but doing the
same thing in my code (without the new resize) also hides the batch. I'm
guessing that's because of the default projection? However it doesn't
seem to help to add the new resize.
Any further advice or pointers?
I think your batch may be clipped since pyglet renders it at z = 0 by
default, and your near clipping plane is at 0.1. Try translating
before drawing:
glPushMatrix()
glTranslatef(0.0, 0.0, 5.0)
// draw
glPopMatrix()
> In the same example the code also translates to z = -5.0, but doing the same
> thing in my code (without the new resize) also hides the batch. I'm guessing
> that's because of the default projection? However it doesn't seem to help to
> add the new resize.
Again, I think the batch is clipped, this time since pyglet's default
orthogonal projection has near and far clipping planes of -1 and 1. I
don't know why combining the translation with the resize code doesn't
work. Can you post a minimal but complete pyglet script that
reproduces the problem?
--
Mikael Lind
http://elemel.se/
I've made a zip of the script below that includes an image, available here:
http://sites.google.com/site/georgekoliver/Home/pyglet_perspective_test.zip?attredirects=0&d=1
The script:
import pyglet
from pyglet.gl import *
def resize(width, height):
if height==0:
height=1
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45, 1.0*width/height, -1.0, 100.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
window = pyglet.window.Window(640, 480)
window.on_resize=resize
batch = pyglet.graphics.Batch()
image = pyglet.image.load('crate.bmp')
crate = pyglet.sprite.Sprite(image, 100, 100, batch=batch)
@window.event
def on_draw():
window.clear()
batch.draw()
if __name__ == '__main__':
pyglet.app.run()
Commenting out the resize() and the assignment to window.on_resize shows
the image as expected, but including the resize gives me a blank window.
I've modified the gluPerspective slightly from the example I took it
from, where they had:
gluPerspective(45, 1.0*width/height, .1, 100.0)
I changed 0.1 to -1, guessing maybe that pyglet was drawing the batch at
z=0? But obviously that doesn't help (nor does keeping it at 0.1 I
should add).
The nehe example I looked at gives me hope, as it clearly shows the 2D
texture first in a straight-on view (i.e. like a regular 2D ortho
projection) but then 'tilting' in perspective when the code rotates the
cube, though maybe I'm misunderstanding that?
Incidentally that example is available here, it's lesson 07.
http://groups.google.com/group/pyglet-users/web/pyglet%20nehe.zip
-1 is an invalid near clip plane for a perspective projection. (You
can't look at something that's in or behind your eye.)
> The nehe example I looked at gives me hope, as it clearly shows the 2D
> texture first in a straight-on view (i.e. like a regular 2D ortho
> projection) but then 'tilting' in perspective when the code rotates the
> cube, though maybe I'm misunderstanding that?
I've changed your script a little so that it shows something on the screen.
Changes:
- Position the sprite at (0, 0) instead of (100, 100).
- Translate 1000 units into the screen before drawing the batch.
- Change the near and far clip planes to to 0.1 and 10000.
The changed script:
import pyglet
from pyglet.gl import *
def resize(width, height):
if height==0:
height=1
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45, 1.0*width/height, 0.1, 10000)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
window = pyglet.window.Window(640, 480)
window.on_resize=resize
batch = pyglet.graphics.Batch()
image = pyglet.image.load('crate.bmp')
crate = pyglet.sprite.Sprite(image, 0, 0, batch=batch)
@window.event
def on_draw():
window.clear()
glPushMatrix()
glTranslatef(0, 0, -1000)
batch.draw()
glPopMatrix()
if __name__ == '__main__':
pyglet.app.run()
--
Mikael Lind
http://elemel.se/
Wow, that really helps, thanks! Another mistake I realized I was making
was setting glLoadIdentity in the set_state of the CustomGroup.
In experimenting it seems like I can substitute a glLoadIdentity in
place of the Pop/Push of the matrix, like:
@window.event
def on_draw():
window.clear()
glLoadIdentity()
glTranslatef(-W_W/2, -W_H/2, -1000)
batch.draw()
Is that doing the same thing by resetting the matrix, or is that not
recommended?
That depends on what you want to do. Read The Fine Manual. :-)