Skip to main content

News

Topic: TurboSphere (Read 190996 times) previous topic - next topic

0 Members and 4 Guests are viewing this topic.
Re: TurboSphere
Reply #105
Hm, I just had this awesome thought: if you're using OpenGL for all the rendering, how hard would it be to expose a GLSL interface to JS and allow using shaders?

Re: TurboSphere
Reply #106
Simple. About as simple as inlining them in the TurboSphere or plugin source, actually. Since I'm not using Glut or Glew (or anything else like that), so I already am binding up all the necessary functions by hand for use in C++.

And funny, I was just thinking about doing it, too.

Partially because it's a cool idea (a very cool idea), but also because I highly doubt any other engine lets you do that. How often do you get to use custom OpenGL shaders in combination with a 2D, script-based game engine?

I also like the idea because it's simple to deal with any GLSL errors in the included shaders. I can fairly easily make it hard to screw things up with game-included shaders. It could possibly be the easiest way for someone to tinker with GLSL, actually.

Re: TurboSphere
Reply #107
LOVE2D has that feature, and is actually one of the reasons I was thinking of switching. LOVE has a very fast scripting language (Lua; it can use LuaJIT) + OpenGL + shaders + physics, while Sphere has a slow scripting language (ancient SpiderMonkey) + fast software graphics + networking + a built-in map engine + a very nice API. TurboSphere will have a fast scripting language (V8 is close to LuaJIT) + OpenGL + shaders + networking + a very nice API, and eventually a built-in map engine. Hm, long-term a physics (Box2D, probably) plugin would be rather nice.

Incidentally, wanting to play with GLSL is what made me think of that. :)

Re: TurboSphere
Reply #108
I'll have to have a look at how it's done in LOVE2D. I have an idea how I would expose it, but I'm curious how it's done over there.

Also, all the plugins are using OpenGL now. Once I compile and test on Windows, I'll make a release. A lot of silliness on Windows with compiling plugins that relied on a compatible graphics plugin existing is now solved by using OpenGL, as well. Or it should be anyway, I haven't tried yet.

I upgraded the TTF Font plugin, too. It caches often used strings, which more than offsets the change to using fully blended font rendering. I figure if I don't pretty text, why am I using a TrueType font?
  • Last Edit: April 25, 2013, 05:13:32 pm by Flying Jester

  • DaVince
  • [*][*][*][*][*]
  • Administrator
  • Used Sphere for, like, half my life
Re: TurboSphere
Reply #109
That screenshot is a mess. A beautiful mess. :)

Re: TurboSphere
Reply #110
Messes are the best way to test alpha blending.  ;D

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: TurboSphere
Reply #111
TurboSphere supports TT fonts? Nice!
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

Re: TurboSphere
Reply #112
TrueType fonts were the first graphics I actually got working. True story.

The release may be a bit delayed. I'm removing all the immediate mode stuff I put in there to get things up and working (and am almost done with that), and a few bits broke when I ported it to Windows. I'll make a release of it just for the sake of having a working OpenGL plugin pack out there, but it has some flaws.

If you want to play with a working OpenGL plugin pack right now, the source is on GitHub and builds quite well in Linux and somewhat well in Windows. There are a couple complicated bits if you don't use Scons, and I think the Scons file is an older version that doesn't quite work out of the box on Windows (I should really fix that).

I am thinking that it might be useful to have an image.tileBlit function, that blits an image with a given x, y, (and maybe width and height), and repeats it a given number of times for the width and height (or just makes the dimensions the base dimensions * number of repeats). Mostly because I found that quite a useful thing to do with a modified Majestic, and it can be done very easily in hardware.

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: TurboSphere
Reply #113

I am thinking that it might be useful to have an image.tileBlit function, that blits an image with a given x, y, (and maybe width and height), and repeats it a given number of times for the width and height (or just makes the dimensions the base dimensions * number of repeats). Mostly because I found that quite a useful thing to do with a modified Majestic, and it can be done very easily in hardware.


Bending the texturing hardware to your will, huh? ;)
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: TurboSphere
Reply #114

I am thinking that it might be useful to have an image.tileBlit function, that blits an image with a given x, y, (and maybe width and height), and repeats it a given number of times for the width and height (or just makes the dimensions the base dimensions * number of repeats). Mostly because I found that quite a useful thing to do with a modified Majestic, and it can be done very easily in hardware.


I see some limited use for it, but not for really for custom map engines. It has a lot to do with the fact that at one point many tiles would have changed, and so not always is one tile being repeated. I think the use of a sprite batcher is better, many modern game engines use one (XNA, pixi, etc): they increase the drawing FPS 1000% in some cases.

It has to do with the communication between the CPU/RAM and GPU/VRAM. Drawing hundreds of small images can be slower than batching them into 1 image and drawing portions of that image to screen. Here's the general algorithm:

1. "Draw" all images to screen. They aren't actually being drawn at this point.
2. For each object:
    a. Keep track of the image handle being used, don't store repeat handles.
    b. Keep track of the x/y locations of all drawn objects.
3. Take all the images and put them into one large batch. It's up to you how to create this 'texture atlas'.
4. Send it to the GPU, and perform source/destination blits. The source being the texture-packed location of the image drawn, and the destination being where the user wanted to put it.
5. See the magic at play.

That basic framework can really speed graphics up. Of course, there's more to it. If you introduce different blit modes, they have to also be passed to the sprite batcher (so in other words it changes the API for drawing GFX). If you want to use shaders on particular blits then they might as well just be sent to different sprite batches altogether (perhaps not even seeing a speedup).

An API would be something like this, (how XNA does it).
Code: (JS) [Select]

var sb = new SpriteBatch();
while (true) {
    sb.begin();

    sb.blit(image, x, y, red);
    sb.blit(image2, x2, y2, red);
    sb.blit(image3, x3, y3, red);

    sb.end();
   
    FlipScreen();
}


The sprite batch is *not* like drawing to a canvas and drawing that whole canvas to screen. It's just an organizational tool.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

Re: TurboSphere
Reply #115
Sprite batches would be so amazingly useful. I'm actually working on a custom map engine currently (for Tiled maps), and they would be excellent. Currently I'm drawing everything to one big image and blitting that (it's about 200 FPS on Sphere 1.6) which is about twice as fast as drawing every tile individually. However, the maps can get pretty big, and blitting enormous images like that can't be good for performance. So I was going to chunk the really big image into a few large ones, and blit them depending on the camera. This approach, however, would be better for performance and much easier to implement. (Although since I'd like the game to run on default Sphere 1.5+ (at least until TS is more stable/has networking functions) so I'd probably have to keep the chunking approach.)

I'd really like sprite batches in Sphere. LOVE2D has them, but I never looked into how they work. It looks insanely useful. Thanks for the explanation Radnen.

Re: TurboSphere
Reply #116

I see some limited use for it, but not for really for custom map engines. It has a lot to do with the fact that at one point many tiles would have changed, and so not always is one tile being repeated.


Oh definitely not specifically for maps. But it's something that I end up doing somewhat regularly, and it can be done very easily and quickly. In fact, not much higher overhead, if at all, than would be just blitting a single image normally.


I think the use of a sprite batcher is better, many modern game engines use one (XNA, pixi, etc): they increase the drawing FPS 1000% in some cases.

It has to do with the communication between the CPU/RAM and GPU/VRAM. Drawing hundreds of small images can be slower than batching them into 1 image and drawing portions of that image to screen. Here's the general algorithm:

1. "Draw" all images to screen. They aren't actually being drawn at this point.
2. For each object:
    a. Keep track of the image handle being used, don't store repeat handles.
    b. Keep track of the x/y locations of all drawn objects.


That's the complicated bit right there. The Sphere API is not well suited to this, it's pretty much a shadowy reflection of GL immediate mode, and doesn't control graphical element persistence. I could work out something to deal with it, but I'm just getting everything up and running right now.


3. Take all the images and put them into one large batch. It's up to you how to create this 'texture atlas'.
4. Send it to the GPU, and perform source/destination blits. The source being the texture-packed location of the image drawn, and the destination being where the user wanted to put it.
5. See the magic at play.

That basic framework can really speed graphics up. Of course, there's more to it. If you introduce different blit modes, they have to also be passed to the sprite batcher (so in other words it changes the API for drawing GFX). If you want to use shaders on particular blits then they might as well just be sent to different sprite batches altogether (perhaps not even seeing a speedup).

An API would be something like this, (how XNA does it).
Code: (JS) [Select]

var sb = new SpriteBatch();
while (true) {
    sb.begin();

    sb.blit(image, x, y, red);
    sb.blit(image2, x2, y2, red);
    sb.blit(image3, x3, y3, red);

    sb.end();
   
    FlipScreen();
}


The sprite batch is *not* like drawing to a canvas and drawing that whole canvas to screen. It's just an organizational tool.


If I introduced new parts to the API to handle this, it could be done very easily. It makes me a little wary that what you wrote looks suspiciously like immediate mode GL, though.

As far as blitting performance, at the moment TurboSphere is fairly evenly split between being CPU and GPU bound. Each image has an associated texture in VRam, and a blit just calls up that texture to be blit. I'll do some testing to see how the performance is between minimal large blits and many small blits.

The thing is, having all image blits occur close together won't do that much (or at least I don't think it will). I think a much larger performance gain could be granted by having some sort of batcher that stores a series of images and primitives and related coordinates that are modifiable (but hopefully won't all be modified every frame) and just calling the batcher to blit them all at some point in the game loop. It would even be simple to translate their positions all at once by some value. Having some form of graphical element persistence would make it much easier to use the faster and more modern parts of graphics hardware, and it's what I've been imagining for the new map engine as well.

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: TurboSphere
Reply #117

Currently I'm drawing everything to one big image and blitting that (it's about 200 FPS on Sphere 1.6) which is about twice as fast as drawing every tile individually.


