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

Author Topic: How to handle a GBuffer with SFML?  (Read 3817 times)

0 Members and 1 Guest are viewing this topic.

tetra

  • Newbie
  • *
  • Posts: 16
    • View Profile
How to handle a GBuffer with SFML?
« on: May 27, 2015, 07:08:55 pm »
Hi, I'm working on implementing a deferred renderer in my SFML project.

However, there are some things that I am confused about. Specifically, I don't understand how to translate some OpenGL code I found on a tutorial (http://ogldev.atspace.co.uk/www/tutorial35/tutorial35.html) to SFML.

I think the main thing is the interaction between the draw buffer and the fragment shader.

In the tutorial, the init() function of the GBuffer is as follows:

bool GBuffer::Init(unsigned int WindowWidth, unsigned int WindowHeight)
{
    // Create the FBO
    glGenFramebuffers(1, &m_fbo);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);

    // Create the gbuffer textures
    glGenTextures(ARRAY_SIZE_IN_ELEMENTS(m_textures), m_textures);
    glGenTextures(1, &m_depthTexture);

    for (unsigned int i = 0 ; i < ARRAY_SIZE_IN_ELEMENTS(m_textures) ; i++) {
       glBindTexture(GL_TEXTURE_2D, m_textures[i]);
       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
       glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, m_textures[i], 0);
    }

    // depth
    glBindTexture(GL_TEXTURE_2D, m_depthTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, WindowWidth, WindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
                  NULL);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0);

    GLenum DrawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 };
    glDrawBuffers(ARRAY_SIZE_IN_ELEMENTS(DrawBuffers), DrawBuffers);

    GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

    if (Status != GL_FRAMEBUFFER_COMPLETE) {
        printf("FB error, status: 0x%x\n", Status);
        return false;
    }

    // restore default FBO
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

    return true;
}

Now, I think I have most of that down, except for the DrawBuffer thing (where it attaches the draw buffers so that the fragment shader can output those textures to the buffer.)

Here is my implementation in JSFML, where fbo is a RenderTexture, and the other variables are Textures:

    public boolean init(int windowWidth, int windowHeight) {

        // create the FBO
        try {
            fbo.create(windowWidth, windowHeight);
        } catch (TextureCreationException ex) {
            System.err.println("Error creating F!");
            return false;
        }

        // create gbuffer textures
        for (int i = 0; i < textures.length; i++) {
            try {
                textures[i].create(windowWidth, windowHeight);
            } catch (TextureCreationException ex) {
                System.err.println("Error creating GBuffer textures!");
                return false;
            }
        }

        // depth
        try {
            depthTexture.create(windowWidth, windowHeight);
        } catch (TextureCreationException ex) {
            System.err.println("Error creating depth texture!");
            return false;        
        }
       
        return true;
    }

As you can see, I stop at the depth texture creation, because I do not understand how to initialize the draw buffer. Also, I feel like I need to properly attach those textures to the framebuffer. How would I do that?

Can anyone help me translate that code, or point out any errors I have already?
« Last Edit: May 27, 2015, 09:22:27 pm by tetra »

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: How to handle a Geometry Buffer with SFML?
« Reply #1 on: May 27, 2015, 08:27:19 pm »
SFML is not designed as a 1:1 replacement for OpenGL. It is able to wrap basic functionality such as textures and shaders, but that is pretty much it. The advanced FBO usage with multiple texture attachments is far beyond the scope of what SFML is and will ever be.

If you want to learn OpenGL via that tutorial series then I suggest you focus on actually learning OpenGL, and not how you can get OpenGL stuff done using pure SFML. It also seems to me from your questions and code like you don't really understand what is being explained and done in the tutorial. Copying and pasting/translating code without actually understanding it just won't work, especially when it comes to OpenGL.

You need to take a step back and start from the beginning of the tutorial series and work your way up, no short cuts. There is a reason why that tutorial on deferred shading is tutorial 35. You will quickly notice already in the early tutorials that it doesn't make sense to use anything else but raw OpenGL when following the tutorial series.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

tetra

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: How to handle a Geometry Buffer with SFML?
« Reply #2 on: May 27, 2015, 08:43:25 pm »
I know what the code does, I was just wondering if I could replicate it in SFML. I understand exactly what it does.

I would rather keep using JSFML; is there any way I could mix opengl with it? I know you can with C++ SFML, but what about JSFML? Or is it all or none? By that, I mean, I want to keep the opengl abstraction for ease of use, but be able to use pure opengl when I need to. Is this possible?

I know this is suited for the other subforum, I'll look there.
« Last Edit: May 27, 2015, 08:54:26 pm by tetra »

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: How to handle a Geometry Buffer with SFML?
« Reply #3 on: May 27, 2015, 09:04:50 pm »
It is possible, but you need to know what each SFML class actually does, and this you can find out by reading the corresponding documentation and even browsing the source code if you have to.

I just find it strange that you go ahead and create multiple textures and a RenderTexture thinking it is an FBO (and nothing more) and then end up wondering how to create a depth texture, even asking about a "geometry buffer" in the thread title, which is completely misleading. If you would have just asked whether you could create a depth-only texture in SFML or if you could attach images to the RenderTexture yourself, you wouldn't have to post all that code you did. The simple answer to those questions would have been: no.

Like I said, I'm still not 100% convinced you fully understand what you are trying to translate, primarily because you don't use the proper vocabulary to express what you intend to do using SFML. OpenGL provides the bits you build your pieces out of. When you ask whether something can be done in SFML, you ask about the bits, not the pieces.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

tetra

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: How to handle a Geometry Buffer with SFML?
« Reply #4 on: May 27, 2015, 09:16:16 pm »
I think I've been using Geometry Buffer in place of GBuffer, when they are not interchanegable. I am sorry.

Laurent said that the equivalent of an FBO in SFML is a RenderTexture, so that's why I'm using that.

The reason I'm asking about that in the thread title, is because that's what this is: a buffer to store multiple textures, each with its own vertex attribute. Those attributes are separated and written to the textures using the DrawBuffer.

Sorry if I was unclear, I have an idea of how the process works, I'm just not great at expressing exactly what I need to accomplish.

tetra

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: How to handle a Geometry Buffer with SFML?
« Reply #5 on: May 27, 2015, 09:19:38 pm »
If you're saying that I really should go through all the tutorials beforehand (using LWJGL instead of JSFML) to actually understand the process, and finally use SFML when I actually need to integrate it into my game, then I'll do that. But I feel that there is some SFML functionality that I'm not finding that will enable me to store the textures, and write to them.
« Last Edit: May 27, 2015, 09:30:48 pm by tetra »