Exemplo n.º 1
0
    def update_texture_rgb24(self, img_data, x, y, width, height, rowstride):
        drawable = self.glarea.get_gl_drawable()
        context = self.glarea.get_gl_context()
        if not drawable.gl_begin(context):
            raise Exception("** Cannot create OpenGL rendering context!")
        assert self.textures is not None

        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[0])
        glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstride/3)

        if self.current_mode == GLClientWindow.MODE_YUV:
            raise Exception("** YUV -> RGB mode change unimplemented!")
        elif self.current_mode == GLClientWindow.MODE_UNINITIALIZED:
            log("Creating new RGB texture")
            w, h = self.get_size()
            # First time we draw must be full image
            assert w == width and h == height
            glEnable(GL_TEXTURE_RECTANGLE_ARB)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0)
            self.current_mode = GLClientWindow.MODE_RGB
        log("Updating RGB texture")
        glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, img_data)
        drawable.gl_end()
        self.render_image()
Exemplo n.º 2
0
    def _do_paint_rgb24(self, img_data, x, y, w, h, rowstride, options, callbacks):
        log("do_paint_rgb24(%s bytes, %s, %s, %s, %s, %s, %s, %s)", len(img_data), x, y, w, h, rowstride, options, callbacks)
        ww, wh = self.size
        if x+w>ww or y+h>wh:
            log("do_paint_rgb24: ignoring paint which would overflow the backing area")
            return
        drawable = self.gl_init()
        if not drawable:
            log("do_paint_rgb24: cannot paint yet..")
            return
        try:
            #cleanup if we were doing yuv previously:
            if self.pixel_format!=GLPixmapBacking.RGB24:
                self.remove_shader()
                self.pixel_format = GLPixmapBacking.RGB24

            glEnable(GL_TEXTURE_RECTANGLE_ARB)
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[0])
            glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstride/3)
            for texture in (GL_TEXTURE1, GL_TEXTURE2):
                glActiveTexture(texture)
                glDisable(GL_TEXTURE_RECTANGLE_ARB)

            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
            glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, w, h, GL_RGB, GL_UNSIGNED_BYTE, img_data)

            glBegin(GL_QUADS)
            for rx,ry in ((x, y), (x, y+h), (x+w, y+h), (x+w, y)):
                glTexCoord2i(rx, ry)
                glVertex2i(rx, ry)
            glEnd()
        finally:
            self.gl_end(drawable)
Exemplo n.º 3
0
    def update_texture_rgb24(self, img_data, x, y, width, height, rowstride):
        drawable = self.glarea.get_gl_drawable()
        context = self.glarea.get_gl_context()
        if not drawable.gl_begin(context):
            raise Exception("** Cannot create OpenGL rendering context!")
        assert self.textures is not None

        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[0])
        glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstride / 3)

        if self.current_mode == GLClientWindow.MODE_YUV:
            raise Exception("** YUV -> RGB mode change unimplemented!")
        elif self.current_mode == GLClientWindow.MODE_UNINITIALIZED:
            log("Creating new RGB texture")
            w, h = self.get_size()
            # First time we draw must be full image
            assert w == width and h == height
            glEnable(GL_TEXTURE_RECTANGLE_ARB)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
                            GL_NEAREST)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
                            GL_NEAREST)
            glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, w, h, 0, GL_RGB,
                         GL_UNSIGNED_BYTE, 0)
            self.current_mode = GLClientWindow.MODE_RGB
        log("Updating RGB texture")
        glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width, height,
                        GL_RGB, GL_UNSIGNED_BYTE, img_data)
        drawable.gl_end()
        self.render_image()
Exemplo n.º 4
0
    def update_planar_textures(self, x, y, width, height, img, pixel_format, scaling=False):
        assert self.textures is not None, "no OpenGL textures!"
        log("%s.update_planar_textures%s", self, (x, y, width, height, img, pixel_format))

        divs = get_subsampling_divs(pixel_format)
        if self.pixel_format is None or self.pixel_format!=pixel_format or self.texture_size!=(width, height):
            self.pixel_format = pixel_format
            self.texture_size = (width, height)
            self.gl_marker("Creating new planar textures, pixel format %s", pixel_format)
            # Create textures of the same size as the window's
            empty_buf = b"\0"*(width*height)
            pixel_data = self.pixels_for_upload(empty_buf)[1]

            for texture, index in ((GL_TEXTURE0, TEX_Y), (GL_TEXTURE1, TEX_U), (GL_TEXTURE2, TEX_V)):
                (div_w, div_h) = divs[index]
                glActiveTexture(texture)
                target = GL_TEXTURE_RECTANGLE_ARB
                glBindTexture(target, self.textures[index])
                mag_filter = GL_NEAREST
                if scaling or (div_w > 1 or div_h > 1):
                    mag_filter = GL_LINEAR
                glTexParameteri(target, GL_TEXTURE_MAG_FILTER, mag_filter)
                glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
                set_texture_level()
                glTexImage2D(target, 0, GL_LUMINANCE, width//div_w, height//div_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixel_data)
                #glBindTexture(target, 0)        #redundant: we rebind below:

        self.gl_marker("updating planar textures: %sx%s %s", width, height, pixel_format)
        rowstrides = img.get_rowstride()
        img_data = img.get_pixels()
        assert len(rowstrides)==3 and len(img_data)==3
        for texture, index, tex_name in (
            (GL_TEXTURE0, TEX_Y, "Y"),
            (GL_TEXTURE1, TEX_U, "U"),
            (GL_TEXTURE2, TEX_V, "V"),
            ):
            div_w, div_h = divs[index]
            w = width//div_w
            h = height//div_h
            if w==0 or h==0:
                log.error("Error: zero dimension %ix%i for %s planar texture %s", w, h, pixel_format, tex_name)
                log.error(" screen update %s dropped", (x, y, width, height))
                continue
            glActiveTexture(texture)

            target = GL_TEXTURE_RECTANGLE_ARB
            glBindTexture(target, self.textures[index])
            self.set_alignment(w, rowstrides[index], tex_name)
            upload, pixel_data = self.pixels_for_upload(img_data[index])
            log("texture %s: div=%s, rowstride=%s, %sx%s, data=%s bytes, upload=%s",
                index, divs[index], rowstrides[index], w, h, len(pixel_data), upload)
            glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0)
            try:
                glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, 0)
            except:
                pass
            glTexSubImage2D(target, 0, 0, 0, w, h, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixel_data)
            glBindTexture(target, 0)
