fsleyes.gl.glvolume

This module provides the GLVolume class, which creates and encapsulates the data and logic required to render 2D slice of an Image instance.

class fsleyes.gl.glvolume.GLVolume(image, overlayList, displayCtx, canvas, threedee)[source]

Bases: fsleyes.gl.glimageobject.GLImageObject

The GLVolume class is a GLImageObject which encapsulates the data and logic required to render Image overlays in 2D and 3D.

A GLVolume instance may be used to render an Image instance which has a Display.overlayType equal to volume. It is assumed that this Image instance is associated with a Display instance which, in turn, contains a VolumeOpts instance, containing display options specific to volume rendering.

Version dependent modules

The GLVolume class makes use of the functions defined in the gl14.glvolume_funcs or the gl21.glvolume_funcs modules, which provide OpenGL version specific details for creation/storage of vertex data, and for rendering.

These version dependent modules must provide the following functions:

init(GLVolume)

Perform any necessary initialisation.

destroy(GLVolume)

Perform any necessary clean up.

compileShaders(GLVolume)

(Re-)Compile the shader programs.

updateShaderState(GLVolume)

Updates the shader program states when display parameters are changed.

preDraw(GLVolume, xform, bbox)

Initialise the GL state, ready for drawing.

draw2D(GLVolume, zpos, xform)

Draw a slice of the image at the given zpos. If xform is not None, it must be applied as a transformation on the vertex coordinates.

draw3D(GLVolume, xform, bbox)

Draw the image in 3D. If xform is not None, it must be applied as a transformation on the vertex coordinates.

drawAll(Glvolume, zposes, xforms)

Draws slices at each of the specified zposes, applying the corresponding xforms to each.

postDraw(GLVolume, xform, bbox)

Clear the GL state after drawing.

2D rendering

Images are rendered in essentially the same way, regardless of which OpenGL version-specific module is used. The image data itself is stored as an ImageTexture. This ImageTexture is managed by the resources module, so may be shared by many GLVolume instances. The current colour maps (defined by the VolumeOpts.cmap and VolumeOpts.negativeCmap properties) are stored as ColourMapTexture instances. A slice through the texture is rendered using six vertices, located at the respective corners of the image bounds.

Image voxels may be clipped according to the VolumeOpts.clippingRange property. By default, the voxel value is compared against the clipping range, but the VolumeOpts.clipImage property allows the data from a different image (of the same dimensions) to be used for clipping. If specified, this clipping image is stored as another ImageTexture.

If the ColourMapOpts.modulateAlpha setting is active, the opacity of rendered voxels is modulated by the voxel intensity. If VolumeOpts.modulateImage is also set, the opacity is modulated by the values in a different image - in this case, this image is stored in another ImageTexture.

An AuxImageTextureManager is used to manage the clip and modulate textures.

3D rendering

In 3D, images are rendered using a ray-casting approach. The image bounding box is drawn as a cuboid. Then for each pixel, a ray is cast from the ‘camera’ through the image texture. The resulting colour is generated from sampling points along the ray.

The glvolume_funcs modules are expected to perform this rendering off-screen, using two RenderTexture instances, available as attributes renderTexture1 and``renderTexture2``. After a call to draw3D, the final result is assuemd to be contained in renderTexture1.

Textures

The GLVolume class uses the following textures:

  • An ImageTexture, a 3D texture which contains image data. This is bound to texture unit 0.

  • A ColourMapTexture, a 1D texture which contains the colour map defined by the VolumeOpts.cmap property. This is bound to texture unit 1.

  • A ColourMapTexture, a 1D texture which contains the colour map defined by the VolumeOpts.negativeCmap property. This is bound to texture unit 2.

  • An ImageTexture which contains the clippimg image data. This is bound to texture unit 3. If the VolumeOpts.clipImage property is not specified (i.e. it has a value of None), this texture will not be bound - in this case, the image texture is used for clipping.

  • Two RenderTexture instances which are used for 3D rendering. Both of these textures have depth buffers. When one of these textures is being drawn it is bound to texture units 4 (for RGBA) and 5 (for depth).

Attributes

The following attributes are available on a GLVolume instance:

imageTexture

The ImageTexture which stores the image data.

clipTexture

