def bind_depth_texture(self, size): """Create depth texture for shadow map.""" width, height = size texture_type = GL_TEXTURE_2D self.__depth_map_fbo = glGenFramebuffers(1) depth_map = self.__textures_ids[len(self.__textures)] glBindTexture(texture_type, depth_map) self.__textures.append(2) glTexImage2D(texture_type, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, None) glTexParameteri(texture_type, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexParameteri(texture_type, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(texture_type, GL_TEXTURE_WRAP_S, GL_REPEAT) glTexParameteri(texture_type, GL_TEXTURE_WRAP_T, GL_REPEAT) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS) glBindFramebuffer(GL_FRAMEBUFFER, self.__depth_map_fbo) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_map, 0) glDrawBuffer(GL_NONE) glReadBuffer(GL_NONE) glBindFramebuffer(GL_FRAMEBUFFER, 0)
def _loadTexture(self): """ Load texture data from current image object """ ix, iy, image = self.image_obj.getTextureData() # allocate texture object if never yet done [bruce 060207 revised all related code, to fix bug 1059] if self.tex_name is None: self.tex_name = glGenTextures(1) # note: by experiment (iMac G5 Panther), this returns a single number (1L, 2L, ...), not a list or tuple, # but for an argument >1 it returns a list of longs. We depend on this behavior here. [bruce 060207] # initialize texture data glBindTexture(GL_TEXTURE_2D, self.tex_name) # 2d texture (x and y size) glPixelStorei(GL_UNPACK_ALIGNMENT, 1) self.have_mipmaps = False if debug_pref("smoother tiny textures", Choice_boolean_False, prefs_key=True): #bruce 060212 new feature; only takes effect when image is reloaded for some reason (like "load image" button) gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, ix, iy, GL_RGBA, GL_UNSIGNED_BYTE, image) self.have_mipmaps = True else: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, image) # 0 is mipmap level, GL_RGBA is internal format, ix, iy is size, 0 is borderwidth, # and (GL_RGBA, GL_UNSIGNED_BYTE, image) describe the external image data. [bruce 060212 comment] ## self._initTextureEnv() #bruce 060207 do this in draw method, not here self.assy.o.gl_update() return
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()
def _do_paint_rgb24(self, img_data, x, y, width, height, rowstride, options, callbacks): debug( "%s._do_paint_rgb24(x=%d, y=%d, width=%d, height=%d, rowstride=%d)", self, x, y, width, height, rowstride) drawable = self.gl_init() if not drawable: debug("%s._do_paint_rgb24(..) drawable is not set!", self) return False try: 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( "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) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0) 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(drawable) # present_fbo has reset state already finally: drawable.gl_end() return True
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
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
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()
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
def gl_tex_image_2d(self, image, target=GL_TEXTURE_2D, internal_format=GL_RGBA, border=False, with_mipmaps=False): """Load the currently bound texture with data from an image, with automatic scaling to power-of-2 size and optional mipmap generation.""" border = bool(border) if border and with_mipmaps: raise ValueError("Bordered texture cannot have mipmaps") b2 = 2 * border width, height = image.size twidth = pow2up(width - b2) + b2 theight = pow2up(height - b2) + b2 # print "GUI.GGLTextures.Texture.gl_tex_image_2d: before scaling: size =", (width, height) ### if width <> twidth or height <> theight: # print "GUI.GGLTextures.Texture.gl_tex_image_2d: scaling image to size", (twidth, theight) ### from Pixmaps import Pixmap image2 = Pixmap(twidth, theight) def scale(canvas): image.draw(canvas, (0, 0, width, height), (0, 0, twidth, theight)) image2.with_canvas(scale) image = image2 format, type, data = self._gl_get_texture_data(image) if with_mipmaps: # print "GUI.GGLTextures.Texture.gl_tex_image_2d: loading mipmaps" ### gluBuild2DMipmaps(target, internal_format, twidth, theight, format, type, data) else: # print "GUI.GGLTextures.Texture.gl_tex_image_2d: loading texture" ### glTexImage2D(target, 0, internal_format, twidth, theight, border, format, type, data)
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")
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
def load_texture(self, img: Image) -> None: img_data = np.fromstring(img.tobytes(), np.uint8) width, height = img.size self._texture = glGenTextures(1) glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glBindTexture(GL_TEXTURE_2D, self._texture) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) mode = GL_RGBA if img.mode == "RGB": mode = GL_RGB glTexImage2D( GL_TEXTURE_2D, 0, mode, width, height, 0, mode, GL_UNSIGNED_BYTE, img_data, ) glGenerateMipmap(GL_TEXTURE_2D)
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
def init_back_texture(self, width, height): if self.fbo is None: self.fbo = glGenFramebuffers(1) glActiveTexture(GL_TEXTURE0 + 1) if self.bfTex is not None: glDeleteTextures([self.bfTex]) self.bfTex = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, self.bfTex) glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) w = int(width) h = int(height) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, w, h, 0, GL_RGBA, GL_FLOAT, None) glBindFramebuffer(GL_FRAMEBUFFER, self.fbo) glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, self.bfTex, 0) glBindFramebuffer(GL_FRAMEBUFFER, 0) glBindTexture(GL_TEXTURE_2D, 0)
def _loadTexture(self): """ Load texture data from current image object """ ix, iy, image = self.image_obj.getTextureData() # allocate texture object if never yet done [bruce 060207 revised all related code, to fix bug 1059] if self.tex_name is None: self.tex_name = glGenTextures(1) # note: by experiment (iMac G5 Panther), this returns a single number (1L, 2L, ...), not a list or tuple, # but for an argument >1 it returns a list of longs. We depend on this behavior here. [bruce 060207] # initialize texture data glBindTexture(GL_TEXTURE_2D, self.tex_name) # 2d texture (x and y size) glPixelStorei(GL_UNPACK_ALIGNMENT,1) self.have_mipmaps = False if debug_pref("smoother tiny textures", Choice_boolean_False, prefs_key = True): #bruce 060212 new feature; only takes effect when image is reloaded for some reason (like "load image" button) gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, ix, iy, GL_RGBA, GL_UNSIGNED_BYTE, image) self.have_mipmaps = True else: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, image) # 0 is mipmap level, GL_RGBA is internal format, ix, iy is size, 0 is borderwidth, # and (GL_RGBA, GL_UNSIGNED_BYTE, image) describe the external image data. [bruce 060212 comment] ## self._initTextureEnv() #bruce 060207 do this in draw method, not here self.assy.o.gl_update() return
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()
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)
def gl_init(self): drawable = self.gl_begin() w, h = self.size debug("GL Pixmap backing size: %d x %d, drawable=%s", w, h, drawable) if not drawable: return None if not self.gl_setup: # 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 # Initialize frame_terminator GL debugging extension if available if glInitFrameTerminatorGREMEDY and glInitFrameTerminatorGREMEDY() == True: glFrameTerminatorGREMEDY = 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 # - render to offscreen FBO glEnable(GL_FRAGMENT_PROGRAM_ARB) if self.textures is None: self.textures = glGenTextures(5) debug("textures for wid=%s of size %s : %s", self.wid, 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]) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0) 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) self.gl_setup = True return drawable
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 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
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
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
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 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))
def _update_texture(self, w, h, pixels): print("update_texture id=%s" % self.drawing_area.texture_id) if self.drawing_area.texture_id is not None: glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.drawing_area.texture_id) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels) glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
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()
def set_texture(m): texture_data = np.array(m.texture_image, dtype='int8') m.textureID = glGenTextures(1) glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glBindTexture(GL_TEXTURE_2D, m.textureID) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture_data.shape[1], texture_data.shape[0], 0, GL_BGR, GL_UNSIGNED_BYTE, texture_data.flatten()) glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST) # must be GL_FASTEST, GL_NICEST or GL_DONT_CARE glGenerateMipmap(GL_TEXTURE_2D)
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
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()
def _do_paint_rgb24(self, img_data, x, y, width, height, rowstride, options, callbacks): debug("%s._do_paint_rgb24(x=%d, y=%d, width=%d, height=%d, rowstride=%d)", self, x, y, width, height, rowstride) drawable = self.gl_init() if not drawable: debug("%s._do_paint_rgb24(..) drawable is not set!", self) return False try: 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("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) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0) 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(drawable) # present_fbo has reset state already finally: drawable.gl_end() return True
def __init__(self, w, h, format=GL_RGBA, internalFormat=None): self._id = glGenTextures(1); self._w = w self._h = h if internalFormat is None: internalFormat = format # crashes _sometimes_ when self._w * self._h > 888*888 glBindTexture(GL_TEXTURE_2D, self._id); glTexImage2D(GL_TEXTURE_2D, 0, format, self._w, self._h, 0, internalFormat, GL_UNSIGNED_BYTE, None); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glBindTexture(GL_TEXTURE_2D, 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
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 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 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()
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()
def config_texture(self): w, h = self.size pixels = "\0" * w * h * 4 # Create Texture print("glBindTexture(GL_TEXTURE_RECTANGLE_ARB) size=%s" % str(self.size)) self.texture_id = glGenTextures(1) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.texture_id) print("done") glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels) glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
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
def read_texture(filename): image_data = 0 is_hdr = False size = () if OpenEXR.isOpenExrFile(filename): is_hdr = True img = OpenEXR.InputFile(filename) FLOAT = Imath.PixelType(Imath.PixelType.FLOAT) (r, g, b) = ( img.channel(chan, FLOAT) for chan in ('R', 'G', 'B')) dw = img.header()['dataWindow'] size = (dw.max.x - dw.min.x + 1, dw.max.y - dw.min.y + 1) r_data = np.fromstring(r, dtype=np.float32) g_data = np.fromstring(g, dtype=np.float32) b_data = np.fromstring(b, dtype=np.float32) image_data = np.dstack((r_data, g_data, b_data)) img.close() else: try: image = Image.open(filename) except IOError as ex: print('IOError: failed to open texture file %s' % filename) return -1 print('opened file: size=', image.size, 'format=', image.format) image_data = np.array(list(image.getdata()), np.uint8) size = image.size image.close() texture_id= glGenTextures(1) glPixelStorei(GL_UNPACK_ALIGNMENT, 4) glBindTexture(GL_TEXTURE_2D, texture_id) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0) 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) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) if is_hdr: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, size[0], size[1], 0, GL_RGB, GL_FLOAT, image_data) else: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size[0], size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, image_data) return texture_id
def texturit(filn: str) -> int: """Import a Texture and return the texture buffer handle. Better by RGBA formatted, too.""" wa = glGenTextures(1) with Image.open(filn) as i: ix, iy, im = i.size[0], i.size[1], i.tobytes('raw', 'RGBA') glBindTexture(GL_TEXTURE_2D, wa) glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, im) glGenerateMipmap(GL_TEXTURE_2D) glBindTexture(GL_TEXTURE_2D, 0) return wa
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)
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
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
def get_textureid_with_text(text, fgcolor, bgcolor): if not hasattr(get_textureid_with_text, 'cache'): get_textureid_with_text.cache = {} import zlib uid = str(zlib.crc32(text)) + str(zlib.crc32(np.array(fgcolor))) + str( zlib.crc32(np.array(bgcolor))) if uid not in get_textureid_with_text.cache: from PIL import ImageFont from PIL import Image from PIL import ImageDraw font = ImageFont.truetype( os.path.join(os.path.dirname(__file__), "ressources", "Arial.ttf"), 100) imsize = (128, 128) bgarray = np.asarray(np.zeros((imsize[0], imsize[1], 3)), np.uint8) bgarray[:, :, 0] += bgcolor[0] bgarray[:, :, 1] += bgcolor[1] bgarray[:, :, 2] += bgcolor[2] img = Image.fromarray(bgarray) draw = ImageDraw.Draw(img) w, h = draw.textsize(text, font=font) text_pos = ((imsize[0] - w) / 2, (imsize[1] - h) / 2) draw.text(text_pos, text, fill=tuple(np.asarray(fgcolor, np.uint8)), font=font) texture_data = np.asarray( np.array(img.getdata()).reshape(img.size[0], img.size[1], 3) * 255, np.uint8) textureID = glGenTextures(1) glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glBindTexture(GL_TEXTURE_2D, textureID) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture_data.shape[1], texture_data.shape[0], 0, GL_BGR, GL_UNSIGNED_BYTE, texture_data.flatten()) glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST) # must be GL_FASTEST, GL_NICEST or GL_DONT_CARE glGenerateMipmap(GL_TEXTURE_2D) get_textureid_with_text.cache[uid] = textureID return get_textureid_with_text.cache[uid]
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)
def _create_texture(self): pixels = "\0" * 320 * 240 * 4 w = 320 h = 240 # Create Texture tex_id = glGenTextures(1) print("glBindTexture(GL_TEXTURE_RECTANGLE_ARB)") glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex_id) print("done") glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels) glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) self.texture_id = tex_id
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 draw(self, eyeX, horizonY, cardList): """draw the card in place, using small/large image data as needed """ with pushMatrix(): pos = num.array(self.center) pos[2] += self.z.x if self.zoom: full = [eyeX, horizonY, 6.3] pos = lerp(pos, full, self.zoom) glTranslatef(*pos) layers = [('thumb', 1, self.thumbImage.getData('thumb'))] if self.zoom: data = self.thumbImage.getData('full') if data is not None: layers.append(('full', 1, data)) # once opacity is fadable, and it's at 1, then we # can remove the thumb layer from the list. layers.reverse() # fix opengl draw order so hires is on top for size, opacity, imgData in layers: if imgData is None: # need to unset tx here! glCallList(cardList) # or draw a blank border, maybe some load status # indication else: (w,h), textureData = imgData glBindTexture(GL.GL_TEXTURE_2D, 0) glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, w, h, 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, textureData) glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR) glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR) # card facing +Z from -1<x<1 -1<y<1 glCallList(cardList)
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)
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)
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)
def loadTexture(image_obj, tex_name = 0): #e arg want_mipmaps """ Load texture data from current image object; return have_mipmaps, tex_name (also leave that texture bound, BTW) """ # note: some of this code has been copied into exprs/images.py, class # texture_holder [bruce 061125] ix, iy, image = image_obj.getTextureData() # allocate texture object if necessary if not tex_name: tex_name = glGenTextures(1) # It's deprecated to let this happen much. [070308] print "debug fyi: texture_helpers.loadTexture allocated tex_name %r" %\ (tex_name,) # note: by experiment (iMac G5 Panther), this returns a single number # (1L, 2L, ...), not a list or tuple, but for an argument >1 it returns # a list of longs. We depend on this behavior here. [bruce 060207] tex_name = int(tex_name) # make sure it worked as expected assert tex_name != 0 # initialize texture data glBindTexture(GL_TEXTURE_2D, tex_name) # 2d texture (x and y size) glPixelStorei(GL_UNPACK_ALIGNMENT,1) ###k what's this? have_mipmaps = False ##want_mipmaps = debug_pref("smoother tiny textures", ## Choice_boolean_False, prefs_key = True) want_mipmaps = True if want_mipmaps: gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, ix, iy, GL_RGBA, GL_UNSIGNED_BYTE, image) have_mipmaps = True else: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, image) # 0 is mipmap level, GL_RGBA is internal format, ix, iy is size, 0 # is borderwidth, and (GL_RGBA, GL_UNSIGNED_BYTE, image) describe # the external image data. [bruce 060212 comment] return have_mipmaps, tex_name
def load_texture(image): image = limit_pixels_count(image, args.pixels_limit) width, height = image.size image = image.tostring("raw", "RGBX", 0, -1) # Create Texture _id = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, _id) glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glTexImage2D( GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image ) 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_WRAP_S, GL_REPEAT) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL) return _id
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
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 _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
def setupTransforms(self, transforms): # note: this is only called from test_drawing.py (as of before 090302) """ Fill a block of transforms. Depending on the setting of TEXTURE_XFORMS and UNIFORM_XFORMS, the transforms are either in texture memory, or in a uniform array of mat4s ("constant memory"), or unsupported (error if we need any here). @param transforms: A list of transform matrices, where each transform is a flattened list (or Numpy array) of 16 numbers. """ self.n_transforms = nTransforms = len(transforms) if not self.supports_transforms(): assert not nTransforms, "%r doesn't support transforms" % self return self.setActive(True) # Must activate before setting uniforms. assert self._has_uniform("n_transforms") # redundant with following glUniform1iARB(self._uniform("n_transforms"), self.n_transforms) # The shader bypasses transform logic if n_transforms is 0. # (Then location coordinates are in global modeling coordinates.) if nTransforms > 0: if UNIFORM_XFORMS: # Load into constant memory. The GL_EXT_bindable_uniform # extension supports sharing this array of mat4s through a VBO. # XXX Need to bank-switch this data if more than N_CONST_XFORMS. C_transforms = numpy.array(transforms, dtype = numpy.float32) glUniformMatrix4fvARB(self._uniform("transforms"), # Don't over-run the array size. min(len(transforms), N_CONST_XFORMS), GL_TRUE, # Transpose. C_transforms) elif TEXTURE_XFORMS: # Generate a texture ID and bind the texture unit to it. self.transform_memory = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, self.transform_memory) ## These seem to have no effect with a vertex shader. ## glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) ## glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) # XXX Needed? glEnable(GL_TEXTURE_2D) # Load the transform data into the texture. # # Problem: SIGSEGV kills Python in gleTextureImagePut under # glTexImage2D with more than 250 transforms (16,000 bytes.) # Maybe there's a 16-bit signed size calculation underthere, that's # overflowing the sign bit... Work around by sending transforms to # the texture unit in batches with glTexSubImage2D.) glTexImage2D(GL_TEXTURE_2D, 0, # Level zero - base image, no mipmap. GL_RGBA32F_ARB, # Internal format is floating point. # Column major storage: width = N, height = 4 * RGBA. nTransforms, 4 * 4, 0, # No border. # Data format and type, null pointer to allocate space. GL_RGBA, GL_FLOAT, None) # XXX Split this off into a setTransforms method. batchSize = 250 nBatches = (nTransforms + batchSize-1) / batchSize for i in range(nBatches): xStart = batchSize * i xEnd = min(nTransforms, xStart + batchSize) xSize = xEnd - xStart glTexSubImage2D(GL_TEXTURE_2D, 0, # Subimage x and y offsets and sizes. xStart, 0, xSize, 4 * 4, # List of matrices is flattened into a sequence. GL_RGBA, GL_FLOAT, transforms[xStart:xEnd]) continue # Read back to check proper loading. if CHECK_TEXTURE_XFORM_LOADING: mats = glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT) nMats = len(mats) print "setupTransforms\n[[", for i in range(nMats): nElts = len(mats[i]) perLine = 8 nLines = (nElts + perLine-1) / perLine for line in range(nLines): jStart = perLine * line jEnd = min(nElts, jStart + perLine) for j in range(jStart, jEnd): print "%.2f" % mats[i][j], continue if line < nLines-1: print "\n ", pass if i < nMats-1: print "]\n [", pass continue print "]]" pass else: # should never happen if SUPPORTS_XFORMS is defined correctly assert 0, "can't setupTransforms unless UNIFORM_XFORMS or TEXTURE_XFORMS is set" pass self.setActive(False) # Deactivate again. return