Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Depth buffer with default sfml rendering, gl_FragDepth.  (Read 3062 times)

0 Members and 1 Guest are viewing this topic.

Sopel

  • Newbie
  • *
  • Posts: 2
    • View Profile
Depth buffer with default sfml rendering, gl_FragDepth.
« on: July 12, 2017, 01:37:45 am »
I need a pixel precise depth testing where depth is dependent on colors in some texture. So basically I have to set it in fragment shader with gl_FragDepth. To do that I need to enable depth testing, so I made a little demo to get in touch with it. (eventually I need it with a RenderTexture, if there any notable differences with setting it up please let me know)

#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>
#include <iostream>
#include <cassert>

int main()
{
    sf::ContextSettings settings;
    settings.depthBits = 24;
    settings.stencilBits = 8;
    settings.antialiasingLevel = 0;
    settings.majorVersion = 0;
    settings.minorVersion = 0;

    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML Depth Buffer Test", 7u, settings);
    assert(window.getSettings().depthBits == 24);
    window.setActive(true);
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glDepthFunc(GL_LEQUAL);
    glDepthRange(0.0f, 1.0f);
    glClearDepth(1.0f);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    sf::Shader shader;
    shader.loadFromMemory(
        "\n void main()"
        "\n {"
        "\n     gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
        "\n     gl_FrontColor = gl_Color;"
        "\n }",

        "\n void main()"
        "\n {"
        "\n     gl_FragColor = gl_Color;"
        "\n     gl_FragDepth = gl_Color.b;"
        "\n }"
    );

    sf::RenderStates renderStates;
    renderStates.shader = &shader;

    int i = 0;
    for (;;)
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed) return 0;
        }

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        sf::RectangleShape shape1;
        shape1.setPosition(100.0f, 100.0f);
        shape1.setFillColor(sf::Color(255, 0, 128, 255));
        shape1.setSize(sf::Vector2f(300.0f, 300.0f));

        // ugly way to switch between colors
        // first rectangle uses 128, second jumps between 1 and 201 as can be seen on cout
        const int b = (i % 1000 > 500) * 200 + 1;
        std::cout << b << '\n';
        ++i;

        sf::RectangleShape shape2;
        shape2.setPosition(300.0f, 300.0f);
        shape2.setFillColor(sf::Color(0, 255, b, 255));
        shape2.setSize(sf::Vector2f(400.0f, 200.0f));

        window.draw(shape1, renderStates);
        window.draw(shape2, renderStates);

        window.display();
    }

    return 0;
}
I draw two rectangles, second one has changing blue color component and fragment shader uses it as a depth. I expect them to change order, but it's not happening.

I don't have a good opengl background, and I wanted to keep it simple (I don't have time to properly learn opengl right now). I tried everything I could find but most of it was about actual 3d rendering with perspective set through opengl (which to my knowlege shouldn't matter, but...). The rest is applied in the code above or was tried but failed.

I'm using SFML version 2.3.1, can upgrade if absolutely required.
« Last Edit: July 12, 2017, 01:47:49 am by Sopel »

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Depth buffer with default sfml rendering, gl_FragDepth.
« Reply #1 on: July 12, 2017, 02:05:35 am »
SFML will initialize its OpenGL states the first time something is drawn to a RenderTarget which means that depth testing will be disabled the first time you draw a rectangle. You can work around this by explicitly pre-initializing the RenderTarget before you set your own states with window.resetGLStates(); but this is essentially playing with fire. Unless you know exactly how SFML is implemented in a given version you can't be sure that messing with its OpenGL states will lead to the desired effects.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Sopel

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Depth buffer with default sfml rendering, gl_FragDepth.
« Reply #2 on: July 12, 2017, 12:40:31 pm »
Thank you!

Both ways work for me (i will probably make it an ugly way by drawing something first, as you suggest the other is implementation specific), and when using an intermidiate render target everything is the same too.