<commit_before>from pyglet import gl
from ctypes import byref, create_string_buffer, c_char, c_char_p, c_int, c_float, cast, pointer, POINTER
import numpy as np
from .utils import gl as ugl
try:
    from UserDict import UserDict  # Python 2
except ImportError:
    from collections import UserDict  # Python 3
from six import iteritems


class UniformArray(np.ndarray): pass


class UniformCollection(UserDict, object):
    """Dict-like that converts data to arrays and sends all data to a Shader as uniform arrays."""

    _sendfuns = {'f': [gl.glUniform1f, gl.glUniform2f, gl.glUniform3f, gl.glUniform4f],
                'i':   [gl.glUniform1i, gl.glUniform2i, gl.glUniform3i, gl.glUniform4i]
                }

    def __init__(self, **kwargs):
        super(UniformCollection, self).__init__()
        for key, value in iteritems(kwargs):
            self[key] = value

    def __setitem__(self, key, value):
        uniform = np.array([value]) if not hasattr(value, '__iter__') else np.array(value)
        uniform = uniform.view(UniformArray)  # Cast as a UniformArray for 'loc' to be set as an attribute later.
        name = key.encode('ascii')
        self.data[name] = uniform

    def send(self):

        for name, array in iteritems(self):

            # Attach a shader location value to the array, for quick memory lookup. (gl calls are expensive, for some reason)
            try:
                loc = array.loc
            except AttributeError:
                array.loc = gl.glGetUniformLocation(Shader._bound.id, name)
                loc = array.loc

            sendfun = self._sendfuns[array.dtype.kind][len(array) - 1]  # Find correct glUniform function
            sendfun(loc, *array)



#
# Copyright <NAME> 2008
#
# Distributed under the Boost Software License, Version 1.0
# (see http://www.boost.org/LICENSE_1_0.txt)
#


class Shader(ugl.BindingContextMixin, ugl.BindNoTargetMixin):

    bindfun = gl.glUseProgram
    uniformf_funs = (gl.glUniform1f, gl.glUniform2f, gl.glUniform3f, gl.glUniform4f)
    uniformi_funs = (gl.glUniform1i, gl.glUniform2i, gl.glUniform3i, gl.glUniform4i)

    def __init__(self, vert='', frag='', geom=''):
        """
        GLSL Shader program object for rendering in OpenGL.

        Args:
          - vert (str): The vertex shader program  string<commit_msg>UniformCollection now asks OpenGL directly for the currently-bound shader, removing its dependency on the Shader class and making it more generally useful.<commit_after>from pyglet import gl
from ctypes import byref, create_string_buffer, c_char, c_char_p, c_int, c_float, cast, pointer, POINTER
import numpy as np
from .utils import gl as ugl
try:
    from UserDict import UserDict  # Python 2
except ImportError:
    from collections import UserDict  # Python 3
from six import iteritems


class UniformArray(np.ndarray): pass


class UniformCollection(UserDict, object):
    """Dict-like that converts data to arrays and sends all data to a Shader as uniform arrays."""

    _sendfuns = {'f': [gl.glUniform1f, gl.glUniform2f, gl.glUniform3f, gl.glUniform4f],
                'i':   [gl.glUniform1i, gl.glUniform2i, gl.glUniform3i, gl.glUniform4i]
                }

    def __init__(self, **kwargs):
        super(UniformCollection, self).__init__()
        for key, value in iteritems(kwargs):
            self[key] = value

    def __setitem__(self, key, value):
        uniform = np.array([value]) if not hasattr(value, '__iter__') else np.array(value)
        uniform = uniform.view(UniformArray)  # Cast as a UniformArray for 'loc' to be set as an attribute later.
        name = key.encode('ascii')
        self.data[name] = uniform

    def send(self):

        for name, array in iteritems(self):

            # Attach a shader location value to the array, for quick memory lookup. (gl calls are expensive, for some reason)
            try:
                loc = array.loc
            except AttributeError:
                shader_id = c_int(0)
                gl.glGetIntegerv(gl.GL_CURRENT_PROGRAM, byref(shader_id))
                if shader_id.value == 0:
                    raise UnboundLocalError("Shader not bound to OpenGL context--uniform cannot be sent.")
                array.loc = gl.glGetUniformLocation(shader_id.value, name)
                loc = array.loc

            sendfun = self._sendfuns[array.dtype.kind][len(array) - 1]  # Find correct glUniform function
            sendfun(loc, *array)



#
# Copyright <NAME> 2008
#
# Distributed under the Boost Software License, Version 1.0
# (see http://www.boost.org/LICENSE_1_0.txt)
#


class Shader(ugl.BindingContextMixin, ugl.BindNoTargetMixin):

    bindfun = gl.glUseProgram
    uniformf_funs = (gl.glUniform1f, gl.glUniform2f, gl.glUniform3f, gl.glUniform4f)
    uniformi_funs = (gl.glUniform1i, gl.glUniform2i, gl.glUniform3i, gl.glUniform4i)

    def __init__(self, vert='', frag='', geom=''):
        """
        GLSL Shader program object for rendering in OpenGL.

        Args:
          - vert (str): The vertex shader program  string
{'fraction_non_alphanumeric': 0.09568145800316957, 'fraction_numerical': 0.011093502377179081, 'mean_word_length': 2.8134441087613293, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1154627', 'n_tokens_mistral': 1584, 'n_tokens_neox': 1502, 'n_words': 468}