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

Author Topic: Batching and other graphical improvements  (Read 10853 times)

0 Members and 1 Guest are viewing this topic.

jdindia

  • Newbie
  • *
  • Posts: 13
    • View Profile
Batching and other graphical improvements
« on: March 07, 2009, 02:18:05 am »
I started my current project using SFML, but relatively early on I shifted to raw OpenGL in place of SFML sprites; keeping SFML for window creation and image loading.  I quite like the clean code style of SFML, in stark contrast to the make-shift disaster that I slowly hacked together over the course of my project.

However, SFML doesn't really do what I want.  I'd like state sorting/sprite batching, and looking forward I'd really like to be able to play with render to texture and perhaps even shaders.  I can imagine things like texture compression and built in sprite animation eventually being convenient as well.

Most of the recent changes I've seen to SFML have been in non-graphical areas, which is fine.  I'm curious what the level of interest is for graphical additions like I've suggested.  From my brief poking around in the sprite and renderwindow internals, I don't see how batching could be added without significantly changing things.  I could be wrong.  I see some of what I've listed on the roadmap.  Does that mean Laurent has design ideas, or just a general interest in the feature?

I have a pretty clear idea of what I want to be able to do.  I'm even willing to help SFML get there since I'll being doing some of this stuff anyways.  I'm just not clear on what direction SFML is heading in or whether the help is wanted.  =)  I can honestly see a fancy batching rendering system being confusing and 'ugly' in comparison to what SFML already has.

dorkfish

  • Newbie
  • *
  • Posts: 38
    • View Profile
Batching and other graphical improvements
« Reply #1 on: March 07, 2009, 08:14:59 am »
batch rendering and render to texture/image are set to be implemented in sfml2. As for shaders, GLSL is available in sfml as PostFX. PostFX, as I understand it, is just GLSL with a few SFML-specific macros or extensions. There's a basic tutorial on working with it here: http://www.sfml-dev.org/tutorials/1.4/graphics-postfx.php

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Batching and other graphical improvements
« Reply #2 on: March 07, 2009, 10:56:02 am »
I haven't a clear idea of how I'm going to implement the batching system yet. I'm opened to all suggestions :)
Laurent Gomila - SFML developer

jdindia

  • Newbie
  • *
  • Posts: 13
    • View Profile
Batching and other graphical improvements
« Reply #3 on: March 07, 2009, 01:27:46 pm »
Heh.  I somehow never looked at PostFX.  I guess the name threw me.  I didn't realize it was shader support.

I'll see if I can't take some time this weekend to doodle out a few batch rendering schemes.  Unfortunately, I suspect part of the problem is simply implementing and profiling different techniques to see what kind of speed-up you get.

jdindia

  • Newbie
  • *
  • Posts: 13
    • View Profile
Batching and other graphical improvements
« Reply #4 on: March 08, 2009, 03:28:42 am »
Ok, the task of batch rendering can roughly be broken up into two parts, the sorting and the actual rendering.  Because we have to sort, I don't think there's any way around having some kind of container that you queue drawables into each frame.  I think you'd almost certainly want to add some kind of layer variable to drawables.  Then sorting would be something like layer/[view]/topology/image/blend mode (topology might be better last, it depends).

From there I see two possibilities.  The first is to have the drawables give the data necessary to the renderer.
Code: [Select]

void BatchRenderer::render()
{
    sort queue
    for each drawable in queue
        get drawable render information
        draw the stuff
    empty the queue
}

I could see this being made potentially fairly fast, but it's probably harder to extend.  If you needed some new topology or something, you'd have to add it to the render function.

