Пример #1
0
 def load_texture(path):
     import pygame
     #Cargo la imagen a memoria. pygame se hace cargo de decodificarla correctamente
     surf = pygame.image.load(path)
     surf = pygame.transform.flip(surf, False, True)
     #Obtengo la matriz de colores de la imagen en forma de un array binario
     #Le indico el formato en que quiero almacenar los datos (RGBA) y que invierta la matriz, para poder usarla correctamente con OpenGL
     image = pygame.image.tostring(surf, 'RGBA', 1)
     #Obentego las dimensiones de la imagen
     ix, iy = surf.get_rect().size
     #Creo una textura vacia en memoria de video, y me quedo con el identificador (texid) para poder referenciarla
     texid = glGenTextures(1)
     #Activo esta nueva textura para poder cargarle informacion
     glBindTexture(GL_TEXTURE_2D, texid)
     #Seteo los tipos de filtro a usar para agrandar y achivar la textura
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
     #Cargo la matriz de colores dentro de la textura
     #Los parametros que le paso son:
     # - Tipo de textura, en este caso GL_TEXTURE_2D
     # - Nivel de mipmap, en este caso 0 porque no estoy usando mas niveles
     # - Formato en que quiero almacenar los datos en memoria de video, GL_RGB en este caso, porque no necesito canal Alfa
     # - Ancho de la textura
     # - Alto de la textura
     # - Grosor en pixels del borde, en este caso 0 porque no quiero agregar borde a al imagen
     # - Formato de los datos de la imagen, en este caso GL_RGBA que es como lo leimos con pygame.image
     # - Formato de los canales de color, GL_UNSIGNED_BYTE quiere decir que son 8bits para cada canal
     # - La imagen, en este caso la matriz de colores que creamos con pygame.image.tostring
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
     #Una vez que tengo todo cargado, desactivo la textura para evitar que se dibuje por error mas adelante
     #Cada vez que quiera usarla, puedo hacer glBindTexture con el identificador (texid) que me guarde al crearla
     glBindTexture(GL_TEXTURE_2D, 0)
     #devuelvo el identificador de la textura para que pueda ser usada mas adelante
     return texid
Пример #2
0
    def parse_mtl(filename):
        contents = {}
        mtl = None
        for line in open(filename, "r"):
            if line.startswith('#'): continue
            values = line.split()
            if not values: continue
            if values[0] == 'newmtl':
                mtl = contents[values[1]] = {}
            elif mtl is None:
                raise ValueError("mtl file doesn't start with newmtl stmt")
            elif values[0] == 'map_Kd':

                # load the texture referred to by this declaration
                mtl[values[0]] = values[1]
                surf_file = mtl['map_Kd']
                if surf_file.endswith('.tga'):
                    TGA_Header
                surf = pygame.image.load()
                image = pygame.image.tostring(surf, 'RGBA', 1)
                ix, iy = surf.get_rect().size
                texid = mtl['texture_Kd'] = glGenTextures(1)
                glBindTexture(GL_TEXTURE_2D, texid)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                                GL_LINEAR)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
                                GL_LINEAR)
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ix, iy, 0, GL_RGBA,
                             GL_UNSIGNED_BYTE, image)
            else:
                mtl[values[0]] = list(map(float, values[1:]))
        return contents
Пример #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()
Пример #4
0
    def __init__(self, face: freetype.Face, char: str) -> None:
        if face.load_char(char, freetype.FT_LOAD_RENDER):
            raise RuntimeError('failed to load char \'%s\'' % char)
        glyph = face.glyph
        bitmap = glyph.bitmap

        assert bitmap.pixel_mode == freetype.FT_PIXEL_MODE_GRAY, \
            "We haven't implemented support for other pixel modes"

        glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT)
        glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE)
        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1)

        self._texture_id = glGenTextures(1)
        self._width = bitmap.width
        self._height = bitmap.rows

        self._descender = glyph.bitmap_top - self._height
        self._bearing_x = glyph.bitmap_left
        self._advance = numpy.array(
            [face.glyph.advance.x / 64.0, face.glyph.advance.y / 64.0])

        glBindTexture(GL_TEXTURE_2D, self._texture_id)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        data = numpy.array(bitmap.buffer,
                           numpy.ubyte).reshape(self._height, self._width)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, self._width, self._height, 0,
                     GL_ALPHA, GL_UNSIGNED_BYTE, numpy.flipud(data))

        glPopClientAttrib()
Пример #5
0
def set_texture_level():
    #only really needed with some drivers (NVidia)
    #may cause errors with older drivers:
    try:
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    except:
        pass
Пример #6
0
def set_texture_level(target=GL_TEXTURE_RECTANGLE_ARB):
    #only really needed with some drivers (NVidia)
    #may cause errors with older drivers:
    try:
        glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    except:
        pass
Пример #7
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()
Пример #8
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)
Пример #9
0
def set_texture_level():
    #only really needed with some drivers (NVidia)
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_BASE_LEVEL, 0)
    #may cause errors with older drivers:
    try:
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAX_LEVEL, 0)
    except:
        pass
Пример #10
0
def set_texture_level():
    #only really needed with some drivers (NVidia)
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_BASE_LEVEL, 0)
    #may cause errors with older drivers:
    try:
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAX_LEVEL, 0)
    except:
        pass
Пример #11
0
    def gl_init(self):
        drawable = self.gl_begin()
        w, h = self.size
        debug("%s.gl_init() GL Pixmap backing size: %d x %d, drawable=%s",
              self, w, h, drawable)
        if not drawable:
            return None

        if not self.debug_setup:
            self.debug_setup = True
            self.gl_init_debug()

        if not self.gl_setup:
            self.gl_marker("Initializing GL context for window size %d x %d" %
                           (w, h))
            # Initialize viewport and matrices for 2D rendering
            glViewport(0, 0, w, h)
            glMatrixMode(GL_PROJECTION)
            glLoadIdentity()
            glOrtho(0.0, w, h, 0.0, -1.0, 1.0)
            glMatrixMode(GL_MODELVIEW)
            # Could be more optimal to use vertex arrays:
            # glEnableClientState(GL_VERTEX_ARRAY)
            # glEnableClientState(GL_TEXTURE_COORD_ARRAY)

            # Clear background to transparent black
            glClearColor(0.0, 0.0, 0.0, 0.0)

            # Default state is good for YUV painting:
            #  - fragment program enabled
            #  - YUV fragment program bound
            #  - render to offscreen FBO
            if self.textures is None:
                self.gl_init_textures()

            # Define empty FBO texture and set rendering to FBO
            glEnable(GL_FRAGMENT_PROGRAM_ARB)
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO])
            # nvidia needs this even though we don't use mipmaps (repeated through this file):
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)
            glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,
                         self.texture_pixel_format, w, h, 0,
                         self.texture_pixel_format, GL_UNSIGNED_BYTE, None)
            glBindFramebuffer(GL_FRAMEBUFFER, self.offscreen_fbo)
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                   GL_TEXTURE_RECTANGLE_ARB,
                                   self.textures[TEX_FBO], 0)
            glClear(GL_COLOR_BUFFER_BIT)

            # Create and assign fragment programs
            if not self.shaders:
                self.gl_init_shaders()

            # Bind program 0 for YUV painting by default
            glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB,
                             self.shaders[YUV2RGB_SHADER])
            self.gl_setup = True
        return drawable