Exemplo n.º 5
0
    def update_planar_textures(self,
                               x,
                               y,
                               width,
                               height,
                               img,
                               pixel_format,
                               scaling=False):
        assert self.textures is not None, "no OpenGL textures!"
        log("%s.update_planar_textures%s", self,
            (x, y, width, height, img, pixel_format))

        divs = get_subsampling_divs(pixel_format)
        if self.pixel_format is None or self.pixel_format != pixel_format or self.texture_size != (
                width, height):
            self.pixel_format = pixel_format
            self.texture_size = (width, height)
            self.gl_marker("Creating new planar textures, pixel format %s" %
                           pixel_format)
            # Create textures of the same size as the window's
            glEnable(GL_TEXTURE_RECTANGLE_ARB)

            for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1),
                                   (GL_TEXTURE2, 2)):
                (div_w, div_h) = divs[index]
                glActiveTexture(texture)
                glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index])
                glEnable(GL_TEXTURE_RECTANGLE_ARB)
                mag_filter = GL_NEAREST
                if scaling or (div_w > 1 or div_h > 1):
                    mag_filter = GL_LINEAR
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
                                GL_TEXTURE_MAG_FILTER, mag_filter)
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
                                GL_TEXTURE_MIN_FILTER, GL_NEAREST)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)
                glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
                             width / div_w, height / div_h, 0, GL_LUMINANCE,
                             GL_UNSIGNED_BYTE, None)

        self.gl_marker("updating planar textures: %sx%s %s" %
                       (width, height, pixel_format))
        rowstrides = img.get_rowstride()
        img_data = img.get_pixels()
        assert len(rowstrides) == 3 and len(img_data) == 3
        for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1),
                               (GL_TEXTURE2, 2)):
            (div_w, div_h) = divs[index]
            glActiveTexture(texture)
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index])
            glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[index])
            pixel_data = img_data[index]
            log("texture %s: div=%s, rowstride=%s, %sx%s, data=%s bytes",
                index, divs[index], rowstrides[index], width / div_w,
                height / div_h, len(pixel_data))
            glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width / div_w,
                            height / div_h, GL_LUMINANCE, GL_UNSIGNED_BYTE,
                            pixel_data)
Exemplo n.º 6
0
    def update_texture_yuv(self, img_data, x, y, width, height, rowstrides, pixel_format):
        assert x==0 and y==0
        assert self.textures is not None, "no OpenGL textures!"

        if self.pixel_format is None or self.pixel_format!=pixel_format or self.texture_size!=(width, height):
            self.pixel_format = pixel_format
            self.texture_size = (width, height)
            divs = get_subsampling_divs(pixel_format)
            debug("GL creating new YUV textures for pixel format %s using divs=%s", pixel_format, divs)
            self.gl_marker("Creating new YUV textures")
            # Create textures of the same size as the window's
            glEnable(GL_TEXTURE_RECTANGLE_ARB)

            for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)):
                (div_w, div_h) = divs[index]
                glActiveTexture(texture)
                glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index])
                glEnable(GL_TEXTURE_RECTANGLE_ARB)
                mag_filter = GL_NEAREST
                if div_w > 1 or div_h > 1:
                    mag_filter = GL_LINEAR
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, mag_filter)
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
                glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, width/div_w, height/div_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0)

            debug("Assigning fragment program")
            glEnable(GL_FRAGMENT_PROGRAM_ARB)
            if not self.yuv_shader:
                self.yuv_shader = [ 1 ]
                glGenProgramsARB(1, self.yuv_shader)
                glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv_shader[0])
                prog = GL_COLORSPACE_CONVERSIONS
                glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, len(prog), prog)
                err = glGetString(GL_PROGRAM_ERROR_STRING_ARB)
                if err:
                    #FIXME: maybe we should do something else here?
                    log.error(err)

        self.gl_marker("Updating YUV textures")
        divs = get_subsampling_divs(pixel_format)
        U_width = 0
        U_height = 0
        for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)):
            (div_w, div_h) = divs[index]
            glActiveTexture(texture)
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index])
            glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[index])
            glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width/div_w, height/div_h, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[index])
            if index == 1:
                U_width = width/div_w
                U_height = height/div_h
            elif index == 2:
                if width/div_w != U_width:
                    log.error("Width of V plane is %d, differs from width of corresponding U plane (%d), pixel_format is %d", width/div_w, U_width, pixel_format)
                if height/div_h != U_height:
                    log.error("Height of V plane is %d, differs from height of corresponding U plane (%d)", height/div_h, U_height)
Exemplo n.º 7
0
    def refresh(self):
        img = self.textureData
        mi, ma = self.histogramScale
        pic_ny, pic_nx = img.shape
        if img.dtype.type in (numpy.float64, numpy.int32, numpy.uint32):
            data = img.astype(numpy.float32)
            imgString = data.tostring()
            imgType = numpy.float32
        else:
            imgString = img.tostring()
            imgType = img.dtype.type

        # maxUShort: value that represents "maximum color" - i.e. white
        if img.dtype.type == numpy.uint16:
            maxUShort = (1 << 16) - 1
        elif img.dtype.type == numpy.int16:
            maxUShort = (1 << 15) - 1
        elif img.dtype.type == numpy.uint8:
            maxUShort = (1 << 8) - 1
        else:
            maxUShort = 1

        mmrange = float(ma) - float(mi)
        fBias = -float(mi) / mmrange
        f = maxUShort / mmrange

        glBindTexture(GL_TEXTURE_2D, self.texture)
        glPixelTransferf(GL_RED_SCALE, f)
        glPixelTransferf(GL_GREEN_SCALE, f)
        glPixelTransferf(GL_BLUE_SCALE, f)

        glPixelTransferf(GL_RED_BIAS, fBias)
        glPixelTransferf(GL_GREEN_BIAS, fBias)
        glPixelTransferf(GL_BLUE_BIAS, fBias)

        glPixelTransferi(GL_MAP_COLOR, False)

        if img.dtype.type in (numpy.float64, numpy.int32, numpy.uint32,
                              numpy.complex64, numpy.complex128):
            itSize = 4
            glPixelStorei(GL_UNPACK_SWAP_BYTES,
                          False)  # create native float32 copy - see below
        else:
            itSize = img.itemsize
            glPixelStorei(GL_UNPACK_SWAP_BYTES, not img.dtype.isnative)

        glPixelStorei(GL_UNPACK_ALIGNMENT, itSize)

        if imgType not in dtypeToGlTypeMap:
            raise ValueError("Unsupported data mode %s" % str(imgType))
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pic_nx, pic_ny, GL_LUMINANCE,
                        dtypeToGlTypeMap[imgType], imgString)
