0

I am trying to render a scene with partially transparent sprites in Pyglet. I want to activate z depth test to render them but this yields the following:

two images overlapping

The two images incorrectly overlap.

The code I use is the following

import pyglet as pg
from pyglet.gl import *

window = pg.window.Window(width=320, height=320)
glEnable(GL_DEPTH_TEST)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
batch = pg.graphics.Batch()

im1 = pg.image.load(
    'resources/sprites/npc/soldier/walk/0.png')
sprite1 = pg.sprite.Sprite(im1, x=100, y=100, z=1, batch=batch)
im2 = pg.image.load(
    'resources/sprites/npc/soldier/walk/0.png')
sprite2 = pg.sprite.Sprite(im2, x=150, y=150, z=0, batch=batch)

@window.event
def on_draw():
    window.clear()
    batch.draw()

pg.app.run()

The image I use is here npc_walking

As you can see in the code, I tried blending but this has no effect.

I also tried glEnable(GL_ALPHA_TEST) (cf opengl z-sorting transparency) but since it is deprecated, I don't know how to use the discard solution in Pyglet.

Anthony
  • 11
  • 4

1 Answers1

1

I figured out a solution,

It was indeed to discard fragments with 0 transparency but since GL_ALPHA_TEST is discarded you have to write some OpenGL code.

To do that in Pyglet, add the following at the beginning of your code

pyglet.sprite.fragment_source = """#version 150 core
in vec4 vertex_colors;
in vec3 texture_coords;
out vec4 final_colors;

uniform sampler2D sprite_texture;

void main()
{
    final_colors = texture(sprite_texture, texture_coords.xy) * vertex_colors;
    if (final_colors.a == 0) discard;
} """
Anthony
  • 11
  • 4
  • Looks like you found the solution. There is an example of depth sprite in pyglet examples: https://github.com/pyglet/pyglet/blob/master/examples/sprite/depth_sprite.py – Charlie Mar 27 '23 at 18:19