Пример #12
0
 def __init__(self):
     self._texId = glGenTextures(1)
     self._width = None
     self._height = None
     # Bind an ID for this texture
     glBindTexture(GL_TEXTURE_2D, self._texId)
     # Use bilinear filtering if the texture has to be scaled
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
Пример #13
0
    def gl_init(self):
        drawable = self.gl_begin()
        w, h = self.size
        log("%s.gl_init() GL Pixmap backing size: %d x %d, drawable=%s", self, w, h, drawable)
        if not drawable:
            return  None

        if not self.debug_setup:
            self.debug_setup = True
            self.gl_init_debug()

        if not self.gl_setup:
            self.gl_marker("Initializing GL context for window size %d x %d" % (w, h))
            # Initialize viewport and matrices for 2D rendering
            glViewport(0, 0, w, h)
            glMatrixMode(GL_PROJECTION)
            glLoadIdentity()
            glOrtho(0.0, w, h, 0.0, -1.0, 1.0)
            glMatrixMode(GL_MODELVIEW)
            # Could be more optimal to use vertex arrays:
            # glEnableClientState(GL_VERTEX_ARRAY)
            # glEnableClientState(GL_TEXTURE_COORD_ARRAY)

            # Clear background to transparent black
            glClearColor(0.0, 0.0, 0.0, 0.0)

            # we don't use the depth (2D only):
            glDisable(GL_DEPTH_TEST)
            # only do alpha blending in present_fbo:
            glDisable(GL_BLEND)

            # Default state is good for YUV painting:
            #  - fragment program enabled
            #  - YUV fragment program bound
            #  - render to offscreen FBO
            if self.textures is None:
                self.gl_init_textures()

            # Define empty FBO texture and set rendering to FBO
            glEnable(GL_FRAGMENT_PROGRAM_ARB)
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO])
            # nvidia needs this even though we don't use mipmaps (repeated through this file):
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)
            glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, self.texture_pixel_format, w, h, 0, self.texture_pixel_format, GL_UNSIGNED_BYTE, None)
            glBindFramebuffer(GL_FRAMEBUFFER, self.offscreen_fbo)
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO], 0)
            glClear(GL_COLOR_BUFFER_BIT)

            # Create and assign fragment programs
            if not self.shaders:
                self.gl_init_shaders()

            # Bind program 0 for YUV painting by default
            glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.shaders[YUV2RGB_SHADER])
            self.gl_setup = True
        return drawable
Пример #14
0
    def _do_paint_rgb24(self, img_data, x, y, width, height, rowstride,
                        options, callbacks):
        debug("_do_paint_rgb24(x=%d, y=%d, width=%d, height=%d rowstride=%d)",
              x, y, width, height, rowstride)
        drawable = self.gl_init()
        if not drawable:
            debug("OpenGL cannot paint rgb24, drawable is not set")
            return False

        self.set_rgb24_paint_state()

        # Compute alignment and row length
        row_length = 0
        alignment = 1
        for a in [2, 4, 8]:
            # Check if we are a-aligned - ! (var & 0x1) means 2-aligned or better, 0x3 - 4-aligned and so on
            if (rowstride & a - 1) == 0:
                alignment = a
        # If number of extra bytes is greater than the alignment value,
        # then we also have to set row_length
        # Otherwise it remains at 0 (= width implicitely)
        if (rowstride - width * 3) > a:
            row_length = width + (rowstride - width * 3) / 3

        self.gl_marker(
            "Painting RGB24 update at %d,%d, size %d,%d, stride is %d, row length %d, alignment %d"
            % (x, y, width, height, rowstride, row_length, alignment))
        # Upload data as temporary RGB texture
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_RGB])
        glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length)
        glPixelStorei(GL_UNPACK_ALIGNMENT, alignment)
        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, 4, width, height, 0, GL_RGB,
                     GL_UNSIGNED_BYTE, img_data)

        # Draw textured RGB quad at the right coordinates
        glBegin(GL_QUADS)
        glTexCoord2i(0, 0)
        glVertex2i(x, y)
        glTexCoord2i(0, height)
        glVertex2i(x, y + height)
        glTexCoord2i(width, height)
        glVertex2i(x + width, y + height)
        glTexCoord2i(width, 0)
        glVertex2i(x + width, y)
        glEnd()

        # Present update to screen
        self.present_fbo()
        # present_fbo has resetted state already

        drawable.gl_end()
        return True
Пример #15
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)
Пример #16
0
    def gl_init(self):
        #must be called within a context!
        #performs init if needed
        if not self.debug_setup:
            self.debug_setup = True
            self.gl_init_debug()

        if not self.gl_setup:
            w, h = self.size
            self.gl_marker("Initializing GL context for window size %d x %d", w, h)
            # Initialize viewport and matrices for 2D rendering
            glViewport(0, 0, w, h)
            glMatrixMode(GL_PROJECTION)
            glLoadIdentity()
            glOrtho(0.0, w, h, 0.0, -1.0, 1.0)
            glMatrixMode(GL_MODELVIEW)
            # Mesa docs claim: this hint can improve the speed of texturing
            #when perspective-correct texture coordinate interpolation isn't needed,
            #such as when using a glOrtho() projection:
            glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)
            # Could be more optimal to use vertex arrays:
            # glEnableClientState(GL_VERTEX_ARRAY)
            # glEnableClientState(GL_TEXTURE_COORD_ARRAY)

            # Clear background to transparent black
            glClearColor(0.0, 0.0, 0.0, 0.0)

            # we don't use the depth (2D only):
            glDisable(GL_DEPTH_TEST)
            # only do alpha blending in present_fbo:
            glDisable(GL_BLEND)

            # Default state is good for YUV painting:
            #  - fragment program enabled
            #  - YUV fragment program bound
            #  - render to offscreen FBO
            if self.textures is None:
                self.gl_init_textures()

            # Define empty FBO texture and set rendering to FBO
            glEnable(GL_FRAGMENT_PROGRAM_ARB)
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO])
            # nvidia needs this even though we don't use mipmaps (repeated through this file):
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)
            glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, self.texture_pixel_format, w, h, 0, self.texture_pixel_format, GL_UNSIGNED_BYTE, None)
            glBindFramebuffer(GL_FRAMEBUFFER, self.offscreen_fbo)
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO], 0)
            glClear(GL_COLOR_BUFFER_BIT)

            # Create and assign fragment programs
            if not self.shaders:
                self.gl_init_shaders()

            # Bind program 0 for YUV painting by default
            glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.shaders[YUV2RGB_SHADER])
            self.gl_setup = True
Пример #17
0
def main(path=None):
    glutInit(sys.argv)

    if sys.platform == 'darwin':
        if not path:
            path = dialog()

    if not path:
        sys.exit(0)

    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE)
    glutInitWindowPosition(0, 0)
    glutInitWindowSize(730, 650)

    win = glutCreateWindow(b'MIDI Player')

    (width, height, img) = read_image(join(dirname(__file__), 'mixer.ppm'))
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
    texture = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,
                 GL_UNSIGNED_BYTE, img)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)

    glMatrixMode(GL_TEXTURE)
    glLoadIdentity()
    glScale(1 / width, 1 / height, 1)

    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glOrtho(0, 730, 0, 650, 0, 1)

    player = Player(win, path, width, height)

    glutDisplayFunc(player.display_func)
    glutKeyboardFunc(player.keyboard_func)
    glutMouseFunc(player.mouse_func)
    glutMotionFunc(player.motion_func)
    glutIdleFunc(player.process_events)

    submenus = []
    for instrument in range(128):
        if instrument % 8 == 0:
            submenus.append([
                families[instrument // 8],
                glutCreateMenu(player.change_instrument)
            ])
        glutAddMenuEntry(instruments[instrument].encode('ascii'), instrument)
    glutCreateMenu(player.change_instrument)
    for family, submenu in submenus:
        glutAddSubMenu(family.encode('ascii'), submenu)
    glutAttachMenu(GLUT_RIGHT_BUTTON)

    glutMainLoop()
Пример #18
0
def main(path=None):
    glutInit(sys.argv)

    if sys.platform == 'darwin':
        if not path:
            path = dialog()

    if not path:
        sys.exit(0)

    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE)
    glutInitWindowPosition(0, 0)
    glutInitWindowSize(730, 650)

    win = glutCreateWindow(b'MIDI Player')

    (width, height, img) = read_image(join(dirname(__file__), 'mixer.ppm'))
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
    texture = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
                 GL_RGB, GL_UNSIGNED_BYTE, img)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)

    glMatrixMode(GL_TEXTURE)
    glLoadIdentity()
    glScale(1/width, 1/height, 1)

    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glOrtho(0, 730, 0, 650, 0, 1)

    player = Player(win, path, width, height)

    glutDisplayFunc(player.display_func)
    glutKeyboardFunc(player.keyboard_func)
    glutMouseFunc(player.mouse_func)
    glutMotionFunc(player.motion_func)
    glutIdleFunc(player.process_events)

    submenus = []
    for instrument in range(128):
        if instrument % 8 == 0:
            submenus.append([families[instrument // 8],
                             glutCreateMenu(player.change_instrument)])
        glutAddMenuEntry(instruments[instrument].encode('ascii'), instrument)
    glutCreateMenu(player.change_instrument)
    for family, submenu in submenus:
        glutAddSubMenu(family.encode('ascii'), submenu)
    glutAttachMenu(GLUT_RIGHT_BUTTON)

    glutMainLoop()
Пример #19
0
def make_texture(
        filename=None,
        image=None,
        interpolate=True,
        alpha=False,
        integer=False,
        maxlod=None):
    if image == None:
        image = pygame.image.load(filename)
    pixels = pygame.image.tostring(image, "RGBA" if alpha else "RGB", True)
    texture = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture)
    glTexParameteri(
        GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
        GL_NEAREST_MIPMAP_NEAREST if interpolate else GL_NEAREST)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     GL_CLAMP_TO_EDGE)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     GL_CLAMP_TO_EDGE)
    if maxlod is not None:
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, maxlod)
    if alpha:
        if integer:
            targetformat = GL_RGBA8UI
            sourceformat = GL_RGBA_INTEGER
        else:
            targetformat = GL_RGBA8
            sourceformat = GL_RGBA
    else:
        if integer:
            targetformat = GL_RGB8UI
            sourceformat = GL_RGB_INTEGER
        else:
            targetformat = GL_RGB8
            sourceformat = GL_RGB
    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE)
    glTexImage2D(
        GL_TEXTURE_2D,
        0,
        targetformat,
        image.get_width(),
        image.get_height(),
        0,
        sourceformat,
        GL_UNSIGNED_BYTE,
        pixels)

    print glGetTexLevelParameteriv(
            GL_TEXTURE_2D,
            0,
            GL_TEXTURE_INTERNAL_FORMAT)
    return texture
Пример #20
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()
Пример #21
0
def LoadTexture(path):

    # запросим у OpenGL свободный индекс текстуры
    texture = glGenTextures(1)

    # сделаем текстуру активной
    glBindTexture(GL_TEXTURE_2D, texture)

    # загружаем изображение-текстуру
    image = Image.open(path)
    image = image.transpose(Image.FLIP_TOP_BOTTOM)
    img_data = image.convert("RGBA").tobytes()
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, img_data)
    glGenerateMipmap(GL_TEXTURE_2D)

    # установим параметры фильтрации текстуры - линейная фильтрация
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                    GL_LINEAR_MIPMAP_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

    # установим параметры "оборачиваниея" текстуры - отсутствие оборачивания
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)  #GL_REPEAT
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)  #GL_REPEAT

    # возвращаем текстуру
    return texture
Пример #22
0
    def drawBackgroundGL(self, painter, rect):
        painter.beginNativePainting()
        
        #This will clear the screen, but also introduce flickering
        glClearColor(0.0, 1.0, 0.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
        
        #update the textures of those patches that were updated
        for t in self._updatableTiles:
            patch = self.imagePatches[t][self._numLayers]
            if patch.texture > -1:
                self._glWidget.deleteTexture(patch.texture)
            patch.texture = self._glWidget.bindTexture(patch.image)
            #see 'backingstore' example by Ariya Hidayat
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
            #this ensures a seamless transition between tiles
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
        self._updatableTiles = []
        
        drawnTiles = 0
        for patches in self.imagePatches:
            patch = patches[self._numLayers]
            if not patch.rectF.intersect(rect): continue
            patch.drawTexture()
            drawnTiles +=1

        #print "ImageView2D.drawBackgroundGL: drew %d of %d tiles" % (drawnTiles, len(self.imagePatches))
        painter.endNativePainting()
    def _setup_texture(self, context_id: str):
        """Set up the texture for a given context"""
        gl_texture = self._gl_textures[context_id] = glGenTextures(
            1
        )  # Create the texture location
        glBindTexture(GL_TEXTURE_2D, gl_texture)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)

        glBindTexture(GL_TEXTURE_2D, gl_texture)
        glTexImage2D(
            GL_TEXTURE_2D,
            0,
            GL_RGBA,
            self._image_width,
            self._image_height,
            0,
            GL_RGBA,
            GL_UNSIGNED_BYTE,
            self._image,
        )
        glBindTexture(GL_TEXTURE_2D, 0)
        log.info("Finished setting up texture atlas in OpenGL")
Пример #24
0
def makeGLTexture(image_data: np.ndarray, w: int, h: int, repeat=False) -> int:
    """Loading pygame.Surface as OpenGL texture
    :return New Texture key"""

    # getting data from pygame.Surface

    # bind new texture
    key = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, key)

    # SETTING UP
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                    GL_NEAREST)  # настройка сжатия
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
                    GL_NEAREST)  # настройка растяжения

    if repeat:
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)

    glTexImage2D(GL_TEXTURE_2D, GL_ZERO, GL_RGBA, w, h, GL_ZERO, GL_RGBA,
                 GL_UNSIGNED_BYTE, image_data)
    #

    # unbind new texture
    glBindTexture(GL_TEXTURE_2D, 0)

    return key
Пример #25
0
    def _createTexture(self):
        surface = self._textureImage
        width = surface.get_width()
        height = surface.get_height()
        raw = pygame.image.tostring(surface, "RGBA", 0)

        texture = glGenTextures(1)
        # glGenTextures fails by returning 0, particularly if there's no GL
        # context yet.
        assert texture != 0
        glBindTexture(GL_TEXTURE_2D, texture)

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)

        glTexImage2D(
            GL_TEXTURE_2D, 0,
            GL_RGBA, width, height, 0,
            GL_RGBA,
            GL_UNSIGNED_BYTE,
            raw)

        return texture
Пример #26
0
    def paint_rgb24(self, img_data, x, y, width, height, rowstride):
        # OpenGL begin
        if not self.gldrawable.gl_begin(self.glcontext):
            log.error("OUCH")
            return False

        # Upload texture
        if not self.texture:
            self.texture = glGenTextures(1)

        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.texture)
        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);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
        glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstride/3)
        glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data);

        vtxarrays=1
        if vtxarrays == 1:
            texcoords = [ [ 0, 0 ],
                          [ 0, height],
                          [ width, height],
                          [ width, 0] ]
            vtxcoords = texcoords

            glVertexPointeri(vtxcoords)
            glTexCoordPointeri(texcoords)
            glDrawArrays(GL_QUADS, 0, 4);
        else:
            glBegin(GL_QUADS);
            glTexCoord2i(0, 0);
            glVertex2i(0, 0);

            glTexCoord2i(0, height);
            glVertex2i(0, height);

            glTexCoord2i(width, height);
            glVertex2i(width, height);

            glTexCoord2i(width, 0);
            glVertex2i(width, 0);
            glEnd()

        # OpenGL end
#self.gldrawable.swap_buffers()
#       self.gldrawable.swap_buffers()
        glFinish()
        self.gldrawable.gl_end()
Пример #27
0
    def paint_rgb24(self, img_data, x, y, width, height, rowstride):
        # OpenGL begin
        if not self.gldrawable.gl_begin(self.glcontext):
            log.error("OUCH")
            return False

        # Upload texture
        if not self.texture:
            self.texture = glGenTextures(1)

        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.texture)
        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)
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
        glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstride / 3)
        glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, width, height, 0,
                     GL_RGB, GL_UNSIGNED_BYTE, img_data)

        vtxarrays = 1
        if vtxarrays == 1:
            texcoords = [[0, 0], [0, height], [width, height], [width, 0]]
            vtxcoords = texcoords

            glVertexPointeri(vtxcoords)
            glTexCoordPointeri(texcoords)
            glDrawArrays(GL_QUADS, 0, 4)
        else:
            glBegin(GL_QUADS)
            glTexCoord2i(0, 0)
            glVertex2i(0, 0)

            glTexCoord2i(0, height)
            glVertex2i(0, height)

            glTexCoord2i(width, height)
            glVertex2i(width, height)

            glTexCoord2i(width, 0)
            glVertex2i(width, 0)
            glEnd()

        # OpenGL end
#self.gldrawable.swap_buffers()
#       self.gldrawable.swap_buffers()
        glFinish()
        self.gldrawable.gl_end()
Пример #28
0
    def _do_paint_rgb24(self, img_data, x, y, width, height, rowstride, options, callbacks):
        debug("_do_paint_rgb24(x=%d, y=%d, width=%d, height=%d rowstride=%d)", x, y, width, height, rowstride)
        drawable = self.gl_init()
        if not drawable:
            debug("OpenGL cannot paint rgb24, drawable is not set")
            return False

        self.set_rgb24_paint_state()

        # Compute alignment and row length
        row_length = 0
        alignment = 1
        for a in [2, 4, 8]:
            # Check if we are a-aligned - ! (var & 0x1) means 2-aligned or better, 0x3 - 4-aligned and so on
            if (rowstride & a-1) == 0: 
                alignment = a
        # If number of extra bytes is greater than the alignment value,
        # then we also have to set row_length
        # Otherwise it remains at 0 (= width implicitely)
        if (rowstride - width * 3) > a:
            row_length = width + (rowstride - width * 3) / 3
            
        self.gl_marker("Painting RGB24 update at %d,%d, size %d,%d, stride is %d, row length %d, alignment %d" % (x, y, width, height, rowstride, row_length, alignment))
        # Upload data as temporary RGB texture
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_RGB])
        glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length)
        glPixelStorei(GL_UNPACK_ALIGNMENT, alignment)
        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, 4, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)

        # Draw textured RGB quad at the right coordinates
        glBegin(GL_QUADS)
        glTexCoord2i(0, 0)
        glVertex2i(x, y)
        glTexCoord2i(0, height)
        glVertex2i(x, y+height)
        glTexCoord2i(width, height)
        glVertex2i(x+width, y+height)
        glTexCoord2i(width, 0)
        glVertex2i(x+width, y)
        glEnd()

        # Present update to screen
        self.present_fbo()
        # present_fbo has resetted state already

        drawable.gl_end()
        return True
Пример #29
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)
Пример #30
0
    def create(self, width, height):
        self.texture = glGenTextures(1)
        glBindTexture(GL_TEXTURE_CUBE_MAP, self.texture)
        for i in range(6):
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,
                         GL_DEPTH_COMPONENT, width, height, 0,
                         GL_DEPTH_COMPONENT, GL_FLOAT, None)

        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,
                        GL_CLAMP_TO_EDGE)
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,
                        GL_CLAMP_TO_EDGE)
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R,
                        GL_CLAMP_TO_EDGE)
Пример #31
0
    def do_paint_rgb(self, rgb_format, img_data, x, y, width, height, rowstride, options, callbacks):
        log("%s.do_paint_rgb(%s, %s bytes, x=%d, y=%d, width=%d, height=%d, rowstride=%d, options=%s)", self, rgb_format, len(img_data), x, y, width, height, rowstride, options)
        context = self.gl_context()
        if not context:
            log("%s._do_paint_rgb(..) no context!", self)
            fire_paint_callbacks(callbacks, False, "no opengl context")
            return
        if not options.get("paint", True):
            fire_paint_callbacks(callbacks)
            return

        try:
            upload, img_data = self.pixels_for_upload(img_data)

            with context:
                self.gl_init()
                self.set_rgb_paint_state()

                #convert it to a GL constant:
                pformat = PIXEL_FORMAT_TO_CONSTANT.get(rgb_format.decode())
                assert pformat is not None, "could not find pixel format for %s" % rgb_format

                self.gl_marker("%s update at (%d,%d) size %dx%d (%s bytes), using GL %s format=%s",
                               rgb_format, x, y, width, height, len(img_data), upload, CONSTANT_TO_PIXEL_FORMAT.get(pformat))

                # Upload data as temporary RGB texture
                glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_RGB])
                self.set_alignment(width, rowstride, rgb_format)
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
                set_texture_level()
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)
                glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, self.texture_pixel_format, width, height, 0, pformat, GL_UNSIGNED_BYTE, img_data)

                # Draw textured RGB quad at the right coordinates
                glBegin(GL_QUADS)
                glTexCoord2i(0, 0)
                glVertex2i(x, y)
                glTexCoord2i(0, height)
                glVertex2i(x, y+height)
                glTexCoord2i(width, height)
                glVertex2i(x+width, y+height)
                glTexCoord2i(width, 0)
                glVertex2i(x+width, y)
                glEnd()

                self.paint_box(options.get("encoding"), options.get("delta", -1)>=0, x, y, width, height)

                # Present update to screen
                self.present_fbo(x, y, width, height, options.get("flush", 0))
                # present_fbo has reset state already
            fire_paint_callbacks(callbacks)
        except Exception as e:
            log("Error in %s paint of %i bytes, options=%s)", rgb_format, len(img_data), options)
            fire_paint_callbacks(callbacks, False, "OpenGL %s paint error: %s" % (rgb_format, e))
Пример #32
0
    def __init__(self, resource_context: ResourceManager, asset_key: str):
        self._contents = {}
        current_mtl: dict = None

        file_data = resource_context.load('assets', asset_key)

        for line in file_data:
            line = line.decode("utf-8")  # Convert bytes line to a string
            if line.startswith('#'):
                # Ignore comments in the file.
                continue

            values = line.split()
            if not values:
                # Ignore empty lines.
                continue

            attribute_name = values[0]
            if attribute_name == 'newmtl':
                # Create a new empty material.
                current_mtl = self._contents[values[1]] = {}
            elif current_mtl is None:
                raise ValueError("mtl file must start with newmtl statement")
            elif attribute_name == 'map_Kd':
                # Diffuse texture map - load the image into memory.
                image_name = values[1]
                image_file_data = resource_context.load('assets', image_name)
                with Image.open(image_file_data) as image:
                    image_width, image_height = image.size
                    image = image.convert("RGBA").tobytes("raw", "RGBA")

                # Bind the image as a texture that can be used for rendering.
                texture_id = glGenTextures(1)
                current_mtl['texture_Kd'] = texture_id  # pylint: disable=unsupported-assignment-operation

                glBindTexture(GL_TEXTURE_2D, texture_id)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                                GL_LINEAR)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
                                GL_LINEAR)
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_width,
                             image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
            else:
                # Store the values for this attribute as a list of float values.
                current_mtl[attribute_name] = list(map(float, values[1:]))  # pylint: disable=unsupported-assignment-operation
def load_texture(path, texture):
    glBindTexture(GL_TEXTURE_2D, texture)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    image = Image.open(path)
    image = image.transpose(Image.FLIP_TOP_BOTTOM)
    img_data = image.convert("RGBA").tobytes()
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, img_data)
    return texture
Пример #34
0
	def __init__(self, imagefile, points=[], alpha=1.0):
		super(ImageActor, self).__init__()
		
		im = Image.open(imagefile)
		# Try to open the image file
		try:
			ix, iy, image = im.size[0], im.size[1], im.tostring("raw", "RGBA", 0, -1)
		except SystemError:
			ix, iy, image = im.size[0], im.size[1], im.tostring("raw", "RGBX", 0, -1)
		
		# get a texture buffer	
		glActiveTexture(GL_TEXTURE0) 
		self.texid = glGenTextures(1)
		# Bind the texture
		glBindTexture(GL_TEXTURE_2D, self.texid)
		glPixelStorei(GL_UNPACK_ALIGNMENT,1)
		
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
		
		# Upload the image
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
		
		# Generate the points for the billboard
		if points == []:
			points = [Point(0,0), Point(ix,0), Point(ix,-iy), Point(0,-iy)]
		if len(points) != 4:
			raise Exception("Image needs 4 points, %d provided" % len(points))
		
		# Generate the UV map
		uv = [Point(0,1), Point(1,1), Point(1,0), Point(0,0)]
		
		a = []
		for i in [0,1,2,0,2,3]:
			point = points[i]
			tex = uv[i]
			a.extend([point.x, point.y, tex.x, tex.y])
		
		# Assign the VBO
		super(ImageActor, self)._assignVBO(a)
		
		self.alpha = float(alpha)
Пример #35
0
def drawShadowMaps(lights, layerLoc):
    """
    draws shadow maps for debugging.
    note that a special shader is required to display the depth-component-only textures
    """
    
    i = 0
    for light in lights:
        if light.shadowMapArray==None: continue
        shadowMapArray = light.shadowMapArray
        shadowMaps = shadowMapArray.shadowMaps
        
        glBindTexture( GL_TEXTURE_2D_ARRAY, shadowMapArray.texture.glID )
        glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_NONE )
        
        for j in range(len(shadowMaps)):
            glViewport(130*i, 0, 128, 128)
            
            glUniform1f(layerLoc, float(j))
            
            glBegin(GL_QUADS)
            glVertex3f(-1.0, -1.0, 0.0)
            glVertex3f( 1.0, -1.0, 0.0)
            glVertex3f( 1.0,  1.0, 0.0)
            glVertex3f(-1.0,  1.0, 0.0)
            glEnd()
            
            i += 1
        
        if shadowMapArray.textureType=="sampler2DArrayShadow":
            glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE )
        else:
            glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_NONE )
Пример #36
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)
Пример #37
0
def load(file_path):
    img = Image.open(file_path, 'r').convert('RGB')

    img_data = np.array(img, dtype=np.uint8)
    width, height = img.size

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

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,
                 GL_UNSIGNED_BYTE, img_data)

    return texture
Пример #38
0
 def load_texture(cls, file_name):
     texture = glGenTextures(1)
     glBindTexture(GL_TEXTURE_2D, texture)
     # Set the texture wrapping parameters
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
     # Set texture filtering parameters
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
     # load image
     image = Image.open(file_name)
     img_data = numpy.array(list(image.getdata()), numpy.uint8)
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width, image.height, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
     glEnable(GL_TEXTURE_2D)
     return texture
Пример #39
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)
def load_texture_pygame(path, texture):
    import pygame
    glBindTexture(GL_TEXTURE_2D, texture)
    # Set the texture wrapping parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    # Set texture filtering parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    # load image
    image = pygame.image.load(path)
    image = pygame.transform.flip(image, False, True)
    image_width, image_height = image.get_rect().size
    img_data = pygame.image.tostring(image, "RGBA")
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_width, image_height, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, img_data)
    return texture
Пример #41
0
 def create(self):
     tex = glGenTextures(1)
     glBindTexture(GL_TEXTURE_2D, tex)
     
     # Set the texture wrapping parameters
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
     
     # Set texture filtering parameters
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
     
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self.width,
                  self.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, self.image)
                 
     self.tex = tex
     self.status |= Resource.CREATED
Пример #42
0
 def upload_cursor_texture(self, width, height, pixels):
     upload, pixel_data = self.pixels_for_upload(pixels)
     rgb_format = "RGBA"
     glActiveTexture(GL_TEXTURE0)
     target = GL_TEXTURE_RECTANGLE_ARB
     glEnable(target)
     glBindTexture(target, self.textures[TEX_CURSOR])
     self.set_alignment(width, width*4, rgb_format)
     glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
     glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
     glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)
     glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)
     glTexImage2D(target, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel_data)
     log("GL cursor %ix%i uploaded %i bytes of %s pixel data using %s",
         width, height, len(pixels), rgb_format, upload)
     glBindTexture(target, 0)
     glDisable(target)
Пример #43
0
    def bindTexture(self):
        glBindTexture(GL_TEXTURE_2D, self.texture)
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR)
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST)
        # These two are only really needed for megatiles; normal
        # tiles don't have to deal with texture wrapping.
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)

        img = self.textureData

        pic_ny, pic_nx = img.shape
        tex_nx,tex_ny = getTexSize(pic_nx,pic_ny)

        imgType = img.dtype.type
        if imgType not in dtypeToGlTypeMap:
            raise ValueError("Unsupported data mode %s" % str(imgType))
        glTexImage2D(GL_TEXTURE_2D,0,  GL_RGB, tex_nx,tex_ny, 0, 
                     GL_LUMINANCE, dtypeToGlTypeMap[imgType], None)
Пример #44
0
 def upload_cursor_texture(self, target, cursor_data):
     width = cursor_data[3]
     height = cursor_data[4]
     pixels = cursor_data[8]
     if len(pixels)<width*4*height:
         log.error("Error: invalid cursor pixel buffer for %ix%i", width, height)
         log.error(" expected %i bytes but got %i", width*height*4, len(pixels))
         log.error(" %s", repr_ellipsized(hexstr(pixels)))
         return
     upload, pixel_data = self.pixels_for_upload(pixels)
     rgb_format = "BGRA"
     self.set_alignment(width, width*4, rgb_format)
     glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
     glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
     set_texture_level(target)
     glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)
     glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)
     glTexImage2D(target, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixel_data)
     log("GL cursor %ix%i uploaded %i bytes of %s pixel data using %s", width, height, len(pixels), rgb_format, upload)
Пример #45
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)
Пример #46
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)
def load_texture(path, tex):
    """Loads texture from image for GLFW."""
    glBindTexture(GL_TEXTURE_2D, tex)

    # Set the texture wrapping parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)

    # Set texture filtering parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

    # load image
    image = Image.open(path)
    image = image.transpose(Image.FLIP_TOP_BOTTOM)
    img_data = image.convert("RGBA").tobytes()
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, img_data)

    glBindTexture(GL_TEXTURE_2D, 0)

    return tex
Пример #48
0
    def __init__(self, path):
        img = Image.open(path)
        img = img.transpose(Image.FLIP_TOP_BOTTOM)
        self.m_Width = img.width
        self.m_Height = img.height
        self.m_LocalBuffer = img.convert("RGBA").tobytes()

        self.m_RendererID = glGenTextures(1)
        glBindTexture(GL_TEXTURE_2D, self.m_RendererID)

        # glPixelStorei(GL_UNPACK_ALIGNMENT, 1)

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, self.m_Width, self.m_Height,
                     0, GL_RGBA, GL_UNSIGNED_BYTE, self.m_LocalBuffer)
        glBindTexture(GL_TEXTURE_2D, 0)

        if self.m_LocalBuffer:
            del self.m_LocalBuffer
Пример #49
0
    def _do_paint_rgb(self, bpp, img_data, x, y, width, height, rowstride, options):
        log("%s._do_paint_rgb(%s, %s bytes, x=%d, y=%d, width=%d, height=%d, rowstride=%d, options=%s)", self, bpp, len(img_data), x, y, width, height, rowstride, options)
        context = self.gl_context()
        if not context:
            log("%s._do_paint_rgb(..) no context!", self)
            return False

        #TODO: move this code up to the decode thread section
        upload, img_data = self.pixels_for_upload(img_data)

        with context:
            self.gl_init()
            self.set_rgb_paint_state()

            rgb_format = options.get(b"rgb_format")
            if not rgb_format:
                #Older servers may not tell us the pixel format, so we must infer it:
                if bpp==24:
                    rgb_format = "RGB"
                else:
                    assert bpp==32
                    rgb_format = "RGBA"
            else:
                rgb_format = rgb_format.decode()
            #convert it to a GL constant:
            pformat = PIXEL_FORMAT_TO_CONSTANT.get(rgb_format)
            assert pformat is not None, "could not find pixel format for %s (bpp=%s)" % (rgb_format, bpp)

            bytes_per_pixel = len(rgb_format)       #ie: BGRX -> 4
            # Compute alignment and row length
            row_length = 0
            alignment = 1
            for a in [2, 4, 8]:
                # Check if we are a-aligned - ! (var & 0x1) means 2-aligned or better, 0x3 - 4-aligned and so on
                if (rowstride & a-1) == 0:
                    alignment = a
            # If number of extra bytes is greater than the alignment value,
            # then we also have to set row_length
            # Otherwise it remains at 0 (= width implicitely)
            if (rowstride - width * bytes_per_pixel) >= alignment:
                row_length = width + (rowstride - width * bytes_per_pixel) // bytes_per_pixel

            self.gl_marker("%s %sbpp update at (%d,%d) size %dx%d (%s bytes), stride=%d, row length %d, alignment %d, using GL %s format=%s",
                           rgb_format, bpp, x, y, width, height, len(img_data), rowstride, row_length, alignment, upload, CONSTANT_TO_PIXEL_FORMAT.get(pformat))

            # Upload data as temporary RGB texture
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_RGB])
            glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length)
            glPixelStorei(GL_UNPACK_ALIGNMENT, alignment)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_BASE_LEVEL, 0)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAX_LEVEL, 0)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)
            glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, self.texture_pixel_format, width, height, 0, pformat, GL_UNSIGNED_BYTE, img_data)

            # Draw textured RGB quad at the right coordinates
            glBegin(GL_QUADS)
            glTexCoord2i(0, 0)
            glVertex2i(x, y)
            glTexCoord2i(0, height)
            glVertex2i(x, y+height)
            glTexCoord2i(width, height)
            glVertex2i(x+width, y+height)
            glTexCoord2i(width, 0)
            glVertex2i(x+width, y)
            glEnd()

            self.paint_box(options.get("encoding"), options.get("delta", -1)>=0, x, y, width, height)

            # Present update to screen
            self.present_fbo(x, y, width, height, options.get("flush", 0))
            # present_fbo has reset state already
        return True
Пример #50
0
    def do_present_fbo(self):
        self.gl_marker("Presenting FBO on screen")
        # Change state to target screen instead of our FBO
        glBindFramebuffer(GL_FRAMEBUFFER, 0)

        if self._alpha_enabled:
            # transparent background:
            glClearColor(0.0, 0.0, 0.0, 0.0)
        else:
            # plain white no alpha:
            glClearColor(1.0, 1.0, 1.0, 1.0)

        # Draw FBO texture on screen
        self.set_rgb_paint_state()
        bw, bh = self.size
        ww, wh = self.render_size

        if self.glconfig.is_double_buffered() or bw!=ww or bh!=wh:
            #refresh the whole window:
            rectangles = ((0, 0, bw, bh), )
        else:
            #paint just the rectangles we have accumulated:
            rectangles = self.pending_fbo_paint
        self.pending_fbo_paint = []
        log("do_present_fbo: painting %s", rectangles)

        glEnable(GL_TEXTURE_RECTANGLE_ARB)
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO])
        if self._alpha_enabled:
            # support alpha channel if present:
            glEnablei(GL_BLEND, self.textures[TEX_FBO])
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)

        #viewport for painting to window:
        glViewport(0, 0, ww, wh)
        if ww!=bw or wh!=bh:
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR)

        glBegin(GL_QUADS)
        for x,y,w,h in rectangles:
            #note how we invert coordinates..
            tx1, ty1, tx2, ty2 = x, bh-y,  x+w, bh-y-h
            vx1, vy1, vx2, vy2 = x, y,     x+w, y+h
            glTexCoord2i(tx1, ty1)
            glVertex2i(vx1, vy1)        #top-left of window viewport
            glTexCoord2i(tx1, ty2)
            glVertex2i(vx1, vy2)        #bottom-left of window viewport
            glTexCoord2i(tx2, ty2)
            glVertex2i(vx2, vy2)        #bottom-right of window viewport
            glTexCoord2i(tx2, ty1)
            glVertex2i(vx2, vy1)        #top-right of window viewport
        glEnd()
        glDisable(GL_TEXTURE_RECTANGLE_ARB)

        if self.paint_spinner:
            #add spinner:
            dim = min(bw/3.0, bh/3.0)
            t = time.time()
            count = int(t*4.0)
            bx = bw//2
            by = bh//2
            for i in range(8):      #8 lines
                glBegin(GL_POLYGON)
                c = cv.trs[count%8][i]
                glColor4f(c, c, c, 1)
                mi1 = math.pi*i/4-math.pi/16
                mi2 = math.pi*i/4+math.pi/16
                glVertex2i(int(bx+math.sin(mi1)*10), int(by+math.cos(mi1)*10))
                glVertex2i(int(bx+math.sin(mi1)*dim), int(by+math.cos(mi1)*dim))
                glVertex2i(int(bx+math.sin(mi2)*dim), int(by+math.cos(mi2)*dim))
                glVertex2i(int(bx+math.sin(mi2)*10), int(by+math.cos(mi2)*10))
                glEnd()

        #if desired, paint window border
        if self.border and self.border.shown:
            #double size since half the line will be off-screen
            glLineWidth(self.border.size*2)
            glBegin(GL_LINE_LOOP)
            glColor4f(self.border.red, self.border.green, self.border.blue, self.border.alpha)
            for px,py in ((0, 0), (bw, 0), (bw, bh), (0, bh)):
                glVertex2i(px, py)
            glEnd()

        # Show the backbuffer on screen
        self.gl_show()
        self.gl_frame_terminator()

        #restore pbo viewport
        glViewport(0, 0, bw, bh)
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST)

        self.unset_rgb_paint_state()
        log("%s(%s, %s)", glBindFramebuffer, GL_FRAMEBUFFER, self.offscreen_fbo)
        glBindFramebuffer(GL_FRAMEBUFFER, self.offscreen_fbo)
        log("%s.do_present_fbo() done", self)
Пример #51
0
    def do_present_fbo(self):
        bw, bh = self.size
        ww, wh = self.render_size

        self.gl_marker("Presenting FBO on screen")
        # Change state to target screen instead of our FBO
        glBindFramebuffer(GL_FRAMEBUFFER, 0)
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0)

        if self._alpha_enabled:
            # transparent background:
            glClearColor(0.0, 0.0, 0.0, 0.0)
        else:
            # plain white no alpha:
            glClearColor(1.0, 1.0, 1.0, 1.0)

        # Draw FBO texture on screen
        self.set_rgb_paint_state()

        rect_count = len(self.pending_fbo_paint)
        if self.glconfig.is_double_buffered() or bw!=ww or bh!=wh:
            #refresh the whole window:
            rectangles = ((0, 0, bw, bh), )
        else:
            #paint just the rectangles we have accumulated:
            rectangles = self.pending_fbo_paint
        self.pending_fbo_paint = []
        log("do_present_fbo: painting %s", rectangles)

        glEnable(GL_TEXTURE_RECTANGLE_ARB)
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO])
        if self._alpha_enabled:
            # support alpha channel if present:
            glEnablei(GL_BLEND, self.textures[TEX_FBO])
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)

        if SAVE_BUFFERS:
            glBindFramebuffer(GL_READ_FRAMEBUFFER, self.offscreen_fbo)
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO])
            glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO], 0)
            glReadBuffer(GL_COLOR_ATTACHMENT0)
            glViewport(0, 0, bw, bh)
            from OpenGL.GL import glGetTexImage
            size = bw*bh*4
            import numpy
            data = numpy.empty(size)
            img_data = glGetTexImage(GL_TEXTURE_RECTANGLE_ARB, 0, GL_BGRA, GL_UNSIGNED_BYTE, data)
            from PIL import Image, ImageOps
            img = Image.frombuffer("RGBA", (bw, bh), img_data, "raw", "BGRA", bw*4)
            img = ImageOps.flip(img)
            kwargs = {}
            if SAVE_BUFFERS=="jpeg":
                kwargs = {
                          "quality"     : 0,
                          "optimize"    : False,
                          }
            t = time.time()
            tstr = time.strftime("%H-%M-%S", time.localtime(t))
            filename = "./W%i-FBO-%s.%03i.%s" % (self.wid, tstr, (t*1000)%1000, SAVE_BUFFERS)
            log("do_present_fbo: saving %4ix%-4i pixels, %7i bytes to %s", bw, bh, size, filename)
            img.save(filename, SAVE_BUFFERS, **kwargs)
            glBindFramebuffer(GL_READ_FRAMEBUFFER, 0)

        #viewport for painting to window:
        glViewport(0, 0, ww, wh)
        if ww!=bw or wh!=bh:
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR)

        glBegin(GL_QUADS)
        for x,y,w,h in rectangles:
            #note how we invert coordinates..
            tx1, ty1, tx2, ty2 = x, bh-y,  x+w, bh-y-h
            vx1, vy1, vx2, vy2 = x, y,     x+w, y+h
            glTexCoord2i(tx1, ty1)
            glVertex2i(vx1, vy1)        #top-left of window viewport
            glTexCoord2i(tx1, ty2)
            glVertex2i(vx1, vy2)        #bottom-left of window viewport
            glTexCoord2i(tx2, ty2)
            glVertex2i(vx2, vy2)        #bottom-right of window viewport
            glTexCoord2i(tx2, ty1)
            glVertex2i(vx2, vy1)        #top-right of window viewport
        glEnd()
        glDisable(GL_TEXTURE_RECTANGLE_ARB)

        if self.paint_spinner:
            #add spinner:
            dim = min(bw/3.0, bh/3.0)
            t = time.time()
            count = int(t*4.0)
            bx = bw//2
            by = bh//2
            for i in range(8):      #8 lines
                glBegin(GL_POLYGON)
                c = cv.trs[count%8][i]
                glColor4f(c, c, c, 1)
                mi1 = math.pi*i/4-math.pi/16
                mi2 = math.pi*i/4+math.pi/16
                glVertex2i(int(bx+math.sin(mi1)*10), int(by+math.cos(mi1)*10))
                glVertex2i(int(bx+math.sin(mi1)*dim), int(by+math.cos(mi1)*dim))
                glVertex2i(int(bx+math.sin(mi2)*dim), int(by+math.cos(mi2)*dim))
                glVertex2i(int(bx+math.sin(mi2)*10), int(by+math.cos(mi2)*10))
                glEnd()

        #if desired, paint window border
        if self.border and self.border.shown:
            #double size since half the line will be off-screen
            glLineWidth(self.border.size*2)
            glBegin(GL_LINE_LOOP)
            glColor4f(self.border.red, self.border.green, self.border.blue, self.border.alpha)
            for px,py in ((0, 0), (bw, 0), (bw, bh), (0, bh)):
                glVertex2i(px, py)
            glEnd()

        if self.pointer_overlay:
            x, y, _, _, size, start_time = self.pointer_overlay
            elapsed = time.time()-start_time
            if elapsed<6:
                alpha = max(0, (5.0-elapsed)/5.0)
                glLineWidth(1)
                glBegin(GL_LINES)
                glColor4f(0, 0, 0, alpha)
                glVertex2i(x-size, y)
                glVertex2i(x+size, y)
                glVertex2i(x, y-size)
                glVertex2i(x, y+size)
                glEnd()
            else:
                self.pointer_overlay = None

        # Show the backbuffer on screen
        self.gl_show(rect_count)
        self.gl_frame_terminator()

        #restore pbo viewport
        glViewport(0, 0, bw, bh)
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST)

        self.unset_rgb_paint_state()
        log("%s(%s, %s)", glBindFramebuffer, GL_FRAMEBUFFER, self.offscreen_fbo)
        glBindFramebuffer(GL_FRAMEBUFFER, self.offscreen_fbo)
        log("%s.do_present_fbo() done", self)
