Пример #1
0
    def set_data(self, data, format=None, shape=None, offset=None, data_type=None, level=0, swizzle=None, **kwargs):
        def set_swizzle(swizzle):
            # sets the swizzle before loading
            # only available on OpenGL Core
            if isinstance(swizzle, (list, tuple)):
                swizzle = (GL.GLint * len(swizzle))(*swizzle)
            elif isinstance(swizzle, basestring):
                result = [
                    Texture.channels[channel]
                    for channel in swizzle.lower()
                ]
                swizzle = (GL.GLint * len(result))(*result)

            GL.glTexParameteriv(self._target, GL.GL_TEXTURE_SWIZZLE_RGBA, swizzle)

        ndims = Texture.target_ndims[self._target]
        _, func = Texture.funcs[ndims]

        if not shape:
            # take the shape from the data
            # but ignore the last dimension
            # this will cause a problem if the data is not in the appropriate shape
            if data.ndims != (ndims + 1):
                raise ValueError('Data must be appropriate shape if shape not specified')
            shape = data.shape[:-1]

        if not offset:
            offset = [0] * ndims

        if not data_type:
            # infer the data type from the numpy dtype
            data_type = numpy_utils.dtype_gl_enum(data.dtype)

        if not format:
            # infer the passed data format using the last dimension of the data
            num_channels = data.shape[-1]
            format = Texture.inferred_formats[num_channels]

        if gl.is_core():
            if swizzle:
                set_swizzle(swizzle)

        args = [
            self.target,
            level,] + \
            list(offset) + \
            list(shape) + [
            format,
            data_type,
            data,
        ]

        func(*args)
Пример #2
0
    def allocate(self, shape, data_type, internal_format=None, **kwargs):
        # assume same format of data
        if not internal_format:
            internal_format = self._internal_format
        else:
            self._internal_format = internal_format

        ndims = Texture.target_ndims[self._target]
        func, _ = Texture.funcs[ndims]

        border = 1 if self._border else 0

        self._shape = tuple(shape)

        if not data_type:
            # attempt to detect the data type from the dtype
            data_type = numpy_utils.dtype_gl_enum(data.dtype)
        else:
            # if we have a dtype
            # determine what type of dtype it is
            if isinstance(data_type, numpy.dtype):
                # numpy dtype
                data_type = numpy_utils.dtype_gl_enum(data_type)
            elif isinstance(data_type, basestring):
                # numpy dtype string
                data_type = numpy_utils.dtype_gl_enum(numpy.dtype(data_type))

        args = [
            self.target,
            0,
            internal_format,] + \
            list(shape) + [
            border,
            GL.GL_RED,  # just use any valid value
            data_type,
            None,
        ]

        func(*args)
Пример #3
0
    def allocate(self, shape, data_type, internal_format=None, **kwargs):
        # assume same format of data
        if not internal_format:
            internal_format = self._internal_format
        else:
            self._internal_format = internal_format

        ndims = Texture.target_ndims[self._target]
        func, _ = Texture.funcs[ndims]

        border = 1 if self._border else 0

        self._shape = tuple(shape)

        if not data_type:
            # attempt to detect the data type from the dtype
            data_type = numpy_utils.dtype_gl_enum(data.dtype)
        else:
            # if we have a dtype
            # determine what type of dtype it is
            if isinstance(data_type, numpy.dtype):
                # numpy dtype
                data_type = numpy_utils.dtype_gl_enum(data_type)
            elif isinstance(data_type, basestring):
                # numpy dtype string
                data_type = numpy_utils.dtype_gl_enum(numpy.dtype(data_type))

        args = [
            self.target,
            0,
            internal_format,] + \
            list(shape) + [
            border,
            GL.GL_RED,  # just use any valid value
            data_type,
            None,
        ]

        func(*args)
Пример #4
0
    def from_dtype( cls, buffer, dtype, name, offset = 0, **kwargs ):
        import numpy_utils

        args = {
            'buffer':   buffer,
            'values_per_vertex':    numpy_utils.dtype_element_count( dtype, name ),
            'gl_type':  numpy_utils.dtype_gl_enum( dtype, name ),
            'stride':   dtype.itemsize,
            'offset':   offset + numpy_utils.dtype_offset( dtype, name )
            }
        args.update( kwargs )

        return cls( **args )
Пример #5
0
    def set_data(self,
                 data,
                 format=None,
                 shape=None,
                 offset=None,
                 data_type=None,
                 level=0,
                 swizzle=None,
                 **kwargs):
        def set_swizzle(swizzle):
            # sets the swizzle before loading
            # only available on OpenGL Core
            if isinstance(swizzle, (list, tuple)):
                swizzle = (GL.GLint * len(swizzle))(*swizzle)
            elif isinstance(swizzle, basestring):
                result = [
                    Texture.channels[channel] for channel in swizzle.lower()
                ]
                swizzle = (GL.GLint * len(result))(*result)

            GL.glTexParameteriv(self._target, GL.GL_TEXTURE_SWIZZLE_RGBA,
                                swizzle)

        ndims = Texture.target_ndims[self._target]
        _, func = Texture.funcs[ndims]

        if not shape:
            # take the shape from the data
            # but ignore the last dimension
            # this will cause a problem if the data is not in the appropriate shape
            if data.ndims != (ndims + 1):
                raise ValueError(
                    'Data must be appropriate shape if shape not specified')
            shape = data.shape[:-1]

        if not offset:
            offset = [0] * ndims

        if not data_type:
            # infer the data type from the numpy dtype
            data_type = numpy_utils.dtype_gl_enum(data.dtype)

        if not format:
            # infer the passed data format using the last dimension of the data
            num_channels = data.shape[-1]
            format = Texture.inferred_formats[num_channels]

        if gl.is_core():
            if swizzle:
                set_swizzle(swizzle)

        args = [
            self.target,
            level,] + \
            list(offset) + \
            list(shape) + [
            format,
            data_type,
            data,
        ]

        func(*args)
