小狗。 OpenGL。如何根据 "z" 轴在其他前面绘制矩形
Pyglet. OpenGL. How to draw rect in front of other based on "z" axis
环境:
Python: 3.6.6
小狗版本:1.3.2
OS(两者均转载):Windows 10 个主机,Ubuntu 14.04 个访客(没有 3d 加速的 Virtualbox)
代码:
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()
问题:
蓝色矩形绘制在红色前面。我希望 z
轴负责定义应该在前面绘制的对象。
问题:
我怎样才能做到这一点?
还是我在理解这样的过程中遗漏了什么?
您必须启用 Depth Test
pyglet.graphics.glEnable(pyglet.graphics.GL_DEPTH_TEST)
注意,默认的深度函数是GL_LESS
,这会导致一个片段被丢弃,如果一个片段已经在同一个地方绘制,并且新片段的深度大于或等于前片段的深度。
如果未启用深度测试,则后面的几何图形始终绘制在前面的几何图形之上。
如果要将红色图像混合在蓝色图像上,则必须禁用深度测试并且必须在蓝色图像之后绘制红色图像。对于 Blending the drawing order is crucial.The later object is blended to the former by the blending function (glBlendFunc
) and blend equation (glBlendEquation
).
更改图像的顺序:
self.add_rect("red.png", x=10, y=10, z=10)
self.add_rect("blue.png", x=0, y=0, z=0)
环境:
Python: 3.6.6
小狗版本:1.3.2
OS(两者均转载):Windows 10 个主机,Ubuntu 14.04 个访客(没有 3d 加速的 Virtualbox)
代码:
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()
问题:
蓝色矩形绘制在红色前面。我希望 z
轴负责定义应该在前面绘制的对象。
问题:
我怎样才能做到这一点?
还是我在理解这样的过程中遗漏了什么?
您必须启用 Depth Test
pyglet.graphics.glEnable(pyglet.graphics.GL_DEPTH_TEST)
注意,默认的深度函数是GL_LESS
,这会导致一个片段被丢弃,如果一个片段已经在同一个地方绘制,并且新片段的深度大于或等于前片段的深度。
如果未启用深度测试,则后面的几何图形始终绘制在前面的几何图形之上。
如果要将红色图像混合在蓝色图像上,则必须禁用深度测试并且必须在蓝色图像之后绘制红色图像。对于 Blending the drawing order is crucial.The later object is blended to the former by the blending function (glBlendFunc
) and blend equation (glBlendEquation
).
更改图像的顺序:
self.add_rect("red.png", x=10, y=10, z=10)
self.add_rect("blue.png", x=0, y=0, z=0)