Immediate mode in OpenGL consists of glBegin
/glEnd
calls, with one or more glVertex
calls (the minimum legal number depending on the mode param of your glBegin
call), and optionally other vertex attribute specification calls (glColor
, glTexCoord
, etc), between them.
glBegin
instructs the GL driver that you're starting to draw a point, line or polygon.
glTexCoord
, glColor
, glNormal
, etc just set a "current value" for the texture coordinate, colour, normal, etc.
glVertex
takes those "current values", together with the position information that you supply with the glVertex
call, and transfers the lot to the driver.
glEnd
completes the point, line or polygon.
The major advantage to immediate mode is that you need to plan absolutely nothing up-front. You can just issue a glBegin
call and start sending aribtrary geometry to your driver and hardware.
The major disadvantages to immediate mode include that it incurs a lot of function call overhead into the GL driver, and that vertex data must always be sent to the graphics hardware, even if that vertex data is unchanged from last time it was used.
These disadvantages can combine to make immediate mode slow. How slow? Well, faster than you might think (and definitely faster than some people might give you the impression it is). Quake and Quake II both used immediate mode so it's clearly quite capable of handling certain workloads with acceptable performance.
The first disadvantage was addressed in OpenGL 1.1 (1997) by the addition of vertex arrays, which allowed for the number of GL calls to specify a point, line or polygon, which could easily get into double figures, to drop to one (not including some setup calls).
The second disadvantage was addressed in OpenGL 1.5 (2003) by the addition of vertex buffer objects, which built on the vertex array specification and which allowed for data that didn't need to change to be kept in GPU memory.
I draw attention to these dates and version numbers because, and once again contrary to information you may see elsewhere, these are actually very old additions to OpenGL (both were in fact added before shaders were) and are widely available even on low-end commodity hardware.
What you are calling retained mode is primarily use of vertex buffer objects as a source for vertex data rather than just specifying it on-the-fly via immediate mode.
Modern OpenGL is the term typically used to refer to a usage of OpenGL in which vertex buffer objects and shaders are the only way of drawing available, being constrained by what is known as a "core profile". It is also possible to create what is known as a "compatibility profile" giving you the ability to mix certain features of modern and old-style OpenGL; mixing immediate mode with shaders would be one example.
Which should you use?
There's no clear-cut answer to this; it's really going to depend on the needs of your program.
Immediate mode, because of it's on-the-fly nature, is great for prototyping and fast iteration of new code.
The performance penalties of immediate mode primarily mount up as the polygon count increases, but yet we have seen from the examples of Quake and Quake II that there is a point at which it's still plenty fast enough.
Immediate mode, being older, might seem as though it's more compatible but that's not actually the case. It's not available on mobile devices at all for example; these primarily use OpenGL ES which has no immediate mode.
Immediate mode has been removed from OpenGL core profiles, so if you're using a GL core profile you won't have it available either.
Using vertex buffer objects requires a certain amount of up-front investment; you need to plan out your buffer usage and update strategy, and a poorly thought-out buffer object implementation can actually run slower than immediate mode (primarily by introducing multiple CPU/GPU sync points). On the other hand, get it right and if your workload is heavy enough you'll go 10s or 100s of times faster.
glBegin
andglEnd
) that's deprecated since OpenGL 3.0. Btw, if you think "Retained Mode" isglNewList
et.al. that's deprecated too. So, use Vertext Buffer Objects. You need to redraw each frame because that is how GDI+ works. Some people would say that that is still "Inmediate Mode" if you send them each frame... well, call it whatever you want, that's what you gotta do. \$\endgroup\$glBegin
andglEnd
not at all. If you want to use up to date techniques, try OpenGL in C# – an object oriented introduction to OpenTK \$\endgroup\$