From c87b98e3f77d575db11e81a619db5b5c32fba871 Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauld.mccarthy@gmail.com> Date: Tue, 5 Jan 2016 11:30:45 +0000 Subject: [PATCH] Tensor/ARB assembly documentation. --- fsl/fsleyes/gl/gl14/gllabel_frag.prog | 6 +- fsl/fsleyes/gl/gl14/gllinevector_vert.prog | 15 ++--- fsl/fsleyes/gl/gl14/glmodel_frag.prog | 6 +- fsl/fsleyes/gl/gl14/glvector_frag.prog | 49 +++++++++-------- fsl/fsleyes/gl/gl14/glvolume_frag.prog | 6 +- fsl/fsleyes/gl/gl21/gltensor_funcs.py | 64 +++++++++++++++++++--- fsl/fsleyes/gl/gltensor.py | 31 +++++++++-- fsl/fsleyes/gl/shaders/glsl/program.py | 4 ++ 8 files changed, 118 insertions(+), 63 deletions(-) diff --git a/fsl/fsleyes/gl/gl14/gllabel_frag.prog b/fsl/fsleyes/gl/gl14/gllabel_frag.prog index 72badca3b..47835b5db 100644 --- a/fsl/fsleyes/gl/gl14/gllabel_frag.prog +++ b/fsl/fsleyes/gl/gl14/gllabel_frag.prog @@ -16,7 +16,7 @@ # outlines. The yzw components specify the # border/outline widths along each axis. # -# Input attributes: +# Input varyings: # # texCoord - Fragment texture coordinates # voxCoord - Fragment voxel coordinates @@ -26,10 +26,6 @@ # imageTexture - 3D texture containing the image data # lutTexture - 1D texture containing the lookup table colours # -# Outputs: -# -# result.color - Fragment colour. -# # Author: Paul McCarthy <pauldmccarthy@gmail.com> # diff --git a/fsl/fsleyes/gl/gl14/gllinevector_vert.prog b/fsl/fsleyes/gl/gl14/gllinevector_vert.prog index 525c90508..9a8c43c5e 100644 --- a/fsl/fsleyes/gl/gl14/gllinevector_vert.prog +++ b/fsl/fsleyes/gl/gl14/gllinevector_vert.prog @@ -2,18 +2,15 @@ # # Vertex program for rendering GLLineVector instances. # -# Inputs: -# state.matrix.mvp - MVP transformation matrix -# vertex.position - Vertex position in the voxel coordinate system. +# Input parameters: # -# program.local[0] - (first three components) inverse of image shape -# program.local[1] - (first three components) Offset to apply to transformed -# voxel coordinates before flooring to integers. +# invImageShape - (first three components) inverse of image shape +# voxelOffsets - (first three components) Offset to apply to transformed +# voxel coordinates before flooring to integers. # # Outputs: -# result.position - the vertex position -# result.texcoord[0] - the texture coordinates -# result.texcoord[1] - the voxel coordinates +# texCoord - the texture coordinates +# voxCoord - the voxel coordinates # # Author: Paul McCarthy <pauldmccarthy@gmail.com> # diff --git a/fsl/fsleyes/gl/gl14/glmodel_frag.prog b/fsl/fsleyes/gl/gl14/glmodel_frag.prog index a1f2d079c..3d3d1ee04 100644 --- a/fsl/fsleyes/gl/gl14/glmodel_frag.prog +++ b/fsl/fsleyes/gl/gl14/glmodel_frag.prog @@ -8,12 +8,8 @@ # Input textures: # renderTexture - 2D texture containing the rendered model. # -# Input attributes: +# Input varyings: # texCoord - Texture coordinates -# -# -# Outputs: -# result.color - Fragment colour. # # Author: Paul McCarthy <pauldmccarthy@gmail.com> # diff --git a/fsl/fsleyes/gl/gl14/glvector_frag.prog b/fsl/fsleyes/gl/gl14/glvector_frag.prog index fb815f3bd..3a3fdb0a7 100644 --- a/fsl/fsleyes/gl/gl14/glvector_frag.prog +++ b/fsl/fsleyes/gl/gl14/glvector_frag.prog @@ -16,36 +16,37 @@ # # - Uses those voxel values to colour the fragment. # -# Required inputs: -# -# fragment.texcoord[0] - Fragment texture coordinates -# fragment.texcoord[1] - Fragment voxel coordinates +# Input parameters: +# +# voxValXform - Transformation matrix which transforms the vector +# image voxel values from their texture value +# to the original data range. # -# 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. +# cmapXform - 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[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. +# imageShape - Image shape - number of voxels along the xyz +# dimensions in the image # -# program.local[8] - Image shape - number of voxels along the xyz -# dimensions in the image +# clipping - Clipping thresholds. The (x) component contains +# the low clipping threshold, and the (y) component +# contains the high threshold. # -# program.local[9] - Clipping thresholds. The (x) component contains -# the low clipping threshold, and the (y) component -# contains the high threshold. +# Input textures: # -# Outputs: +# vectorTexture - 3D texture containing the vector data. +# modulateTexture - 3D texture containing brightness modulation values. +# clipTexture - 3D texture containing clipping values. +# xColourTexture - 1D texture containing the X vector component colour map. +# yColourTexture - 1D texture containing the Y vector component colour map. +# zColourTexture - 1D texture containing the Z vector component colour map. # -# result.color - The fragment colour. +# Input varyings: +# +# texCoord - Fragment texture coordinates +# voxCoord - Fragment voxel coordinates # # Author: Paul McCarthy <pauldmccarthy@gmail.com> # diff --git a/fsl/fsleyes/gl/gl14/glvolume_frag.prog b/fsl/fsleyes/gl/gl14/glvolume_frag.prog index d446c432f..dd032c6bb 100644 --- a/fsl/fsleyes/gl/gl14/glvolume_frag.prog +++ b/fsl/fsleyes/gl/gl14/glvolume_frag.prog @@ -47,7 +47,7 @@ # colour map is used), as a voxel value, normalised to # the image texture value range. # -# Input attributes: +# Input varyings: # # texCoord - Fragment texture coordinates # voxCoord - Fragment voxel coordinates @@ -59,10 +59,6 @@ # colourTexture - 1D texture containing colour map # negColourTexture - 1D texture containing negative colour map # -# Outputs: -# -# result.color - The fragment colour -# # Author: Paul McCarthy <pauldmccarthy@gmail.com> # diff --git a/fsl/fsleyes/gl/gl21/gltensor_funcs.py b/fsl/fsleyes/gl/gl21/gltensor_funcs.py index 1eb5784de..5dd6871ea 100644 --- a/fsl/fsleyes/gl/gl21/gltensor_funcs.py +++ b/fsl/fsleyes/gl/gl21/gltensor_funcs.py @@ -4,8 +4,45 @@ # # Author: Paul McCarthy <pauldmccarthy@gmail.com> # +"""This module provides functions which are used by the :class:`.GLTensor` +class for rendering :class:`.TensorImage` overlays in an OpenGL 2.1 compatible +manner. -import logging + +The eigenvalues and eigenvectors of the ``TensorImage`` are stored as 3D +:class:`.ImageTexture` instances, using the :mod:`.gl.resources` module. For +each voxel, the vertices of a unit sphere are passed to the ``gltensor`` +vertex shader, which looks up the eigenvectors and values for the voxel, and +transforms the sphere accordingly. + + +The rendering code makes use of the OpenGL ``ARB_draw_instanced`` extension +so that voxel coordinates do not need to be repeated for every vertex of +a single tensor. + + +If the :attr:`.VectorOpts.colourImage` property is not set, the ``glvector`` +fragment shader is used to colour the tensors. Otherwise, the ``glvolume`` +fragment shader is used to colour the tensors according to the specified +``colourImage``. The functions in the :mod:`.gl21.glvector_funcs` module +are used to manage the fragment shader. + + +The following textures are used for rendering a ``GLTensor`` instance - this +is in addition to the textures that are used for :class:`.GLVector` instances +(of which the ``GLTensor`` is a sub-class): + + ============== ================== ================== + Attribute name Description Texture unit + ============== ================== ================== + ``v1Texture`` First eigenvector ``gl.GL_TEXTURE8`` + ``v2Texture`` Second eigenvector ``gl.GL_TEXTURE9`` + ``v3Texture`` Third eigenvector ``gl.GL_TEXTURE10`` + ``l1Texture`` First eigenvalue ``gl.GL_TEXTURE11`` + ``l2Texture`` Second eigenvalue ``gl.GL_TEXTURE12`` + ``l3Texture`` Third eigenvalue ``gl.GL_TEXTURE13`` + ============== ================== ================== +""" import numpy as np @@ -20,12 +57,9 @@ import fsl.fsleyes.gl.textures as textures import glvector_funcs -log = logging.getLogger(__name__) - - def init(self): - """Compiles and configures the vertex and fragment shader programs, and - creates textures and vertex buffers. + """Creates textures for the tensor eigenvalue and eigenvector images, + and calls :func:`compileShaders` and :func:`updateShaderState`. """ image = self.image @@ -37,7 +71,6 @@ def init(self): l2 = image.L2() l3 = image.L3() - def vPrefilter(d): return d.transpose((3, 0, 1, 2)) @@ -72,6 +105,8 @@ def init(self): def destroy(self): + """Deletes the :class:`.GLSLShader`, and all textures. """ + self.shader.delete() self.shader = None @@ -86,10 +121,17 @@ def destroy(self): def compileShaders(self): + """Creates a :class:`.GLSLShader` for drawing this ``GLTensor``. This is + done via a call to :func:`.gl21.glvector_funcs.compileShaders`. + """ self.shader = glvector_funcs.compileShaders(self, 'gltensor', indexed=True) def updateShaderState(self): + """Updates the state of the vertex and fragment shaders. The fragment + shader is updated via the :func:`.gl21.glvector_funcs.updateShaderState` + function. + """ shader = self.shader opts = self.displayOpts @@ -154,8 +196,8 @@ def updateShaderState(self): def preDraw(self): - """Must be called before :func:`draw`. Loads the shader programs, binds - textures, and enables vertex arrays. + """Must be called before :func:`draw`. Loads the shader programs, does + some shader state configuration, and binds textures to texture units. """ shader = self.shader @@ -183,6 +225,9 @@ def preDraw(self): def draw(self, zpos, xform=None): + """Generates voxel coordinates for each tensor to be drawn, does some + final shader state configuration, and draws the tensors. + """ image = self.image opts = self.displayOpts @@ -223,6 +268,7 @@ def draw(self, zpos, xform=None): def postDraw(self): + """Unloads the shader program, and unbinds the textures. """ self.shader.unloadAtts() self.shader.unload() diff --git a/fsl/fsleyes/gl/gltensor.py b/fsl/fsleyes/gl/gltensor.py index 8ef0097a3..af54f9497 100644 --- a/fsl/fsleyes/gl/gltensor.py +++ b/fsl/fsleyes/gl/gltensor.py @@ -20,11 +20,23 @@ import fsl.fsleyes.gl as fslgl class GLTensor(glvector.GLVector): """The ``GLTensor`` class encapsulates the logic required to render - :class:`.TensorImage` overlays. + :class:`.TensorImage` overlays. Most of the functionality is in the + :mod:`.gl21.gltensor_funcs` module. + + .. note:: The ``GLTensor`` is not supported on versions of OpenGL older + than 2.1. """ def __init__(self, image, display): + """Create a ``GLTensor``. Calls the :func:`.gl21.gltensor_funcs.init` + function. + + :arg image: A :class:`.TensorImage` overlay. + + :arg display: The :class:`.Display` instance associated with the + ``image``. + """ glvector.GLVector.__init__(self, image, display, @@ -88,32 +100,39 @@ class GLTensor(glvector.GLVector): def compileShaders(self): - """Overrides :meth:`.GLVector.compileShaders`. + """Overrides :meth:`.GLVector.compileShaders`. Calls the + :func:`.gl21.gltensor_funcs.compileShaders` function. """ fslgl.gltensor_funcs.compileShaders(self) def updateShaderState(self): - """Overrides :meth:`.GLVector.updateShaderState`. + """Overrides :meth:`.GLVector.updateShaderState`. Calls the + :func:`.gl21.gltensor_funcs.updateShaderState` function. """ fslgl.gltensor_funcs.updateShaderState(self) def preDraw(self): - """Overrides :meth:`.GLVector.preDraw`. + """Overrides :meth:`.GLVector.preDraw`. Calls the + :meth:`.GLVector.preDraw` method, and the + :func:`.gl21.gltensor_funcs.preDraw` function. """ glvector.GLVector.preDraw(self) fslgl.gltensor_funcs.preDraw(self) def draw(self, zpos, xform=None): - """ + """Overrides :meth:`.GLVector.draw`. Calls the + :func:`.gl21.gltensor_funcs.draw` function. """ fslgl.gltensor_funcs.draw(self, zpos, xform) def postDraw(self): - """Overrides :meth:`.GLVector.postDraw`. + """Overrides :meth:`.GLVector.postDraw`. Calls the + :meth:`.GLVector.postDraw` method, and the + :func:`.gl21.gltensor_funcs.postDraw` function. """ glvector.GLVector.postDraw(self) fslgl.gltensor_funcs.postDraw(self) diff --git a/fsl/fsleyes/gl/shaders/glsl/program.py b/fsl/fsleyes/gl/shaders/glsl/program.py index 4a959518a..cc466420a 100644 --- a/fsl/fsleyes/gl/shaders/glsl/program.py +++ b/fsl/fsleyes/gl/shaders/glsl/program.py @@ -255,6 +255,10 @@ class GLSLShader(object): :arg divisor: If specified, this value is used as a divisor for this attribute via the ``glVetexAttribDivisor`` function. + + .. note:: If a ``divisor`` is specified, the OpenGL + ``ARB_instanced_arrays`` extension must be + available. """ aType = self.types[ name] -- GitLab