Exemplo n.º 8
0
    def update_texture_yuv(self, img_data, x, y, width, height, rowstrides, pixel_format):
        window_width, window_height = self.size
        assert self.textures is not None, "no OpenGL textures!"

        if self.pixel_format is None or self.pixel_format!=pixel_format:
            self.pixel_format = pixel_format
            divs = self.get_subsampling_divs(pixel_format)
            log("GL creating new YUV textures for pixel format %s using divs=%s", pixel_format, divs)
            # Create textures of the same size as the window's
            glEnable(GL_TEXTURE_RECTANGLE_ARB)

            for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)):
                div = divs[index]
                glActiveTexture(texture)
                glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index])
                glEnable(GL_TEXTURE_RECTANGLE_ARB)
                mag_filter = GL_NEAREST
                if div>1:
                    mag_filter = GL_LINEAR
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, mag_filter)
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
                glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, window_width/div, window_height/div, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0)

            log("Assigning fragment program")
            glEnable(GL_FRAGMENT_PROGRAM_ARB)
            if not self.yuv_shader:
                self.yuv_shader = [ 1 ]
                glGenProgramsARB(1, self.yuv_shader)
                glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv_shader[0])
                prog = GL_COLORSPACE_CONVERSIONS
                glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, len(prog), prog)
                err = glGetString(GL_PROGRAM_ERROR_STRING_ARB)
                if err:
                    #FIXME: maybe we should do something else here?
                    log.error(err)
                glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv_shader[0])

        # Clamp width and height to the actual texture size
        if x + width > window_width:
            width = window_width - x
        if y + height > window_height:
            height = window_height - y

        divs = self.get_subsampling_divs(pixel_format)
        for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)):
            div = divs[index]
            glActiveTexture(texture)
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index])
            glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[index])
            glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width/div, height/div, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[index])
        glFlush()
Exemplo n.º 9
0
    def update_planar_textures(self, x, y, width, height, img, pixel_format, scaling=False):
        assert x==0 and y==0
        assert self.textures is not None, "no OpenGL textures!"
        debug("%s.update_planar_textures%s", self, (x, y, width, height, img, pixel_format))

        divs = get_subsampling_divs(pixel_format)
        if self.pixel_format is None or self.pixel_format!=pixel_format or self.texture_size!=(width, height):
            self.pixel_format = pixel_format
            self.texture_size = (width, height)
            self.gl_marker("Creating new planar textures, pixel format %s" % pixel_format)
            # Create textures of the same size as the window's
            glEnable(GL_TEXTURE_RECTANGLE_ARB)

            for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)):
                (div_w, div_h) = divs[index]
                glActiveTexture(texture)
                glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index])
                glEnable(GL_TEXTURE_RECTANGLE_ARB)
                mag_filter = GL_NEAREST
                if scaling or (div_w > 1 or div_h > 1):
                    mag_filter = GL_LINEAR
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, mag_filter)
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)
                glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, width/div_w, height/div_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, None)


        self.gl_marker("updating planar textures: %sx%s %s" % (width, height, pixel_format))
        U_width = 0
        U_height = 0
        rowstrides = img.get_rowstride()
        img_data = img.get_pixels()
        assert len(rowstrides)==3
        assert len(img_data)==3
        for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)):
            (div_w, div_h) = divs[index]
            glActiveTexture(texture)
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index])
            glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[index])
            pixel_data = img_data[index][:]
            debug("texture %s: div=%s, rowstride=%s, %sx%s, data=%s bytes", index, divs[index], rowstrides[index], width/div_w, height/div_h, len(pixel_data))
            glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width/div_w, height/div_h, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixel_data)
            if index == 1:
                U_width = width/div_w
                U_height = height/div_h
            elif index == 2:
                if width/div_w != U_width:
                    log.error("Width of V plane is %d, differs from width of corresponding U plane (%d), pixel_format is %d", width/div_w, U_width, pixel_format)
                if height/div_h != U_height:
                    log.error("Height of V plane is %d, differs from height of corresponding U plane (%d), pixel_format is %d", height/div_h, U_height, pixel_format)
Exemplo n.º 10
0
    def from_matrix(cls, matrix):
        """Creates a texture from given matrix file.

        :param matrix: The matrix.
        :type matrix: list

        :returns: The texture instance.
        :rtype: :class:`renderer.Texture`
        """
        w, h = len(matrix[0]), len(matrix)

        grid = bytes(chain.from_iterable(reversed(matrix)))

        tex = glGenTextures(1)
        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_2D, tex)

        # This code is necessary to handle non-power-of-two textures with small
        # sizes.
        # TODO: refactor this
        param_ids = [
            GL_UNPACK_ALIGNMENT,
            GL_UNPACK_ROW_LENGTH,
            GL_UNPACK_SKIP_ROWS,
            GL_UNPACK_SKIP_PIXELS,
        ]
        old_params = {
            p: glGetInteger(p)
            for p in param_ids
        }

        glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)
        glPixelStorei(GL_UNPACK_SKIP_ROWS, 0)
        glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0)
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_R8, w, h)
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RED, GL_UNSIGNED_BYTE, grid)

        for p, v in old_params.items():
            glPixelStorei(p, v)

        glBindTexture(GL_TEXTURE_2D, 0)

        return Texture(tex, w, h, GL_TEXTURE_2D)
