2
\$\begingroup\$

Platform is OpenGL ES 1.x. I am using glGetFloatv() to get MODELVIEW matrix. This allows me to compute points, where I need to draw a shadow effect. This is very handy, as I can forget about complexity of scene (its translations, rotations, etc.) – and by simple 3x1 matrix multiplication get the points.

But here it is stated that the call should be avoided. Is it correct recommendation? Can be glGetFloatv() omitted?

\$\endgroup\$

3 Answers 3

4
\$\begingroup\$

From a pure performance standpoint, the glGet*() functions should generally be avoided where possible, as they can introduce unnecessary synchronization points inside the graphics driver. Basically, when you call glGet*(), the driver may have to stall the CPU and wait for the GPU to finish any outstanding rendering operations, so that a correct and up-to-date value can be returned from glGet*(). Even better, the performance penalty may vary from driver to driver, so what runs fine on one platform may be unacceptably slow on another.

The faster (but much less convenient) solution is to manually cache any necessary render state in the application code. For example, when you pass a MODELVIEW matrix to OpenGL, keep an extra copy around for yourself, so you don't need to call glGetFloatv() later to retrieve it.

That said, a single call to glGetFloatv() per frame probably isn't going to kill your performance. Just use these functions sparingly, be aware of their potential side effects, and profile often!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ How is it less convient? You have one miraclous function call less and one handy variable more. \$\endgroup\$
    – API-Beast
    Aug 25, 2012 at 23:07
  • 2
    \$\begingroup\$ @Mr.Beast I just meant that it adds more global state for your application to keep track of, and more code you have to write to manage it. It's not a huge chore, but it's less convenient than just using a standard GL function. \$\endgroup\$ Aug 26, 2012 at 4:05
3
\$\begingroup\$

The fastest way to solve this would be to use modern, programmable pipeline OpenGL (2.0 ES), since you would typically be creating the model, view and projection matrices on the client side, and would thus never need to request them from the server.

I don't know if this is an option for you -- you may be supporting older devices.

\$\endgroup\$
2
\$\begingroup\$

This is going to be driver-dependent behaviour, so an absolute one-size-fits-all answer won't be possible. However, while the general rule is that any glGet call should be avoided, in certain cases they can be used without undue problems.

The reason for this is that not every glGet call will be dependent on the result of previous GPU-side operations, and that it's only those that are so dependent that will involve synchronization and pipeline stall/flush problems.

In the case of the current modelview matrix, this will - generally - always be calculated CPU-side by the driver, then sent to the GPU for actual use when a draw call occurs. So a glGetFloatv on the current modelview matrix won't actually need to round-trip to the GPU - it can just grab the copy of it that the driver is storing CPU-side and give that back to your program.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .