diff options
Diffstat (limited to 'silx/gui/_glutils/Program.py')
-rw-r--r-- | silx/gui/_glutils/Program.py | 202 |
1 files changed, 0 insertions, 202 deletions
diff --git a/silx/gui/_glutils/Program.py b/silx/gui/_glutils/Program.py deleted file mode 100644 index 87eec5f..0000000 --- a/silx/gui/_glutils/Program.py +++ /dev/null @@ -1,202 +0,0 @@ -# coding: utf-8 -# /*########################################################################## -# -# Copyright (c) 2014-2019 European Synchrotron Radiation Facility -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# -# ###########################################################################*/ -"""This module provides a class to handle shader program compilation.""" - -__authors__ = ["T. Vincent"] -__license__ = "MIT" -__date__ = "25/07/2016" - - -import logging -import weakref - -import numpy - -from . import Context, gl - -_logger = logging.getLogger(__name__) - - -class Program(object): - """Wrap OpenGL shader program. - - The program is compiled lazily (i.e., at first program :meth:`use`). - When the program is compiled, it stores attributes and uniforms locations. - So, attributes and uniforms must be used after :meth:`use`. - - This object supports multiple OpenGL contexts. - - :param str vertexShader: The source of the vertex shader. - :param str fragmentShader: The source of the fragment shader. - :param str attrib0: - Attribute's name to bind to position 0 (default: 'position'). - On certain platform, this attribute MUST be active and with an - array attached to it in order for the rendering to occur.... - """ - - def __init__(self, vertexShader, fragmentShader, - attrib0='position'): - self._vertexShader = vertexShader - self._fragmentShader = fragmentShader - self._attrib0 = attrib0 - self._programs = weakref.WeakKeyDictionary() - - @staticmethod - def _compileGL(vertexShader, fragmentShader, attrib0): - program = gl.glCreateProgram() - - gl.glBindAttribLocation(program, 0, attrib0.encode('ascii')) - - vertex = gl.glCreateShader(gl.GL_VERTEX_SHADER) - gl.glShaderSource(vertex, vertexShader) - gl.glCompileShader(vertex) - if gl.glGetShaderiv(vertex, gl.GL_COMPILE_STATUS) != gl.GL_TRUE: - raise RuntimeError(gl.glGetShaderInfoLog(vertex)) - gl.glAttachShader(program, vertex) - gl.glDeleteShader(vertex) - - fragment = gl.glCreateShader(gl.GL_FRAGMENT_SHADER) - gl.glShaderSource(fragment, fragmentShader) - gl.glCompileShader(fragment) - if gl.glGetShaderiv(fragment, - gl.GL_COMPILE_STATUS) != gl.GL_TRUE: - raise RuntimeError(gl.glGetShaderInfoLog(fragment)) - gl.glAttachShader(program, fragment) - gl.glDeleteShader(fragment) - - gl.glLinkProgram(program) - if gl.glGetProgramiv(program, gl.GL_LINK_STATUS) != gl.GL_TRUE: - raise RuntimeError(gl.glGetProgramInfoLog(program)) - - attributes = {} - for index in range(gl.glGetProgramiv(program, - gl.GL_ACTIVE_ATTRIBUTES)): - name = gl.glGetActiveAttrib(program, index)[0] - namestr = name.decode('ascii') - attributes[namestr] = gl.glGetAttribLocation(program, name) - - uniforms = {} - for index in range(gl.glGetProgramiv(program, gl.GL_ACTIVE_UNIFORMS)): - name = gl.glGetActiveUniform(program, index)[0] - namestr = name.decode('ascii') - uniforms[namestr] = gl.glGetUniformLocation(program, name) - - return program, attributes, uniforms - - def _getProgramInfo(self): - glcontext = Context.getCurrent() - if glcontext not in self._programs: - raise RuntimeError( - "Program was not compiled for current OpenGL context.") - return self._programs[glcontext] - - @property - def attributes(self): - """Vertex attributes names and locations as a dict of {str: int}. - - WARNING: - Read-only usage. - To use only with a valid OpenGL context and after :meth:`use` - has been called for this context. - """ - return self._getProgramInfo()[1] - - @property - def uniforms(self): - """Program uniforms names and locations as a dict of {str: int}. - - WARNING: - Read-only usage. - To use only with a valid OpenGL context and after :meth:`use` - has been called for this context. - """ - return self._getProgramInfo()[2] - - @property - def program(self): - """OpenGL id of the program. - - WARNING: - To use only with a valid OpenGL context and after :meth:`use` - has been called for this context. - """ - return self._getProgramInfo()[0] - - # def discard(self): - # pass # Not implemented yet - - def use(self): - """Make use of the program, compiling it if necessary""" - glcontext = Context.getCurrent() - - if glcontext not in self._programs: - self._programs[glcontext] = self._compileGL( - self._vertexShader, - self._fragmentShader, - self._attrib0) - - if _logger.getEffectiveLevel() <= logging.DEBUG: - gl.glValidateProgram(self.program) - if gl.glGetProgramiv( - self.program, gl.GL_VALIDATE_STATUS) != gl.GL_TRUE: - _logger.debug('Cannot validate program: %s', - gl.glGetProgramInfoLog(self.program)) - - gl.glUseProgram(self.program) - - def setUniformMatrix(self, name, value, transpose=True, safe=False): - """Wrap glUniformMatrix[2|3|4]fv - - :param str name: The name of the uniform. - :param value: The 2D matrix (or the array of matrices, 3D). - Matrices are 2x2, 3x3 or 4x4. - :type value: numpy.ndarray with 2 or 3 dimensions of float32 - :param bool transpose: Whether to transpose (True, default) or not. - :param bool safe: False: raise an error if no uniform with this name; - True: silently ignores it. - - :raises KeyError: if no uniform corresponds to name. - """ - assert value.dtype == numpy.float32 - - shape = value.shape - assert len(shape) in (2, 3) - assert shape[-1] in (2, 3, 4) - assert shape[-1] == shape[-2] # As in OpenGL|ES 2.0 - - location = self.uniforms.get(name) - if location is not None: - count = 1 if len(shape) == 2 else shape[0] - transpose = gl.GL_TRUE if transpose else gl.GL_FALSE - - if shape[-1] == 2: - gl.glUniformMatrix2fv(location, count, transpose, value) - elif shape[-1] == 3: - gl.glUniformMatrix3fv(location, count, transpose, value) - elif shape[-1] == 4: - gl.glUniformMatrix4fv(location, count, transpose, value) - - elif not safe: - raise KeyError('No uniform: %s' % name) |