Custom GPU Capabilities         Custom GPU capabilities is a feature for testing how Ogre behaves on GPU's with fewer features than the developer's GPU

Introduction

Custom GPU capabilities is a feature for testing how Ogre behaves on GPU's with fewer features than the developer's GPU. Alternatives to using custom capabilities are running the same app on a different GPU (you might need several computers) and editing the material definitions to use only the older GPU features. Custom capabilities is faster than both of these alternative.

The feature works by loading .rendercaps files and initializing OGRE RenderSystem using that information. .rendercaps contains one or more RenderSystemCapabilities definitions, which describe what capabilities and shaders are supported given GPU (say GeForce 3) on either DirectX or OpenGL system. For example, to see what your application might look like on a card that doesn't support programmable fragment shaders, you might tell Ogre to initialize your DirectX RenderSystem with the capabilities of "NVIDIA GeForce"

Usage

Using custom capabilities is very simple. All you need is to pass the optional customCapabilitiesConfig argument to the Root::initialise method. customCapabilitiesConfig is a config file that looks like this:

Custom Capabilities=NVidia GeForce 2

[Capabilities Database]
FileSystem=../../../Media/CustomCapabilities/


The "Custom Capabilities" setting tells Ogre::Root which GPU profile to use to initialize the RenderSystem. "Capabilities Database" section describes the location of .rendercaps files (it can be any Ogre archive type). If the name of "Custom Capabilities" GPU is not found in the database, Ogre will not start.


Warning



Custom capabilities does not check if your GPU really supports the capabilities you're saying it supports. If you have a .rendercaps entry that over represents your real GPU capabilities Ogre behavior will be unpredictable (most likely your application will crash)

Internals

This feature adds 2 new classes to Ogre. It also modifies heavily the RenderSystemCapabilities, GLRenderSystem and D3D9RenderSystem classes. The two new classes are RenderSystemCapabilitiesManager (RSCManager for the rest of this article) and RenderSystemCapabilitiesSerializer (RSCSerializer)

The RSCManager and RSCSerializer work together to read a .rendercaps files and build RenderSystemCapabilities objects. RSCSerializer is also capable of dumping RSC objects to .rendercaps files.

RSCManager and RSCSerializer are tightly coupled. The developer asks RSCManager to read an archive (zip, filesystem, etc.) containing some .rendercaps files. RSCManager opens each file as a DataStream and passes it on to RSCSerializer. The serializer reads the stream and for every render_system_capabilities entry (there may be more than one in a single .rendercaps) it builds a RSC object. It then notifies RSCManager that such object was read and ignores it from there on. RSCManager is in charge of deleting every RSC object that the serializer reads.

The developers talks to RSCManager, asking it to read some files and then asking it from a single named RSC object from all the files that have been read.

Here is an example of using custom render system capabilities without Ogre::Root.

// we need to be able to create FileSystem archives to load .rendercaps from the filesystem
fileSystemArchiveFactory = new FileSystemArchiveFactory();

// set up archive manager for reading the filesystem
archiveManager = new ArchiveManager();
ArchiveManager::getSingleton().addArchiveFactory( fileSystemArchiveFactory );
 
rscManager = new RenderSystemCapabilitiesManager();


If you have Ogre::Root object, the RSCManager is already initialized and you can get it like any other manager:

RenderSystemCapabilitiesManager* rscManager = RenderSystemCapabilitiesManager::getSingletonPtr();


After initializing RSCManager, you need to load an archive with .rendercaps files and query for the specific RSC you need.

// load an archive (this will invoke RSCSerializer for every file in the archive)
rscManager->parseCapabilitiesFromArchive("Media/CapabilitiesDatabase", "FileSystem", true);

// request a parsed capability
RenderSystemCapabilities* rsc = rscManager->loadParsedCapabilities("NVidia GeForce 2");


Finally, tell the RenderSystem that you want to use custom capabilities. Note: you MUST do this before creating your first window. You can do this either by going through the Root object

mRoot->useCustomRenderSystemCapabilities(rsc);

or by asking the render system directly

mMyRenderSystem->useCustomRenderSystemCapabilities(rsc);