diff --git a/fsl/fsleyes/gl/gl14/gllabel_sw_frag.prog b/fsl/fsleyes/gl/gl14/gllabel_sw_frag.prog
deleted file mode 100644
index 4c542500c612d0a5e71e39f66edb96b9b4efcd17..0000000000000000000000000000000000000000
--- a/fsl/fsleyes/gl/gl14/gllabel_sw_frag.prog
+++ /dev/null
@@ -1,47 +0,0 @@
-!!ARBfp1.0
-#
-# Restricted fragment program used for rendering GLLabel instances.
-# This is to be used with the glvolume_sw_vert.prog vertex shader.
-#
-# This version does not perform image bounds checking, and does not
-# provide outline/border functionality.
-#
-# Inputs:
-#   fragment.texcoord[0] - Fragment texture coordinates
-#
-#   program.local[0]
-#   program.local[1]
-#   program.local[2]
-#   program.local[3]     - Matrix which transforms image texture
-#                          data into the original data range
-#   program.local[5]     - 1.0 / (number of labels in the lookup table)
-#
-# Outputs:
-#   result.color         - Fragment colour.
-#
-# Author: Paul McCarthy <pauldmccarthy@gmail.com>
-#
-
-TEMP  lutCoord;
-TEMP  invNumLabels;
-TEMP  voxValue;
-
-# look up image voxel value
-# from 3D image texture
-TEX voxValue, fragment.texcoord[0], texture[0], 3D;
-
-# Scale the texture value
-# to its original voxel value
-MOV lutCoord, voxValue;
-MAD lutCoord, lutCoord, program.local[0].x, program.local[3].x;
-
-# Scale the voxel value to
-# a lut texture coordinate
-ADD lutCoord, lutCoord, { 0.5, 0, 0, 0 };
-MUL lutCoord, lutCoord, program.local[5];
-
-# look up the appropriate colour
-# in the 1D colour map texture
-TEX result.color, lutCoord.x, texture[1], 1D;
-
-END
diff --git a/fsl/fsleyes/gl/gl14/gllinevector_sw_vert.prog b/fsl/fsleyes/gl/gl14/gllinevector_sw_vert.prog
deleted file mode 100644
index 15f1280bcac9b3484cbc79d2e1eb0534348cb577..0000000000000000000000000000000000000000
--- a/fsl/fsleyes/gl/gl14/gllinevector_sw_vert.prog
+++ /dev/null
@@ -1,29 +0,0 @@
-!!ARBvp1.0
-#
-# Vertex program for rendering GLLineVector instances. Identical to
-# gllinevector_vert.prog, but does not calculate voxel coordinates.
-#
-# Inputs:
-#    state.matrix.mvp   - MVP transformation matrix
-#    vertex.position    - Vertex position in the voxel coordinate system.
-#    vertex texcoord[0] - Texture coordinates
-#
-# Outputs:
-#    result.position    - the vertex position
-#    result.texcoord[0] - the texture coordinates
-#
-
-TEMP texCoord;
-
-# Transform the vertex position (which is in voxel
-# coordinates) into display coordinates.  It is
-# assumed that a voxel->display transformation has
-# been encoded into the mvp matrix.
-DP4 result.position.x, state.matrix.mvp.row[0], vertex.position;
-DP4 result.position.y, state.matrix.mvp.row[1], vertex.position;
-DP4 result.position.z, state.matrix.mvp.row[2], vertex.position;
-DP4 result.position.w, state.matrix.mvp.row[3], vertex.position;
-
-MOV result.texcoord[0], vertex.texcoord[0];
-
-END
diff --git a/fsl/fsleyes/gl/gl14/glvector_sw_frag.prog b/fsl/fsleyes/gl/gl14/glvector_sw_frag.prog
deleted file mode 100644
index ab9a82cd14f2e1d158cc7f88ad5624fb9d22483d..0000000000000000000000000000000000000000
--- a/fsl/fsleyes/gl/gl14/glvector_sw_frag.prog
+++ /dev/null
@@ -1,119 +0,0 @@
-!!ARBfp1.0
-#
-# Fragment program used for rendering GLVector instances.
-# Identical to glvector_frag.prog, but omits voxel coordinate
-# bounds checking.
-#
-# This fragment program does the following:
-# 
-#  - Retrieves the voxel coordinates corresponding to the fragment
-# 
-#  - Uses those voxel coordinates to look up the corresponding xyz
-#    directions value in the 3D RGB image texture.
-#
-#  - Looks up the colours corresponding to those xyz directions.
-#
-#  - Modulates those colours by the modulation texture.
-#
-#  - Uses those voxel values to colour the fragment.
-#
-# Required inputs:
-# 
-#   fragment.texcoord[0] - Fragment texture coordinates
-#
-#   program.local[0]
-#   program.local[1]
-#   program.local[2]
-#   program.local[3] - Transformation matrix which transforms the vector
-#                      image voxel values from their texture value
-#                      to the original data range.
-#
-#   program.local[4]
-#   program.local[5]
-#   program.local[6]
-#   program.local[7] - Transformation matrix which transforms the vector
-#                      image voxel values from their data values
-#                      to a value which can be used as texture coordinates
-#                      for the colour map textures.
-#
-#   program.local[8] - Image shape - number of voxels along the xyz
-#                      dimensions in the image
-#
-#   program.local[9] - Modulation threshold (x component) - if the 
-#                      modulation value is less than this, the fragment
-#                      is set to fully transparent.
-#
-# Outputs:
-#
-#   result.color     - The fragment colour.
-#
-# Author: Paul McCarthy <pauldmccarthy@gmail.com>
-#
-
-TEMP  voxCoord;
-TEMP  modValue;
-TEMP  voxValue;
-TEMP  xColour;
-TEMP  yColour;
-TEMP  zColour;
-TEMP  fragColour;
-PARAM voxValXform[4] = { program.local[0],
-                         program.local[1],
-                         program.local[2],
-                         program.local[3] };
-PARAM cmapXform[4]   = { program.local[4],
-                         program.local[5],
-                         program.local[6],
-                         program.local[7] };
-                         
-PARAM imageShape     =   program.local[8];
-PARAM modThres       =   program.local[9];
-
-# retrieve the voxel coordinates 
-MOV voxCoord, fragment.texcoord[1];
-
-# look up vector values
-# from the 3D RGB texture
-TEX voxValue, fragment.texcoord[0], texture[0], 3D;
-
-# Look up the modulation value
-# from the modulation texture
-TEX modValue, fragment.texcoord[0], texture[1], 3D;
-
-# Transform vector values from their normalised 
-# texture range to their original data range,
-# and take the absolue value
-MAD voxValue, voxValue, voxValXform[0].x, voxValXform[3].x;
-ABS voxValue, voxValue;
-MAD voxValue, voxValue, cmapXform[  0].x, cmapXform[  3].x;
-
-# Apply the modulation value
-MUL voxValue, voxValue, modValue.x;
-
-# Use the vector values to look up the
-# colours for each xyz direction
-TEX xColour, voxValue.x, texture[2], 1D;
-TEX yColour, voxValue.y, texture[3], 1D;
-TEX zColour, voxValue.z, texture[4], 1D;
-
-# Cumulatively combine the rgb
-# channels of those three colours
-MOV fragColour,             xColour;
-ADD fragColour, fragColour, yColour;
-ADD fragColour, fragColour, zColour;
-
-# Take the highest alpha of the three colour maps
-MAX fragColour.a, xColour.a,    yColour.a;
-MAX fragColour.a, fragColour.a, zColour.a;
-
-# Clear the fragment if the modulation
-# vaue does not meet the threshold
-MOV modValue,   modValue.x;
-SUB modValue,   modValue, modThres.x;
-CMP fragColour, modValue.x, { 0, 0, 0, 0 }, fragColour;
-
-# Colour the pixel!
-MOV result.color, fragColour;
-
-END
-
diff --git a/fsl/fsleyes/gl/gl14/glvolume_sw_frag.prog b/fsl/fsleyes/gl/gl14/glvolume_sw_frag.prog
deleted file mode 100644
index 9276d56d820ab2891c4da2abb171cc8ac36bec53..0000000000000000000000000000000000000000
--- a/fsl/fsleyes/gl/gl14/glvolume_sw_frag.prog
+++ /dev/null
@@ -1,56 +0,0 @@
-!!ARBfp1.0
-#
-# Fragment program used for rendering GLVolume instances. This is a faster
-# (and more limited) version of the standard glvolume_frag.prog shader, which
-# does not perform bounds checking, and does not allow the clipping range to
-# be inverted.
-
-# Required inputs:
-#
-#   fragment.texcoord[0] - Fragment texture coordinates
-#
-#   program.local[0]  
-#   program.local[1]
-#   program.local[2]
-#   program.local[3]     - Matrix which transforms voxel values into the range
-#                          [0, 1], for use as a colour map texture coordinate
-#
-#   program.local[5]     - Vector containing clipping values - voxels with a
-#                          value below the low threshold (x), or above the
-#                          high threshold (y) will not be shown. Assumed to
-#                          be normalised to the image texture value range.
-#
-# Outputs:
-#
-#   result.color         - The fragment colour
-#
-# Author: Paul McCarthy <pauldmccarthy@gmail.com>
-#
-
-TEMP voxClip;
-TEMP voxValue;
-  
-# look up image voxel value
-# from 3D image texture
-TEX voxValue, fragment.texcoord[0], texture[0], 3D;
-
-# If the voxel value is outside the
-# clipping range, don't draw it
-
-# Test the low clipping range
-SUB voxClip, voxValue.x, program.local[5].x;
-KIL voxClip;
-
-# And the high clipping range
-SUB voxClip, program.local[5].y, voxValue.x;
-KIL voxClip;
-
-# Scale voxel value according
-# to the current display range
-MAD voxValue, voxValue, program.local[0].x, program.local[3].x;
-
-# look up the appropriate colour
-# in the 1D colour map texture
-TEX result.color, voxValue.x, texture[1], 1D;
-
-END
diff --git a/fsl/fsleyes/gl/gl14/glvolume_sw_vert.prog b/fsl/fsleyes/gl/gl14/glvolume_sw_vert.prog
deleted file mode 100644
index 5e01a841b0c49cde5ed00bcd8bbfb054eef5863a..0000000000000000000000000000000000000000
--- a/fsl/fsleyes/gl/gl14/glvolume_sw_vert.prog
+++ /dev/null
@@ -1,25 +0,0 @@
-!!ARBvp1.0
-#
-# Vertex program for rendering GLVolume instances.
-#
-# This version is slightly faster than the standard glvolume_vert.prog shader
-# The only difference is that this version only copies texture coordinates
-# through to the fragment program, not voxel coordinates,
-#
-# Inputs:
-#    vertex.texcoord[0] - Texture coordinates.
-#
-#
-# Outputs:
-#    result.texcoord[0] - Texture coordinates.
-#
-
-# Transform the vertex position into display coordinates
-DP4 result.position.x, state.matrix.mvp.row[0], vertex.position;
-DP4 result.position.y, state.matrix.mvp.row[1], vertex.position;
-DP4 result.position.z, state.matrix.mvp.row[2], vertex.position;
-DP4 result.position.w, state.matrix.mvp.row[3], vertex.position;
-
-MOV result.texcoord[0], vertex.texcoord[0];
-
-END
diff --git a/fsl/fsleyes/gl/gl21/gllabel_sw_frag.glsl b/fsl/fsleyes/gl/gl21/gllabel_sw_frag.glsl
deleted file mode 100644
index 2a43781e1c5500b0e40d165d688ff0601089bba5..0000000000000000000000000000000000000000
--- a/fsl/fsleyes/gl/gl21/gllabel_sw_frag.glsl
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Fast (but extremely limited) OpenGL fragment shader used for rendering
- * GLLabel instances. Outline/border mode is not supported.
- *
- * Author: Paul McCarthy <pauldmccarthy@gmail.com>
- */
-#version 120
-
-/*
- * Texture containing image data.
- */
-uniform sampler3D imageTexture;
-
-/*
- * Texture containing lookup table colours.
- */
-uniform sampler1D lutTexture;
-
-/*
- * Transformation matrix which transforms image texture data into
- * its actual data range.
- */
-uniform mat4 voxValXform;
-
-/*
- * Shape of the image texture.
- */
-uniform vec3 imageShape;
-
-/*
- * Total number of colours in the lookup table texture.
- */
-uniform float numLabels;
-
-/*
- * Image texture coordinates.
- */
-varying vec3 fragTexCoord;
-
-
-void main(void) {
-
-    float voxValue = texture3D(imageTexture, fragTexCoord).r;
-    float lutCoord = ((voxValXform * vec4(voxValue, 0, 0, 1)).x + 0.5) / numLabels;
-    
-    gl_FragColor = texture1D(lutTexture, lutCoord);
-}
diff --git a/fsl/fsleyes/gl/gl21/gllinevector_sw_vert.glsl b/fsl/fsleyes/gl/gl21/gllinevector_sw_vert.glsl
deleted file mode 100644
index b82395d2b5d3b50eebe8e1ecdc709867a9377154..0000000000000000000000000000000000000000
--- a/fsl/fsleyes/gl/gl21/gllinevector_sw_vert.glsl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * OpenGL vertex shader used for rendering GLLineVector instances.
- *
- * Author: Paul McCarthy <pauldmccarthy@gmail.com>
- */
-#version 120
-
-attribute vec3 vertex;
-
-attribute vec3 texCoord;
-
-varying vec3 fragTexCoord;
-
-void main(void) {
-
-  fragTexCoord = texCoord;
-
-  gl_Position = gl_ModelViewProjectionMatrix * vec4(vertex, 1);
-}
diff --git a/fsl/fsleyes/gl/gl21/glvector_sw_frag.glsl b/fsl/fsleyes/gl/gl21/glvector_sw_frag.glsl
deleted file mode 100644
index 366d85e5ae2be571193397faac7f12ac053105b4..0000000000000000000000000000000000000000
--- a/fsl/fsleyes/gl/gl21/glvector_sw_frag.glsl
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * OpenGL fragment shader used for colouring GLRGBVector and GLLineVector
- * instances.
- *
- * Author: Paul McCarthy <pauldmccarthy@gmail.com>
- */
-#version 120
-
-/*
- * Vector image containing XYZ vector data.
- */
-uniform sampler3D imageTexture;
-
-/*
- * Modulation texture containing values by
- * which the vector colours are to be modulated.
- */
-uniform sampler3D modTexture;
-
-/*
- * If the modulation value is below this
- * threshold, the fragment is made
- * transparent.
- */
-uniform float modThreshold;
-
-/*
- * Colour map for the X vector component.
- */
-uniform sampler1D xColourTexture;
-
-/*
- * Colour map for the Y vector component.
- */
-uniform sampler1D yColourTexture;
-
-/*
- * Colour map for the Z vector component.
- */
-uniform sampler1D zColourTexture;
-
-/*
- * Matrix which transforms from vector image
- * texture values to their original data range.
- */
-uniform mat4 voxValXform;
-
-/*
- * Matrix which transforms from vector image data
- * values to colour map texture coordinates.
- */
-uniform mat4 cmapXform;
-
-/*
- * Corresponding texture coordinates
- */
-varying vec3 fragTexCoord;
-
-
-void main(void) {
-
-  /*
-   * Look up the xyz vector values
-   */
-  vec3 voxValue = texture3D(imageTexture, fragTexCoord).xyz;
-
-  /* Look up the modulation value */
-  float modValue = texture3D(modTexture, fragTexCoord).x;
-
-  /*
-   * Transform the voxel texture values 
-   * into a range suitable for colour texture
-   * lookup, and take the absolute value
-   */
-  voxValue *= voxValXform[0].x;
-  voxValue += voxValXform[3].x;
-  voxValue  = abs(voxValue);
-  voxValue *= cmapXform[0].x;
-  voxValue += cmapXform[3].x;
-
-  /* Apply the modulation value */
-  voxValue *= modValue;
-
-  /* Look up the colours for the xyz components */
-  vec4 xColour = texture1D(xColourTexture, voxValue.x);
-  vec4 yColour = texture1D(yColourTexture, voxValue.y);
-  vec4 zColour = texture1D(zColourTexture, voxValue.z);
-
-  /* Combine those colours */
-  vec4 voxColour = xColour + yColour + zColour;
-
-  /* Take the highest alpha of the three colour maps */
-  voxColour.a = max(max(xColour.a, yColour.a), zColour.a);
-
-  /* Knock out voxels where the modulation value is below the threshold */
-  if (modValue < modThreshold)
-      voxColour.a = 0.0;
-
-  gl_FragColor = voxColour;
-}
diff --git a/fsl/fsleyes/gl/gl21/glvolume_sw_frag.glsl b/fsl/fsleyes/gl/gl21/glvolume_sw_frag.glsl
deleted file mode 100644
index 22c2da2839f19d2107c88a09a55e7b400bf0d2e6..0000000000000000000000000000000000000000
--- a/fsl/fsleyes/gl/gl21/glvolume_sw_frag.glsl
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Fast but limited OpenGL fragment shader used for rendering GLVolume
- * instances.
- *
- * Author: Paul McCarthy <pauldmccarthy@gmail.com>
- */
-#version 120
-
-/*
- * image data texture.
- */
-uniform sampler3D imageTexture;
-
-/*
- * Texture containing the colour map.
- */
-uniform sampler1D colourTexture;
-
-/*
- * Shape of the imageTexture.
- */
-uniform vec3 imageShape;
-
-/*
- * Transformation matrix to apply to the voxel value,
- * so it can be used as a texture coordinate in the
- * colourTexture.
- */
-uniform mat4 voxValXform;
-
-/*
- * Clip voxels below this value.
- */
-uniform float clipLow;
-
-/*
- * Clip voxels above this value.
- */
-uniform float clipHigh;
-
-/*
- * Image texture coordinates.
- */
-varying vec3 fragTexCoord;
-
-
-void main(void) {
-
-    /*
-     * Look up the voxel value 
-     */
-    float voxValue = texture3D(imageTexture, fragTexCoord).r;
-
-    /*
-     * Clip out of range voxel values
-     */
-    if (voxValue < clipLow || voxValue > clipHigh) {
-      
-      gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
-      return;
-    }
-
-    /*
-     * Transform the voxel value to a colour map texture
-     * coordinate, and look up the colour for the voxel value
-     */
-    voxValue     = voxValXform[0].x * voxValue + voxValXform[3].x;
-    gl_FragColor = texture1D(colourTexture, voxValue);
-}
diff --git a/fsl/fsleyes/gl/gl21/glvolume_sw_vert.glsl b/fsl/fsleyes/gl/gl21/glvolume_sw_vert.glsl
deleted file mode 100644
index f7f4d0f8e587382fb764a3cfd1413d46c268ec8e..0000000000000000000000000000000000000000
--- a/fsl/fsleyes/gl/gl21/glvolume_sw_vert.glsl
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * OpenGL vertex shader used for rendering GLVolume instances.
- *
- * Author: Paul McCarthy <pauldmccarthy@gmail.com>
- */
-#version 120
-
-attribute vec3 vertex;
-attribute vec3 texCoord;
-varying   vec3 fragTexCoord;
-
-void main(void) {
-
-  fragTexCoord = texCoord;
-  gl_Position = gl_ModelViewProjectionMatrix * vec4(vertex, 1);
-}
diff --git a/fsl/fsleyes/gl/shaders.py b/fsl/fsleyes/gl/shaders.py
index 9bf0c72356496c5323bb3c383e6a7d93d10b63fc..770c1b937bd225ee761ae3670583cb38dd8c51b0 100644
--- a/fsl/fsleyes/gl/shaders.py
+++ b/fsl/fsleyes/gl/shaders.py
@@ -224,52 +224,42 @@ def compileShaders(vertShaderSrc, fragShaderSrc):
     return program
 
 
