Пример #1
0
    def __init__( self, types, dtype ):
        """Creates a new Uniform object.

        This should only be called by inherited Uniform classes.

        Types is a dictionary with the following format:
            key: GL enumeration type as a string, Eg. 'GL_FLOAT_VEC4'.
            value: (uniform setter function, number of values per variable)

        The function is used when setting the uniform value.

        The number of values per variable is used to determine the number of
        variables passed to a uniform.
        Ie. Numver of variables = number of values / values per variable
        """
        super( Uniform, self ).__init__()

        self._types = _generate_enum_map( types )
        self._dtype = dtype

        # these values are set in _set_data which is called by
        # shader.uniforms when an assignment is made
        # this allows users to create uniforms and assign them to
        # a shader
        self._program = None
        self._name = None
        self._type = None
        self._func = None
        self._num_values = None
        self._location = None
Пример #2
0
    def __init__(self, types, dtype):
        """Creates a new Uniform object.

        This should only be called by inherited Uniform classes.

        Types is a dictionary with the following format:
            key: GL enumeration type as a string, Eg. 'GL_FLOAT_VEC4'.
            value: (uniform setter function, number of values per variable)

        The function is used when setting the uniform value.

        The number of values per variable is used to determine the number of
        variables passed to a uniform.
        Ie. Numver of variables = number of values / values per variable
        """
        super(Uniform, self).__init__()

        self._types = _generate_enum_map(types)
        self._dtype = dtype

        # these values are set in _set_data which is called by
        # shader.uniforms when an assignment is made
        # this allows users to create uniforms and assign them to
        # a shader
        self._program = None
        self._name = None
        self._type = None
        self._func = None
        self._num_values = None
        self._location = None
