From 0e73962ca3cb29f09fade08a87c81930f79296ad Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauld.mccarthy@gmail.com> Date: Tue, 29 Dec 2015 14:45:22 +0000 Subject: [PATCH] Some documentation for GLSL package modules. --- fsl/fsleyes/gl/glsl/parse.py | 18 +++++-- fsl/fsleyes/gl/glsl/program.py | 99 ++++++++++++++++++++++++++++++++-- fsl/fsleyes/gl/shaders.py | 2 +- setup.py | 1 + 4 files changed, 110 insertions(+), 10 deletions(-) diff --git a/fsl/fsleyes/gl/glsl/parse.py b/fsl/fsleyes/gl/glsl/parse.py index abe2d591a..e4ed5ea1b 100644 --- a/fsl/fsleyes/gl/glsl/parse.py +++ b/fsl/fsleyes/gl/glsl/parse.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # # parse.py - Simple parser for extracting information about a GLSL program. - +# # Author: Paul McCarthy <pauldmccarthy@gmail.com> # # Based on work by Nicolas P. Rougier @@ -51,11 +51,12 @@ about the program. from __future__ import print_function - +import sys import logging import pyparsing as pp + log = logging.getLogger(__name__) @@ -167,11 +168,14 @@ def parseGLSL(source): return decs -if __name__ == '__main__': - import sys +def main(): + """If this module is executed as a script, this function is called. + It expects a path to a ``glsl`` file as a single parameter. This file + is parsed, and information about it printed to standard output. + """ if len(sys.argv) != 2: - print('Usage: glslparse.py file.glsl') + print('Usage: {}.py file.glsl'.format(__name__)) sys.exit(0) infile = sys.argv[1] @@ -187,3 +191,7 @@ if __name__ == '__main__': print('\n--{}--\n'.format(d.upper())) for t, n in v: print('{}: {}'.format(t, n)) + + +if __name__ == '__main__': + main() diff --git a/fsl/fsleyes/gl/glsl/program.py b/fsl/fsleyes/gl/glsl/program.py index 91bbf3517..60ee3b04a 100644 --- a/fsl/fsleyes/gl/glsl/program.py +++ b/fsl/fsleyes/gl/glsl/program.py @@ -30,14 +30,85 @@ GLSL_ATTRIBUTE_TYPES = { 'vec3' : (gl.GL_FLOAT, 3), 'vec4' : (gl.GL_FLOAT, 3) } +"""This dictionary contains mappings between GLSL data types, and their +corresponding GL types and sizes. +""" class ShaderProgram(object): + """The ``ShaderProgram`` class encapsulates information and logic about + a GLSL 1.20 shader program, comprising a vertex shader and a fragment + shader. It provides methods to set shader attribute and uniform values, + to configure attributes, and to load/unload the program. Furthermore, + the ``ShaderProgram`` makes sure that all uniform and attribut variables + are converted to the appropriate type. The following methods are available + on a ``ShaderProgram``: + + + .. autosummary:: + :nosignatures: + + load + unload + delete + loadAtts + unloadAtts + set + setAtt + setIndices + + + Typical usage of a ``ShaderProgram`` will look something like the + following:: + + vertSrc = 'vertex shader source' + fragSrc = 'vertex shader source' + + program = ShaderProgram(vertSrc, fragSrc) + + # Load the program + program.load() + + # Set some uniform values + program.set('lighting', True) + program.set('lightPos', [0, 0, -1]) + + # Create and set vertex attributes + vertices, normals = createVertices() + + program.setAtt('vertex', vertices) + program.setAtt('normal', normals) + + # Load the attributes + program.loadAtts() + + # Draw the scene + gl.glDrawArrays(gl.GL_TRIANGLES, 0, len(vertices)) - def __init__(self, - vertSrc, - fragSrc, - indexed=False): + # Clear the GL state + program.unload() + program.unloadAtts() + + + # Delete the program when + # we no longer need it + program.delete() + """ + + + def __init__(self, vertSrc, fragSrc, indexed=False): + """Create a ``ShaderProgram``. + + :arg vertSrc: String containing vertex shader source code. + + :arg fragSrc: String containing fragment shader source code. + + :arg indexed: If ``True``, it is assumed that the vertices processed + by this shader program will be drawn using an index + array. A vertex buffer object is created to store + vertex indices - this buffer is expected to be populated + via the :meth:`setIndices` method. + """ self.program = self.__compile(vertSrc, fragSrc) @@ -95,10 +166,16 @@ class ShaderProgram(object): def load(self): + """Loads this ``ShaderProgram`` into the GL state. + """ gl.glUseProgram(self.program) def loadAtts(self): + """Binds all of the shader program ``attribute`` variables - you + must set the data for each attribute via :meth:`setAtt` before + calling this method. + """ for att in self.vertAttributes: aPos = self.positions[ att] @@ -124,6 +201,8 @@ class ShaderProgram(object): def unloadAtts(self): + """Disables all vertex attributes, and unbinds associated vertex buffers. + """ for att in self.vertAttributes: gl.glDisableVertexAttribArray(self.positions[att]) @@ -140,10 +219,12 @@ class ShaderProgram(object): def unload(self): + """Unloads the GL shader program. """ gl.glUseProgram(0) def delete(self): + """Deletes all GL resources managed by this ``ShaderProgram`. """ gl.glDeleteProgram(self.program) for buf in self.buffers.values(): @@ -152,6 +233,7 @@ class ShaderProgram(object): def set(self, name, value): + """Sets the value for the specified GLSL ``uniform`` variable. """ vPos = self.positions[name] vType = self.types[ name] @@ -169,6 +251,11 @@ class ShaderProgram(object): def setAtt(self, name, value, divisor=None): + """Sets the value for the specified GLSL ``attribute`` variable. + + :arg divisor: If specified, this value is used as a divisor for this + attribute via the ``glVetexAttribDivisor`` function. + """ aType = self.types[ name] aBuf = self.buffers[name] @@ -196,6 +283,10 @@ class ShaderProgram(object): def setIndices(self, indices): + """If an index array is to be used by this ``ShaderProgram`` (see the + ``indexed`` argument to :meth:`__init__`), the index array may be set + via this method. + """ if self.indexBuffer is None: raise RuntimeError('Shader program was not ' diff --git a/fsl/fsleyes/gl/shaders.py b/fsl/fsleyes/gl/shaders.py index 5a9161f02..df7a03ea3 100644 --- a/fsl/fsleyes/gl/shaders.py +++ b/fsl/fsleyes/gl/shaders.py @@ -22,7 +22,7 @@ following functions: compileShaders -Some functions are also provided which make setting program variables a bit +Some functions are also provided which make setting ARB program variables a bit less painful: diff --git a/setup.py b/setup.py index d50084c83..34dcd079c 100644 --- a/setup.py +++ b/setup.py @@ -50,6 +50,7 @@ setup( install_requires=[ 'pyopengl>=3.1.0', + 'pyparsing>=2.0.3', 'numpy>=1.8.1', 'scipy>=0.14.0', 'matplotlib>=1.3.1', -- GitLab