Exemplo n.º 11
0
    def render_to_texture(self, text):
        """Renders the given string to a texture object.

        :param text: Text to render.
        :type text: str

        :returns: The resulting texture object.
        :rtype: :class:`renderer.Texture`
        """
        # render the text to a SDL_Surface structure
        surf_ptr = ttf.TTF_RenderText_Solid(
            self.font,
            text.encode('utf8'),
            sdl.SDL_Color())
        if not surf_ptr:
            raise SDLError('failed to render text to surface: {}'.format(
                ttf.TTF_GetError()))

        # retrieve a pointer to pixel data
        surf = surf_ptr.contents
        pixels = ctypes.cast(surf.pixels, ctypes.POINTER(ctypes.c_char))

        # create and fill an OpenGL rectangle texture (that is, a texture which
        # can have arbitrary non-power-of-two size and is accessed using
        # UV coordinates which are linearly mapped to the texture size)
        tex = glGenTextures(1)
        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_2D, tex)
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_R8, surf.w, surf.h)
        glTexSubImage2D(
            GL_TEXTURE_2D,
            0,
            0,
            0,
            surf.w,
            surf.h,
            GL_RED,
            GL_UNSIGNED_BYTE,
            pixels)
        glBindTexture(GL_TEXTURE_2D, 0)

        sdl.SDL_FreeSurface(surf_ptr)

        return Texture(tex, surf.w, surf.h, GL_TEXTURE_2D)
Exemplo n.º 12
0
    def blit_buffer(self,
                    buffer,
                    size=None,
                    mode='RGB',
                    format=None,
                    pos=(0, 0),
                    buffertype=GL_UNSIGNED_BYTE):
        '''Blit a buffer into a texture.

        :Parameters:
            `buffer` : str
                Image data
            `size` : tuple, default to texture size
                Size of the image (width, height)
            `mode` : str, default to 'RGB'
                Image mode, can be one of RGB, RGBA, BGR, BGRA
            `format` : glconst, default to None
                if format is passed, it will be used instead of mode
            `pos` : tuple, default to (0, 0)
                Position to blit in the texture
            `buffertype` : glglconst, default to GL_UNSIGNED_BYTE
                Type of the data buffer
        '''
        if size is None:
            size = self.size
        if format is None:
            format = self.mode_to_gl_format(mode)
        target = self.target
        glBindTexture(target, self.id)
        glEnable(target)

        # activate 1 alignement, of window failed on updating weird size
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1)

        # need conversion ?
        pdata, format = self._convert_buffer(buffer, format)

        # transfer the new part of texture
        glTexSubImage2D(target, 0, pos[0], pos[1], size[0], size[1], format,
                        buffertype, pdata)

        glFlush()
        glDisable(target)
Exemplo n.º 13
0
    def from_image(cls, image):
        """Creates a texture from given image file.

        :param image: Image.
        :type image: :class:`PIL.Image`

        :returns: The texture instance.
        :rtype: :class:`renderer.Texture`
        """
        w, h = image.size

        tex = glGenTextures(1)
        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_2D, tex)
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, w, h)
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, image.tobytes())
        glBindTexture(GL_TEXTURE_2D, 0)

        return Texture(tex, w, h)
Exemplo n.º 14
0
    def update_planar_textures(self, x, y, width, height, img, pixel_format, scaling=False):
        assert self.textures is not None, "no OpenGL textures!"
        log("%s.update_planar_textures%s", self, (x, y, width, height, img, pixel_format))

        divs = get_subsampling_divs(pixel_format)
        if self.pixel_format is None or self.pixel_format!=pixel_format or self.texture_size!=(width, height):
            self.pixel_format = pixel_format
            self.texture_size = (width, height)
            self.gl_marker("Creating new planar textures, pixel format %s", pixel_format)
            # Create textures of the same size as the window's
            glEnable(GL_TEXTURE_RECTANGLE_ARB)

            for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)):
                (div_w, div_h) = divs[index]
                glActiveTexture(texture)
                glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index])
                glEnable(GL_TEXTURE_RECTANGLE_ARB)
                mag_filter = GL_NEAREST
                if scaling or (div_w > 1 or div_h > 1):
                    mag_filter = GL_LINEAR
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, mag_filter)
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
                set_texture_level()
                glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, width//div_w, height//div_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, None)

        self.gl_marker("updating planar textures: %sx%s %s", width, height, pixel_format)
        rowstrides = img.get_rowstride()
        img_data = img.get_pixels()
        assert len(rowstrides)==3 and len(img_data)==3
        for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)):
            (div_w, div_h) = divs[index]
            glActiveTexture(texture)
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index])
            glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[index])
            upload, pixel_data = self.pixels_for_upload(img_data[index])
            log("texture %s: div=%s, rowstride=%s, %sx%s, data=%s bytes, upload=%s", index, divs[index], rowstrides[index], width//div_w, height//div_h, len(pixel_data), upload)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_BASE_LEVEL, 0)
            try:
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAX_LEVEL, 0)
            except:
                pass
            glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width//div_w, height//div_h, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixel_data)