The second strategy (which I think probably fits SFML best) would be to add a new virtual member function on drawables (private and friends with the batchrenderer).  Then create a class BatchRenderState (my nomenclature shouldn't be taken as recommended, just using whatever comes to mind) that holds the current state and the batched data.
That would look something like this:
Code: [Select]

void BatchRenderer::render
{
    sort queue
    for each renderable in queue
        drawable->batchrender ( batchrenderstate );
    batchrenderstate.finished
    empty the queue
}

A drawable batchrender function would then look something like this:
Code: [Select]

void SomeDrawable::batchrender ( batchrenderstate )
{
    batchrenderstate.setstate ( drawable's topology, image, etc. );
    batchrenderstate.setdata ( drawable's vertices, texture coords, etc. )
}

The batchrenderstate object would watch for state changes, thus ending the current batch and would actually call opengl with whatever it had stored up so far.  If things were written well, you could even call opengl inside the drawable::batchrender without passing the data to the state object, as long as you informed the state object accordingly (a flush type command, or set state without data).

I think a few things could be problematic, namely child drawables (since you can't push/pop and have a good batch renderer), the current color, the view (you have to queue everything, so if you have different views that has to go in there as well).  For views, one solution is to have per layer views, so the renderer can change the view when the layer changes.  That might work for colors as well (colorable layers vs normal layers).  Heh, you could even do blend modes that way to avoid having to check lots of state with each drawable.

There are some potential speed optimizations as well, for example, maybe instead of setdata, it's getdataptr and then the drawable stuffs the data in itself.  *shrug*

Anyway, a proposal at least. =)  Now that I've thought it out, it's less complicated than I expected.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Batching and other graphical improvements
« Reply #5 on: March 08, 2009, 10:46:39 am »
Hey, thanks for this long reply :)

That's indeed what a good batch renderer would look like. But this solution has some problems that you already noticed: everything which is related to what is currently drawn may not work with such a system (View, PostFx, Image::CopyScreen, RenderWindow::Capture, external OpenGL calls, ...). That's my main concern actually.

That's why I was starting to think about a less general/automatic solution, like a sf::Batch class that the user would have to feed explicitely with other drawables. This way, all the batching process would happen in a single call (window.Draw(batch)), and not break the rest.
But of course this solution has its own drawbacks as well.

I still haven't found the perfect solution :)
Laurent Gomila - SFML developer

jdindia

  • Newbie
  • *
  • Posts: 13
    • View Profile
Batching and other graphical improvements
« Reply #6 on: March 08, 2009, 11:55:30 am »
Quote from: "Laurent"

I still haven't found the perfect solution :)


I don't think there is one.  =/  Batching inherently means state changes spanning across drawable boundaries, which breaks the current model.

jeffm2009

  • Newbie
  • *
  • Posts: 1
    • View Profile
Batching and other graphical improvements
« Reply #7 on: September 18, 2009, 10:54:15 pm »
I have been trying to work on a similar project (and I'm glad I found this discussion BTW). After spending a lot of time on it I tend to agree that there really is no perfect solution, unfortunately.

Sigvatr

  • Newbie
  • *
  • Posts: 32
    • MSN Messenger - msn@sigvatr.com
    • AOL Instant Messenger - SigvatrAIM
    • View Profile
    • http://www.sigvatr.com
Batching and other graphical improvements
« Reply #8 on: September 19, 2009, 12:25:43 am »
I'm doing the same thing as you guys and using straight up OpenGL. I'll keep you posted if I come up with any ideas.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Batching and other graphical improvements
« Reply #9 on: September 19, 2009, 11:03:16 am »
Actually I've found a good solution, I'm still working on it but it's almost complete. It is 100% automatic, doesn't require a Z-buffer, and even allows me to solve all the "pixel perfect rendering" issues :)

It should be in the sfml2 branch soon.
Laurent Gomila - SFML developer

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Batching and other graphical improvements
« Reply #10 on: September 19, 2009, 02:43:11 pm »
Quote
and even allows me to solve all the "pixel perfect rendering" issues :)

That sounds perfect. I guess I can drop my std::floor calls then? ;)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Batching and other graphical improvements
« Reply #11 on: September 19, 2009, 03:17:23 pm »
Quote
I guess I can drop my std::floor calls then?

I hope so!

I'm trying to test every sample code that previously failed to render properly, so if you have one to submit I'll be glad to test my new fix on it ;)
Laurent Gomila - SFML developer

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Batching and other graphical improvements
« Reply #12 on: September 19, 2009, 07:54:57 pm »
Well it's more a complete GUI based on SFML. Not so easy to send and test on the side. ;) If it's a small fix, it'd be great to get it so I could test it, too.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Batching and other graphical improvements
« Reply #13 on: September 19, 2009, 11:10:31 pm »
It's a huge fix (not the fix itself, but the batching code that allows it), sorry.

You'll have to wait for the next commit ;)
Laurent Gomila - SFML developer