ImFusion SDK 4.3
ObjectPicking Class Reference

#include <ImFusion/Core/GL/ObjectPicking.h>

Helper class to consolidate functionality for implementing object picking of rendered geometry. More...

Detailed Description

Helper class to consolidate functionality for implementing object picking of rendered geometry.

The term "object picking" refers to the process of attaching an additional helper texture to the used FBO in which you can encode per-pixel object ownership information. Then, in the fragment shader in addition to the regular color output you write to this texture to encode the currently rendered object/element. The OpenGL rendering pipeline will use the same per-fragment processing for all attachments so that the picking texture is correctly filled wrt. the scissor, stencil, and depth tests. Finally, after the rendering you can use the picking texture to lookup the object identity for each pixel, for instance to determine on which object a user has clicked.

GL::ObjectPicking implements this using a 2-channel texture to store picking information in terms of Object ID (to distinguish multiple objects rendered into the same scene) and Element ID (to distinguish individual parts of a single rendered object):

  • The Object ID is managed by the ObjectPicking instance: all known objects must first be registered either during reset() or using registerObject(). This will generate a unique ID for each object so that it can be assigned automatically inside the picking shader include.
  • In contrast, the Element ID is managed by the user and has to be passed to the shader manually. Depending on the use case you can decide if you use a constant ID for the entire object or if you need to distinguish different parts within one object (e.g. faces of a mesh).

Multiple actors collaborate in order to implement the functionality:

  1. An entity that hosts and manages the GL::ObjectPicking instance. At the beginning of the render loop this entity must reset/initialize the data structure by calling reset().
  2. Every entity that wants to store picking information needs to include the ObjectPicking shader include and then call picking_writeIndex(uint elementId):
    #pragma include "ImFusionGL/ObjectPicking.glh"
    uint elementId = [...];
    picking_writeIndex(elementId);
    On the client side, you must setup your shader so that it has access to the object picking data structures. Therefore, call enable() after enabling your shader and before rendering any geometry.
  3. If an entity has finished rendering picking information and a subsequent render call does not write picking information, you must call disable(). Otherwise, your GPU might write random data into the picking buffer later.
  4. After all geometry has been rendered you can access the ObjectPicking instance and query the picking info for the pixels of your choice.

In the ImFusion view framework, step 1 will be implemented for instance by a GlVolumeView. Step 2 is implemented by selected GlObjects. Since the GlView is passed to void GlObject::draw() it can access the view's ObjectPicking instance in order to support writing picking info.

Note
GL::ObjectPicking will always use framebuffer attachment/output location 1 for writing picking information. Unfortunately, there is no viable way to provide a customization point for this. Thus, users of this class and its shader include must not use that attachment point themselves.
Warning
Due to the nature of its implementation GL::ObjectPicking does not work with deferred rendering/compositing techniques and can therefore for instance not be combined with GL::OrderIndependentTransparency.

Classes

struct  PickingInfo
 Structure encoding picking information for a single pixel. More...
 

Public Member Functions

void reset (GL::Framebuffer &fbo, vec2i viewportSize, std::vector< const void * > knownObjects)
 Initializes and resets object picking data structures.
 
void registerObject (const void *object)
 Register an object instance so that it receives its own unique ID and is known to the picking backend.
 
void enable (GL::Program &program, const void *object) const
 Bind all object picking structures to the given shader so that you can use the shader include.
 
void enable (GL::Program &program, uint32_t objectId) const
 Bind all object picking structures to the given shader so that you can use the shader include.
 
void disable () const
 Disable object picking by detaching the picking texture from the FBO passed during reset() and issuing a glDrawBuffers() call.
 
uint32_t objectId (const void *object) const
 Return the object ID for the given void. Unknown objects have an ID of 0xFFFFFFFF.
 
const void * objectWithId (uint32_t id) const
 Return void for the given ID. Returns nullptr for unknown id.
 
std::vector< PickingInfogetPickingInfo (const std::vector< vec2i > &pixels, const void *object=nullptr) const
 Return the picking information for the given pixels with optional filtering.
 
const TexturepickingTexture () const
 Getter for m_pickingTexture.
 

Member Function Documentation

◆ reset()

void reset ( GL::Framebuffer & fbo,
vec2i viewportSize,
std::vector< const void * > knownObjects )

Initializes and resets object picking data structures.

This function must be called every time at the beginning of the render loop.

Parameters
fboFramebuffer object to attach the picking texture to. ObjectPicking will keep a reference to it and use it during enable()/disable().
viewportSizeViewport size in pixels
knownObjectsSet of all objects that are known to render, used to assign unique object ids. If you don't know all object yet you can later call registerObject().

◆ enable() [1/2]

void enable ( GL::Program & program,
const void * object ) const

Bind all object picking structures to the given shader so that you can use the shader include.

Note
This function attaches the picking texture to the FBO passed during reset() and issues a glDrawBuffers() call.
Parameters
programShader to prepare for writing object picking info.
objectPointer to the object that the shader belongs to, will use objectId() to generate the ID for it.

◆ enable() [2/2]

void enable ( GL::Program & program,
uint32_t objectId ) const

Bind all object picking structures to the given shader so that you can use the shader include.

This overload lets the user choose an arbitrary ID to be written. For objects that were registered during reset() or with registerObject() it can be used in connection with objectId() to get a valid ID. Otherwise the user has to track the used IDs and map the return value of getPickingInfo() themselves.

Warning
No measures are taken to assert uniqueness of the given objectId.
Note
This function attaches the picking texture to the FBO passed during reset() and issues a glDrawBuffers() call.
Parameters
programShader to prepare for writing object picking info.
objectIdA numeric ID used for rendering this object

◆ getPickingInfo()

std::vector< PickingInfo > getPickingInfo ( const std::vector< vec2i > & pixels,
const void * object = nullptr ) const

Return the picking information for the given pixels with optional filtering.

Parameters
pixelsSet of pixels to query picking information for.
objectOptional object to filter picking information for; no filtering will be performed if this is null.

◆ pickingTexture()

const Texture * pickingTexture ( ) const

Getter for m_pickingTexture.

Warning
Use with care as the internal format of the texture may be changed at any time.

The documentation for this class was generated from the following file:
Search Tab / S to search, Esc to close