Пример #3
0
_enum_string_map = _generate_enum_map(
    {
        "GL_VERTEX_SHADER":       "GL_VERTEX_SHADER",
        "GL_FRAGMENT_SHADER":     "GL_FRAGMENT_SHADER",
        "GL_GEOMETRY_SHADER":     "GL_GEOMETRY_SHADER",
        "GL_FLOAT":               "GL_FLOAT",
        "GL_FLOAT_VEC2":          "GL_FLOAT_VEC2",
        "GL_FLOAT_VEC3":          "GL_FLOAT_VEC3",
        "GL_FLOAT_VEC4":          "GL_FLOAT_VEC4",
        "GL_INT":                 "GL_INT",
        "GL_INT_VEC2":            "GL_INT_VEC2",
        "GL_INT_VEC3":            "GL_INT_VEC3",
        "GL_INT_VEC4":            "GL_INT_VEC4",
        "GL_UNSIGNED_INT":        "GL_UNSIGNED_INT",
        "GL_UNSIGNED_INT_VEC2":   "GL_UNSIGNED_INT_VEC2",
        "GL_UNSIGNED_INT_VEC3":   "GL_UNSIGNED_INT_VEC3",
        "GL_UNSIGNED_INT_VEC4":   "GL_UNSIGNED_INT_VEC4",
        "GL_UNSIGNED_INT_ATOMIC_COUNTER": "GL_UNSIGNED_INT_ATOMIC_COUNTER",
        "GL_FLOAT_MAT2":          "GL_FLOAT_MAT2",
        "GL_FLOAT_MAT3":          "GL_FLOAT_MAT3",
        "GL_FLOAT_MAT4":          "GL_FLOAT_MAT4",
        "GL_FLOAT_MAT2x3":        "GL_FLOAT_MAT2x3",
        "GL_FLOAT_MAT2x4":        "GL_FLOAT_MAT2x4",
        "GL_FLOAT_MAT3x2":        "GL_FLOAT_MAT3x2",
        "GL_FLOAT_MAT3x4":        "GL_FLOAT_MAT3x4",
        "GL_FLOAT_MAT4x2":        "GL_FLOAT_MAT4x2",
        "GL_FLOAT_MAT4x3":        "GL_FLOAT_MAT4x3",
        "GL_SAMPLER_1D":          "GL_SAMPLER_1D",
        "GL_SAMPLER_2D":          "GL_SAMPLER_2D",
        "GL_SAMPLER_3D":          "GL_SAMPLER_3D",
        "GL_SAMPLER_CUBE":        "GL_SAMPLER_CUBE",
        "GL_SAMPLER_1D_SHADOW":   "GL_SAMPLER_1D_SHADOW",
        "GL_SAMPLER_2D_SHADOW":   "GL_SAMPLER_2D_SHADOW",
        "GL_SAMPLER_1D_ARRAY":    "GL_SAMPLER_1D_ARRAY",
        "GL_SAMPLER_2D_ARRAY":    "GL_SAMPLER_2D_ARRAY",
        "GL_SAMPLER_1D_ARRAY_SHADOW": "GL_SAMPLER_1D_ARRAY_SHADOW",
        "GL_SAMPLER_2D_ARRAY_SHADOW": "GL_SAMPLER_2D_ARRAY_SHADOW",
        "GL_SAMPLER_2D_MULTISAMPLE":  "GL_SAMPLER_2D_MULTISAMPLE",
        "GL_SAMPLER_2D_MULTISAMPLE_ARRAY":    "GL_SAMPLER_2D_MULTISAMPLE_ARRAY",
        "GL_SAMPLER_CUBE_SHADOW": "GL_SAMPLER_CUBE_SHADOW",
        "GL_SAMPLER_BUFFER":      "GL_SAMPLER_BUFFER",
        "GL_SAMPLER_2D_RECT":     "GL_SAMPLER_2D_RECT",
        "GL_SAMPLER_2D_RECT_SHADOW":  "GL_SAMPLER_2D_RECT_SHADOW",
        "GL_INT_SAMPLER_1D":      "GL_INT_SAMPLER_1D",
        "GL_INT_SAMPLER_2D":      "GL_INT_SAMPLER_2D",
        "GL_INT_SAMPLER_3D":      "GL_INT_SAMPLER_3D",
        "GL_INT_SAMPLER_CUBE":    "GL_INT_SAMPLER_CUBE",
        "GL_INT_SAMPLER_1D_ARRAY":    "GL_INT_SAMPLER_1D_ARRAY",
        "GL_INT_SAMPLER_2D_ARRAY":    "GL_INT_SAMPLER_2D_ARRAY",
        "GL_INT_SAMPLER_2D_MULTISAMPLE":  "GL_INT_SAMPLER_2D_MULTISAMPLE",
        "GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY":    "GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY",
        "GL_INT_SAMPLER_BUFFER":  "GL_INT_SAMPLER_BUFFER",
        "GL_INT_SAMPLER_2D_RECT": "GL_INT_SAMPLER_2D_RECT",
        "GL_UNSIGNED_INT_SAMPLER_1D": "GL_UNSIGNED_INT_SAMPLER_1D",
        "GL_UNSIGNED_INT_SAMPLER_2D": "GL_UNSIGNED_INT_SAMPLER_2D",
        "GL_UNSIGNED_INT_SAMPLER_3D": "GL_UNSIGNED_INT_SAMPLER_3D",
        "GL_UNSIGNED_INT_SAMPLER_CUBE":   "GL_UNSIGNED_INT_SAMPLER_CUBE",
        "GL_UNSIGNED_INT_SAMPLER_1D_ARRAY":   "GL_UNSIGNED_INT_SAMPLER_1D_ARRAY",
        "GL_UNSIGNED_INT_SAMPLER_2D_ARRAY":   "GL_UNSIGNED_INT_SAMPLER_2D_ARRAY",
        "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE": "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE",
        "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY":   "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY",
        "GL_UNSIGNED_INT_SAMPLER_BUFFER": "GL_UNSIGNED_INT_SAMPLER_BUFFER",
        "GL_UNSIGNED_INT_SAMPLER_2D_RECT":    "GL_UNSIGNED_INT_SAMPLER_2D_RECT",
        "GL_IMAGE_1D":            "GL_IMAGE_1D",
        "GL_IMAGE_2D":            "GL_IMAGE_2D",
        "GL_IMAGE_3D":            "GL_IMAGE_3D",
        "GL_IMAGE_2D_RECT":       "GL_IMAGE_2D_RECT",
        "GL_IMAGE_CUBE":          "GL_IMAGE_CUBE",
        "GL_IMAGE_BUFFER":        "GL_IMAGE_BUFFER",
        "GL_IMAGE_1D_ARRAY":      "GL_IMAGE_1D_ARRAY",
        "GL_IMAGE_2D_ARRAY":      "GL_IMAGE_2D_ARRAY",
        "GL_IMAGE_2D_MULTISAMPLE":    "GL_IMAGE_2D_MULTISAMPLE",
        "GL_IMAGE_2D_MULTISAMPLE_ARRAY":  "GL_IMAGE_2D_MULTISAMPLE_ARRAY",
        "GL_INT_IMAGE_1D":        "GL_INT_IMAGE_1D",
        "GL_INT_IMAGE_2D":        "GL_INT_IMAGE_2D",
        "GL_INT_IMAGE_3D":        "GL_INT_IMAGE_3D",
        "GL_INT_IMAGE_2D_RECT":   "GL_INT_IMAGE_2D_RECT",
        "GL_INT_IMAGE_CUBE":      "GL_INT_IMAGE_CUBE",
        "GL_INT_IMAGE_BUFFER":    "GL_INT_IMAGE_BUFFER",
        "GL_INT_IMAGE_1D_ARRAY":  "GL_INT_IMAGE_1D_ARRAY",
        "GL_INT_IMAGE_2D_ARRAY":  "GL_INT_IMAGE_2D_ARRAY",
        "GL_INT_IMAGE_2D_MULTISAMPLE":    "GL_INT_IMAGE_2D_MULTISAMPLE",
        "GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY":  "GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY",
        "GL_UNSIGNED_INT_IMAGE_1D":   "GL_UNSIGNED_INT_IMAGE_1D",
        "GL_UNSIGNED_INT_IMAGE_2D":   "GL_UNSIGNED_INT_IMAGE_2D",
        "GL_UNSIGNED_INT_IMAGE_3D":   "GL_UNSIGNED_INT_IMAGE_3D",
        "GL_UNSIGNED_INT_IMAGE_2D_RECT":  "GL_UNSIGNED_INT_IMAGE_2D_RECT",
        "GL_UNSIGNED_INT_IMAGE_CUBE": "GL_UNSIGNED_INT_IMAGE_CUBE",
        "GL_UNSIGNED_INT_IMAGE_BUFFER":   "GL_UNSIGNED_INT_IMAGE_BUFFER",
        "GL_UNSIGNED_INT_IMAGE_1D_ARRAY": "GL_UNSIGNED_INT_IMAGE_1D_ARRAY",
        "GL_UNSIGNED_INT_IMAGE_2D_ARRAY": "GL_UNSIGNED_INT_IMAGE_2D_ARRAY",
        "GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE":   "GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE",
        "GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY": "GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY",
        }
    )
Пример #4
0
_enum_string_map = _generate_enum_map({
    "GL_VERTEX_SHADER":
    "GL_VERTEX_SHADER",
    "GL_FRAGMENT_SHADER":
    "GL_FRAGMENT_SHADER",
    "GL_GEOMETRY_SHADER":
    "GL_GEOMETRY_SHADER",
    "GL_FLOAT":
    "GL_FLOAT",
    "GL_FLOAT_VEC2":
    "GL_FLOAT_VEC2",
    "GL_FLOAT_VEC3":
    "GL_FLOAT_VEC3",
    "GL_FLOAT_VEC4":
    "GL_FLOAT_VEC4",
    "GL_INT":
    "GL_INT",
    "GL_INT_VEC2":
    "GL_INT_VEC2",
    "GL_INT_VEC3":
    "GL_INT_VEC3",
    "GL_INT_VEC4":
    "GL_INT_VEC4",
    "GL_UNSIGNED_INT":
    "GL_UNSIGNED_INT",
    "GL_UNSIGNED_INT_VEC2":
    "GL_UNSIGNED_INT_VEC2",
    "GL_UNSIGNED_INT_VEC3":
    "GL_UNSIGNED_INT_VEC3",
    "GL_UNSIGNED_INT_VEC4":
    "GL_UNSIGNED_INT_VEC4",
    "GL_UNSIGNED_INT_ATOMIC_COUNTER":
    "GL_UNSIGNED_INT_ATOMIC_COUNTER",
    "GL_FLOAT_MAT2":
    "GL_FLOAT_MAT2",
    "GL_FLOAT_MAT3":
    "GL_FLOAT_MAT3",
    "GL_FLOAT_MAT4":
    "GL_FLOAT_MAT4",
    "GL_FLOAT_MAT2x3":
    "GL_FLOAT_MAT2x3",
    "GL_FLOAT_MAT2x4":
    "GL_FLOAT_MAT2x4",
    "GL_FLOAT_MAT3x2":
    "GL_FLOAT_MAT3x2",
    "GL_FLOAT_MAT3x4":
    "GL_FLOAT_MAT3x4",
    "GL_FLOAT_MAT4x2":
    "GL_FLOAT_MAT4x2",
    "GL_FLOAT_MAT4x3":
    "GL_FLOAT_MAT4x3",
    "GL_SAMPLER_1D":
    "GL_SAMPLER_1D",
    "GL_SAMPLER_2D":
    "GL_SAMPLER_2D",
    "GL_SAMPLER_3D":
    "GL_SAMPLER_3D",
    "GL_SAMPLER_CUBE":
    "GL_SAMPLER_CUBE",
    "GL_SAMPLER_1D_SHADOW":
    "GL_SAMPLER_1D_SHADOW",
    "GL_SAMPLER_2D_SHADOW":
    "GL_SAMPLER_2D_SHADOW",
    "GL_SAMPLER_1D_ARRAY":
    "GL_SAMPLER_1D_ARRAY",
    "GL_SAMPLER_2D_ARRAY":
    "GL_SAMPLER_2D_ARRAY",
    "GL_SAMPLER_1D_ARRAY_SHADOW":
    "GL_SAMPLER_1D_ARRAY_SHADOW",
    "GL_SAMPLER_2D_ARRAY_SHADOW":
    "GL_SAMPLER_2D_ARRAY_SHADOW",
    "GL_SAMPLER_2D_MULTISAMPLE":
    "GL_SAMPLER_2D_MULTISAMPLE",
    "GL_SAMPLER_2D_MULTISAMPLE_ARRAY":
    "GL_SAMPLER_2D_MULTISAMPLE_ARRAY",
    "GL_SAMPLER_CUBE_SHADOW":
    "GL_SAMPLER_CUBE_SHADOW",
    "GL_SAMPLER_BUFFER":
    "GL_SAMPLER_BUFFER",
    "GL_SAMPLER_2D_RECT":
    "GL_SAMPLER_2D_RECT",
    "GL_SAMPLER_2D_RECT_SHADOW":
    "GL_SAMPLER_2D_RECT_SHADOW",
    "GL_INT_SAMPLER_1D":
    "GL_INT_SAMPLER_1D",
    "GL_INT_SAMPLER_2D":
    "GL_INT_SAMPLER_2D",
    "GL_INT_SAMPLER_3D":
    "GL_INT_SAMPLER_3D",
    "GL_INT_SAMPLER_CUBE":
    "GL_INT_SAMPLER_CUBE",
    "GL_INT_SAMPLER_1D_ARRAY":
    "GL_INT_SAMPLER_1D_ARRAY",
    "GL_INT_SAMPLER_2D_ARRAY":
    "GL_INT_SAMPLER_2D_ARRAY",
    "GL_INT_SAMPLER_2D_MULTISAMPLE":
    "GL_INT_SAMPLER_2D_MULTISAMPLE",
    "GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY":
    "GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY",
    "GL_INT_SAMPLER_BUFFER":
    "GL_INT_SAMPLER_BUFFER",
    "GL_INT_SAMPLER_2D_RECT":
    "GL_INT_SAMPLER_2D_RECT",
    "GL_UNSIGNED_INT_SAMPLER_1D":
    "GL_UNSIGNED_INT_SAMPLER_1D",
    "GL_UNSIGNED_INT_SAMPLER_2D":
    "GL_UNSIGNED_INT_SAMPLER_2D",
    "GL_UNSIGNED_INT_SAMPLER_3D":
    "GL_UNSIGNED_INT_SAMPLER_3D",
    "GL_UNSIGNED_INT_SAMPLER_CUBE":
    "GL_UNSIGNED_INT_SAMPLER_CUBE",
    "GL_UNSIGNED_INT_SAMPLER_1D_ARRAY":
    "GL_UNSIGNED_INT_SAMPLER_1D_ARRAY",
    "GL_UNSIGNED_INT_SAMPLER_2D_ARRAY":
    "GL_UNSIGNED_INT_SAMPLER_2D_ARRAY",
    "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE":
    "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE",
    "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY":
    "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY",
    "GL_UNSIGNED_INT_SAMPLER_BUFFER":
    "GL_UNSIGNED_INT_SAMPLER_BUFFER",
    "GL_UNSIGNED_INT_SAMPLER_2D_RECT":
    "GL_UNSIGNED_INT_SAMPLER_2D_RECT",
    "GL_IMAGE_1D":
    "GL_IMAGE_1D",
    "GL_IMAGE_2D":
    "GL_IMAGE_2D",
    "GL_IMAGE_3D":
    "GL_IMAGE_3D",
    "GL_IMAGE_2D_RECT":
    "GL_IMAGE_2D_RECT",
    "GL_IMAGE_CUBE":
    "GL_IMAGE_CUBE",
    "GL_IMAGE_BUFFER":
    "GL_IMAGE_BUFFER",
    "GL_IMAGE_1D_ARRAY":
    "GL_IMAGE_1D_ARRAY",
    "GL_IMAGE_2D_ARRAY":
    "GL_IMAGE_2D_ARRAY",
    "GL_IMAGE_2D_MULTISAMPLE":
    "GL_IMAGE_2D_MULTISAMPLE",
    "GL_IMAGE_2D_MULTISAMPLE_ARRAY":
    "GL_IMAGE_2D_MULTISAMPLE_ARRAY",
    "GL_INT_IMAGE_1D":
    "GL_INT_IMAGE_1D",
    "GL_INT_IMAGE_2D":
    "GL_INT_IMAGE_2D",
    "GL_INT_IMAGE_3D":
    "GL_INT_IMAGE_3D",
    "GL_INT_IMAGE_2D_RECT":
    "GL_INT_IMAGE_2D_RECT",
    "GL_INT_IMAGE_CUBE":
    "GL_INT_IMAGE_CUBE",
    "GL_INT_IMAGE_BUFFER":
    "GL_INT_IMAGE_BUFFER",
    "GL_INT_IMAGE_1D_ARRAY":
    "GL_INT_IMAGE_1D_ARRAY",
    "GL_INT_IMAGE_2D_ARRAY":
    "GL_INT_IMAGE_2D_ARRAY",
    "GL_INT_IMAGE_2D_MULTISAMPLE":
    "GL_INT_IMAGE_2D_MULTISAMPLE",
    "GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY":
    "GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY",
    "GL_UNSIGNED_INT_IMAGE_1D":
    "GL_UNSIGNED_INT_IMAGE_1D",
    "GL_UNSIGNED_INT_IMAGE_2D":
    "GL_UNSIGNED_INT_IMAGE_2D",
    "GL_UNSIGNED_INT_IMAGE_3D":
    "GL_UNSIGNED_INT_IMAGE_3D",
    "GL_UNSIGNED_INT_IMAGE_2D_RECT":
    "GL_UNSIGNED_INT_IMAGE_2D_RECT",
    "GL_UNSIGNED_INT_IMAGE_CUBE":
    "GL_UNSIGNED_INT_IMAGE_CUBE",
    "GL_UNSIGNED_INT_IMAGE_BUFFER":
    "GL_UNSIGNED_INT_IMAGE_BUFFER",
    "GL_UNSIGNED_INT_IMAGE_1D_ARRAY":
    "GL_UNSIGNED_INT_IMAGE_1D_ARRAY",
    "GL_UNSIGNED_INT_IMAGE_2D_ARRAY":
    "GL_UNSIGNED_INT_IMAGE_2D_ARRAY",
    "GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE":
    "GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE",
    "GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY":
    "GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY",
})
Пример #5
0
class VertexBuffer( object ):

    _target_string_map = _generate_enum_map(
        {
            "GL_ARRAY_BUFFER":          "GL_ARRAY_BUFFER",
            "GL_TEXTURE_BUFFER":        "GL_TEXTURE_BUFFER",
            "GL_ELEMENT_ARRAY_BUFFER":  "GL_ELEMENT_ARRAY_BUFFER",
            "GL_ATOMIC_COUNTER_BUFFER": "GL_ATOMIC_COUNTER_BUFFER",
            "GL_COPY_READ_BUFFER":      "GL_COPY_READ_BUFFER",
            "GL_COPY_WRITE_BUFFER":     "GL_COPY_WRITE_BUFFER",
            "GL_DRAW_INDIRECT_BUFFER":  "GL_DRAW_INDIRECT_BUFFER",
            "GL_DISPATCH_INDIRECT_BUFFER":  "GL_DISPATCH_INDIRECT_BUFFER",
            "GL_PIXEL_PACK_BUFFER":     "GL_PIXEL_PACK_BUFFER",
            "GL_PIXEL_UNPACK_BUFFER":   "GL_PIXEL_UNPACK_BUFFER",
            "GL_SHADER_STORAGE_BUFFER": "GL_SHADER_STORAGE_BUFFER",
            "GL_TRANSFORM_FEEDBACK_BUFFER": "GL_TRANSFORM_FEEDBACK_BUFFER",
            "GL_UNIFORM_BUFFER":        "GL_UNIFORM_BUFFER",
            }
        )

    _usage_string_map = _generate_enum_map(
        {
            "GL_STREAM_DRAW":           "GL_STREAM_DRAW",
            "GL_STREAM_READ":           "GL_STREAM_READ",
            "GL_STREAM_COPY":           "GL_STREAM_COPY",
            "GL_STATIC_DRAW":           "GL_STATIC_DRAW",
            "GL_STATIC_READ":           "GL_STATIC_READ",
            "GL_STATIC_COPY":           "GL_STATIC_COPY",
            "GL_DYNAMIC_DRAW":          "GL_DYNAMIC_DRAW",
            "GL_DYNAMIC_READ":          "GL_DYNAMIC_READ",
            "GL_DYNAMIC_COPY":          "GL_DYNAMIC_COPY",
            }
        )

    @staticmethod
    def target_to_string( target ):
        return VertexBuffer._target_string_map[ target ]

    @staticmethod
    def usage_to_string( usage ):
        return VertexBuffer._usage_string_map[ usage ]

    @staticmethod
    def bound_buffer( type ):
        """Returns the handle of the currently bound buffer.

        The buffer target type is required as there are 3 different
        buffer properties we can check.

        OpenGL provides individual binding stacks for the following
        buffer target types stacks:
            * GL_TEXTURE_BUFFER
            * GL_ELEMENT_ARRAY_BUFFER
            * All other buffer target types.

        :param int type: The buffer target type.
        :rtype: int
        :return: The handle of the currently bound buffer.
        """
        if type == GL.GL_TEXTURE_BUFFER:
            enum = GL.GL_TEXTURE_BUFFER_BINDING
        elif type == GL.GL_ELEMENT_ARRAY_BUFFER:
            enum = GL.GL_ELEMENT_ARRAY_BUFFER_BINDING
        else:
            enum = GL.GL_ARRAY_BUFFER_BINDING

        return GL.glGetInteger( enum )


    @parameters_as_numpy_arrays( 'data' )
    def __init__(
        self,
        target = GL.GL_ARRAY_BUFFER,
        usage = GL.GL_STATIC_DRAW,
        nbytes = None,
        data = None
        ):
        """Creates a Vertex Buffer with the specified attributes.

        The usage parameter can be changed by calling allocate with
        a different usage.

        :param int nbytes: If passed in, the buffer will be allocated.
        :param numpy.array data: If passed in, it will over-ride nbytes and will also
            populate the buffer with the specified data.
        :param int handle: If passed in, the buffer will use the specified handle
            instead of creating a new one.
            If the target differs from the original buffer, an error will
            be triggered by OpenGL when the buffer is used.
        """
        super( VertexBuffer, self ).__init__()

        self._target = target
        self._usage = usage
        self._nbytes = 0
        self._handle = GL.glGenBuffers( 1 )

        if data != None:
            nbytes = data.nbytes

        if nbytes:
            self.bind()
            self.allocate( usage, nbytes )
            if data != None:
                self.set_data( data )
            self.unbind()

    @property
    def handle( self ):
        return self._handle

    @property
    def target( self ):
        return self._target

    @property
    def usage( self ):
        return self._usage

    @property
    def nbytes( self ):
        return self._nbytes

    @property
    def bound( self ):
        """Returns the bind state of the buffer.

        :rtype: boolean
        :return: Returns True if the buffer is currently bound.
        """
        return VertexBuffer.bound_buffer( self.target ) == self.handle

    def bind( self ):
        """Unbinds the current buffer.

        This will deactivate the buffer.

        Asserts that the buffer is currently bound.
        """
        if self.bound:
            raise ValueError( "Buffer is already bound" )
        GL.glBindBuffer( self.target, self.handle )

    def unbind( self ):
        if not self.bound:
            raise ValueError( "Buffer is not bound" )
        GL.glBindBuffer( self.target, 0 )

    def allocate( self, usage, nbytes ):
        """Allocates a new buffer on the GPU.

        If the buffer has already been allocated, it will be freed.

        The handle is not changed by this operation.

        .. note:: Existing data will be lost.
        """
        if not self.bound:
            raise ValueError( "Buffer is not bound" )

        GL.glBufferData( self.target, nbytes, None, usage )
        self._nbytes = nbytes
        self._usage = usage

    @parameters_as_numpy_arrays( 'data' )
    def set_data( self, data, offset = 0 ):
        """Populates the buffer with the specified data.

        The buffer must be allocated before data can be set.

        :raise ValueError: Raised if the buffer is not currently bound.
        :raise OverflowError: Raised if the data size exceeds the buffer's bounds.

        .. seealso:: `py:func:pygly.vertex_buffer.Buffer.allocate`
        """
        if not self.bound:
            raise ValueError( "Buffer is not bound" )

        if (offset + data.nbytes) > self.nbytes:
            raise OverflowError( "Data would overflow buffer" )

        GL.glBufferSubData( self.target, offset, data.nbytes, data )

    def get_data( self, offset = 0, nbytes = None ):
        """Returns the data currently in the buffer.

        :raise ValueError: Raised if the buffer is not currently bound.
        """
        if not nbytes:
            nbytes = self.nbytes

        if not self.bound:
            raise ValueError( "Buffer is not bound" )

        data = numpy.empty( self.buffer.shape, self.buffer.dtype )
        GL.glGetBufferSubData(
            self.buffer.target,
            offset,
            nbytes,
            data
            )
        return data

    def __str__( self ):
        return  "%s(target=%s, usage=%s, nbytes=%d)" % (
            self.__class__.__name__,
            VertexBuffer.target_to_string( self.target ),
            VertexBuffer.usage_to_string( self.usage ),
            self.nbytes
            )