-def getVertexShader(globj, sw=False):
+def getVertexShader(globj):
     """Returns the vertex shader source for the given GL object."""
-    return _getShader(globj, 'vert', sw)
+    return _getShader(globj, 'vert')
 
 
-def getFragmentShader(globj, sw=False):
+def getFragmentShader(globj):
     """Returns the fragment shader source for the given GL object.""" 
-    return _getShader(globj, 'frag', sw)
+    return _getShader(globj, 'frag')
 
 
 
 _shaderTypePrefixMap = td.TypeDict({
     
-    ('GLVolume',     'vert', False) : 'glvolume',
-    ('GLVolume',     'vert', True)  : 'glvolume_sw',
-    ('GLVolume',     'frag', False) : 'glvolume',
-    ('GLVolume',     'frag', True)  : 'glvolume_sw',
-
-    ('GLLabel',      'vert', False) : 'glvolume',
-    ('GLLabel',      'vert', True)  : 'glvolume_sw', 
-    ('GLLabel',      'frag', False) : 'gllabel',
-    ('GLLabel',      'frag', True)  : 'gllabel_sw', 
+    ('GLVolume',     'vert') : 'glvolume',
+    ('GLVolume',     'frag') : 'glvolume',
+
+    ('GLLabel',      'vert') : 'glvolume',
+    ('GLLabel',      'frag') : 'gllabel',
     
-    ('GLRGBVector',  'vert', False) : 'glvolume',
-    ('GLRGBVector',  'vert', True)  : 'glvolume_sw',
+    ('GLRGBVector',  'vert') : 'glvolume',
     
-    ('GLRGBVector',  'frag', False) : 'glvector',
-    ('GLRGBVector',  'frag', True)  : 'glvector_sw',
+    ('GLRGBVector',  'frag') : 'glvector',
 
-    ('GLLineVector', 'vert', False) : 'gllinevector',
-    ('GLLineVector', 'vert', True)  : 'gllinevector_sw',
+    ('GLLineVector', 'vert') : 'gllinevector',
     
-    ('GLLineVector', 'frag', False) : 'glvector',
-    ('GLLineVector', 'frag', True)  : 'glvector_sw',
+    ('GLLineVector', 'frag') : 'glvector',
 
-    ('GLModel',      'vert', False) : 'glmodel',
-    ('GLModel',      'vert', True)  : 'glmodel',
-    ('GLModel',      'frag', False) : 'glmodel',
-    ('GLModel',      'frag', True)  : 'glmodel',
+    ('GLModel',      'vert') : 'glmodel',
+    ('GLModel',      'frag') : 'glmodel',
 })
 """This dictionary provides a mapping between :class:`.GLObject` types,
 and file name prefixes, identifying the shader programs to use.
 """
 
 
