Is using glScalef(...) frowned upon for 2D?

Are there any tangible performance issues relating to using glScalef(…) to render a 2D tile-based scene?

As probably thousands of other people on here are doing, I’m creating a 2D tile-based game, and part of that requires me to draw my grainy, poorly-designed 16x16 pixel textures (read in from a texture atlas) at a much higher size than they’re designed. The entire scene is ‘zoomed in’ by a factor of 3 or 4 (I’m thinking this will be user-definable). But I’m wondering whether I should really be using glScalef to do this, or just simply draw the quads bigger?

I’m only calling glScalef(…) once before the tiles are rendered. It doesn’t get called again until the next render pass, so there’s no continual use of the function for each tile.

Thoughts would be welcome on this - I’m keen to try and use this method to up-scale bitmap font rendering too!

Thanks!

All of the OpenGL fixed function transformations ie glTranslate(), glRotate(), glScale() etc. perform the transformation the same way. They combine the transformation into the current matrix. Hence using glScale() will have absolutely no effect on performance (other than the actual call to glScale() which is trivial), doing things cpu side by drawing bigger quads would be worse.

The only reason it could be frowned upon is because it’s for immediate mode (but I believe it can be used for other rendering modes too, this needs confirmation) which is deprecated. But if immediate mode works for you, then by all means use it.

The glScale(), as I stated above, is part of the fixed function pipeline. It can be used with immediate mode or deferred rendering.

There are two different options in OpenGL which everyone gets confused about.

Immediate Mode vs Deferred Rendering
Immediate mode uses commands like glVertex3f(), glTexCoord2f(), glVertexAttrib3f() in between glBegin(), glEnd() blocks. It is called immediate because you send OpenGL the vertex data and the primitives are rendered (pretty much) immediately. Deferred rendering uses VBOs. You send OpenGL the vertex data and it keeps it. You can render primitives with it at any time, hence the rendering is deferred from sending the data.

Fixed Function Pipeline vs Programmable Pipeline
Fixed function uses commands like glTranslatef(), glRotate(), glScalef(), glOrtho(), glMatrixMode() as well as (amongst other things) all of OpenGL’s built in lighting support. It is called fixed function because the primitives are modified through set fixed functions, you can modify the parameters of the functions (like the contents of the matrix) but it is quite an inflexible system if you want to to do anything beyond what it is designed for. The programmable pipeline uses shaders to modify the primitives and it is called programmable because, guess what, it is programmable. This means you can do pretty much whatever you want. One important thing to note is that you can still access the fixed function matrices and lighting parameters in earlier versions of OpenGL so if you make use of them, then the above functions will still work.

I hope that clears things up.