diff --git a/fsl/fsleyes/gl/gl21/glrgbvector_funcs.py b/fsl/fsleyes/gl/gl21/glrgbvector_funcs.py index 00d52f972f268c1b8a2e4b4b7c0abf38db3242fc..3f7a72d5cb3cb83e9c87773f2e588ad004a67050 100644 --- a/fsl/fsleyes/gl/gl21/glrgbvector_funcs.py +++ b/fsl/fsleyes/gl/gl21/glrgbvector_funcs.py @@ -16,11 +16,8 @@ by this module. """ -import OpenGL.GL as gl -import OpenGL.raw.GL._types as gltypes - -import glvolume_funcs -import glvector_funcs +import glvolume_funcs +import glvector_funcs def init(self): @@ -29,20 +26,18 @@ def init(self): information. """ - self.shaders = None + self.shader = None compileShaders( self) updateShaderState(self) - self.vertexAttrBuffer = gl.glGenBuffers(1) - def destroy(self): """Destroys the vertex buffer and vertex/fragment shaders created in :func:`init`. """ - gl.glDeleteBuffers(1, gltypes.GLuint(self.vertexAttrBuffer)) - gl.glDeleteProgram(self.shaders) + self.shader.delete() + self.shader = None def compileShaders(self): @@ -50,23 +45,18 @@ def compileShaders(self): :class:`.GLRGBVector` instances. Stores references to the shader programs, and to all shader variables on the ``GLRGBVector`` instance. """ - - vertUniforms = [] - vertAtts = ['vertex', 'voxCoord', 'texCoord'] - - glvector_funcs.compileShaders(self, vertAtts, vertUniforms) + self.shader = glvector_funcs.compileShaders(self) def updateShaderState(self): """Updates all shader program variables. """ - opts = self.displayOpts - + opts = self.displayOpts useSpline = opts.interpolation == 'spline' - gl.glUseProgram(self.shaders) + self.shader.load() glvector_funcs.updateFragmentShaderState(self, useSpline=useSpline) - gl.glUseProgram(0) + self.shader.unload() preDraw = glvolume_funcs.preDraw diff --git a/fsl/fsleyes/gl/gl21/glvector_funcs.py b/fsl/fsleyes/gl/gl21/glvector_funcs.py index 30a4d1524e9f4efe62488f2d29c7412db045cf5f..1885af218cbf6d3abfa99ba09d2dd12c7d840a0d 100644 --- a/fsl/fsleyes/gl/gl21/glvector_funcs.py +++ b/fsl/fsleyes/gl/gl21/glvector_funcs.py @@ -6,128 +6,89 @@ # -import OpenGL.GL as gl -import numpy as np +import fsl.fsleyes.gl.shaders as shaders +import fsl.fsleyes.gl.glsl.program as glslprogram +import fsl.utils.transform as transform -import fsl.fsleyes.gl.shaders as shaders -import fsl.utils.transform as transform +def compileShaders(self): -def compileShaders(self, vertAtts, vertUniforms): - - if self.shaders is not None: - gl.glDeleteProgram(self.shaders) + if self.shader is not None: + self.shader.delete() opts = self.displayOpts useVolumeFragShader = opts.colourImage is not None - if useVolumeFragShader: - fragShader = 'GLVolume' - fragUniforms = ['imageTexture', 'clipTexture', 'colourTexture', - 'negColourTexture', 'imageIsClip', 'useNegCmap', - 'imageShape', 'useSpline', 'img2CmapXform', - 'clipLow', 'clipHigh', 'texZero', - 'invertClip'] - else: - fragShader = self - fragUniforms = ['imageTexture', 'modulateTexture', 'clipTexture', - 'clipLow', 'clipHigh', 'xColourTexture', - 'yColourTexture', 'zColourTexture', 'voxValXform', - 'cmapXform', 'imageShape', 'useSpline'] - - vertShaderSrc = shaders.getVertexShader( self) - fragShaderSrc = shaders.getFragmentShader(fragShader) + if useVolumeFragShader: fragShader = 'GLVolume' + else: fragShader = self + + vertSrc = shaders.getVertexShader( self) + fragSrc = shaders.getFragmentShader(fragShader) - self.shaders = shaders.compileShaders(vertShaderSrc, fragShaderSrc) - self.shaderVars = shaders.getShaderVars(self.shaders, - vertAtts, - vertUniforms, - fragUniforms) + return glslprogram.ShaderProgram(vertSrc, fragSrc) -def updateFragmentShaderState( - self, - useSpline=False): +def updateFragmentShaderState(self, useSpline=False): """ """ opts = self.displayOpts - svars = self.shaderVars + shader = self.shader useVolumeFragShader = opts.colourImage is not None + invClipValXform = self.clipTexture .invVoxValXform + clippingRange = opts.clippingRange + imageShape = self.vectorImage.shape[:3] + + # Transform the clip threshold into + # the texture value range, so the + # fragment shader can compare texture + # values directly to it. + if opts.clipImage is not None: + clipLow = clippingRange[0] * \ + invClipValXform[0, 0] + invClipValXform[3, 0] + clipHigh = clippingRange[1] * \ + invClipValXform[0, 0] + invClipValXform[3, 0] + else: + clipLow = 0 + clipHigh = 1 + if useVolumeFragShader: voxValXform = self.colourTexture.voxValXform invVoxValXform = self.colourTexture.invVoxValXform - invClipValXform = self.clipTexture .invVoxValXform - clippingRange = opts.clippingRange - imageShape = self.vectorImage.shape[:3] - imageShape = np.array(imageShape, dtype=np.float32) texZero = 0.0 * invVoxValXform[0, 0] + invVoxValXform[3, 0] - - img2CmapXform = transform.concat( + img2CmapXform = transform.concat( voxValXform, self.cmapTexture.getCoordinateTransform()) - img2CmapXform = np.array(img2CmapXform, dtype=np.float32).ravel('C') - - if opts.clipImage is not None: - clipLow = clippingRange[0] * \ - invClipValXform[0, 0] + invClipValXform[3, 0] - clipHigh = clippingRange[1] * \ - invClipValXform[0, 0] + invClipValXform[3, 0] - else: - clipLow = 0 - clipHigh = 1 - - gl.glUniform1i(svars['imageTexture'], 3) - gl.glUniform1i(svars['clipTexture'], 2) - gl.glUniform1i(svars['colourTexture'], 7) - gl.glUniform1i(svars['negColourTexture'], 7) - - gl.glUniformMatrix4fv(svars['img2CmapXform'], 1, False, img2CmapXform) - gl.glUniform3fv( svars['imageShape'], 1, imageShape) - - gl.glUniform1i(svars['imageIsClip'], False) - gl.glUniform1i(svars['useNegCmap'], False) - gl.glUniform1i(svars['useSpline'], useSpline) - gl.glUniform1f(svars['clipLow'], clipLow) - gl.glUniform1f(svars['clipHigh'], clipHigh) - gl.glUniform1f(svars['texZero'], texZero) - gl.glUniform1i(svars['invertClip'], False) + + shader.set('imageTexture', 3) + shader.set('clipTexture', 2) + shader.set('colourTexture', 7) + shader.set('negColourTexture', 7) + shader.set('img2CmapXform', img2CmapXform) + shader.set('imageShape', imageShape) + shader.set('imageIsClip', False) + shader.set('useNegCmap', False) + shader.set('useSpline', useSpline) + shader.set('clipLow', clipLow) + shader.set('clipHigh', clipHigh) + shader.set('texZero', texZero) + shader.set('invertClip', False) else: - # The coordinate transformation matrices for - # each of the three colour textures are identical - voxValXform = self.imageTexture.voxValXform - invClipValXform = self.clipTexture .invVoxValXform - cmapXform = self.xColourTexture.getCoordinateTransform() - imageShape = np.array(self.vectorImage.shape, dtype=np.float32) - clippingRange = opts.clippingRange - - # Transform the clip threshold into - # the texture value range, so the - # fragment shader can compare texture - # values directly to it. - if opts.clipImage is not None: - clipLow = clippingRange[0] * \ - invClipValXform[0, 0] + invClipValXform[3, 0] - clipHigh = clippingRange[1] * \ - invClipValXform[0, 0] + invClipValXform[3, 0] - else: - clipLow = 0 - clipHigh = 1 - - gl.glUniform1i(svars['imageTexture'], 0) - gl.glUniform1i(svars['modulateTexture'], 1) - gl.glUniform1i(svars['clipTexture'], 2) - gl.glUniform1i(svars['xColourTexture'], 4) - gl.glUniform1i(svars['yColourTexture'], 5) - gl.glUniform1i(svars['zColourTexture'], 6) - - gl.glUniformMatrix4fv(svars['voxValXform'], 1, False, voxValXform) - gl.glUniformMatrix4fv(svars['cmapXform'], 1, False, cmapXform) - - gl.glUniform3fv(svars['imageShape'], 1, imageShape) - gl.glUniform1f( svars['clipLow'], clipLow) - gl.glUniform1f( svars['clipHigh'], clipHigh) - gl.glUniform1f( svars['useSpline'], useSpline) + voxValXform = self.imageTexture.voxValXform + cmapXform = self.xColourTexture.getCoordinateTransform() + + shader.set('imageTexture', 0) + shader.set('modulateTexture', 1) + shader.set('clipTexture', 2) + shader.set('xColourTexture', 4) + shader.set('yColourTexture', 5) + shader.set('zColourTexture', 6) + shader.set('voxValXform', voxValXform) + shader.set('cmapXform', cmapXform) + shader.set('imageShape', imageShape) + shader.set('clipLow', clipLow) + shader.set('clipHigh', clipHigh) + shader.set('useSpline', useSpline)