Skip to content
Snippets Groups Projects
Commit f38315e2 authored by Paul McCarthy's avatar Paul McCarthy
Browse files

GLVolume clip-by-another-image working. Might need some testing.

parent ff958b0e
No related branches found
No related tags found
No related merge requests found
......@@ -91,7 +91,9 @@ def updateShaderState(self):
# range, but the shader needs them to be in image
# texture value range (0.0 - 1.0). So let's scale
# them.
xform = self.imageTexture.invVoxValXform
if opts.clipImage is None: xform = self.imageTexture.invVoxValXform
else: xform = self.clipTexture .invVoxValXform
clipLow = opts.clippingRange[0] * xform[0, 0] + xform[3, 0]
clipHigh = opts.clippingRange[1] * xform[0, 0] + xform[3, 0]
texZero = 0.0 * xform[0, 0] + xform[3, 0]
......@@ -117,15 +119,15 @@ def updateShaderState(self):
gl.glUniform1f(svars['texZero'], texZero)
gl.glUniform1f(svars['invertClip'], opts.invertClipping)
gl.glUniform1f(svars['useNegCmap'], opts.useNegativeCmap)
gl.glUniform1f(svars['imageIsClip'], 1)
gl.glUniform1f(svars['imageIsClip'], opts.clipImage is None)
gl.glUniformMatrix4fv(svars['voxValXform'], 1, False, vvx)
# Set up the colour and image textures
gl.glUniform1i(svars['imageTexture'], 0)
gl.glUniform1i(svars['clipTexture'], 0)
gl.glUniform1i(svars['colourTexture'], 1)
gl.glUniform1i(svars['negColourTexture'], 2)
gl.glUniform1i(svars['clipTexture'], 3)
gl.glUseProgram(0)
......
......@@ -88,6 +88,14 @@ class GLVolume(globject.GLImageObject):
image bounds.
Image voxels may be clipped according to the
:attr:`.VolumeOpts.clippingRange` property. By default, the voxel value
is compared against the clipping range, but the
:attr:`.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 :class:`.ImageTexture`.
**Textures**
......@@ -102,7 +110,13 @@ class GLVolume(globject.GLImageObject):
- A :class:`.ColourMapTexture`, a 1D texture which contains the
colour map defined by the :attr:`.VolumeOpts.negativeCmap` property.
This is bound to texture unit 2.
This is bound to texture unit 2.
- An :class:`.ImageTexture` which contains the clippimg image data.
This is bound to texture unit 1. If the :attr:`.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.
**Attributes**
......@@ -110,9 +124,12 @@ class GLVolume(globject.GLImageObject):
The following attributes are available on a ``GLVolume`` instance:
==================== =================================================
==================== ==================================================
``imageTexture`` The :class:`.ImageTexture` which stores the image
data.
``clipTexture`` The :class:`.ImageTexture` which stores the clip
image data. If :attr:`.VolumeOpts.clipImage`
is ``None``, this attribute will also be ``None``.
``colourTexture`` The :class:`.ColourMapTexture` used to store the
colour map.
``negColourTexture`` The :class:`.ColourMapTexture` used to store the
......@@ -120,7 +137,7 @@ class GLVolume(globject.GLImageObject):
``texName`` A name used for the ``imageTexture``,
``colourTexture``, and ``negColourTexture`. The
name for the latter is suffixed with ``'_neg'``.
==================== =================================================
==================== ==================================================
"""
......@@ -139,15 +156,17 @@ class GLVolume(globject.GLImageObject):
# updated when its display properties are changed
self.addDisplayListeners()
# Create an image texture and a colour map texture
self.texName = '{}_{}'.format(type(self).__name__, id(self.image))
# Create an image texture, clip texture, and a colour map texture
self.texName = '{}_{}'.format(type(self).__name__, id(self.image))
self.imageTexture = None
self.imageTexture = None
self.clipTexture = None
self.colourTexture = textures.ColourMapTexture(self.texName)
self.negColourTexture = textures.ColourMapTexture(
'{}_neg'.format(self.texName))
self.refreshImageTexture()
self.refreshClipTexture()
self.refreshColourTextures()
fslgl.glvolume_funcs.init(self)
......@@ -161,11 +180,15 @@ class GLVolume(globject.GLImageObject):
"""
glresources.delete(self.imageTexture.getTextureName())
if self.clipTexture is not None:
glresources.delete(self.clipTexture.getTextureName())
self.colourTexture .destroy()
self.negColourTexture.destroy()
self.imageTexture = None
self.clipTexture = None
self.colourTexture = None
self.negColourTexture = None
......@@ -222,9 +245,15 @@ class GLVolume(globject.GLImageObject):
fslgl.glvolume_funcs.updateShaderState(self)
self.onUpdate()
def clipUpdate(*a):
self.refreshClipTexture()
fslgl.glvolume_funcs.updateShaderState(self)
self.onUpdate()
display.addListener('alpha', lName, colourUpdate, weak=False)
opts .addListener('displayRange', lName, colourUpdate, weak=False)
opts .addListener('clippingRange', lName, shaderUpdate, weak=False)
opts .addListener('clipImage', lName, clipUpdate, weak=False)
opts .addListener('invertClipping', lName, shaderUpdate, weak=False)
opts .addListener('cmap', lName, colourUpdate, weak=False)
opts .addListener('negativeCmap', lName, colourUpdate, weak=False)
......@@ -269,6 +298,7 @@ class GLVolume(globject.GLImageObject):
display.removeListener( 'alpha', lName)
opts .removeListener( 'displayRange', lName)
opts .removeListener( 'clippingRange', lName)
opts .removeListener( 'clipImage', lName)
opts .removeListener( 'invertClipping', lName)
opts .removeListener( 'cmap', lName)
opts .removeListener( 'negativeCmap', lName)
......@@ -326,6 +356,32 @@ class GLVolume(globject.GLImageObject):
textures.ImageTexture,
texName,
self.image,
interp=interp)
def refreshClipTexture(self):
"""Refreshes the :class:`.ImageTexture` used to store the
:attr:`.VolumeOpts.clipImage`.
"""
opts = self.displayOpts
clipImage = opts.clipImage
texName = '{}_{}'.format(type(self).__name__, id(clipImage))
if self.clipTexture is not None:
glresources.delete(self.clipTexture.getTextureName())
self.clipTexture = None
if clipImage is None:
return
if opts.interpolation == 'none': interp = gl.GL_NEAREST
else: interp = gl.GL_LINEAR
self.clipTexture = glresources.get(
texName,
textures.ImageTexture,
texName,
clipImage,
interp=interp)
......@@ -365,6 +421,9 @@ class GLVolume(globject.GLImageObject):
self.colourTexture .bindTexture(gl.GL_TEXTURE1)
self.negColourTexture.bindTexture(gl.GL_TEXTURE2)
if self.clipTexture is not None:
self.clipTexture .bindTexture(gl.GL_TEXTURE3)
fslgl.glvolume_funcs.preDraw(self)
......@@ -400,5 +459,8 @@ class GLVolume(globject.GLImageObject):
self.imageTexture .unbindTexture()
self.colourTexture .unbindTexture()
self.negColourTexture.unbindTexture()
if self.clipTexture is not None:
self.clipTexture.unbindTexture()
fslgl.glvolume_funcs.postDraw(self)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment