Skip to content
Snippets Groups Projects
Commit 35776684 authored by Paul McCarthy's avatar Paul McCarthy
Browse files

Documentation for shaders package.

parent 9a448761
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/env python #!/usr/bin/env python
# #
# __init__.py - # __init__.py - Funtions for managing OpenGL shader programs.
# #
# Author: Paul McCarthy <pauldmccarthy@gmail.com> # Author: Paul McCarthy <pauldmccarthy@gmail.com>
# #
"""The ``shaders`` package contains classes and functions for parsing,
compiling, and managing OpenGL shader programs. Two types of shader
program are supported:
- GLSL 1.20 vertex and fragment shaders.
- ``ARB_vertex_program`` and ``ARB_fragment_program`` shader programs.
The :mod:`.glsl` and :mod:`.arbp` packages respectively define the
:class:`.GLSLShader` and :class:`.ARBPShader` classes, which may be
used to manage shader programs of the corresponding type.
Some package-level functions are defined here, for finding and loading
shader source code:
- :func:`getVertexShader`: Locate and load the source code for a specific
vertex shader.
- :func:`getFragmentShader`: Locate and load the source code for a specific
fragment shader.
Each of these functions locate shader source files, load the source code, and
run them through the :func:`preprocess` function, which performs some simple
preprocessing on the source. This applies to both GLSL and ARB assembly
shader programs.
"""
import logging
import os.path as op import os.path as op
...@@ -15,36 +45,34 @@ import glsl.program as glslprogram ...@@ -15,36 +45,34 @@ import glsl.program as glslprogram
import arbp.program as arbpprogram import arbp.program as arbpprogram
log = logging.getLogger(__name__)
GLSLShader = glslprogram.GLSLShader GLSLShader = glslprogram.GLSLShader
ARBPShader = arbpprogram.ARBPShader ARBPShader = arbpprogram.ARBPShader
def getVertexShader(prefix): def getVertexShader(prefix):
"""Returns the vertex shader source for the given GL object.""" """Returns the vertex shader source for the given GL type (e.g.
'glvolume').
"""
return _getShader(prefix, 'vert') return _getShader(prefix, 'vert')
def getFragmentShader(prefix): def getFragmentShader(prefix):
"""Returns the fragment shader source for the given GL object.""" """Returns the fragment shader source for the given GL type."""
return _getShader(prefix, 'frag') return _getShader(prefix, 'frag')
def _getShader(prefix, shaderType): def _getShader(prefix, shaderType):
"""Returns the shader source for the given GL object and the given """Returns the shader source for the given GL type and the given
shader type ('vert' or 'frag'). shader type ('vert' or 'frag').
""" """
fname = _getFileName(prefix, shaderType) fname = _getFileName(prefix, shaderType)
with open(fname, 'rt') as f: src = f.read() with open(fname, 'rt') as f: src = f.read()
return _preprocess(src) return preprocess(src)
def _getFileName(prefix, shaderType): def _getFileName(prefix, shaderType):
"""Returns the file name of the shader program for the given GL object """Returns the file name of the shader program for the given GL type
and shader type. The ``globj`` parameter may alternately be a string, and shader type.
in which case it is used as the prefix for the shader program file name.
""" """
if fslgl.GL_VERSION == '2.1': if fslgl.GL_VERSION == '2.1':
...@@ -61,7 +89,7 @@ def _getFileName(prefix, shaderType): ...@@ -61,7 +89,7 @@ def _getFileName(prefix, shaderType):
prefix, shaderType, suffix)) prefix, shaderType, suffix))
def _preprocess(src): def preprocess(src):
"""'Preprocess' the given shader source. """'Preprocess' the given shader source.
This amounts to searching for lines containing '#pragma include filename', This amounts to searching for lines containing '#pragma include filename',
......
#!/usr/bin/env python #!/usr/bin/env python
# #
# parse.py - # parse.py - Very simple parser for ARB assembly shader programs.
# #
# Author: Paul McCarthy <pauldmccarthy@gmail.com> # Author: Paul McCarthy <pauldmccarthy@gmail.com>
# #
"""This module provides functions for use with OpenGL ``ARB_vertex_program``
and ``ARB_fragment_program`` assembly source code. It defines a simple
templating system, allowing ARB assembly programs to be written in such a way
that input parameters, vertex attributes, texture locations, and texture
coordinates and do not have to be hard coded in the source.
import re .. note:: This module is used by the :class:`.ARBPShader` class - if you use
the :class:`.ARBShader` class, you will not need to use this module
at all.
import jinja2 as j2
import jinja2.meta as j2meta
Instead, place holder tokens can be used in the source code. These tokens may
be parsed (using ``jinja2``) by the :func:`parseARBP` function. Values can
then be assigned to the place holders using the :func:`fillARBP` function.
#
# {{ param_paramName }} -> program.local[X]
#
# Or, if 'paramName' has length > 1
#
# {{ param4_paramName }} -> { program.local[x], program.local[x + 1], ... }
# {{ attr_attName }} -> vertex.texcoord[N] An example
# ----------
# {{ texture_texName }} -> texture[N]
As an example, consider the following vertex program, for drawing a slice
from a 3D image texture::
# Maybe this too? In vertex program:
# {{ varying_outputName }} -> result.texcoord[N] !!ARBvp1.0
#
# In fragment program: PARAM imageShape = program.local[0];
# {{ varying_outputName }} -> fragment.texcoord[N]
# 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;
# Transform the texture coordinates (which are
# between 0 and 1) into voxel coordinates (which
# are within the image voxel dimensions).
MOV voxCoord, vertex.texcoord[0];
MUL voxCoord, voxCoord, imageShape;
# Pass the texture coordinates and
# corresponding voxel coordinates
# through to the fragment program.
MOV result.texcoord[0], vertex.texcoord[0];
MOV result.texcoord[1], voxCoord;
END
And the corresponding fragment program, which looks up the voxel value
and colours the fragment accordingly:
!!ARBfp1.0
TEMP voxValue;
# A transformation matrix (encoding a linear
# offset/scale) which transforms a voxel value
# from the image texture data range to the
# colour map texture input coordinate range.
PARAM voxValXform[4] = { program.local[0],
program.local[1],
program.local[2],
program.local[3] };
# Get the voxel value
TEX voxValue.x, fragment.texcoord[0], texture[0], 3D;
# Transform the voxel value
MAD voxValue, voxValue, voxValXform[0].x, voxValXform[3].x;
# Get the colour that corresponds to the voxel value
TEX result.color, voxValue.x, texture[1], 1D;
This program requires:
- The image shape to be specified as a program parameter at index 0.
- Image texture coordinates to be passed as coordinates on texture unit 0.
- Both the vertex and fragment programs to know which texture units the
texture and voxel coordinates are passed through on.
- The image texture to be bound to texture unit 0.
- The colour map texture to be bound to texture unit 1.
By using this module, all of these requirements can be removed by re-writing
the vertex program as follows::
!!ARBvp1.0
PARAM imageShape = {{ param_imageShape }};
TEMP voxCoord;
# 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;
# Transform the texture coordinates (which are
# between 0 and 1) into voxel coordinates (which
# are within the image voxel dimensions).
MOV voxCoord, {{ attr_texCoord }};
MUL voxCoord, voxCoord, imageShape;
# Pass the texture coordinates and
# corresponding voxel coordinates
# through to the fragment program.
MOV {{ varying_texCoord }}, {{ attr_texCoord }};
MOV {{ varying_voxCoord }}, voxCoord;
END
And the fragment program::
!!ARBfp1.0
TEMP voxValue;
# A transformation matrix (encoding a linear
# offset/scale) which transforms a voxel value
# from the image texture data range to the
# colour map texture input coordinate range.
PARAM voxValXform[4] = {{ param4_voxValXform }};
# Get the voxel value
TEX voxValue.x, {{ varying_texCoord }}, {{ texture_imageTexture }}, 3D;
# Transform the voxel value
MAD voxValue, voxValue, voxValXform[0].x, voxValXform[3].x;
# Get the colour that corresponds to the voxel value
TEX result.color, voxValue.x, {{ texture_colourMapTexture }}, 1D;
The :func:`parseARBP` function parses the source code and returns information
about all declared items. The :func:`fillARBP` function can then be used to
assign explicit values to each of the items::
vertSrc = '!!ARBvp1.0 vertex shader source'
fragSrc = '!!ARBfp1.0 fragment shader source'
# Get information about all parameters,
# attributes, textures, and varyings.
items = parse.parseARBP(vertSrc, fragSrc)
# ...
# You have to calculate positions for
# parameters, attributes and textures.
# Positions for varying items are
# automatically calculated for you.
# ...
vertParams = {'imageShape' : 0}
vertParamLens = {'imageShape' : 1}
fragParams = {'voxValXform' : 0}
fragParamLens = {'voxValXform' : 4}
textures = {'imageTexture' : 0,
'colourMapTexture' : 1}
attrs = {'texCoord' : 0}
# Fill in the template
vertSrc, fragSrc = parse.fillARBP(vertSrc,
fragSrc,
vertParams,
vertParamLens,
fragParams,
fragParamLens,
textures,
attrs)
# Now you can compile the source
# code and run your program!
Template tokens
---------------
The following items may be specified as template tokens. As depicted in
the example above, a token is specified in the following manner::
{{ tokenPrefix_itemName }}
Prefixes for each item type are as follows:
===================== ============
Item Token prefix
===================== ============
*Parameters*: ``param``
*Vertex attributes* ``attr``
*Textures* ``texture``
*Varying attributes* ``varying``
===================== ============
Parameters
==========
*Parameters* are constant values which are passed to every instantiation of a
shader program - they are equivalent to ``uniform`` values in a GLSL program.
In a normal ARB assembly program, parameters are accessed as follows::
PARAM imageShape = program.local[0];
When using this module, you may instead access parameters in this way::
PARAM imageShape = {{ param_imageShape }};
Parameters with a length greater than 1 (e.g. matrix parameters) are
traditionally accessed in this way::
PARAM xform[4] = { program.local[0],
program.local[1],
program.local[2],
program.local[3] };
When using this module, you may access matrix parameters in this way::
PARAM xform[4] = {{ param4_xform }};
Vertex attributes
=================
*Vertex attributes* are values which are associated with every rendered
vertex. They are equivalent to ``attribute`` values in a GLSL program.
In a normal ARB assembly program, one would typically pass vertex
attributes as texture coordinates bound to a specified texture unit::
PARAM texCoord = vertex.texcoord[0];
When using this module, you may access vertex attributes as follows::
PARAM texCoord = {{ attr_texCoord }};
Textures
========
In a typical ARB assembly program, the texture unit to which each texture is
bound must be hard coded::
TEX voxelValue, texCoord, texture[0], 3D;
This can be avoided by using texture tokens::
TEX voxelValue, texCoord, {{ texture_imageTexture }}, 3D;
Varying attributes
==================
Varying attributes are attributes which are generated in the vertex program,
and passed through to the fragment program. They are equivalent to ``varying``
values in a GLSXL program. In an ARB assembly program, they are typically
passed and accessed as texture coordinates::
!!ARBvp1.0
# In the vertex program, we pass varying
# attribute through as texture coordinates:
MOV result.texcoord[0], texCoord;
MOV result.texcoord[1], voxCoord;
# ...
!!ARBfp1.0
# ...
# In the fragment program, we access varying
# attrbutes as texture coordinates
TEMP texCoord;
TEMP voxCoord;
MOV texCoord, fragment.texcoord[0];
MOV voxCoord, fragment.texcoord[1];
# ...
This can be avoided by using the :func:`fillARBP` function, which will
automatically assign texture coordinate positions to each varying attribute.
The assembly code can thus be re-written as follows::
!!ARBvp1.0
# ...
MOV {{ varying_texCoord }}, texCoord;
MOV {{ varying_voxCoord }}, voxCoord;
# ...
!!ARBfp1.0
# ...
TEMP texCoord;
TEMP voxCoord;
MOV texCoord, {{ varying_texCoord }};
MOV voxCoord, {{ varying_voxCoord }};
# ...
"""
import re
import jinja2 as j2
import jinja2.meta as j2meta
def parseARBP(vertSrc, fragSrc): def parseARBP(vertSrc, fragSrc):
"""Parses the given ``ARB_vertex_program`` and ``ARB_fragment_program`` """Parses the given ``ARB_vertex_program`` and ``ARB_fragment_program``
code, and returns information about all declared variables. code, and returns information about all declared variables.
""" """
vParams, vTextures, vAttrs, vVaryings = _findDeclaredVariables(vertSrc) vParams, vTextures, vAttrs, vVaryings = _findDeclaredVariables(vertSrc)
...@@ -58,6 +353,36 @@ def fillARBP(vertSrc, ...@@ -58,6 +353,36 @@ def fillARBP(vertSrc,
fragParamLens, fragParamLens,
textures, textures,
attrs): attrs):
"""Fills in the given ARB assembly code, replacing all template tokens
with the values specified by the various arguments.
:arg vertSrc: Vertex program source.
:arg fragSrc: Fragment program source.
:arg vertParams: Dictionary of ``{name : position}`` mappings,
specifying the position indices of all vertex
program parameters.
:arg vertParamLens: Dictionary ``{name : length}`` mappings,
specifying the lengths of all vertex program
parameters.
:arg fragParams: Dictionary of ``{name : position}`` mappings,
specifying the position indices of all fragment
program parameters.
:arg fragParamLens: Dictionary ``{name : length}`` mappings,
specifying the lengths of all fragment program
parameters.
:arg textures: Dictionary of `{name : textureUnit}`` mappings,
specifying the texture unit to use for each texture.
:arg attrs: Dictionary of `{name : textureUnit}`` mappings,
specifying the texture unit to use for each vertex
attribute.
"""
vertVars = _findDeclaredVariables(vertSrc) vertVars = _findDeclaredVariables(vertSrc)
fragVars = _findDeclaredVariables(fragSrc) fragVars = _findDeclaredVariables(fragSrc)
...@@ -113,6 +438,9 @@ def fillARBP(vertSrc, ...@@ -113,6 +438,9 @@ def fillARBP(vertSrc,
def _findDeclaredVariables(source): def _findDeclaredVariables(source):
"""Parses the given ARB assembly program source, and returns information
about all template tokens defined within.
"""
env = j2.Environment() env = j2.Environment()
ast = env.parse(source) ast = env.parse(source)
...@@ -157,6 +485,9 @@ def _checkVariableValidity(vertVars, ...@@ -157,6 +485,9 @@ def _checkVariableValidity(vertVars,
fragParamMap, fragParamMap,
textureMap, textureMap,
attrMap): attrMap):
"""Checks the information about a vertex/fragment program, and raises
an error if it looks like something is wrong.
"""
vParams, vTextures, vAttrs, vVaryings = vertVars vParams, vTextures, vAttrs, vVaryings = vertVars
fParams, fTextures, fAttrs, fVaryings = fragVars fParams, fTextures, fAttrs, fVaryings = fragVars
...@@ -187,6 +518,7 @@ def _checkVariableValidity(vertVars, ...@@ -187,6 +518,7 @@ def _checkVariableValidity(vertVars,
def _makeVaryingMap(vertVaryings, fragVaryings): def _makeVaryingMap(vertVaryings, fragVaryings):
"""Generates texture unit indices for all varying attributes. """
indices = range(len(vertVaryings)) indices = range(len(vertVaryings))
varyingMap = dict(zip(vertVaryings, indices)) varyingMap = dict(zip(vertVaryings, indices))
...@@ -194,6 +526,8 @@ def _makeVaryingMap(vertVaryings, fragVaryings): ...@@ -194,6 +526,8 @@ def _makeVaryingMap(vertVaryings, fragVaryings):
def _param(number, length): def _param(number, length):
"""Generates ARB assembly for the named vertex/fragment program parameter.
"""
if length == 1: if length == 1:
return 'program.local[{}]'.format(number) return 'program.local[{}]'.format(number)
...@@ -205,13 +539,16 @@ def _param(number, length): ...@@ -205,13 +539,16 @@ def _param(number, length):
def _texture(number): def _texture(number):
"""Generates ARB assembly for a texture."""
return 'texture[{}]'.format(number) return 'texture[{}]'.format(number)
def _attr(number): def _attr(number):
"""Generates ARB assembly for a vertex attribute. """
return 'vertex.texcoord[{}]'.format(number) return 'vertex.texcoord[{}]'.format(number)
def _varying(number, vert): def _varying(number, vert):
"""Generates ARB assembly for a varying attribute. """
if vert: return 'result.texcoord[{}]' .format(number) if vert: return 'result.texcoord[{}]' .format(number)
else: return 'fragment.texcoord[{}]'.format(number) else: return 'fragment.texcoord[{}]'.format(number)
#!/usr/bin/env python #!/usr/bin/env python
# #
# program.py - # program.py - The ARBPShader class.
# #
# Author: Paul McCarthy <pauldmccarthy@gmail.com> # Author: Paul McCarthy <pauldmccarthy@gmail.com>
# #
"""This module provides the :class:`ARBPShader` class, which encapsulates
an OpenGL shader program written according to the ``ARB_vertex_program``
and ``ARB_fragment_program`` extensions.
"""
import logging import logging
...@@ -21,8 +25,92 @@ log = logging.getLogger(__name__) ...@@ -21,8 +25,92 @@ log = logging.getLogger(__name__)
class ARBPShader(object): class ARBPShader(object):
"""The ``ARBPShader`` class encapsulates an OpenGL shader program
written according to the ``ARB_vertex_program`` and
``ARB_fragment_program`` extensions. It parses and compiles vertex
and fragment program code, and provides methods to load/unload
the program, and to set vertex/fragment program parameters and vertex
attributes.
The ``ARBPShader`` class assumes that vertex/fragment program source
has been written to work with the functions defined in the
:mod:`.arbp.parse` module, which allows programs to be written so that
parameter, vertex attribute and texture locations do not have to be hard
coded in the source. Texture locations may be specified in
:meth:`__init__`, and parameter/vertex attribute locations are
automatically assigned by the ``ARBPShader``.
The following methods are available on an ``ARBPShader`` instance:
.. autosummary::
:nosignatures:
load
unload
delete
setVertParam
setFragParam
setAttr
Typcical usage of an ``ARBPShader`` will look something like the
following::
vertSrc = 'vertex shader source'
fragSrc = 'vertex shader source'
# You must specify the texture unit
# assignments at creation time.
textures = {
'colourMapTexture' : 0,
'dataTexture' : 1
}
program = GLSLShader(vertSrc, fragSrc, textures)
# Load the program
program.load()
# Set some parameters
program.setVertParam('transform', np.eye(4))
program.setFragParam('clipping', [0, 1, 0, 0])
# Create and set vertex attributes
vertices, normals = createVertices()
program.setAttr('normals', normals)
# Draw the scene
gl.glDrawArrays(gl.GL_TRIANGLES, 0, len(vertices))
# Clear the GL state
program.unload()
# Delete the program when
# it is no longer needed
program.delete()
.. warning:: The ``ARBPShader`` uses texture coordinates to pass vertex
attributes to the shader programs. Therefore, if you are using
an ``ARBPShader`` you cannot directly use texture coordinates.
See also the :class:`.GLSLShader`, which provides similar functionality for
GLSL shader programs.
"""
def __init__(self, vertSrc, fragSrc, textureMap=None): def __init__(self, vertSrc, fragSrc, textureMap=None):
"""Create an ``ARBPShader``.
:arg vertSrc: Vertex program source.
:arg fragSrc: Fragment program source.
:arg textureMap: A dictionary of ``{name : int}`` mappings, specifying
the texture unit assignments.
"""
decs = parse.parseARBP(vertSrc, fragSrc) decs = parse.parseARBP(vertSrc, fragSrc)
...@@ -65,14 +153,23 @@ class ARBPShader(object): ...@@ -65,14 +153,23 @@ class ARBPShader(object):
self.vertexProgram = vp self.vertexProgram = vp
self.fragmentProgram = fp self.fragmentProgram = fp
log.memory('{}.init({})'.format(type(self).__name__, id(self)))
def __del__(self):
"""Prints a log message. """
log.memory('{}.del({})'.format(type(self).__name__, id(self)))
def delete(self): def delete(self):
"""Deletes all GL resources managed by this ``ARBPShader``. """
arbvp.glDeleteProgramsARB(1, gltypes.GLuint(self.vertexProgram)) arbvp.glDeleteProgramsARB(1, gltypes.GLuint(self.vertexProgram))
arbfp.glDeleteProgramsARB(1, gltypes.GLuint(self.fragmentProgram)) arbfp.glDeleteProgramsARB(1, gltypes.GLuint(self.fragmentProgram))
def load(self): def load(self):
"""Loads the shader program. """
gl.glEnable(arbvp.GL_VERTEX_PROGRAM_ARB) gl.glEnable(arbvp.GL_VERTEX_PROGRAM_ARB)
gl.glEnable(arbfp.GL_FRAGMENT_PROGRAM_ARB) gl.glEnable(arbfp.GL_FRAGMENT_PROGRAM_ARB)
...@@ -89,6 +186,7 @@ class ARBPShader(object): ...@@ -89,6 +186,7 @@ class ARBPShader(object):
def unload(self): def unload(self):
"""Unloads the shader program. """
gl.glDisable(arbfp.GL_FRAGMENT_PROGRAM_ARB) gl.glDisable(arbfp.GL_FRAGMENT_PROGRAM_ARB)
gl.glDisable(arbvp.GL_VERTEX_PROGRAM_ARB) gl.glDisable(arbvp.GL_VERTEX_PROGRAM_ARB)
...@@ -100,6 +198,12 @@ class ARBPShader(object): ...@@ -100,6 +198,12 @@ class ARBPShader(object):
def setVertParam(self, name, value): def setVertParam(self, name, value):
"""Sets the value of the specified vertex program parameter.
.. note:: It is assumed that the value is either a sequence of length
4 (for vector parameters), or a ``numpy`` array of shape ``(n, 4)``
(for matrix parameters).
"""
pos = self.vertParamPositions[name] pos = self.vertParamPositions[name]
value = np.array(value, dtype=np.float32).reshape((-1, 4)) value = np.array(value, dtype=np.float32).reshape((-1, 4))
...@@ -111,7 +215,9 @@ class ARBPShader(object): ...@@ -111,7 +215,9 @@ class ARBPShader(object):
def setFragParam(self, name, value): def setFragParam(self, name, value):
"""Sets the value of the specified vertex program parameter. See
:meth:`setVertParam` for infomration about possible values.
"""
pos = self.fragParamPositions[name] pos = self.fragParamPositions[name]
value = np.array(value, dtype=np.float32).reshape((-1, 4)) value = np.array(value, dtype=np.float32).reshape((-1, 4))
...@@ -122,7 +228,12 @@ class ARBPShader(object): ...@@ -122,7 +228,12 @@ class ARBPShader(object):
def setAttr(self, name, value): def setAttr(self, name, value):
"""Sets the value of the specified vertex attribute. Each vertex
attribute is mapped to a texture coordinate. It is assumed that
the given value is a ``numpy`` array of shape ``(n, l)``, where
``n`` is the number of vertices being drawn, and ``l`` is the
number of components in each vertex attribute coordinate.
"""
texUnit = self.__getAttrTexUnit(name) texUnit = self.__getAttrTexUnit(name)
size = value.shape[1] size = value.shape[1]
value = np.array(value, dtype=np.float32) value = np.array(value, dtype=np.float32)
...@@ -133,6 +244,9 @@ class ARBPShader(object): ...@@ -133,6 +244,9 @@ class ARBPShader(object):
def __getAttrTexUnit(self, attr): def __getAttrTexUnit(self, attr):
"""Returns the texture unit identifier which corresponds to the named
vertex attribute.
"""
pos = self.attrPositions[attr] pos = self.attrPositions[attr]
texUnit = 'GL_TEXTURE{}'.format(pos) texUnit = 'GL_TEXTURE{}'.format(pos)
...@@ -142,6 +256,20 @@ class ARBPShader(object): ...@@ -142,6 +256,20 @@ class ARBPShader(object):
def __generatePositions(self, textureMap=None): def __generatePositions(self, textureMap=None):
"""Called by :meth:`__init__`. Generates positions for vertex/fragment
program parameters and vertex attributes.
The lengths of each vertex/fragment parameter are known (see
:mod:`.arbp.parse`), so these parameters are set up to be sequentially
stored in the program parameter memory.
Vertex attributes are passed to the vertex program as texture
coordinates.
If texture units were not specified in ``__init__``, texture units are
also automatically assigned to each texture used in the fragment
program.
"""
vpPoses = {} vpPoses = {}
fpPoses = {} fpPoses = {}
...@@ -179,8 +307,9 @@ class ARBPShader(object): ...@@ -179,8 +307,9 @@ class ARBPShader(object):
def __compile(self, vertSrc, fragSrc): def __compile(self, vertSrc, fragSrc):
"""Compiles the vertex and fragment programs and returns references """Called by :meth:`__init__`. Compiles the vertex and fragment
to the compiled programs. programs and returns references to the compiled programs.
""" """
gl.glEnable(arbvp.GL_VERTEX_PROGRAM_ARB) gl.glEnable(arbvp.GL_VERTEX_PROGRAM_ARB)
......
#!/usr/bin/env python #!/usr/bin/env python
# #
# program.py - Class which encapsulates a GLSL shader program. # program.py - The GLSLShader class.
# #
# Author: Paul McCarthy <pauldmccarthy@gmail.com> # Author: Paul McCarthy <pauldmccarthy@gmail.com>
# #
...@@ -40,7 +40,7 @@ class GLSLShader(object): ...@@ -40,7 +40,7 @@ class GLSLShader(object):
a GLSL 1.20 shader program, comprising a vertex shader and a fragment a GLSL 1.20 shader program, comprising a vertex shader and a fragment
shader. It provides methods to set shader attribute and uniform values, shader. It provides methods to set shader attribute and uniform values,
to configure attributes, and to load/unload the program. Furthermore, to configure attributes, and to load/unload the program. Furthermore,
the ``GLSLShader`` makes sure that all uniform and attribut variables the ``GLSLShader`` makes sure that all uniform and attribute variables
are converted to the appropriate type. The following methods are available are converted to the appropriate type. The following methods are available
on a ``GLSLShader``: on a ``GLSLShader``:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment