Rendering large sprites using OpenGL?

I’m drawing the graphics for a nebula by mixing a bunch of tiles randomly taken from a texture atlas. The tiles overlap by a lot, and that combined with randomly picking them helps make it look less tiled.

Here is a screenshot of what it looks like - the nebula is the purplish strip going diagonally across the screen.

The trouble is that each tile is rather large (around 512x512, though the texture area mapped to it is about half that and gets scaled up). With the overlap, to have the nebula fill a screen’s worth of space requires drawing about 2-3 times the area of the screen worth of tiles. So I might draw 40 512x512 tiles on a nebula-heavy screen.

This ends up being really slow on lower-end graphics cards, with a vast majority of the time spent in Display.update(). (I’m using LWJGL)

Is there something I can do to speed this up? What’s the likely culprit? (fillrate?)

Another related question - what would be a fast way to draw the background image? It’s just putting pixels on the screen, there’s no stretching/blending/etc going on. Right now I’m just drawing it as a textured quad, with GL_BLEND disabled.

Can you explain a bit more about why that is, seems like you’d still only have to fill a screen at any given time. Are you overdrawing or something?

Kev

The nebula graphic on each tile extends about halfway onto adjacent tiles - covering about 4x the area of a single tile. Since there are 16 choices of graphic for each tile (from the texture atlas), the are lots of visual combinations for the different overlaps. The goal is to avoid a tiled appearance.

[quote]What’s the likely culprit? (fillrate?)
[/quote]
Yes!

If you render it once to the framebuffer every frame, you can just as well render it once to a texture and render that texture every frame.

40 quads should be easy to draw even on crap hardware. More likely its fill rate or texture memory that’s causing a bottleneck on the low-end systems (or general crappy performance if most of the time is in Display.update()).

Try drawing one quad across the entire screen with blending and see if you get the same amount of bad performance. Or shrink your viewport to something ridiculous like 5x5 pixels (but do your regular drawing calls). If you see greatly improved performance on the small screen, you’re probably fill limited.

Riven made a post while I was writing this, but I’m adding it anyways.

Yes!

If you render it once to the framebuffer every frame, you can just as well render it once to a texture and render that texture every frame.
[/quote]
Hmm. These get pretty large, though - a map can be say 20,000 pixels wide, and a nebula can cover most of it. Pre-rendering 1024x1024 chunks to a texture as the view moves around might just work though, even if it’s going to be a bit hairy.

Thing is, the frame rate plummets even if a relatively small amount of nebula is on-screen - so I suspect even optimizing it to a point where it’s rendering the area only once would only still get me part of the way there. Is there another angle to take in trying to speed this up?

Thanks, I’ll try that - though the nebula rendering is already so close to drawing one big quad as to be almost the same :slight_smile:

You could use a lower res texture on slower hardware like a 256x256 (or 128x128) instead of 512x512.

Obvious question but are you using mipmapping?

So that would actually help even though the area drawn is the same? Cool, didn’t know that.

Nope. I don’t quite know how it works, but even if I was using it, wouldn’t it only take effect if the texture was being scaled down, not up? (In my case, the texture is smaller than the quads it gets mapped to)

AFAIK, it won’t help if you are fillrate limited, as the same number of texel lookups are done and the same number of pixels are drawn.

Are you using linear to scale up the nebula pieces? I think you could reduce the number of texel lookups by a factor of 4 with nearest. Drawing the pieces to a texture could also provide this benefit by avoiding scaling.

Quick update - I tried rendering 10 partially transparent screen-sized quads on top of everything else, and it didn’t affect the frame rate at all. So seems like fillrate is out. Looks like I have some more investigating to do. Thanks for all the ideas, guys! I’ll post back here after I get this all sorted out.

I have nothing to contribute help wise, but, nice ship and nebula!