Пример #6
0
    def __init__(self,
                 data=None,
                 target=None,
                 internal_format=None,
                 min_filter=GL.GL_NEAREST,
                 mag_filter=GL.GL_NEAREST,
                 wrap_s=GL.GL_REPEAT,
                 wrap_t=GL.GL_REPEAT,
                 shape=None,
                 format=None,
                 data_type=None,
                 border=False,
                 **kwargs):
        """Creates a new texture.

        By default, only the handle will be allocated.
        Optional parameters allow the texture to be allocated and have data set.

        :param GLuint target: The OpenGL texture target type.
        :param GLuint internal_format: The internal format used by this texture.
        :param GLuint min_filter: The minification filter to use for scaling the image down.
            This MUST be set on OpenGL 3.0+ or the texture won't render.
        :param GLuint mag_filter: The magnification filter to use for scaling the image down.
            This MUST be set on OpenGL 3.0+ or the texture won't render.
        :param GLuint wrap_s: The wrap setting for the S dimension.
        :param GLuint wrap_t: The wrap setting for the T dimension.
        :param bool border: Whether or not to apply a border to the texture.
            This MUST be False on OpenGL 3.0+.
        :param iterable data: Data to set on the texture.
            The data shape should represent the dimensions of the texture and
            the number of channels.

            For example, a 32x32 RGBA texture would have the shape (32,32,4).
        :param tuple shape: Specify the data's shape instead of using the shape of the data variable itself.
        :param GLuint data_type: OpenGL data type (GL_FLOAT, etc).
            Inferred from data dtype if not set.
        :param GLuint format: The OpenGL format of the data.
            Inferred from data shape if not set.
        """
        super(Texture, self).__init__()

        if data != None:
            # infer any data we haven't be given
            if not target:
                target = Texture.inferred_targets[data.ndims - 1]

            if not shape:
                shape = data.shape[:-1]

            if not data_type:
                data_type = numpy_utils.dtype_gl_enum(data.dtype)

            if not internal_format:
                internal_format = Texture.inferred_formats[data.shape[-1]]

        # TODO: handle target and format being integers or strings
        self._target = target
        self._internal_format = internal_format
        self._handle = GL.glGenTextures(1)
        self._border = border
        self._shape = shape

        self.bind()

        # we should set the min / mag filter now
        # if we don't set it, the texture won't show up in GL 3+
        # and it's a real bitch to debug
        self.min_filter = min_filter
        self.mag_filter = mag_filter
        self.wrap_s = wrap_s
        self.wrap_t = wrap_t

        if shape and data_type and internal_format:
            self.allocate(shape, data_type, self._internal_format, **kwargs)

            if data != None:
                self.set_data(data,
                              format=format,
                              shape=shape,
                              data_type=data_type,
                              **kwargs)

        self.unbind()
Пример #7
0
    def __init__(
        self,
        data=None,
        target=None,
        internal_format=None,
        min_filter=GL.GL_NEAREST,
        mag_filter=GL.GL_NEAREST,
        wrap_s=GL.GL_REPEAT,
        wrap_t=GL.GL_REPEAT,
        shape=None,
        format=None,
        data_type=None,
        border=False,
        **kwargs
        ):
        """Creates a new texture.

        By default, only the handle will be allocated.
        Optional parameters allow the texture to be allocated and have data set.

        :param GLuint target: The OpenGL texture target type.
        :param GLuint internal_format: The internal format used by this texture.
        :param GLuint min_filter: The minification filter to use for scaling the image down.
            This MUST be set on OpenGL 3.0+ or the texture won't render.
        :param GLuint mag_filter: The magnification filter to use for scaling the image down.
            This MUST be set on OpenGL 3.0+ or the texture won't render.
        :param GLuint wrap_s: The wrap setting for the S dimension.
        :param GLuint wrap_t: The wrap setting for the T dimension.
        :param bool border: Whether or not to apply a border to the texture.
            This MUST be False on OpenGL 3.0+.
        :param iterable data: Data to set on the texture.
            The data shape should represent the dimensions of the texture and
            the number of channels.

            For example, a 32x32 RGBA texture would have the shape (32,32,4).
        :param tuple shape: Specify the data's shape instead of using the shape of the data variable itself.
        :param GLuint data_type: OpenGL data type (GL_FLOAT, etc).
            Inferred from data dtype if not set.
        :param GLuint format: The OpenGL format of the data.
            Inferred from data shape if not set.
        """
        super(Texture, self).__init__()        

        if data != None:
            # infer any data we haven't be given
            if not target:
                target = Texture.inferred_targets[data.ndims - 1]

            if not shape:
                shape = data.shape[:-1]

            if not data_type:
                data_type = numpy_utils.dtype_gl_enum(data.dtype)

            if not internal_format:
                internal_format = Texture.inferred_formats[data.shape[-1]]

        # TODO: handle target and format being integers or strings
        self._target = target
        self._internal_format = internal_format
        self._handle = GL.glGenTextures(1)
        self._border = border
        self._shape = shape

        self.bind()

        # we should set the min / mag filter now
        # if we don't set it, the texture won't show up in GL 3+
        # and it's a real bitch to debug
        self.min_filter = min_filter
        self.mag_filter = mag_filter
        self.wrap_s = wrap_s
        self.wrap_t = wrap_t

        if shape and data_type and internal_format:
            self.allocate(shape, data_type, self._internal_format, **kwargs)

            if data != None:
                self.set_data(data, format=format, shape=shape, data_type=data_type, **kwargs)

        self.unbind()