Exemplo n.º 15
0
    def _do_paint_rgb24(self, img_data, x, y, w, h, rowstride, options,
                        callbacks):
        log("do_paint_rgb24(%s bytes, %s, %s, %s, %s, %s, %s, %s)",
            len(img_data), x, y, w, h, rowstride, options, callbacks)
        ww, wh = self.size
        if x + w > ww or y + h > wh:
            log("do_paint_rgb24: ignoring paint which would overflow the backing area"
                )
            return
        drawable = self.gl_init()
        if not drawable:
            log("do_paint_rgb24: cannot paint yet..")
            return
        try:
            #cleanup if we were doing yuv previously:
            if self.pixel_format != GLPixmapBacking.RGB24:
                self.remove_shader()
                self.pixel_format = GLPixmapBacking.RGB24

            glEnable(GL_TEXTURE_RECTANGLE_ARB)
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[0])
            glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstride / 3)
            for texture in (GL_TEXTURE1, GL_TEXTURE2):
                glActiveTexture(texture)
                glDisable(GL_TEXTURE_RECTANGLE_ARB)

            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
                            GL_NEAREST)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
                            GL_NEAREST)
            glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, w, h, GL_RGB,
                            GL_UNSIGNED_BYTE, img_data)

            glBegin(GL_QUADS)
            for rx, ry in ((x, y), (x, y + h), (x + w, y + h), (x + w, y)):
                glTexCoord2i(rx, ry)
                glVertex2i(rx, ry)
            glEnd()
        finally:
            self.gl_end(drawable)
Exemplo n.º 16
0
    def blit_buffer(self, buffer, size=None, mode='RGB', format=None,
                    pos=(0, 0), buffertype=GL_UNSIGNED_BYTE):
        '''Blit a buffer into a texture.

        :Parameters:
            `buffer` : str
                Image data
            `size` : tuple, default to texture size
                Size of the image (width, height)
            `mode` : str, default to 'RGB'
                Image mode, can be one of RGB, RGBA, BGR, BGRA
            `format` : glconst, default to None
                if format is passed, it will be used instead of mode
            `pos` : tuple, default to (0, 0)
                Position to blit in the texture
            `buffertype` : glglconst, default to GL_UNSIGNED_BYTE
                Type of the data buffer
        '''
        if size is None:
            size = self.size
        if format is None:
            format = self.mode_to_gl_format(mode)
        target = self.target
        glBindTexture(target, self.id)
        glEnable(target)

        # activate 1 alignement, of window failed on updating weird size
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1)

        # need conversion ?
        pdata, format = self._convert_buffer(buffer, format)

        # transfer the new part of texture
        glTexSubImage2D(target, 0, pos[0], pos[1],
                        size[0], size[1], format,
                        buffertype, pdata)

        glFlush()
        glDisable(target)
Exemplo n.º 17
0
    def update(self, pil_image: Image.Image):
        """Update the texture to contain the provided image.

        :param pil_image: The image to write into the texture.
        """
        # Ensure the image is in RGBA format and convert to the raw RGBA bytes.
        image_width, image_height = pil_image.size
        image = pil_image.convert("RGBA").tobytes("raw", "RGBA")

        # Bind the texture so that it can be modified.
        self.bind()
        if (self._width == image_width) and (self._height == image_height):
            # Same size - just need to update the texels.
            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width, image_height,
                            GL_RGBA, GL_UNSIGNED_BYTE, image)
        else:
            # Different size than the last frame (e.g. the Window is resizing)
            # Create a new texture of the correct size.
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_width, image_height,
                         0, GL_RGBA, GL_UNSIGNED_BYTE, image)

        self._width = image_width
        self._height = image_height
Exemplo n.º 18
0
    def setupTransforms(self, transforms):
        # note: this is only called from test_drawing.py (as of before 090302)
        """
        Fill a block of transforms.

        Depending on the setting of TEXTURE_XFORMS and UNIFORM_XFORMS, the
        transforms are either in texture memory, or in a uniform array of mat4s
        ("constant memory"), or unsupported (error if we need any here).

        @param transforms: A list of transform matrices, where each transform is
            a flattened list (or Numpy array) of 16 numbers.
        """
        self.n_transforms = nTransforms = len(transforms)

        if not self.supports_transforms():
            assert not nTransforms, "%r doesn't support transforms" % self
            return

        self.setActive(True)                # Must activate before setting uniforms.

        assert self._has_uniform("n_transforms") # redundant with following
        glUniform1iARB(self._uniform("n_transforms"), self.n_transforms)

        # The shader bypasses transform logic if n_transforms is 0.
        # (Then location coordinates are in global modeling coordinates.)
        if nTransforms > 0:
            if UNIFORM_XFORMS:
                # Load into constant memory.  The GL_EXT_bindable_uniform
                # extension supports sharing this array of mat4s through a VBO.
                # XXX Need to bank-switch this data if more than N_CONST_XFORMS.
                C_transforms = numpy.array(transforms, dtype = numpy.float32)
                glUniformMatrix4fvARB(self._uniform("transforms"),
                                      # Don't over-run the array size.
                                      min(len(transforms), N_CONST_XFORMS),
                                      GL_TRUE, # Transpose.
                                      C_transforms)
            elif TEXTURE_XFORMS:
                # Generate a texture ID and bind the texture unit to it.
                self.transform_memory = glGenTextures(1)
                glBindTexture(GL_TEXTURE_2D, self.transform_memory)
                ## These seem to have no effect with a vertex shader.
                ## glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
                ## glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
                # XXX Needed? glEnable(GL_TEXTURE_2D)

                # Load the transform data into the texture.
                #
                # Problem: SIGSEGV kills Python in gleTextureImagePut under
                # glTexImage2D with more than 250 transforms (16,000 bytes.)
                # Maybe there's a 16-bit signed size calculation underthere, that's
                # overflowing the sign bit... Work around by sending transforms to
                # the texture unit in batches with glTexSubImage2D.)
                glTexImage2D(GL_TEXTURE_2D, 0, # Level zero - base image, no mipmap.
                             GL_RGBA32F_ARB,   # Internal format is floating point.
                             # Column major storage: width = N, height = 4 * RGBA.
                             nTransforms, 4 * 4, 0, # No border.
                             # Data format and type, null pointer to allocate space.
                             GL_RGBA, GL_FLOAT, None)
                # XXX Split this off into a setTransforms method.
                batchSize = 250
                nBatches = (nTransforms + batchSize-1) / batchSize
                for i in range(nBatches):
                    xStart = batchSize * i
                    xEnd = min(nTransforms, xStart + batchSize)
                    xSize = xEnd - xStart
                    glTexSubImage2D(GL_TEXTURE_2D, 0,
                                    # Subimage x and y offsets and sizes.
                                    xStart, 0, xSize, 4 * 4,
                                    # List of matrices is flattened into a sequence.
                                    GL_RGBA, GL_FLOAT, transforms[xStart:xEnd])
                    continue
                # Read back to check proper loading.
                if CHECK_TEXTURE_XFORM_LOADING:
                    mats = glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT)
                    nMats = len(mats)
                    print "setupTransforms\n[[",
                    for i in range(nMats):
                        nElts = len(mats[i])
                        perLine = 8
                        nLines = (nElts + perLine-1) / perLine
                        for line in range(nLines):
                            jStart = perLine * line
                            jEnd = min(nElts, jStart + perLine)
                            for j in range(jStart, jEnd):
                                print "%.2f" % mats[i][j],
                                continue
                            if line < nLines-1:
                                print "\n  ",
                                pass
                        if i < nMats-1:
                            print "]\n [",
                            pass
                        continue
                    print "]]"
                pass
            else:
                # should never happen if SUPPORTS_XFORMS is defined correctly
                assert 0, "can't setupTransforms unless UNIFORM_XFORMS or TEXTURE_XFORMS is set"
            pass
        self.setActive(False)                # Deactivate again.
        return