Пример #52
0
    def _do_paint_rgb(self, bpp, img_data, x, y, width, height, rowstride, options, callbacks):
        debug(
            "%s._do_paint_rgb(%s, %s bytes, x=%d, y=%d, width=%d, height=%d, rowstride=%d)",
            self,
            bpp,
            len(img_data),
            x,
            y,
            width,
            height,
            rowstride,
        )
        drawable = self.gl_init()
        if not drawable:
            debug("%s._do_paint_rgb(..) drawable is not set!", self)
            return False

        try:
            self.set_rgb_paint_state()

            bytes_per_pixel = bpp / 8
            # Compute alignment and row length
            row_length = 0
            alignment = 1
            for a in [2, 4, 8]:
                # Check if we are a-aligned - ! (var & 0x1) means 2-aligned or better, 0x3 - 4-aligned and so on
                if (rowstride & a - 1) == 0:
                    alignment = a
            # If number of extra bytes is greater than the alignment value,
            # then we also have to set row_length
            # Otherwise it remains at 0 (= width implicitely)
            if (rowstride - width * bytes_per_pixel) > a:
                row_length = width + (rowstride - width * bytes_per_pixel) / bytes_per_pixel

            rgb_format = options.get("rgb_format", None)
            self.gl_marker(
                "%s %sbpp update at %d,%d, size %d,%d, stride is %d, row length %d, alignment %d"
                % (rgb_format, bpp, x, y, width, height, rowstride, row_length, alignment)
            )
            # Upload data as temporary RGB texture
            if bpp == 24:
                if rgb_format == "BGR":
                    pformat = GL_BGR
                else:
                    assert rgb_format in ("RGB", None), "invalid 24-bit format: %s" % rgb_format
                    pformat = GL_RGB
            else:
                assert bpp == 32
                if rgb_format == "BGRA":
                    pformat = GL_BGRA
                else:
                    assert rgb_format in ("RGBA", None), "invalid 32-bit format: %s" % rgb_format
                    pformat = GL_RGBA

            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_RGB])
            glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length)
            glPixelStorei(GL_UNPACK_ALIGNMENT, alignment)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
            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_RGBA, width, height, 0, pformat, GL_UNSIGNED_BYTE, img_data)

            # Draw textured RGB quad at the right coordinates
            glBegin(GL_QUADS)
            glTexCoord2i(0, 0)
            glVertex2i(x, y)
            glTexCoord2i(0, height)
            glVertex2i(x, y + height)
            glTexCoord2i(width, height)
            glVertex2i(x + width, y + height)
            glTexCoord2i(width, 0)
            glVertex2i(x + width, y)
            glEnd()

            # Present update to screen
            self.present_fbo(drawable)
            # present_fbo has reset state already
        finally:
            drawable.gl_end()
        return True
Пример #53
0
    def do_paint_rgb(self, rgb_format, img_data, x, y, width, height, rowstride, options, callbacks):
        log("%s.do_paint_rgb(%s, %s bytes, x=%d, y=%d, width=%d, height=%d, rowstride=%d, options=%s)", self, rgb_format, len(img_data), x, y, width, height, rowstride, options)
        context = self.gl_context()
        if not context:
            log("%s._do_paint_rgb(..) no context!", self)
            fire_paint_callbacks(callbacks, False, "no opengl context")
            return
        if not options.get("paint", True):
            fire_paint_callbacks(callbacks)
            return

        try:
            upload, img_data = self.pixels_for_upload(img_data)

            with context:
                self.gl_init()
                self.set_rgb_paint_state()

                #convert it to a GL constant:
                pformat = PIXEL_FORMAT_TO_CONSTANT.get(rgb_format.decode())
                assert pformat is not None, "could not find pixel format for %s" % rgb_format

                bytes_per_pixel = len(rgb_format)       #ie: BGRX -> 4
                # Compute alignment and row length
                row_length = 0
                alignment = 1
                for a in [2, 4, 8]:
                    # Check if we are a-aligned - ! (var & 0x1) means 2-aligned or better, 0x3 - 4-aligned and so on
                    if (rowstride & a-1) == 0:
                        alignment = a
                # If number of extra bytes is greater than the alignment value,
                # then we also have to set row_length
                # Otherwise it remains at 0 (= width implicitely)
                if (rowstride - width * bytes_per_pixel) >= alignment:
                    row_length = width + (rowstride - width * bytes_per_pixel) // bytes_per_pixel

                self.gl_marker("%s update at (%d,%d) size %dx%d (%s bytes), stride=%d, row length %d, alignment %d, using GL %s format=%s",
                               rgb_format, x, y, width, height, len(img_data), rowstride, row_length, alignment, upload, CONSTANT_TO_PIXEL_FORMAT.get(pformat))

                # Upload data as temporary RGB texture
                glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_RGB])
                glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length)
                glPixelStorei(GL_UNPACK_ALIGNMENT, alignment)
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
                set_texture_level()
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)
                glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)
                glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, self.texture_pixel_format, width, height, 0, pformat, GL_UNSIGNED_BYTE, img_data)

                # Draw textured RGB quad at the right coordinates
                glBegin(GL_QUADS)
                glTexCoord2i(0, 0)
                glVertex2i(x, y)
                glTexCoord2i(0, height)
                glVertex2i(x, y+height)
                glTexCoord2i(width, height)
                glVertex2i(x+width, y+height)
                glTexCoord2i(width, 0)
                glVertex2i(x+width, y)
                glEnd()

                self.paint_box(options.get("encoding"), options.get("delta", -1)>=0, x, y, width, height)

                # Present update to screen
                self.present_fbo(x, y, width, height, options.get("flush", 0))
                # present_fbo has reset state already
            fire_paint_callbacks(callbacks)
        except Exception as e:
            log("Error in %s paint of %i bytes, options=%s)", rgb_format, len(img_data), options)
            fire_paint_callbacks(callbacks, False, "OpenGL %s paint error: %s" % (rgb_format, e))
Пример #54
0
 def _set_wrap(self, wrap):
     if wrap == self._gl_wrap:
         return
     self.bind()
     glTexParameteri(self.target, GL_TEXTURE_WRAP_S, wrap)
     glTexParameteri(self.target, GL_TEXTURE_WRAP_T, wrap)
Пример #55
0
 def _set_mag_filter(self, x):
     if x == self._gl_mag_filter:
         return
     self.bind()
     glTexParameteri(self.target, GL_TEXTURE_MAG_FILTER, x)
     self._gl_mag_filter = x
