mono/MonoGame — pull request #761 by tomspilman (2012-09-11 07:16:05+00:00)
Title: Deferred GL RenderState and Shader API (NEEDS TESTING!)

## DO NOT MERGE... TESTING!
## DO NOT MERGE... TESTING!
## DO NOT MERGE... TESTING!

First off I apologize for this pull request getting this big... I may try to cherry pick out some things and submit them separately. For now I just needed to get this out to the public for review.

This merge contains two main features...

## Deferred GL RenderState

The GL code was setup to immediately setup render state. Which meant that if you did this...

```
device.BlendState = BlendState.Opaque;
device.BlendState = BlendState.Additive;
device.BlendState = BlendState.Opaque;
```

... or something similar you would get unnecessary render state changes. Of course you would not do this sort of thing on purpose, but things like this happen all the time in complex rendering code.

What this code change does is defer all application of GL state until one of the GraphicsDevice.Draw() methods are called. At draw time we know exactly the final state to be set.... which results in a perfect application of render state with no possibility of redundant changes.

You will see a performance improvement in just about any game.

## Shader API

XNA exposes an Effect system to the user... you can seemingly only assign one Effect at a time... but under the hood XNA uses shaders.

This is a feature that is exploited by the [XNA Bloom Postprocess sample](http://xbox.create.msdn.com/en-US/education/catalog/sample/bloom). The sample renders a full screen quad using SpriteBatch and custom Effect without a vertex shader. Often this functionality is erroniously attributed to a magical "default shader"... there is no such thing.

What is really happening under the hood is much simpler. SpriteBatch first assigns its own SpriteEffect which has a vertex and pixel shader. After it does that it applies the custom Effect you provided it. If your custom Effect happens to only have a pixel shader then you end up with a mix... the vertex shader from SpriteEffect and your pixel shader.

This is pull request adds a Shader API to MonoGame... for now all marked as internal. The Effect system then sets the vertex and pixel Shader individually on the GraphicsDevice along with ConstantBuffers. Then at Draw() time the right GL shader program is looked up from a cache and applied.

This also means 2MGFX allows you to create effects with only pixel or vertex shaders now.

## TEST ME!

This code so far has been tested with our game and a few sample apps on iOS and Windows 8.

We need others to test their games on it.

We need people to test it on all the other platforms... Linux, MacOS, Android, etc.