Exemplo n.º 19
0
    def update_texture_yuv(self, img_data, x, y, width, height, rowstrides,
                           pixel_format):
        window_width, window_height = self.size
        assert self.textures is not None, "no OpenGL textures!"

        if self.pixel_format is None or self.pixel_format != pixel_format:
            self.pixel_format = pixel_format
            divs = self.get_subsampling_divs(pixel_format)
            log(
                "GL creating new YUV textures for pixel format %s using divs=%s",
                pixel_format, divs)
            # Create textures of the same size as the window's
            glEnable(GL_TEXTURE_RECTANGLE_ARB)

            for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1),
                                   (GL_TEXTURE2, 2)):
                div = divs[index]
                glActiveTexture(texture)
                glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index])
                glEnable(GL_TEXTURE_RECTANGLE_ARB)
                mag_filter = GL_NEAREST
                if div > 1:
                    mag_filter = GL_LINEAR
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
                                GL_TEXTURE_MAG_FILTER, mag_filter)
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
                                GL_TEXTURE_MIN_FILTER, GL_NEAREST)
                glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
                             window_width / div, window_height / div, 0,
                             GL_LUMINANCE, GL_UNSIGNED_BYTE, 0)

            log("Assigning fragment program")
            glEnable(GL_FRAGMENT_PROGRAM_ARB)
            if not self.yuv_shader:
                self.yuv_shader = [1]
                glGenProgramsARB(1, self.yuv_shader)
                glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv_shader[0])
                prog = GL_COLORSPACE_CONVERSIONS
                glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB,
                                   GL_PROGRAM_FORMAT_ASCII_ARB, len(prog),
                                   prog)
                err = glGetString(GL_PROGRAM_ERROR_STRING_ARB)
                if err:
                    #FIXME: maybe we should do something else here?
                    log.error(err)
                glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv_shader[0])

        # Clamp width and height to the actual texture size
        if x + width > window_width:
            width = window_width - x
        if y + height > window_height:
            height = window_height - y

        divs = self.get_subsampling_divs(pixel_format)
        for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1),
                               (GL_TEXTURE2, 2)):
            div = divs[index]
            glActiveTexture(texture)
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index])
            glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[index])
            glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width / div,
                            height / div, GL_LUMINANCE, GL_UNSIGNED_BYTE,
                            img_data[index])
        glFlush()
Exemplo n.º 20
0
    def update_texture_yuv420(self, img_data, x, y, width, height, rowstrides):
        drawable = self.glarea.get_gl_drawable()
        context = self.glarea.get_gl_context()
        window_width, window_height = self.get_size()
        if not drawable.gl_begin(context):
            raise Exception("** Cannot create OpenGL rendering context!")
        assert self.textures is not None

        if self.current_mode == GLClientWindow.MODE_RGB:
            raise Exception("** RGB -> YUV mode change unimplemented!")
        elif self.current_mode == GLClientWindow.MODE_UNINITIALIZED:
            log("Creating new YUV textures")

            # Create textures of the same size as the window's
            glEnable(GL_TEXTURE_RECTANGLE_ARB)
            glActiveTexture(GL_TEXTURE0)
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[0])
            glEnable(GL_TEXTURE_RECTANGLE_ARB)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
                            GL_NEAREST)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
                            GL_NEAREST)
            glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
                         window_width, window_height, 0, GL_LUMINANCE,
                         GL_UNSIGNED_BYTE, 0)

            glActiveTexture(GL_TEXTURE1)
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[1])
            glEnable(GL_TEXTURE_RECTANGLE_ARB)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
                            GL_LINEAR)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
                            GL_NEAREST)
            glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
                         window_width / 2, window_height / 2, 0, GL_LUMINANCE,
                         GL_UNSIGNED_BYTE, 0)

            glActiveTexture(GL_TEXTURE2)
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[2])
            glEnable(GL_TEXTURE_RECTANGLE_ARB)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
                            GL_LINEAR)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
                            GL_NEAREST)
            glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
                         window_width / 2, window_height / 2, 0, GL_LUMINANCE,
                         GL_UNSIGNED_BYTE, 0)

            log("Assigning fragment program")
            glEnable(GL_FRAGMENT_PROGRAM_ARB)
            if not self.yuv420_shader:
                self.yuv420_shader = [1]
                glGenProgramsARB(1, self.yuv420_shader)
                glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB,
                                 self.yuv420_shader[0])
                prog = GL_COLORSPACE_CONVERSIONS
                glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB,
                                   GL_PROGRAM_FORMAT_ASCII_ARB, len(prog),
                                   prog)
                log.error(glGetString(GL_PROGRAM_ERROR_STRING_ARB))
                glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB,
                                 self.yuv420_shader[0])

            self.current_mode = GLClientWindow.MODE_YUV

        # Clamp width and height to the actual texture size
        if x + width > window_width:
            width = window_width - x
        if y + height > window_height:
            height = window_height - y

        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[0])
        glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[0])
        glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width, height,
                        GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[0])

        glActiveTexture(GL_TEXTURE1)
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[1])
        glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[1])
        glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width / 2,
                        height / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE,
                        img_data[1])

        glActiveTexture(GL_TEXTURE2)
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[2])
        glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[2])
        glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width / 2,
                        height / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE,
                        img_data[2])

        drawable.gl_end()
        self.render_image()