-def _getShaderPrefix(globj, shaderType, sw):
+def _getShaderPrefix(globj, shaderType):
     """Returns the prefix identifying the vertex/fragment shader programs to use
     for the given :class:`.GLObject` instance. If ``globj`` is a string, it is
     returned unchanged.
@@ -278,27 +268,27 @@ def _getShaderPrefix(globj, shaderType, sw):
     if isinstance(globj, str):
         return globj
     
-    return _shaderTypePrefixMap[globj, shaderType, sw]
+    return _shaderTypePrefixMap[globj, shaderType]
 
 
-def _setShaderPrefix(globj, shaderType, sw, prefix):
+def _setShaderPrefix(globj, shaderType, prefix):
     """Updates the prefix identifying the vertex/fragment shader programs to use
     for the given :class:`.GLObject` type or instance.
     """
     
-    _shaderTypePrefixMap[globj, shaderType, sw] = prefix
+    _shaderTypePrefixMap[globj, shaderType] = prefix
 
 
-def _getShader(globj, shaderType, sw):
+def _getShader(globj, shaderType):
     """Returns the shader source for the given GL object and the given
     shader type ('vert' or 'frag').
     """
-    fname = _getFileName(globj, shaderType, sw)
+    fname = _getFileName(globj, shaderType)
     with open(fname, 'rt') as f: src = f.read()
     return _preprocess(src)    
 
 
-def _getFileName(globj, shaderType, sw):
+def _getFileName(globj, shaderType):
     """Returns the file name of the shader program for the given GL object
     and shader type. The ``globj`` parameter may alternately be a string,
     in which case it is used as the prefix for the shader program file name.
@@ -314,7 +304,7 @@ def _getFileName(globj, shaderType, sw):
     if shaderType not in ('vert', 'frag'):
         raise RuntimeError('Invalid shader type: {}'.format(shaderType))
 
-    prefix = _getShaderPrefix(globj, shaderType, sw)
+    prefix = _getShaderPrefix(globj, shaderType)
 
     return op.join(op.dirname(__file__), subdir, '{}_{}.{}'.format(
         prefix, shaderType, suffix))