Well, that's not how a sprite batch works, but you might already know that. Just for clarification if you do 2000 calls before it's still going to do 2000 calls after. It doesn't turn 2000 into 1 (like in the section I quoted). The idea is that those 2000 calls came from different parts of memory / different image handles / context's. A sprite batch is one lump image, where all other images are dumped into. The GPU can do 20000+ draw calls easily if they all came from the same place. So the speedup is not from limiting draw calls! It's by doing perhaps even more draw calls than you did before, but all from one place. That is the trick.


I think a much larger performance gain could be granted by having some sort of batcher that stores a series of images and primitives and related coordinates that are modifiable (but hopefully won't all be modified every frame) and just calling the batcher to blit them all at some point in the game loop.


Exactly what I'd like to see! (What er, I've been talking about really!)
  • Last Edit: April 28, 2013, 06:59:40 pm by Radnen
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

Re: TurboSphere
Reply #118


I think a much larger performance gain could be granted by having some sort of batcher that stores a series of images and primitives and related coordinates that are modifiable (but hopefully won't all be modified every frame) and just calling the batcher to blit them all at some point in the game loop.

Exactly what I'd like to see! (What er, I've been talking about really!)


OK, that's good. It looked more like what would happen with your example code is less state changes--which would increase performance, but not by much.

Re: TurboSphere
Reply #119

Well, that's not how a sprite batch works, but you might already know that. Just for clarification if you do 2000 calls before it's still going to do 2000 calls after. It doesn't turn 2000 into 1 (like in the section I quoted). The idea is that those 2000 calls came from different parts of memory / different image handles / context's. A sprite batch is one lump image, where all other images are dumped into. The GPU can do 20000+ draw calls easily if they all came from the same place. So the speedup is not from limiting draw calls! It's by doing perhaps even more draw calls than you did before, but all from one place. That is the trick.

I didn't mean to imply that's how a sprite batch works; rather than that a sprite batch would be a better approach. So a sprite batch would work like I add every tile to the sprite batch, and then render each tile from there as needed? So I'm doing more calls with the sprite batch than with the single-huge-image-blit, but it's much faster with the sprite batch, correct? (Well, for one thing, it wouldn't be drawing 960x1920 images.....)