Exemplo n.º 21
0
    def setupTransforms(self, transforms):
        # note: this is only called from test_drawing.py (as of before 090302)
        """
        Fill a block of transforms.

        Depending on the setting of TEXTURE_XFORMS and UNIFORM_XFORMS, the
        transforms are either in texture memory, or in a uniform array of mat4s
        ("constant memory"), or unsupported (error if we need any here).

        @param transforms: A list of transform matrices, where each transform is
            a flattened list (or Numpy array) of 16 numbers.
        """
        self.n_transforms = nTransforms = len(transforms)

        if not self.supports_transforms():
            assert not nTransforms, "%r doesn't support transforms" % self
            return
        
        self.setActive(True)                # Must activate before setting uniforms.
        
        assert self._has_uniform("n_transforms") # redundant with following
        glUniform1iARB(self._uniform("n_transforms"), self.n_transforms)

        # The shader bypasses transform logic if n_transforms is 0.
        # (Then location coordinates are in global modeling coordinates.)
        if nTransforms > 0:
            if UNIFORM_XFORMS:
                # Load into constant memory.  The GL_EXT_bindable_uniform
                # extension supports sharing this array of mat4s through a VBO.
                # XXX Need to bank-switch this data if more than N_CONST_XFORMS.
                C_transforms = numpy.array(transforms, dtype = numpy.float32)
                glUniformMatrix4fvARB(self._uniform("transforms"),
                                      # Don't over-run the array size.
                                      min(len(transforms), N_CONST_XFORMS),
                                      GL_TRUE, # Transpose.
                                      C_transforms)
            elif TEXTURE_XFORMS:
                # Generate a texture ID and bind the texture unit to it.
                self.transform_memory = glGenTextures(1)
                glBindTexture(GL_TEXTURE_2D, self.transform_memory)
                ## These seem to have no effect with a vertex shader.
                ## glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
                ## glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
                # XXX Needed? glEnable(GL_TEXTURE_2D)

                # Load the transform data into the texture.
                #
                # Problem: SIGSEGV kills Python in gleTextureImagePut under
                # glTexImage2D with more than 250 transforms (16,000 bytes.)
                # Maybe there's a 16-bit signed size calculation underthere, that's
                # overflowing the sign bit... Work around by sending transforms to
                # the texture unit in batches with glTexSubImage2D.)
                glTexImage2D(GL_TEXTURE_2D, 0, # Level zero - base image, no mipmap.
                             GL_RGBA32F_ARB,   # Internal format is floating point.
                             # Column major storage: width = N, height = 4 * RGBA.
                             nTransforms, 4 * 4, 0, # No border.
                             # Data format and type, null pointer to allocate space.
                             GL_RGBA, GL_FLOAT, None)
                # XXX Split this off into a setTransforms method.
                batchSize = 250
                nBatches = (nTransforms + batchSize-1) / batchSize
                for i in range(nBatches):
                    xStart = batchSize * i
                    xEnd = min(nTransforms, xStart + batchSize)
                    xSize = xEnd - xStart
                    glTexSubImage2D(GL_TEXTURE_2D, 0,
                                    # Subimage x and y offsets and sizes.
                                    xStart, 0, xSize, 4 * 4,
                                    # List of matrices is flattened into a sequence.
                                    GL_RGBA, GL_FLOAT, transforms[xStart:xEnd])
                    continue
                # Read back to check proper loading.
                if CHECK_TEXTURE_XFORM_LOADING:
                    mats = glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT)
                    nMats = len(mats)
                    print "setupTransforms\n[[",
                    for i in range(nMats):
                        nElts = len(mats[i])
                        perLine = 8
                        nLines = (nElts + perLine-1) / perLine
                        for line in range(nLines):
                            jStart = perLine * line
                            jEnd = min(nElts, jStart + perLine)
                            for j in range(jStart, jEnd):
                                print "%.2f" % mats[i][j],
                                continue
                            if line < nLines-1:
                                print "\n  ",
                                pass
                        if i < nMats-1:
                            print "]\n [",
                            pass
                        continue
                    print "]]"
                pass
            else:
                # should never happen if SUPPORTS_XFORMS is defined correctly
                assert 0, "can't setupTransforms unless UNIFORM_XFORMS or TEXTURE_XFORMS is set"
            pass
        self.setActive(False)                # Deactivate again.
        return
Exemplo n.º 22
0
    def update_texture_yuv420(self, img_data, x, y, width, height, rowstrides):
        drawable = self.glarea.get_gl_drawable()
        context = self.glarea.get_gl_context()
        window_width, window_height = self.get_size()
        if not drawable.gl_begin(context):
            raise Exception("** Cannot create OpenGL rendering context!")
        assert self.textures is not None

        if self.current_mode == GLClientWindow.MODE_RGB:
            raise Exception("** RGB -> YUV mode change unimplemented!")
        elif self.current_mode == GLClientWindow.MODE_UNINITIALIZED:
            log("Creating new YUV textures")

            # Create textures of the same size as the window's
            glEnable(GL_TEXTURE_RECTANGLE_ARB)
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[0])
            glEnable(GL_TEXTURE_RECTANGLE_ARB)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, window_width, window_height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);

            glActiveTexture(GL_TEXTURE1);
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[1])
            glEnable(GL_TEXTURE_RECTANGLE_ARB)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, window_width/2, window_height/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);

            glActiveTexture(GL_TEXTURE2);
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[2])
            glEnable(GL_TEXTURE_RECTANGLE_ARB)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, window_width/2, window_height/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);

            log("Assigning fragment program")
            glEnable(GL_FRAGMENT_PROGRAM_ARB)
            if not self.yuv420_shader:
                self.yuv420_shader = [ 1 ]
                glGenProgramsARB(1, self.yuv420_shader)
                glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv420_shader[0])
                prog = GL_COLORSPACE_CONVERSIONS
                glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, len(prog), prog)
                log.error(glGetString(GL_PROGRAM_ERROR_STRING_ARB))
                glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv420_shader[0])

            self.current_mode = GLClientWindow.MODE_YUV

        # Clamp width and height to the actual texture size
        if x + width > window_width:
            width = window_width - x
        if y + height > window_height:
            height = window_height - y

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[0])
        glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[0])
        glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[0])

        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[1])
        glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[1])
        glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width/2, height/2, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[1])

        glActiveTexture(GL_TEXTURE2);
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[2])
        glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[2])
        glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width/2, height/2, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[2])

        drawable.gl_end()
        self.render_image()
