Reputation: 494
Python: 3.6.6
pyglet version: 1.3.2
OS(reproduced on both): Windows 10 host, Ubuntu 14.04 guest (Virtualbox without 3d acceleration)
import pyglet
class Window(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(*args, **kwargs)
self.batch = pyglet.graphics.Batch()
self.position = [0, 0, 300.0]
self.vertices_list = []
# BLUE rect
self.add_rect("blue.png", x=0, y=0, z=0)
# RED rect
self.add_rect("red.png", x=10, y=10, z=10)
# Expects RED will be in front of BLUE, but it isn't
# BLUE on top regardless of z value. I tried -10/10, etc.
pyglet.clock.schedule_interval(self.move_red_forward, 1 / 60)
def add_rect(self, file_name, x, y, z):
image = pyglet.image.load(file_name)
image_grid = pyglet.image.ImageGrid(image, 1, 1)
texture_grid = image_grid.get_texture_sequence()
texture_group = pyglet.graphics.TextureGroup(texture_grid)
x_ = (texture_group.texture.width + x)
y_ = (texture_group.texture.height + y)
tex_coords = ('t3f', texture_grid[0].texture.tex_coords)
vert_list = self.batch.add(
4, pyglet.gl.GL_QUADS,
texture_group,
('v3f', (x, y, z,
x_, y, z,
x_, y_, z,
x, y_, z)),
tex_coords)
self.vertices_list.append(vert_list)
def move_red_forward(self, dt):
# move z += 1 for all corners
red_vertices = self.vertices_list[1].vertices
red_vertices[2] += 1
red_vertices[5] += 1
red_vertices[8] += 1
red_vertices[11] += 1
def set_3d(self):
width, height = self.get_size()
pyglet.graphics.glEnable(pyglet.graphics.GL_BLEND)
pyglet.graphics.glBlendFunc(
pyglet.graphics.GL_SRC_ALPHA,
pyglet.graphics.GL_ONE_MINUS_SRC_ALPHA)
pyglet.graphics.glViewport(0, 0, width, height)
pyglet.graphics.glMatrixMode(pyglet.graphics.GL_PROJECTION)
pyglet.graphics.glLoadIdentity()
pyglet.graphics.gluPerspective(90, width / height, 0.1, 6000.0)
pyglet.graphics.glMatrixMode(pyglet.graphics.GL_MODELVIEW)
pyglet.graphics.glLoadIdentity()
x, y, z = self.position
pyglet.graphics.glTranslatef(x, y, -z)
def on_draw(self):
self.clear()
self.set_3d()
self.batch.draw()
if __name__ == '__main__':
window = Window(width=1400, height=800, caption='Pyglet', resizable=True)
pyglet.app.run()
The blue rect is drawn in front of the red. I expect that the z
axis is responsible for defining which object should be drawn in front.
How I can achieve that?
Or did I miss something in the understanding of such process?
Upvotes: 1
Views: 811
Reputation: 210877
You have to enable the Depth Test
pyglet.graphics.glEnable(pyglet.graphics.GL_DEPTH_TEST)
Note, the default depth function is GL_LESS
, this cause that a fragment is discarded, if a fragment has been drawn at the same place, and the new fragment has a depth which is greater or equal than the depth of the former fragment.
If the depth test is not enabled, then the later geometry is always drawn on top of the former.
If you want to blend the red image over the blue one, then the depth test has to be disabled and the red image has to be drawn after the blue image. For Blending the drawing order is crucial.The later object is blended to the former by the blending function (glBlendFunc
) and blend equation (glBlendEquation
).
Change the order of the images:
self.add_rect("red.png", x=10, y=10, z=10)
self.add_rect("blue.png", x=0, y=0, z=0)
Upvotes: 2