PDA

View Full Version : OpenGL: Tweaking and performance



WILL
10-06-2007, 06:32 AM
Ok this one is for all the GL gurus here.

I've been using OpenGL for quite some time now, but I still consider myself to be somewhat of a beginner as I've really only worked with Ortho drawing out simple textured quads and other simple primitives with blend, rotate and scale effects. Nothing too advanced here.

So with that, could someone tell me how much functions like glEnable()/glDisable(), glAlphaFunc/glBlendFunc(), etc... cost me in performance? Is this easy to tell?

Also, what sorts of tricks can be used to speed things up a bit? I've heard of the use of lists, how much needs to be built up around this technique to make it effective? Please consider that I'm sticking to Ortho(2D) perspective, if that really matters.


An example of where I'm trying to go with this is my game Garland's Quest. I have some nifty lava glow in there, which looks alright, but it slows the dickens out of the whole game. And I mean a lot, I'm sure that there are much better ways to go about said effects as I can play AoE 3 and Tron 2.0 with obviously much better detail and nicer looking graphics and it's amazingly smoother. What am I doing so disgustingly wrong here? :eh:

Andreaz
10-06-2007, 06:55 AM
Well, state changes (changing color, binding textures, modifying lighting etc etc) in the current version of OpenGL (and directX for that matter) are one of the most costly operation there is.

And displaylist doesnt help that fact (they only reduces the time to send the command from your program to the gpu).

The easiest way to speed stuff up is to throw your geometry into display lists (they are most likely going to be stored as VBO's if you stick to vertex data in them, wich is fast).

Then, either sort your objects depending on the texture, or do as i've did in Phoenix, add support for powerfull patterns, ie on texture and many images, that way you just binds the texture once and then reuses it without the need to rebind it for each primitive.

WILL
10-06-2007, 08:49 AM
Hmm... well it seems that I may have to do a it of reading before jumping into display lists and VBOs, but I'll get there eventually I think. ;)

As for sorting by texture, thats tricky as far as my engine goes. See I have to draw from the back row down to the front row as I'm using a 2.5D perspective in the game. Have a quick look at these screenshots (http://www.pascalgamedevelopment.com/viewtopic.php?p=29259#29259) to see what I mean.

I guess I could try to optimize the game's generated ".obj" map data files so that the drawing order will be sorted in a way that means less texture binds... That might help a wee bit.

Traveler
10-06-2007, 12:00 PM
Comparing Garland's Quest to Villiage Defense I'd say the solution isn¬Ąt found in an optimized drawing order.

I've used opengl for VD as well, but it has far more different images, than you have now. And in all honesty, the code was not optimized at all. For example, for every sprite or tile I made a new texture binding call, changed color etc. Also, I did not have one large image containing all tiles, instead I used seperate images. On top of that, I think the overall sprite and tile count of your game is far less than what I used in VD.

I'm not saying that you shouldn't look into optimizing your drawing order, as such a thing never hurts, I just think that it wont solve your lava problem.

JernejL
10-06-2007, 02:24 PM
sort your materials when you prepare your models for the game.

WILL
10-06-2007, 08:13 PM
I see what you mean Alex. I'm not really doing anything too complex. basically each character or object is drawn as a single textured quad and has alpha_test or blend functions added to it. Not much to it. Save for the fireballs and exit portals, but still, same thing.

I have another question, though this might be obvious. How much slack would I be saving if I could eliminate the glTranslate() call from say printing a line of text? I just noticed that I loop around the translate function so wouldn't it be a fair bit faster to strip that from the loop and keep going with the quad drawing until I'm done my textout function?

JernejL
10-06-2007, 09:06 PM
I have another question, though this might be obvious. How much slack would I be saving if I could eliminate the glTranslate() call from say printing a line of text? I just noticed that I loop around the translate function so wouldn't it be a fair bit faster to strip that from the loop and keep going with the quad drawing until I'm done my textout function?

For text, translate vertex coords yourself and cache the text geometry data unless it changes.

you won't save much - just a bit, but i think it is good idea to do this.

WILL
10-06-2007, 10:34 PM
Hmm I'm not sure I follow you there. If I'm plotting the vertex coords, how can I be cashing the 'geometry' data? Throw up some pesudeo code. ;)

JernejL
11-06-2007, 04:07 PM
Hmm I'm not sure I follow you there. If I'm plotting the vertex coords, how can I be cashing the 'geometry' data? Throw up some pesudeo code. ;)

caching, as in storing the vertices you plotted directly to screen and instead of recreating them each frame, recreate them when the text actually changed.

WILL
11-06-2007, 05:52 PM
I understand what you mean now.

Can I get a quick pointer as to how I'd go about it? (I don't want it done for me, but some mock-up code or "go look up function gl____()" might get me started on it.)

I'm guessing that this is all VBO stuff huh?

JernejL
11-06-2007, 06:39 PM
glPushMatrix;
glTranslatef(pos.x, pos.y, pos.z);
glRotatef(rot, 0, 0, 1);

glInterleavedArrays(GL_T2F_V3F, 0, @edges[0]);
glDrawElements(GL_quads, 4, GL_UNSIGNED_BYTE, @tennumbers[0]);

glpopMatrix;

where you have gltranslate, glrotate, etc.. do those functions yourself on the cpu, and store the data in some buffer.

User137
12-06-2007, 08:06 AM
Combining as many sprites as possible in single texture really is a speed trick. I'd keep something like 512x512 a limit but sort sprites so that you only need to bind each texture once. Don't try to load too many textures at the beginning if there is a lot. Instead load on demand for texture sets where entering levels, replacing current ones if that is possible for the game.

I never used manual rotating over glRotate. I suppose if you could pre-calculate vertex coordinates (Just UP and LEFT vectors needed) for angles 0-359 with step 1 or some would make a difference, however it needs to be added to position vector. Scaling works fine with this too.

Thanks for the glDrawElements reminder :) i never really knew how to use it. It's of the bit harder part of OpenGL imo.

JernejL
12-06-2007, 03:45 PM
i'm also combining particle sprites into one, i remember one glscene demo which had option to sort material / textures when rendering - and when the materials were sorted so it did low amout of texture state swtches, it really shown in the FPS counter.

another idea is, to use multitexturing, and have 4 different textures bound at all times, and cycle thru them to minimize binding textures.. this way you get even less texture switches, but if you use shaders or special effects much you can't use this technique.