Selection Buffer        

From the Famfamfam Silk icon collection, a white page with black text. Description

The following classes are a C++ implementation of a pixel perfect object selection mechanism.

It works by rendering a single frame to a texture with custom substituted materials that colorize each entity with a unique color (up to 224 colors/objects). The MaterialSwitcher class saves which color belongs to which entity. The SelectionBuffer class then retrieves the correct Entity from the SceneManager. It does not work on StaticGeometry or any other geometry that isn't independent entities, in Ogre terms.

These classes are a C++ port of the Python version found here. The behavior of the C++ version differs from the original Python version in one notable way: render colors are assigned sequentially, rather than randomly. This makes interpreting the debug overlay more visually difficult, but simplifies the code somewhat.


From the Famfamfam Silk icon collection, a green arrow pointing down. Download

Downloadable 7-Zip archive of all eight source files:
From the Famfamfam Silk icon collection, a white page with the yellow compressed icon reminiscent of the Winzip icon. SelectionBufferSource.7z

From the Famfamfam Silk icon collection, a white page with blue 'C++' text. Usage

The following fragments won't work as-is. You'll need to put them in appropriate places to integrate them with your code.

First the necessary include:

#include "SelectionBuffer.h"

Then initialization:

// Hang on to this pointer somewhere (e.g. a member of a user interface manager class)
SelectionBuffer *mSelectionBuffer;

// SceneManager *sceneManager; (previously created)
// RenderWindow *renderWindow; (which can come from calling Ogre::Root::initialise(), among other places)
mSelectionBuffer = new SelectionBuffer(sceneManager, renderWindow);

You'll also need to make sure the material scripts are loaded using the Ogre resource system. (noteSample code not shown.)

Then process every frame:

// showSelectionDebugOverlay is a boolean whose value is determined by, for instance, a key press

Entity *selectedEntity;

// rightMouseClicked is a boolean whose value came from, for instance, 
// an OIS::MouseListener mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id) method
    // mouseAbsX and mouseAbsY are the absolute coordinates of the click from, for instance, an OIS::MouseState
    selectedEntity = mSelectionBuffer->OnSelectionClick(mouseAbsX, mouseAbsY);
    if(selectedEntity != 0)
      LogManager::getSingleton().logMessage("Selected " + selectedEntity->getName());
      // Do something useful to the selected entity here
      LogManager::getSingleton().logMessage("Entity not found");

[+] From the Famfamfam Silk icon collection, a white page with blue 'C++' text. Source

The Ogre eye 16x16 icon. Compatibility

This code is known to work in Ogre 1.6 and Ogre 1.7.