Sign in to follow this  
RuneLancer

Rendering many small bitmaps

Recommended Posts

RuneLancer    253
What would be the best way to render a large amount of very small bitmaps? The text is rendered using bitmapped fonts generated from system fonts. I'm going to make the switch to getting text from a font texture, in order to have a more personalized font and to include special symbols (a cursor, the traditional RPG "sword", "shield", etc logo in front of equipment, etc.) Either way this will mean rendering a large amount of small bitmaps. What I was thinking was to create a display list for each renderable character in the font, then when building a window, I'd create a display list which calls these display lists. For instance, I'd have lists for "D", "E", "H", "L", "O", "R", and "W". When building the window, I'd call the lists for "H", "E", "L", "L", "O", "W", "O", "R", "L", then "D" and get "HELLO WORLD". Is this the best way of doing it? Should I try to render the font to a texture and just display that instead? Or any other ways?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
I'm not sure of the display list stuff but "best way to render a large amount of very small bitmaps" in my opinion would be to put them all into one big bitmap. This minimizes state changes and greatly increases rendering speed.

You could then build a list of verts and display everything in one call (depending on how fancy you get).

This is what I do. When I tried breaking things down into multiple calls, my performance suffered.

Share this post


Link to post
Share on other sites
RuneLancer    253
What you seem to be suggesting is to create a vertex array? That's something I hadn't thought of. I suppose all the calls to these lists would add overhead I could easily avoid with your suggestion. Thanks, I'll give it a shot. :)

Another question. The windows I render are stretched currently. That is, I render 9 quads (the four corners, the four borders, and the center; window sizes can be anything and I have to "build" them like this..) and chop up my window texture into the appropriate parts. But I'm going to have window sets which can tile.

I could render a series of window "tiles" and create my window that way, but ideally I'd want to render the same 9 quads I'm rendering right now and to tile the texture. This wouldn't be a problem if I stored each part of the window in a seperate texture, but I want to avoid that.



Anything I could do, or is the only solution available to me the rendering of multiple tiles instead of just 9?

Share this post


Link to post
Share on other sites
RuneLancer    253
I found this after some extensive searching. Unfortunately this is for DirectX, and not OpenGL. However it illustrates the problem I'm facing in better ways than I have.

Basically I don't want to have to switch between 18 textures (9 for the background and 9 for the foreground; imagine two plates between which the window's contents are sandwiched) to render a window.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
Google for "texture atlas". Atlases are useful when storing sevaral small textures, like characters in fonts and different parts of GUI into one large texture. Just adjust your texture coordinates.

Actually the first result with "texture atlas" is the NVIDIA Texture Atlas Tools, here: http://developer.nvidia.com/object/texture_atlas_tools.html.

Share this post


Link to post
Share on other sites
RuneLancer    253
From the looks of it, an atlas is just a way of storing multiple textures into a single one. This is not what I'm asking for.

All of my texture are in the same bitmap already. And this IS the problem I'm facing: OpenGL handles tiling (GL_REPEAT) by repeating the entire texture, not just a portion of it. AFAIK, you can't tell it to tile 3x the texture at 0.5f,0.5f - 0.75f,0.75f.



A, C, G, and I are fine. Corners don't resize. But I have to tile B, D, E, F, and H. I don't want to end up with a stretched "B", for instance. The black lines represent how the window is created as well as which parts of the GUI are in the bitmap.

The only solution I see is creating a quad per "tile". What I want, ideally, is to avoid creating a bunch of quads if I can get away with the same geometry I currently have. Of course, "ideally" doesn't always equate "possible" ;)

Share this post


Link to post
Share on other sites
deavik    570
You got it right in your last post. I think the best way would be to create small quads each the size of 1 character, texture these quads (so you have as many of these textured quads as you have characters) and create as many display lists as you'll need. Render with glCallLists.

Display lists will probably also be the best way here since it'll precalculate some of the state changes required.

Share this post


Link to post
Share on other sites
RuneLancer    253
Quote:
Original post by deavik
You got it right in your last post. I think the best way would be to create small quads each the size of 1 character, texture these quads (so you have as many of these textured quads as you have characters) and create as many display lists as you'll need. Render with glCallLists.

Display lists will probably also be the best way here since it'll precalculate some of the state changes required.


Yeah... I honestly can't see any other way of doing this, but I was hoping someone would come out of the shadows and go, "Oh dude, there's a secret method of doing this handed down from OpenGL programmer to OpenGL programmer since the birth of time. o_o First, you'll need a squid, three blenders, a cookie jar filled with onions, and flea semen..."

Meh. Feels messy doing it this way. ;) Thanks, I'll post a screenshot once I get it and the font system working.

Share this post


Link to post
Share on other sites
Promit    13246
Quote:
Original post by RuneLancer
I was hoping someone would come out of the shadows and go, "Oh dude, there's a secret method of doing this handed down from OpenGL programmer to OpenGL programmer since the birth of time.
This is that time.

Display lists are an ok solution, but you're still dealing with an uncomfortably large number of batches (and a horrible number of state changes if each character is its own texture), particularly if you're looking at a large amount of text. The alternate way to do this is, start with a single texture containing your entire font. Create some dynamic/stream VBO that is big enough to hold the maximum amount of text that you want to support. Then, when it comes time to render a string, you simply generate the vertices on the fly based on the string, fill the VBO, and then render the whole thing.

Now, to be honest, I have an ulterior motive for posting. I like the Final Fantasy styled window borders you have, a lot, and I'm wondering how you render those oe what source images you're using.

Share this post


Link to post
Share on other sites
RuneLancer    253
I don't have a problem with the font. I have a problem with the windows. Read my later posts; I'm already handling the font like you suggested. ;)

Those windows are my work. I simply applied a blue gradient to them in-game, which is what gives them that oldschool FF look. I might try to give the borders a more rounded look though. The bitmap I posted in my second post is the source window. The rest is handled by the game engine, which merely gives different colors to the window's four corners and interpolates.

This is no different than specifying glColor for each corner of a quad, but since I'm rendering multiple quads to assemble the windows together, I have to calculate the color at various points in the window.

Share this post


Link to post
Share on other sites
Jihodg    1148
to simulate repeat or wraping modes for just a portion of a texture (like in the case of texture atlases) the only way, as far as I know, is using fragment program (pixel shader). The problem with this is that it will probably add complexity to the hole GUI rendering system, and thus losing chances of batch optimization...

So the best solution would be to manually add border tiles to simulate the texture repetition and keep your GUI rendering simple, so you just have to update a dynamic vertex buffer (array) with the tiles, and render as much a you can in one batch.

Share this post


Link to post
Share on other sites
RuneLancer    253
Free Image Hosting at www.ImageShack.us

Totally worked out just like I wanted it. This is a test windowset, so it looks a lil' ugly, but it works just fine. To boot, I don't need multiples of 16 or 32 or whatever, I can now set any size I want and my windows will scale accordingly on their own by stretching the texture evenly to fill in the gaps.

Sweet. Thanks for the help everyone. :)

[Edited by - RuneLancer on April 26, 2006 8:29:58 PM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this