mono/MonoGame — pull request #2371 by thefiddler (2014-04-17 15:11:40+00:00)
Title: RFC: Implement ARB and EXT flavors of FBOs

MonoGame is currently relying on GL_ARB_framebuffer_object without explicitly checking for support. This means it will fail to run on systems that do not support OpenGL 3.x+.

This patch implements a fallback to GL_EXT_framebuffer_object when GL_ARB_framebuffer_object is not supported. (Note that we cannot use GL_EXT_framebuffer_object alone, since many systems support the ARB flavor but not the EXT one.)

Changes:
- Added `GraphicsCapabilities.SupportsFramebufferObjectARB` and `GraphicsCapabilities.SupportsFramebufferObjectEXT`
- Added `FramebufferObject`, `FramebufferObjectEXT`, `RenderbufferObject` and `RenderBufferObjectEXT` classes, under GraphicsDevice.OpenGL.[Framebuffer|Renderbuffer]Object.cs
- Replaced direct calls to GL.Framebuffer* and GL.Renderbuffer* with calls to `GraphicsDevice.Framebuffer.*` and `GraphicsDevice.Renderbuffer.*`

Advantages:
- MonoGame should now run on OpenGL 2.1 cards that do not support GL_ARB_framebuffer_object
- Fewer annoying `#if GLES` regions in `GraphicsDevice.OpenGL` and `RenderTarget2D.OpenGL`
- More consistent error checking without littering `GraphicsDevice` with `CheckGLErrors()`.

Disadvantages:
- The new classes use virtual methods to select the correct implementation during platform setup. This is necessary on desktop platforms. The compiler should be able to remove this on mobile platforms, but it can be explicitly removed if necessary.

There are two alternatives to virtual methods: if-else clauses or delegates. If-else clauses may incur a branch misprediction and delegates consume more memory than virtual methods.