GUIs, Fonts, Quads oh mywtf do I damn well do *pulling my hair out*

Started by
3 comments, last by dave 15 years, 10 months ago
Gah, this is driving me insane! How do people do their GUI/Fonts/etc stuff for user interface related stuff? I don't want to use someone else's library, I actually DO want to re-invent the wheel. It's only a hobby project, so the only "loss" in time is my own (and hair...). I want to understand and know how it actually works all the way down. So, I started on this: http://www.gamedev.net/community/forums/topic.asp?topic_id=497059 For those that are lazy and don't want to click, basically I have a vertex buffer with 4 verts (quad), an index buffer with 6 indices for the quad, and a shader that has a texture data var, vertex offset var and scale var, and texture offset var and scale var. I set those to whatever and render my pretty quad. It works. Go me. The problem is, I'm doing DrawIndexed() for every quad I want, which is just not good for large amounts of text (each letter is a quad), or any other sort of tiny GUI animators or whatever. I did a quick experiment and tried to render ~1000 characters; it just died, lol. So how can I avoid this? How can I make it faster? How can I avoid doing so many draw calls? -I've seen people use dynamic vertex buffers (so static text would thus become static words -> static sentences -> static paragraphs -> 1 draw call -> profit??). I've always read to try and avoid dynamic buffers whenever possible. -I've seen people draw it all to a texture, and then just draw the texture. <- wouldn't that be just as many draw calls? (note: I'm not even sure how to do draw to texture yet). -And of course, I've seen people (read: me) render 1000+ quads each frame. I've spent days trying to figure out how to speed it up. My biggest killer is my text (quad per char), is there another way? What would I do for a very "pretty" like UI where all sorts of things need to move around. What would I do if I wanted to "2D" game? Please help, lol. I'm running out of hair!
Advertisement
I haven’t benchmarked it but I think it’s better in this case to do the transformations on the cpu. You probably have to calculates the positions and the bounding boxes of each glyph in every case and drawing the text with a single draw call can be faster (but you have to profile it). Rendering long static texts to a texture can also be useful to improve the performances.
Are you doing something expensive between draw calls (texture/shader switches etc?)

You could keep a list of all the strings you want to draw then every frame copy it into a vertex buffer and draw it with one call like you said. While it may sound like more workload on the app it will probably be faster as you'll have a lot fewer draw calls. You could speed this up more by only updating the vertex buffer if the text has changed.

The texture method is similer to the one above, you just render the strings to a texture then display part of it on one quad. If you only update the texture when text has changed this should be faster too.

A PC should be able to draw thousands of quads no problem. I would try the vertex buffer method above as I think its the Draw calls that are killing it.


dynamic vb/ib, create your quads every frame adding to the vb/ib (you may be able to reuse existing quads for text that hasnt changed - experiment). Use degenerates to link all the polys for the entire screen.

Basically, an entire screen of text using 1 font type, with the above method, will be done in 1DIP call, getting your performance back. Also, do this all using a 2D Shader.
You should also look to cache any unchanging text into vertex buffers where you don't need to update the data.

This topic is closed to new replies.

Advertisement