Exemplo n.º 23
0
    def update_texture_yuv(self, img_data, x, y, width, height, rowstrides,
                           pixel_format):
        assert x == 0 and y == 0
        assert self.textures is not None, "no OpenGL textures!"

        if self.pixel_format is None or self.pixel_format != pixel_format or self.texture_size != (
                width, height):
            self.pixel_format = pixel_format
            self.texture_size = (width, height)
            divs = get_subsampling_divs(pixel_format)
            debug(
                "GL creating new YUV textures for pixel format %s using divs=%s",
                pixel_format, divs)
            self.gl_marker("Creating new YUV textures")
            # Create textures of the same size as the window's
            glEnable(GL_TEXTURE_RECTANGLE_ARB)

            for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1),
                                   (GL_TEXTURE2, 2)):
                (div_w, div_h) = divs[index]
                glActiveTexture(texture)
                glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index])
                glEnable(GL_TEXTURE_RECTANGLE_ARB)
                mag_filter = GL_NEAREST
                if div_w > 1 or div_h > 1:
                    mag_filter = GL_LINEAR
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
                                GL_TEXTURE_MAG_FILTER, mag_filter)
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
                                GL_TEXTURE_MIN_FILTER, GL_NEAREST)
                glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
                             width / div_w, height / div_h, 0, GL_LUMINANCE,
                             GL_UNSIGNED_BYTE, 0)

            debug("Assigning fragment program")
            glEnable(GL_FRAGMENT_PROGRAM_ARB)
            if not self.yuv_shader:
                self.yuv_shader = [1]
                glGenProgramsARB(1, self.yuv_shader)
                glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv_shader[0])
                prog = GL_COLORSPACE_CONVERSIONS
                glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB,
                                   GL_PROGRAM_FORMAT_ASCII_ARB, len(prog),
                                   prog)
                err = glGetString(GL_PROGRAM_ERROR_STRING_ARB)
                if err:
                    #FIXME: maybe we should do something else here?
                    log.error(err)

        self.gl_marker("Updating YUV textures")
        divs = get_subsampling_divs(pixel_format)
        U_width = 0
        U_height = 0
        for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1),
                               (GL_TEXTURE2, 2)):
            (div_w, div_h) = divs[index]
            glActiveTexture(texture)
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index])
            glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[index])
            glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width / div_w,
                            height / div_h, GL_LUMINANCE, GL_UNSIGNED_BYTE,
                            img_data[index])
            if index == 1:
                U_width = width / div_w
                U_height = height / div_h
            elif index == 2:
                if width / div_w != U_width:
                    log.error(
                        "Width of V plane is %d, differs from width of corresponding U plane (%d), pixel_format is %d",
                        width / div_w, U_width, pixel_format)
                if height / div_h != U_height:
                    log.error(
                        "Height of V plane is %d, differs from height of corresponding U plane (%d)",
                        height / div_h, U_height)
Exemplo n.º 24
0
	def setup(self):
		'''
		Construct the texture atlas for the font
		'''
		face = Face(self.filename)
		face.set_pixel_sizes(0, self.size)
	
		rowh, roww = 0,0
		
		# Determine image size
		for i in xrange(32,128):
			face.load_char( chr(i), FT_LOAD_RENDER)
			bitmap	= face.glyph.bitmap
			
			if roww + bitmap.width + 1 >= 1024: # max texture width
				self.w  = max(self.w, roww)
				self.h	+= rowh
				roww = 0
				rowh = 0
			roww += bitmap.width + 1
			rowh = max(rowh, bitmap.rows)
			
		self.w = max(self.w, roww)
		self.h += rowh
	
	
		## Create texture to hold ASCII glyphs
		
		# Ensure no texture is currently selected
		glActiveTexture(GL_TEXTURE0) 
		self.texid = glGenTextures(1)
		glBindTexture(GL_TEXTURE_2D, self.texid)
		
		glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, self.w, self.h, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0)
		
		# We require 1 byte alignment when uploading texture data
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
		
		# Clamping to edges is important to prevent artifacts when scaling
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
		
		# Linear filtering looks better for text
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
		
	
		# Add glyphs to texture
		ox = 0
		oy = 0
		rowh = 0
		
		# class to hold data
		class CharInfo:
			pass
		
		for i in xrange(32,128):
			face.load_char( chr(i), FT_LOAD_RENDER)
			g = face.glyph
			bitmap = g.bitmap
			
			if ox + bitmap.width + 1 >= 1024: # max texture width
				oy += rowh
				rowh = 0
				ox = 0		
			
			glTexSubImage2D(GL_TEXTURE_2D, 0, ox, oy, bitmap.width, bitmap.rows, GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.buffer)
			
			ci = CharInfo()
			ci.ax = float(g.advance.x >> 6)
			ci.ay = float(g.advance.y >> 6)
			
			ci.bw = float(bitmap.width)
			ci.bh = float(bitmap.rows)
			
			ci.bl = float(g.bitmap_left)
			ci.bt = float(g.bitmap_top)
			
			ci.tx = float(ox) / float(self.w)
			ci.ty = float(oy) / float(self.h)
			self.c[chr(i)] = ci
			
			rowh = max(rowh, bitmap.rows)
			ox += bitmap.width + 1