Click or drag to resize
DigitalRuneGraphics Screens

This topic contains the following sections:

What are graphics screens?

A graphics screen is a layer in a 3D application. Multiple layers can be stacked on one another, for example:

  • The first (back) screen renders the 3D world.
  • In front of this screen is second screen that renders the HUD.
  • In front of these screens is a third screen that renders a 2D GUI, such as an "Options Dialog".

Different types of applications may consist of a different number and different types of layers. Simple applications may only have a single layer that handles all graphics.

The graphics screen is a concept used to separate rendering code into different classes. The abstract base class GraphicsScreen provides the base functionality, but does not implement rendering. The rendering code needs to be added in derived classes. Each derived graphics screen implements its own rendering pipeline. That means, a screen that renders the 3D world can use a different rendering pipeline than a screen that draws the HUD, or the GUI, or debug output. Each graphics screen can use its own type of scene management.

Graphics screens needs to be added to the graphics service (see collection IGraphicsServiceScreens).

C#
// Example:
GraphicsService.Screens.Add(worldGraphicsScreen); // 3D world
GraphicsService.Screens.Add(hudGraphicsScreen);   // HUD
GraphicsService.Screens.Add(guiGraphicsScreen);   // GUI (main menu, options dialog, ...)

The graphics service updates and renders all registered screens back to front. The output of one graphics screens can optionally be passed as input to the next graphics screen.

New graphics screens can be implemented by deriving a new type from GraphicsScreen. Alternatively, a new graphics screen can be created by using a DelegateGraphicsScreen and providing Update and Render callbacks.

DigitalRune Graphics does not provide a predefined rendering pipeline. The rendering pipeline is up to the application. The sample applications demonstrate how to implement different rendering pipelines. For example, the DeferredLightingSample demonstrates how to write a light pre-pass renderer ("deferred lighting").

GraphicsScreen

The GraphicsScreen is the base class of all graphics screens. It mainly consists of an Update and a Render method.

A new graphics screen is created by deriving a new class and implementing OnUpdate and OnRender.

C#
public class MyGraphicsScreen : GraphicsScreen
{
  public MyGraphicsScreen(IGraphicsService graphicsService)
    : base(graphicsService)
  {
    Name = "MyScreen"; // Useful for debugging.

    // TODO: Create any renderers or resources here.
  }

  protected override void OnUpdate(TimeSpan deltaTime)
  {
    // TODO: Implement update logic here.
  }

  protected override void OnRender(RenderContext context)
  {
    var graphicsService = context.GraphicsService;
    var graphicsDevice = graphicsService.GraphicsDevice;

    // TODO: Implement rendering pipeline here.
  }
}

The property Coverage can be set by the derived graphics screen. It determines whether screens in the background are fully covered or not. For example, the 3D world usually covers the entire screen whereas a HUD only covers parts of the screens. The graphics service reads the property to decide whether graphics screens in the background need to be rendered. If screens are completely hidden, they won't be updated or rendered.

Tip Tip

Always set Coverage to Full if the graphics screens covers the entire screen. This improves performance if multiple graphics screens are registered in the graphics service.

The property IsVisible can be used enable/disable a graphics screens.

The properties RenderPreviousScreensToTexture and SourceTextureFormat can be set to render the output of the previous graphics screens into a temporary render target. The output can be read as an input texture by the current graphics screen (see property RenderContextSourceTexture).

DelegateGraphicsScreen

The DelegateGraphicsScreen offers a quick and easy way to add a new graphics screen without implementing a new class. All that is required is an UpdateCallback and a RenderCallback.

C#
// Add a new graphics screen using callbacks.
var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService)
{
  UpdateCallback = delegate(GraphicsScreen screen, TimeSpan deltaTime)
  {
    // TODO: Implement update logic here.
  },
  RenderCallback = delegate(RenderContext context) 
  { 
    var graphicsService = context.GraphicsService;
    var graphicsDevice = graphicsService.GraphicsDevice;

    // TODO: Implement rendering pipeline here.
  }
};

// Register graphics screen in graphics service.
GraphicsService.Screens.Add(delegateGraphicsScreen);