Most rendering APIs (including XNA and DirectX) have what are called "render states". While there are RenderState classes, the term "render state" is a general term which is a variable that can be set before rendering to impact the rendering of objects. When rendering objects, there are many (dozens upon dozens) of states that can be set to control how objects appear. For example, The XNA GraphicsDevice.RenderState.DestinationBlend partly controls how a drawn pixel will blend with the underlying pixel.
FlatRedBall internally sets a variety of render states to achieve certain effects according to user variables. For example, a Sprite's BlendOperation property can potentially change the RenderState's GraphicsDevice.RenderState.SourceBlend and DestinationBlend when being rendered. Therefore, any render state that you rely on in your IDrawableBatch's Draw method must be set in the Draw method. If it is set only in the IDrawableBatch's constructor or elsewhere in the code, your render state may be overwritten by FlatRedBall's rendering code.
Unfortunately, FlatRedBall cannot predict the type of render states you will need in your IDrawableBatch code. Therefore, it's impossible for the engine to adjust its render states to fit your needs. However, FlatRedBall does require certain render states to be set in its rendering code. For performance reasons, FlatRedBall generally sets render states only when switching between categories of objects being rendered (such as Sprites and Texts) or when an object calls for it (such as when one Sprite has a different BlendOperation than the previously-drawn Sprite. Since IDrawableBatches are drawn in the same section of code as ordered Sprites and Texts, render states must be preserved. This means that if you change a render state at the beginning of your IDrawableBatch's Draw method, be sure to set it back to the previous value or else you may encounter unexpected rendering behavior.
Although the feature set for FlatRedBall is rapidly expanding, it is impossible for the engine to handle every graphical possibility. DrawableBatches are a solution to this problem as they allow custom rendering in the engine. A DrawableBatch is a class that implements the IDrawableBatch interface, which allows user-specified rendering through XNA/MonoGame. For a full API reference of MonoGame, see the MonoGame Class Reference.
The following code shows how to create a class that implements IDrawableBatch . This class draws a triangle which uses vertex colors - each point on the triangle is a different color.
The following code shows how the DrawableBatchExample can be used in a screen:
The code above produces the following when the game runs:
MonoGame's SpriteBatch can be used to draw sprites in FlatRedBall coordinates. For example, the following code considers the Camera's position, resolution, zoom, and the object's position:
The IDrawableBatch interface provides considerable freedom in custom drawing. However, the IDrawableBatch's Draw method is a method which is executed during FlatRedBall's Draw call. This means that it is possible to change the state of the graphics device in such a way that will cause FlatRedBall to render incorrectly or even crash. The following lists actions which should not be performed.
The GraphicsDevice's Viewport should not be changed. IDrawableBatches can be added to Layers - including Camera-specific Layers which inherit the containing Camera's viewport. In other words, to render to a portion of the Screen, add the IDrawableBatch to the desired Camera using the SpriteManager's AddToLayer method.
FlatRedBall handles render targets under the hood. Changing the RenderTarget can result in unexpected behavior or crashing. For control over render targets, use the Camera's RenderOrder property. If you are interested in performing something not currently supported by one of the render modes, please post on the forums.
SpriteManager.AddToLayer - This method can be used to put DrawableBatches on layers for additional sorting control.
Boolean get-only Property that specifies whether or not the Update() method will be called on this drawable batch. If you don't need to do any updating logic, just return false. For example:
This is where any updating logic goes. This could include updating positions, moving particles, or anything else that your drawable batch might need to do outside of drawing. This method is actually called inside the FlatRedBallServices' Draw method, so you should not be doing any RenderTarget setting here.
Executes your drawing code. The camera parameter represents the currently drawing camera, and may be used to retrieve camera settings (the SetDeviceViewAndProjection will work with both the BasicEffect and Effect classes, and will set the variables View, Projection, ViewProj, and any variables that have the semantics VIEW or PROJECTION). Any XNA drawing code may be used in this section. However, please note that RenderState is not preserved, so you will need to set any RenderState variables at the beginning of this method. This includes anything on the graphics device, such as a vertex declaration. For more information, read the Render State article.
Here is where you destroy any assets that won't be automatically destroyed when they go out of scope (for example, some types of buffers), and do any other cleanup you might need to perform (removing the batch from some lists, for example).
Did this article leave any questions unanswered? Post any question in our forums for a rapid response.
The Z value controls the ordering of the batch relative to other batches, z-ordered sprites and text objects. Since the rendering performed in IDrawableBatches may be preceded and followed by other FlatRedBall rendeing calls, render states are not preserved between DrawableBatch Draw calls.