Пример #56
0
    def create(width, height, format=GL_RGBA, rectangle=False, mipmap=False):
        '''Create a texture based on size.'''
        target = GL_TEXTURE_2D
        if rectangle:
            if _is_pow2(width) and _is_pow2(height):
                rectangle = False
            else:
                rectangle = False

                try:
                    if Texture._has_texture_nv is None:
                        Texture._has_texture_nv = glInitTextureRectangleNV()
                    if Texture._has_texture_nv:
                        target = GL_TEXTURE_RECTANGLE_NV
                        rectangle = True
                except Exception:
                    pass

                try:
                    if Texture._has_texture_arb is None:
                        Texture._has_texture_arb = glInitTextureRectangleARB()
                    if not rectangle and Texture._has_texture_arb:
                        target = GL_TEXTURE_RECTANGLE_ARB
                        rectangle = True
                except Exception:
                    pass

                if not rectangle:
                    pymt_logger.debug(
                        'Texture: Missing support for rectangular texture')
                else:
                    # Can't do mipmap with rectangle texture
                    mipmap = False

        if rectangle:
            texture_width = width
            texture_height = height
        else:
            texture_width = _nearest_pow2(width)
            texture_height = _nearest_pow2(height)

        texid = glGenTextures(1)
        texture = Texture(texture_width, texture_height, target, texid,
                          mipmap=mipmap)

        texture.bind()
        texture.wrap        = GL_CLAMP_TO_EDGE
        if mipmap:
            texture.min_filter  = GL_LINEAR_MIPMAP_LINEAR
            #texture.mag_filter  = GL_LINEAR_MIPMAP_LINEAR
            glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE)
        else:
            texture.min_filter  = GL_LINEAR
            texture.mag_filter  = GL_LINEAR

        if not Texture.is_gl_format_supported(format):
            format = Texture.convert_gl_format(format)

        data = (GLubyte * texture_width * texture_height *
                Texture.gl_format_size(format))()
        glTexImage2D(target, 0, format, texture_width, texture_height, 0,
                     format, GL_UNSIGNED_BYTE, data)

        if rectangle:
            texture.tex_coords = \
                (0., 0., width, 0., width, height, 0., height)

        glFlush()

        if texture_width == width and texture_height == height:
            return texture

        return texture.get_region(0, 0, width, height)
Пример #57
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
Пример #58
0
    def gl_init(self):
        drawable = self.gl_begin()
        w, h = self.size
        debug("%s.gl_init() GL Pixmap backing size: %d x %d, drawable=%s", self, w, h, drawable)
        if not drawable:
            return  None
        if not self.gl_setup:
            #ensure python knows which scope we're talking about:
            global glInitStringMarkerGREMEDY, glStringMarkerGREMEDY
            global glInitFrameTerminatorGREMEDY, glFrameTerminatorGREMEDY
            # Ask GL to send us all debug messages
            if GL_DEBUG_OUTPUT and gl_debug_callback and glInitDebugKHR() == True:
                glEnable(GL_DEBUG_OUTPUT)
                glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS)
                glDebugMessageCallback(gl_debug_callback, None)
                glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, None, GL_TRUE)
            # Initialize string_marker GL debugging extension if available
            if glInitStringMarkerGREMEDY and glInitStringMarkerGREMEDY() == True:
                log.info("Extension GL_GREMEDY_string_marker available. Will output detailed information about each frame.")
            else:
                # General case - running without debugger, extension not available
                glStringMarkerGREMEDY = None
                #don't bother trying again for another window:
                glInitStringMarkerGREMEDY = None
            # Initialize frame_terminator GL debugging extension if available
            if glInitFrameTerminatorGREMEDY and glInitFrameTerminatorGREMEDY() == True:
                log.info("Enabling GL frame terminator debugging.")
            else:
                glFrameTerminatorGREMEDY = None
                #don't bother trying again for another window:
                glInitFrameTerminatorGREMEDY = None

            self.gl_marker("Initializing GL context for window size %d x %d" % (w, h))
            # Initialize viewport and matrices for 2D rendering
            glViewport(0, 0, w, h)
            glMatrixMode(GL_PROJECTION)
            glLoadIdentity()
            glOrtho(0.0, w, h, 0.0, -1.0, 1.0)
            glMatrixMode(GL_MODELVIEW)
            #TODO glEnableClientState(GL_VERTEX_ARRAY)
            #TODO glEnableClientState(GL_TEXTURE_COORD_ARRAY)

            # Clear to white
            glClearColor(1.0, 1.0, 1.0, 1.0)

            # Default state is good for YUV painting:
            #  - fragment program enabled
            #  - YUV fragment program bound
            #  - render to offscreen FBO
            glEnable(GL_FRAGMENT_PROGRAM_ARB)
            if self.textures is None:
                self.textures = glGenTextures(5)
                debug("%s.gl_init() textures of size %s : %s", self, self.size, self.textures)
            if self.offscreen_fbo is None:
                self.offscreen_fbo = glGenFramebuffers(1)

            # Define empty FBO texture and set rendering to FBO
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO])
            # nvidia needs this even though we don't use mipmaps (repeated through this file):
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)
            glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, None)
            glBindFramebuffer(GL_FRAMEBUFFER, self.offscreen_fbo)
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_FBO], 0)
            glClear(GL_COLOR_BUFFER_BIT)

            # Create and assign fragment programs
            if not self.shaders:
                self.shaders = [ 1, 2 ]
                glGenProgramsARB(2, self.shaders)
                for progid, progstr in ((0, YUV2RGB_shader), (1, RGBP2RGB_shader)):
                    glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.shaders[progid])
                    glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, len(progstr), progstr)
                    err = glGetString(GL_PROGRAM_ERROR_STRING_ARB)
                    if err:
                        #FIXME: maybe we should do something else here?
                        log.error(err)

            # Bind program 0 for YUV painting by default
            glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.shaders[0])
            self.gl_setup = True
        return drawable
Пример #59
0
    def _do_paint_rgb(self, bpp, img_data, x, y, width, height, rowstride, options):
        log("%s._do_paint_rgb(%s, %s bytes, x=%d, y=%d, width=%d, height=%d, rowstride=%d)", self, bpp, len(img_data), x, y, width, height, rowstride)
        drawable = self.gl_init()
        if not drawable:
            log("%s._do_paint_rgb(..) drawable is not set!", self)
            return False

        #deal with buffers uploads by wrapping them if we can, or copy to a string:
        if type(img_data)==buffer:
            if memoryview_type is not None:
                img_data = memoryview_type(img_data)
            else:
                img_data = str(img_data)

        try:
            self.set_rgb_paint_state()

            rgb_format = options.get("rgb_format")
            if not rgb_format:
                #Older servers may not tell us the pixel format, so we must infer it:
                if bpp==24:
                    rgb_format = "RGB"
                else:
                    assert bpp==32
                    rgb_format = "RGBA"
            #convert it to a GL constant:
            pformat = PIXEL_FORMAT_TO_CONSTANT.get(rgb_format)
            assert pformat is not None, "could not find pixel format for %s (bpp=%s)" % (rgb_format, bpp)

            bytes_per_pixel = len(rgb_format)       #ie: BGRX -> 4
            # Compute alignment and row length
            row_length = 0
            alignment = 1
            for a in [2, 4, 8]:
                # Check if we are a-aligned - ! (var & 0x1) means 2-aligned or better, 0x3 - 4-aligned and so on
                if (rowstride & a-1) == 0:
                    alignment = a
            # If number of extra bytes is greater than the alignment value,
            # then we also have to set row_length
            # Otherwise it remains at 0 (= width implicitely)
            if (rowstride - width * bytes_per_pixel) >= alignment:
                row_length = width + (rowstride - width * bytes_per_pixel) / bytes_per_pixel

            self.gl_marker("%s %sbpp update at (%d,%d) size %dx%d (%s bytes), stride=%d, row length %d, alignment %d, using GL upload format=%s" % (rgb_format, bpp, x, y, width, height, len(img_data), rowstride, row_length, alignment, CONSTANT_TO_PIXEL_FORMAT.get(pformat)))

            # Upload data as temporary RGB texture
            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[TEX_RGB])
            glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length)
            glPixelStorei(GL_UNPACK_ALIGNMENT, alignment)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
            glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)
            glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, self.texture_pixel_format, width, height, 0, pformat, GL_UNSIGNED_BYTE, img_data)

            # Draw textured RGB quad at the right coordinates
            glBegin(GL_QUADS)
            glTexCoord2i(0, 0)
            glVertex2i(x, y)
            glTexCoord2i(0, height)
            glVertex2i(x, y+height)
            glTexCoord2i(width, height)
            glVertex2i(x+width, y+height)
            glTexCoord2i(width, 0)
            glVertex2i(x+width, y)
            glEnd()

            # Present update to screen
            self.present_fbo(drawable)
            # present_fbo has reset state already
        finally:
            drawable.gl_end()
        return True
Пример #60
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()