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)
def gl_init_shaders(self): assert self.shaders is None # Create and assign fragment programs self.shaders = [1, 2] glGenProgramsARB(2, self.shaders) for progid, progstr in ((YUV2RGB_SHADER, YUV2RGB_shader), (RGBP2RGB_SHADER, 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)
def gl_init_shaders(self): assert self.shaders is None # Create and assign fragment programs self.shaders = [ 1, 2 ] glGenProgramsARB(2, self.shaders) for progid, progstr in ((YUV2RGB_SHADER, YUV2RGB_shader), (RGBP2RGB_SHADER, 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)
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()
def gl_init_shaders(self): assert self.shaders is None # Create and assign fragment programs self.shaders = [ 1, 2 ] glGenProgramsARB(2, self.shaders) for name, progid, progstr in (("YUV2RGB", YUV2RGB_SHADER, YUV2RGB_shader), ("RGBP2RGB", RGBP2RGB_SHADER, 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: log.error("OpenGL shader %s failed:", name) log.error(" %s", err) raise Exception("OpenGL shader %s setup failure: %s" % (name, err)) else: log("%s shader initialized", name)
def __compile(self, vertSrc, fragSrc): """Called by :meth:`__init__`. Compiles the vertex and fragment programs and returns references to the compiled programs. """ gl.glEnable(arbvp.GL_VERTEX_PROGRAM_ARB) gl.glEnable(arbfp.GL_FRAGMENT_PROGRAM_ARB) # Clear out unnecessary stuff from # the source, and make sure it is # plain ASCII - not unicode. vertSrc = self.__cleanSource(vertSrc) fragSrc = self.__cleanSource(fragSrc) vertSrc = vertSrc.encode('ascii') fragSrc = fragSrc.encode('ascii') fragProg = arbfp.glGenProgramsARB(1) vertProg = arbvp.glGenProgramsARB(1) # vertex program try: arbvp.glBindProgramARB(arbvp.GL_VERTEX_PROGRAM_ARB, vertProg) arbvp.glProgramStringARB(arbvp.GL_VERTEX_PROGRAM_ARB, arbvp.GL_PROGRAM_FORMAT_ASCII_ARB, len(vertSrc), vertSrc) except Exception: position = gl.glGetIntegerv(arbvp.GL_PROGRAM_ERROR_POSITION_ARB) message = gl.glGetString(arbvp.GL_PROGRAM_ERROR_STRING_ARB) message = message.decode('ascii') raise RuntimeError('Error compiling vertex program ({}): ' '{}\n{}'.format(position, message, vertSrc)) # fragment program try: arbfp.glBindProgramARB(arbfp.GL_FRAGMENT_PROGRAM_ARB, fragProg) arbfp.glProgramStringARB(arbfp.GL_FRAGMENT_PROGRAM_ARB, arbfp.GL_PROGRAM_FORMAT_ASCII_ARB, len(fragSrc), fragSrc) except Exception: position = gl.glGetIntegerv(arbfp.GL_PROGRAM_ERROR_POSITION_ARB) message = gl.glGetString(arbfp.GL_PROGRAM_ERROR_STRING_ARB) message = message.decode('ascii') raise RuntimeError('Error compiling fragment program ({}): ' '{}\n{}'.format(position, message, fragSrc)) gl.glDisable(arbvp.GL_VERTEX_PROGRAM_ARB) gl.glDisable(arbfp.GL_FRAGMENT_PROGRAM_ARB) return vertProg, fragProg
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()
def paint_yuv420(self, img_data, x, y, width, height, rowstrides): #import time #before=time.time() # OpenGL begin if not self.gldrawable.gl_begin(self.glcontext): log.error("OUCH") return False # Upload texture if self.textures[0] == 0: self.textures = glGenTextures(3) 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]) # The following fragprog is: # * MIT X11 license, Copyright (c) 2007 by: # * Michael Dominic K. <*****@*****.**> #http://www.mdk.org.pl/2007/11/17/gl-colorspace-conversions prog = """!!ARBfp1.0 # cgc version 3.1.0010, build date Feb 10 2012 # command line args: -profile arbfp1 # source file: yuv.cg #vendor NVIDIA Corporation #version 3.1.0.10 #profile arbfp1 #program main #semantic main.IN #var float2 IN.texcoord1 : $vin.TEXCOORD0 : TEX0 : 0 : 1 #var float2 IN.texcoord2 : $vin.TEXCOORD1 : TEX1 : 0 : 1 #var float2 IN.texcoord3 : $vin.TEXCOORD2 : TEX2 : 0 : 1 #var samplerRECT IN.texture1 : TEXUNIT0 : texunit 0 : 0 : 1 #var samplerRECT IN.texture2 : TEXUNIT1 : texunit 1 : 0 : 1 #var samplerRECT IN.texture3 : TEXUNIT2 : texunit 2 : 0 : 1 #var float4 IN.color : $vin.COLOR0 : COL0 : 0 : 1 #var float4 main.color : $vout.COLOR0 : COL : -1 : 1 #const c[0] = 1.1643835 2.017231 0 0.5 #const c[1] = 0.0625 1.1643835 -0.3917616 -0.81296802 #const c[2] = 1.1643835 0 1.5960271 PARAM c[3] = { { 1.1643835, 2.017231, 0, 0.5 }, { 0.0625, 1.1643835, -0.3917616, -0.81296802 }, { 1.1643835, 0, 1.5960271 } }; TEMP R0; TEMP R1; TEX R0.x, fragment.texcoord[2], texture[2], RECT; ADD R1.z, R0.x, -c[0].w; TEX R1.x, fragment.texcoord[0], texture[0], RECT; TEX R0.x, fragment.texcoord[1], texture[1], RECT; ADD R1.x, R1, -c[1]; ADD R1.y, R0.x, -c[0].w; DP3 result.color.z, R1, c[0]; DP3 result.color.y, R1, c[1].yzww; DP3 result.color.x, R1, c[2]; MOV result.color.w, fragment.color.primary; END # 10 instructions, 2 R-regs """ glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, len(prog), prog) log.error(glGetString(GL_PROGRAM_ERROR_STRING_ARB)) glEnable(GL_FRAGMENT_PROGRAM_ARB) glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv420_shader[0]) 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) glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[0]) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[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) glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[1]) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, width / 2, height / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[1]) 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) glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[2]) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, width / 2, height / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[2]) vtxarrays = 0 if vtxarrays == 1: texcoords = [[0, 0], [0, height], [width, height], [width, 0]] vtxcoords = texcoords texcoords_half = [[0, 0], [0, height / 2], [width / 2, height / 2], [width / 2, 0]] glVertexPointeri(vtxcoords) glActiveTexture(GL_TEXTURE0) glClientActiveTexture(GL_TEXTURE0) glEnableClientState(GL_TEXTURE_COORD_ARRAY) glTexCoordPointeri(texcoords) glActiveTexture(GL_TEXTURE1) glClientActiveTexture(GL_TEXTURE1) glEnableClientState(GL_TEXTURE_COORD_ARRAY) glTexCoordPointeri(texcoords_half) glActiveTexture(GL_TEXTURE2) glClientActiveTexture(GL_TEXTURE2) glEnableClientState(GL_TEXTURE_COORD_ARRAY) glTexCoordPointeri(texcoords_half) glDrawArrays(GL_QUADS, 0, 4) else: glBegin(GL_QUADS) glMultiTexCoord2i(GL_TEXTURE0, 0, 0) glMultiTexCoord2i(GL_TEXTURE1, 0, 0) glMultiTexCoord2i(GL_TEXTURE2, 0, 0) glVertex2i(0, 0) glMultiTexCoord2i(GL_TEXTURE0, 0, height) glMultiTexCoord2i(GL_TEXTURE1, 0, height / 2) glMultiTexCoord2i(GL_TEXTURE2, 0, height / 2) glVertex2i(0, height) glMultiTexCoord2i(GL_TEXTURE0, width, height) glMultiTexCoord2i(GL_TEXTURE1, width / 2, height / 2) glMultiTexCoord2i(GL_TEXTURE2, width / 2, height / 2) glVertex2i(width, height) glMultiTexCoord2i(GL_TEXTURE0, width, 0) glMultiTexCoord2i(GL_TEXTURE1, width / 2, 0) glMultiTexCoord2i(GL_TEXTURE2, width / 2, 0) glVertex2i(width, 0) glEnd() # OpenGL end #self.gldrawable.swap_buffers() # self.gldrawable.swap_buffers() glFinish() self.gldrawable.gl_end()
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()
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()
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
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
def paint_yuv420(self, img_data, x, y, width, height, rowstrides): #import time #before=time.time() # OpenGL begin if not self.gldrawable.gl_begin(self.glcontext): log.error("OUCH") return False # Upload texture if self.textures[0] == 0: self.textures = glGenTextures(3) 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]) # The following fragprog is: # * MIT X11 license, Copyright (c) 2007 by: # * Michael Dominic K. <*****@*****.**> #http://www.mdk.org.pl/2007/11/17/gl-colorspace-conversions prog = """!!ARBfp1.0 # cgc version 3.1.0010, build date Feb 10 2012 # command line args: -profile arbfp1 # source file: yuv.cg #vendor NVIDIA Corporation #version 3.1.0.10 #profile arbfp1 #program main #semantic main.IN #var float2 IN.texcoord1 : $vin.TEXCOORD0 : TEX0 : 0 : 1 #var float2 IN.texcoord2 : $vin.TEXCOORD1 : TEX1 : 0 : 1 #var float2 IN.texcoord3 : $vin.TEXCOORD2 : TEX2 : 0 : 1 #var samplerRECT IN.texture1 : TEXUNIT0 : texunit 0 : 0 : 1 #var samplerRECT IN.texture2 : TEXUNIT1 : texunit 1 : 0 : 1 #var samplerRECT IN.texture3 : TEXUNIT2 : texunit 2 : 0 : 1 #var float4 IN.color : $vin.COLOR0 : COL0 : 0 : 1 #var float4 main.color : $vout.COLOR0 : COL : -1 : 1 #const c[0] = 1.1643835 2.017231 0 0.5 #const c[1] = 0.0625 1.1643835 -0.3917616 -0.81296802 #const c[2] = 1.1643835 0 1.5960271 PARAM c[3] = { { 1.1643835, 2.017231, 0, 0.5 }, { 0.0625, 1.1643835, -0.3917616, -0.81296802 }, { 1.1643835, 0, 1.5960271 } }; TEMP R0; TEMP R1; TEX R0.x, fragment.texcoord[2], texture[2], RECT; ADD R1.z, R0.x, -c[0].w; TEX R1.x, fragment.texcoord[0], texture[0], RECT; TEX R0.x, fragment.texcoord[1], texture[1], RECT; ADD R1.x, R1, -c[1]; ADD R1.y, R0.x, -c[0].w; DP3 result.color.z, R1, c[0]; DP3 result.color.y, R1, c[1].yzww; DP3 result.color.x, R1, c[2]; MOV result.color.w, fragment.color.primary; END # 10 instructions, 2 R-regs """ glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, len(prog), prog) log.error(glGetString(GL_PROGRAM_ERROR_STRING_ARB)) glEnable(GL_FRAGMENT_PROGRAM_ARB) glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv420_shader[0]) 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); glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[0]) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[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); glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[1]) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, width/2, height/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[1]); 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); glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[2]) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, width/2, height/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[2]); vtxarrays=0 if vtxarrays == 1: texcoords = [ [ 0, 0 ], [ 0, height], [ width, height], [ width, 0] ] vtxcoords = texcoords texcoords_half = [ [ 0, 0 ], [ 0, height/2], [ width/2, height/2], [ width/2, 0] ] glVertexPointeri(vtxcoords) glActiveTexture(GL_TEXTURE0); glClientActiveTexture(GL_TEXTURE0) glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointeri(texcoords) glActiveTexture(GL_TEXTURE1); glClientActiveTexture(GL_TEXTURE1) glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointeri(texcoords_half) glActiveTexture(GL_TEXTURE2); glClientActiveTexture(GL_TEXTURE2) glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointeri(texcoords_half) glDrawArrays(GL_QUADS, 0, 4); else: glBegin(GL_QUADS); glMultiTexCoord2i(GL_TEXTURE0, 0, 0); glMultiTexCoord2i(GL_TEXTURE1, 0, 0); glMultiTexCoord2i(GL_TEXTURE2, 0, 0); glVertex2i(0, 0); glMultiTexCoord2i(GL_TEXTURE0, 0, height); glMultiTexCoord2i(GL_TEXTURE1, 0, height/2); glMultiTexCoord2i(GL_TEXTURE2, 0, height/2); glVertex2i(0, height); glMultiTexCoord2i(GL_TEXTURE0, width, height); glMultiTexCoord2i(GL_TEXTURE1, width/2, height/2); glMultiTexCoord2i(GL_TEXTURE2, width/2, height/2); glVertex2i(width, height); glMultiTexCoord2i(GL_TEXTURE0, width, 0); glMultiTexCoord2i(GL_TEXTURE1, width/2, 0); glMultiTexCoord2i(GL_TEXTURE2, width/2, 0); glVertex2i(width, 0); glEnd() # OpenGL end #self.gldrawable.swap_buffers() # self.gldrawable.swap_buffers() glFinish() self.gldrawable.gl_end()
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)