The ImageTexture which stores the clip image data.

modulateTexture

The ImageTexture which stores the modulate image data.

colourTexture

The ColourMapTexture used to store the colour map.

negColourTexture

The ColourMapTexture used to store the negative colour map.

renderTexture1

The first RenderTexture used for 3D rendering.

renderTexture2

The first RenderTexture used for 3D rendering.

texName

A name used for the imageTexture, colourTexture, and negColourTexture`. The name for the latter is suffixed with ``'_neg'.

__init__(image, overlayList, displayCtx, canvas, threedee)[source]

Create a GLVolume object.

Parameters
  • image – An Image object.

  • overlayList – The OverlayList

  • displayCtx – The DisplayContext object managing the scene.

  • canvas – The canvas doing the drawing.

  • threedee – Set up for 2D or 3D rendering.

destroy()[source]

This must be called when this GLVolume object is no longer needed. It performs any needed clean up of OpenGL data (e.g. deleting texture handles), calls removeDisplayListeners(), and calls GLImageObject.destroy().

ready()[source]

Returns True if this GLVolume is ready to be drawn, False otherwise.

texturesReady()[source]

Returns True if the imageTexture and clipTexture (if applicable) are both ready to be used, False otherwise.

property clipTexture

Returns the ImageTexture associated with the VolumeOpts.clipImage.

property modulateTexture

Returns the ImageTexture associated with the VolumeOpts.modulateImage.

addDisplayListeners()[source]

Called by __init__().

Adds a bunch of listeners to the Display object, and the associated VolumeOpts instance, which define how the image should be displayed.

This is done so we can update the colour, vertex, and image data when display properties are changed.

removeDisplayListeners()[source]

Called by destroy(). Removes all the property listeners that were added by addDisplayListeners().

testUnsynced()[source]

Used by the refreshImageTexture() method.

Returns True if certain critical VolumeOpts properties have been unsynced from the parent instance, meaning that this GLVolume instance needs to create its own image texture; returns False otherwise.

updateShaderState(*args, **kwargs)[source]

Calls gl14.glvolume_funcs.updateShaderState() or gl21.glvolume_funcs.updateShaderStatea(), then Notifier.notify(). Uses the idle.idleWhen() function to make sure that it is not called until ready() returns True.

Parameters

alwaysNotify – Must be passed as a keyword argument. If False (the default), notify is only called if glvolume_funcs.updateShaderState returns True. Otherwise, notify is always called.

refreshImageTexture(**kwargs)[source]

Refreshes the ImageTexture used to store the Image data. This is performed through the resources module, so the image texture can be shared between multiple GLVolume instances.

All keyword arguments are passed through to the ImageTexture constructor.

registerAuxImage(which, image, onReady=None)[source]

Calls AuxImageTextureManager.registerAuxImage(), making sure that the texture interpolation is set appropriately.

refreshColourTextures()[source]

Refreshes the ColourMapTexture instances used to colour image voxels.

preDraw(*args, **kwargs)[source]

Binds the ImageTexture to GL_TEXTURE0 and the ColourMapTexture to GL_TEXTURE1, and calls the version-dependent ``preDraw function.

draw2D(*args, **kwargs)[source]

Calls the version dependent draw2D function.

draw3D(*args, **kwargs)[source]

Calls the version dependent draw3D function.

drawAll(*args, **kwargs)[source]

Calls the version dependent drawAll function.

postDraw(*args, **kwargs)[source]

Unbinds the ImageTexture and ColourMapTexture, and calls the version-dependent postDraw function.

getAuxTextureXform(which)[source]

Calculates a transformation matrix which will transform from the image coordinate system into the VolumeOpts.clipImage or VolumeOpts.modulateImage coordinate system. If the property is None, it will be an identity transform.

This transform is used by shader programs to find the auxillary image coordinates that correspond with specific image coordinates.

getModulateValueXform()[source]

Returns an affine transform to normalise alpha modulation values.

The GL volume shaders need to normalise the modulate value by the modulation range to generate an opacity value. We calculate a suitable scale and offset by buildin an affine transform which transforms voxel values from the image/modulate image texture range to 0/1, where 0 corresponds to the low modulate range bound, and 1 to the high modulate range bound. The resulting scale/offset can be used by the shader to convert a modulate value directly into an opacity value.

generateVertices2D(zpos, axes, bbox=None)[source]

Overrides GLImageObject.generateVertices2D().

Appliies the ImageTextureBase.texCoordXform() to the texture coordinates - this is performed to support 2D images/textures.

generateVertices3D(bbox=None)[source]

Overrides GLImageObject.generateVertices3D().

Appliies the ImageTextureBase.texCoordXform() to the texture coordinates - this is performed to support 2D images/textures.

_alphaChanged(*a)[source]

Called when the Display.alpha property changes.

_displayRangeChanged(*a)[source]

Called when the VolumeOpts.displayRange property changes.

_lowClippingRangeChanged(*a)[source]

Called when the low VolumeOpts.clippingRange property changes. Separate listeners are used for the low and high clipping values to avoid unnecessary duplicate refreshes in the event that the VolumeOpts.linkLowRanges or VolumeOpts.linkHighRanges flags are set.

_highClippingRangeChanged(*a)[source]

Called when the high VolumeOpts.clippingRange property changes (see _lowClippingRangeChanged()).

_modulateRangeChanged(*a)[source]

Called when the VolumeOpts.modulateRange property changes.

_clipImageChanged(*a)[source]

Called when the VolumeOpts.clipImage property changes.

_modulateImageChanged(*a)[source]

Called when the VolumeOpts.modulateImage property changes.

_invertClippingChanged(*a)[source]

Called when the VolumeOpts.invertClipping property changes.

_cmapChanged(*a)[source]

Called when the VolumeOpts.cmap or VolumeOpts.negativeCmap properties change.

_useNegativeCmapChanged(*a)[source]

Called when the VolumeOpts.useNegativeCmap property changes.

_invertChanged(*a)[source]

Called when the VolumeOpts.invert property changes.

_modulateAlphaChanged(*a)[source]

Called when the VolumeOpts.modulateAlpha property changes. Calls updateShaderState().

_enableOverrideDataRangeChanged(*a)[source]

Called when the VolumeOpts.enableOverrideDataRange property changes. Calls _volumeChanged().

_overrideDataRangeChanged(*a)[source]

Called when the VolumeOpts.overrideDataRange property changes. Calls _volumeChanged(), but only if VolumeOpts.enableOverrideDataRange is True.

_volumeChanged(*a, **kwa)[source]

Called when the NiftiOpts.volume property changes Also called when other properties, which require a texture refresh, change.

_channelChanged(*a, **kwa)[source]

Called when the NiftiOpts.channel changes. Refreshes the texture.

_interpolationChanged(*a)[source]

Called when the NiftiOpts.interpolation property changes.

_transformChanged(*a)[source]

Called when the NiftiOpts.transform property changes.

_displayXformChanged(*a)[source]

Called when the NiftiOpts.displayXform property changes.

_numStepsChanged(*a)[source]

Called when the Volume3DOpts.numSteps property changes.

_numInnerStepsChanged(*a)[source]

Called when the Volume3DOpts.numInnerSteps property changes.

_resolutionChanged(*a)[source]

Called when the Volume3DOpts.resolution property changes.

_numClipPlanesChanged(*a)[source]

Called when the Volume3DOpts.numClipPlanes property changes.

_clipModeChanged(*a)[source]

Called when the Volume3DOpts.clipMode property changes.

_clipping3DChanged(*a)[source]

Called when any of the Volume3DOpts.clipPosition, Volume3DOpts.clipAzimuth, or Volume3DOpts.clipInclination properties change.

_showClipPlanesChanged(*a)[source]

Called when the Volume3DOpts.showClipPlanes property changes.

_blendFactorChanged(*a)[source]

Called when the Volume3DOpts.showClipPlanes property changes.

_smoothingChanged(*a)[source]

Called when the Volume3DOpts.smoothing property changes.

_imageSyncChanged(*a)[source]

Called when the synchronisation state of the NiftiOpts.volume or VolumeOpts.interpolation properties change.

__texturesChanged(*a)

Called when either the imageTexture or the clipTexture changes. Calls updateShaderState().

__annotations__ = {}
__module__ = 'fsleyes.gl.glvolume'