LibGDX Drawing inter-penetrating 2D sprite in right order (Using 3D logic?)

I’m currently developing 2D top down shooter in libGDX.
What I’m trying to achieve is draw overlapping sprite in right order.

First approach I took was give individual sprite a layer value as float, and sort sprites before drawing it.
It seemed kinda worked at first but just sorting layer can’t solve when sprite should inter-penetrate.
ex)

So after some search I’ve found ‘Enter the Gungeon’ used 3D approach to solve this problem.
They put 2D sprite in 3D world and used depth buffer to draw in right order.

As I’m working my project in libGDX I tried to reproduce same effect using Decal and OrthographicCamera.
I’ve set my world same way as what Enter the Gungeon looks like when using PerspectiveCamera.
But problem is, when applied OrthographicCamera, as decals representing entities are parallel to z axis so only tile floor’s are shown and none of sprite’s are shown

So my question is,

  1. Are there any better way to deal with draw inter-penetrating sprite?
  2. If not, Is there any specific term used to call this 3D approach? As I don’t know exact term of what it called searching info for it is kinda hard.
  3. Is it possible to reproduce this approach in libGDX? How? Do I have to apply some adjustment before applying OrthographicCamera?

TL;DR: Learn OpenGL, watch some Tutorials on Youtube, preferably the LWJGL ones!

[quote]1. Are there any better way to deal with draw inter-penetrating sprite?
[/quote]
There are two main approaches:

  • Use the z-buffer, give everything 3D coordinates. Very easy solution for your problem, if there’s nothing semi-transparent thrown in.
  • Sort it yourself by drawing in a specific order (3D coordinates again), making sure the sprites are small and roughly the same size or else you hit the inter-penetration problem.

[quote]2. If not, Is there any specific term used to call this 3D approach? As I don’t know exact term of what it called searching info for it is kinda hard.
[/quote]
Depth sorting, transparency sorting, sprite sorting, draw order, etc.
https://www.khronos.org/opengl/wiki/Transparency_Sorting

[quote]Is it possible to reproduce this approach in libGDX? How? Do I have to apply some adjustment before applying OrthographicCamera?
[/quote]
Yes, once you understand how it works under the hood. Learn OpenGL, watch tutorials about and practice until you can draw a textured quad and move the camera, then everything will clear up, you will stay clueless until you reach that level.

Thanks for your answer.
But it seems my question was bit vague. So I’ll try to be more specific about it.

You’ve mentioned two approach I can take,
If I’m not misunderstanding, First approach you’ve mentioned is what I’m currently trying to achieve?
(Which Image of “Enter the Gungeon” does)

And Second approach you’ve mentioned is similar to what I called “give individual sprite a layer value as float, and sort” in Question?
(To use sorting and draw in order)
And as I need some Image to be drawn as inter-penetrate, I cannot use sorting approach right?

So what I’m currently trying to do is give every sprite 3d coordinate, but there is a problem .

A is Image I want to create, 4 rectangle inter-penetrating.
B is representation of how I gave 3d coordinate, rotated rectangles to make it inter-penetrate.
C is resulting image I get.

As pixel game, I want resulting image to be pixel perfect, but if I give z-buffer by rotating, resulting pixel is distorted.
How can I retain z-buffer but still draw sprite pixel perfect?

This is what shearing can be used for. You want to move the z coordinate of a rectangle with respect to its x or y coordinate while also keeping the x/y coordinates fixed. Here is a very basic LWJGL 3 example:


import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;
import org.lwjgl.opengl.GL;
public class OverlappingRectangles {
    private static void drawRectangle(float x, float y, float r) {
        glPushMatrix();
        glTranslatef(x, y, 0);
        glRotatef(r, 0, 0, 1);
        glScalef(0.75f, 0.2f, 1);
        // Create shear matrix that maps (x, y, z) to (x, y, x + z)
        glMultMatrixf(new float[] {
                1, 0, 1, 0,
                0, 1, 0, 0,
                0, 0, 1, 0,
                0, 0, 0, 1});
        glBegin(GL_QUADS);
        glVertex2f(-1, -1);
        glVertex2f(1, -1);
        glVertex2f(1, 1);
        glVertex2f(-1, 1);
        glEnd();
        glPopMatrix();
    }
    public static void main(String[] args) {
        if (!glfwInit())
            throw new RuntimeException("Unable to initialize GLFW");
        long window = glfwCreateWindow(500, 500, "Overlapping Rectangles", NULL, NULL);
        if (window == NULL)
            throw new RuntimeException("Failed to create the GLFW window");
        glfwSetKeyCallback(window, (w, k, s, a, m) -> {
            if (k == GLFW_KEY_ESCAPE && a == GLFW_RELEASE)
                glfwSetWindowShouldClose(window, true);
        });
        glfwMakeContextCurrent(window);
        GL.createCapabilities();
        glEnable(GL_DEPTH_TEST);
        while (!glfwWindowShouldClose(window)) {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glColor3f(1, 0, 0);
            drawRectangle(0, 0.5f, 0);
            glColor3f(0, 1, 0);
            drawRectangle(0, -0.5f, 180);
            glColor3f(0, 0, 1);
            drawRectangle(-0.5f, 0, 90);
            glColor3f(1, 1, 0);
            drawRectangle(0.5f, 0, 270);
            glfwSwapBuffers(window);
            glfwPollEvents();
        }
    }
}

Thanks KaiHH! didn’t applied into my code yet, but it seems it will solve my problem.