diff --git a/fsl/data/image.py b/fsl/data/image.py index e2af8913c643ed3714d5ae9b654f50f15f0f6c63..ac1131c4c343c8f205d7252ea7b0876747f7db47 100644 --- a/fsl/data/image.py +++ b/fsl/data/image.py @@ -69,6 +69,7 @@ class Image(props.HasProperties): collections.OrderedDict([ ('volume', '3D/4D volume'), ('mask', '3D/4D mask image'), + ('test', 'I don\'t really know'), ('vector', '3-direction vector image')]), default='volume') """This property defines the type of image data.""" diff --git a/fsl/fslview/displaycontext/display.py b/fsl/fslview/displaycontext/display.py index 81367cac7057a5b92e236da03a209902c925caf5..032ec2aad53298b295f68ac7afacfde7e987d140 100644 --- a/fsl/fslview/displaycontext/display.py +++ b/fsl/fslview/displaycontext/display.py @@ -351,6 +351,7 @@ class Display(props.SyncableHasProperties): optsMap = { 'volume' : volumeopts.VolumeOpts, + 'test' : volumeopts.VolumeOpts, 'vector' : vectoropts.VectorOpts, 'mask' : maskopts. MaskOpts } diff --git a/fsl/fslview/gl/__init__.py b/fsl/fslview/gl/__init__.py index 76f26233f6541287cd2a957186f7cc8745ea81bd..06d8a2d51d7a5b53014abce97d94366d1a004c8e 100644 --- a/fsl/fslview/gl/__init__.py +++ b/fsl/fslview/gl/__init__.py @@ -209,6 +209,7 @@ def bootstrap(glVersion=None): except IndexError: pass thismod.GL_VERSION = verstr + thismod.gltest_funcs = glpkg.gltest_funcs thismod.glvolume_funcs = glpkg.glvolume_funcs thismod.glvector_funcs = glpkg.glvector_funcs thismod._bootstrapped = True diff --git a/fsl/fslview/gl/gl21/__init__.py b/fsl/fslview/gl/gl21/__init__.py index 5f5a552bc887d6b2249a90bd70cc2f40004c756b..d291eb7b6eb3a9172cf35f93ec3097884c770717 100644 --- a/fsl/fslview/gl/gl21/__init__.py +++ b/fsl/fslview/gl/gl21/__init__.py @@ -7,3 +7,4 @@ import glvolume_funcs import glvector_funcs +import gltest_funcs diff --git a/fsl/fslview/gl/gl21/gltest_frag.glsl b/fsl/fslview/gl/gl21/gltest_frag.glsl new file mode 100644 index 0000000000000000000000000000000000000000..500674c4d683fab90ae0a1767832141dad702ee3 --- /dev/null +++ b/fsl/fslview/gl/gl21/gltest_frag.glsl @@ -0,0 +1,16 @@ +#version 120 + +uniform sampler1D colourTexture; +uniform sampler3D imageTexture; +uniform mat4 voxValueXform; + +varying vec3 fragTexCoord; + +void main(void) { + + float value = texture3D(imageTexture, fragTexCoord).x; + + value = (voxValueXform * vec4(value, 0, 0, 0)).x; + + gl_FragColor = texture1D(colourTexture, value); +} diff --git a/fsl/fslview/gl/gl21/gltest_funcs.py b/fsl/fslview/gl/gl21/gltest_funcs.py new file mode 100644 index 0000000000000000000000000000000000000000..52b5259a7ed1a6c1149713d391c633ba96d793d3 --- /dev/null +++ b/fsl/fslview/gl/gl21/gltest_funcs.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# +# gltest_funcs.py - +# +# Author: Paul McCarthy <pauldmccarthy@gmail.com> +# + +import logging + +import OpenGL.GL as gl + +import fsl.utils.transform as transform +import fsl.fslview.gl.shaders as shaders + +log = logging.getLogger(__name__) + +def init(self): + + vertShaderSrc = shaders.getVertexShader( self) + fragShaderSrc = shaders.getFragmentShader(self) + + self.shaders = shaders.compileShaders(vertShaderSrc, fragShaderSrc) + + self.colourTexturePos = gl.glGetUniformLocation(self.shaders, 'colourTexture') + self.imageTexturePos = gl.glGetUniformLocation(self.shaders, 'imageTexture') + self.voxValueXformPos = gl.glGetUniformLocation(self.shaders, 'voxValueXform') + + self.vertexPos = gl.glGetAttribLocation(self.shaders, 'vertex') + self.texCoordPos = gl.glGetAttribLocation(self.shaders, 'texCoord') + + self.vertexBuffer = gl.glGenBuffers(1) + self.indexBuffer = gl.glGenBuffers(1) + self.texCoordBuffer = gl.glGenBuffers(1) + + +def destroy(self): + pass + + +def preDraw(self): + + gl.glUseProgram(self.shaders) + + voxValueXform = transform.concat( + self.imageTexture.voxValXform, + self.colourTexture.getCoordinateTransform()).ravel('C') + + gl.glUniformMatrix4fv( + self.voxValueXformPos, + 1, + False, + voxValueXform) + + gl.glUniform1i(self.imageTexturePos, 0) + gl.glUniform1i(self.colourTexturePos, 1) + + +def draw(self, vertices, indices, texCoords): + + gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertexBuffer) + gl.glBufferData(gl.GL_ARRAY_BUFFER, + vertices.nbytes, + vertices, + gl.GL_STATIC_DRAW) + gl.glVertexAttribPointer( + self.vertexPos, + 3, + gl.GL_FLOAT, + gl.GL_FALSE, + 0, + None) + gl.glEnableVertexAttribArray(self.vertexPos) + + gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.texCoordBuffer) + gl.glBufferData(gl.GL_ARRAY_BUFFER, + texCoords.nbytes, + texCoords, + gl.GL_STATIC_DRAW) + gl.glVertexAttribPointer( + self.texCoordPos, + 3, + gl.GL_FLOAT, + gl.GL_FALSE, + 0, + None) + gl.glEnableVertexAttribArray(self.texCoordPos) + + gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self.indexBuffer) + gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, + indices.nbytes, + indices, + gl.GL_STATIC_DRAW) + + gl.glDrawElements(gl.GL_TRIANGLE_STRIP, 4, gl.GL_UNSIGNED_INT, None) + + +def postDraw(self): + + gl.glDisableVertexAttribArray(self.vertexPos) + gl.glDisableVertexAttribArray(self.texCoordPos) + gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0) + gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, 0) + gl.glUseProgram(0) diff --git a/fsl/fslview/gl/gl21/gltest_vert.glsl b/fsl/fslview/gl/gl21/gltest_vert.glsl new file mode 100644 index 0000000000000000000000000000000000000000..f935123e4b583b071737ca6735cebf71bf76cf9f --- /dev/null +++ b/fsl/fslview/gl/gl21/gltest_vert.glsl @@ -0,0 +1,11 @@ +#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/fslview/gl/globject.py b/fsl/fslview/gl/globject.py index 82837ee3f53d64cdd95d8df6d7140116eff1ec04..83f89fa46db1117624ace87ae7aa8c1dc51fb4a8 100644 --- a/fsl/fslview/gl/globject.py +++ b/fsl/fslview/gl/globject.py @@ -37,11 +37,13 @@ def createGLObject(image, display): import fsl.fslview.gl.glvolume as glvolume import fsl.fslview.gl.glmask as glmask + import fsl.fslview.gl.gltest as gltest import fsl.fslview.gl.glvector as glvector _objectmap = { 'volume' : glvolume.GLVolume, 'mask' : glmask .GLMask, + 'test' : gltest .GLTest, 'vector' : glvector.GLVector } diff --git a/fsl/fslview/gl/gltest.py b/fsl/fslview/gl/gltest.py new file mode 100644 index 0000000000000000000000000000000000000000..c1129f8c4db18204bdea6dc26b4d208844873644 --- /dev/null +++ b/fsl/fslview/gl/gltest.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python +# +# gltest.py - +# +# Author: Paul McCarthy <pauldmccarthy@gmail.com> +# + +import logging + + +import numpy as np +import OpenGL.GL as gl + +import fsl.fslview.gl as fslgl +import fsl.fslview.gl.textures as textures +import fsl.fslview.gl.globject as globject +import fsl.utils.transform as transform + + +log = logging.getLogger(__name__) + + +class GLTest(globject.GLImageObject): + + def __init__(self, image, display): + globject.GLImageObject.__init__(self, image, display) + + texName = '{}_{}'.format(id(self.image), type(self).__name__) + + self.colourTexture = textures.ColourMapTexture(texName) + self.imageTexture = textures.getTexture( + textures.ImageTexture, + texName, + self.image, + self.display) + + + fslgl.gltest_funcs.init(self) + + self.refreshColourTexture() + + + def refreshColourTexture(self): + display = self.display + opts = self.displayOpts + + alpha = display.alpha / 100.0 + cmap = opts.cmap + invert = opts.invert + dmin = opts.displayRange[0] + dmax = opts.displayRange[1] + + self.colourTexture.set(cmap=cmap, + invert=invert, + alpha=alpha, + displayRange=(dmin, dmax)) + + + + def destroy(self): + self.colourTexture.destroy() + textures.deleteTexture(self.imageTexture) + + self.colourTexture = None + self.imageTexture = None + + fslgl.gltest_funcs.destroy(self) + + + def setAxes(self, xax, yax): + self.xax = xax + self.yax = yax + self.zax = 3 - xax - yax + + + def preDraw(self): + + self.imageTexture .bindTexture(gl.GL_TEXTURE0) + self.colourTexture.bindTexture(gl.GL_TEXTURE1) + fslgl.gltest_funcs.preDraw(self) + + + def draw(self, zpos, xform=None): + + voxToDisplayMat = self.display.getTransform('voxel', 'display') + displayToVoxMat = self.display.getTransform('display', 'voxel') + + vertices, indices = globject.slice2D( + self.image.shape[:3], + self.xax, + self.yax, + voxToDisplayMat) + + vertices[:, self.zax] = zpos + + texCoords = transform.transform(vertices, displayToVoxMat) + texCoords /= self.image.shape[:3] + + vertices = np.array(vertices, dtype=np.float32).ravel('C') + texCoords = np.array(texCoords, dtype=np.float32).ravel('C') + indices = np.array(indices, dtype=np.uint32) .ravel('C') + + fslgl.gltest_funcs.draw(self, vertices, indices, texCoords) + + + def postDraw(self): + self.imageTexture .unbindTexture() + self.colourTexture.unbindTexture() + fslgl.gltest_funcs.postDraw(self) diff --git a/fsl/fslview/gl/shaders.py b/fsl/fslview/gl/shaders.py index 17f8967ca9f55a73147cb55ddac5f2004565073c..f02c4e7acedfd67175b19d22ef3a725e960246c7 100644 --- a/fsl/fslview/gl/shaders.py +++ b/fsl/fslview/gl/shaders.py @@ -220,9 +220,11 @@ def _getFileName(globj, shaderType): # than passing a GLObject instance import fsl.fslview.gl.glvolume as glvolume import fsl.fslview.gl.glvector as glvector + import fsl.fslview.gl.gltest as gltest if isinstance(globj, str): prefix = globj elif isinstance(globj, glvolume.GLVolume): prefix = 'glvolume' + elif isinstance(globj, gltest .GLTest): prefix = 'gltest' elif isinstance(globj, glvector.GLVector): prefix = 'glvector' else: raise RuntimeError('Unknown GL object type: ' diff --git a/fsl/fslview/gl/textures/texture.py b/fsl/fslview/gl/textures/texture.py index 626d7d895074af74bd8fa918b4b995d5cdf90c62..5936e099730f6576be9a5d6bcfee61698fad3456 100644 --- a/fsl/fslview/gl/textures/texture.py +++ b/fsl/fslview/gl/textures/texture.py @@ -202,7 +202,7 @@ class Texture2D(Texture): self.unbindTexture() gl.glDisableClientState(gl.GL_VERTEX_ARRAY) - gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY) + gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY) def drawOnBounds(self, xmin, xmax, ymin, ymax, xax, yax):