def load_textures(self, max_num=10): loaded = 0 target = gl.GL_TEXTURE_2D with self.lock: try: for ip in self.image_list: if loaded == max_num: break texture = self.texture_dict[ip] if texture is not None: continue pixels, size = self.image_dict[ip] if pixels is False: # queued # self.texture_dict[ip] = Texture.default_item continue if pixels is None: # could not load # self.texture_dict[ip] = Texture(0, size=(0, 0)) # self.texture_dict[ip] = Texture.default_item self.texture_dict[ip] = Texture.default_item continue texture = gl.glGenTextures(1) self.texture_dict[ip] = Texture( texture, size=(size[0], size[1]) ) self.delay_set.add(ip) self.lock.release() gl.glBindTexture(target, texture) gl.glTexImage2D( target, 0, gl.GL_RGBA, size[0], size[1], 0, TEXTURE_FORMAT, gl.GL_UNSIGNED_BYTE, pixels, ) gl.glTexParameteri( target, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR ) gl.glTexParameteri( target, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR ) gl.glTexParameteri( target, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE ) gl.glTexParameteri( target, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE ) loaded += 1 self.lock.acquire() except Exception as e: print(e)
def load_textures(self, max_num=10): loaded = 0 target = gl.GL_TEXTURE_2D with self.lock: try: for ip in self.image_list: if loaded == max_num: break texture = self.texture_dict[ip] if texture is not None: continue pixels, size = self.image_dict[ip] if pixels is False: # queued # self.texture_dict[ip] = Texture.default_item continue if pixels is None: # could not load # self.texture_dict[ip] = Texture(0, size=(0, 0)) # self.texture_dict[ip] = Texture.default_item self.texture_dict[ip] = Texture.default_item continue texture = gl.glGenTextures(1) self.texture_dict[ip] = Texture( texture, size=(size[0], size[1])) self.delay_set.add(ip) self.lock.release() gl.glBindTexture(target, texture) gl.glTexImage2D( target, 0, gl.GL_RGBA, size[0], size[1], 0, TEXTURE_FORMAT, gl.GL_UNSIGNED_BYTE, pixels) gl.glTexParameteri( target, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) gl.glTexParameteri( target, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) gl.glTexParameteri( target, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE) gl.glTexParameteri( target, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE) loaded += 1 self.lock.acquire() except Exception as e: print(e)
def text( self, text, font, x, y, w=0, h=0, color=(1.0, 1.0, 1.0, 1.0), shadow=False, shadow_color=(0, 0, 0), halign=-1, ): if not text: return 0, 0 # if len(color) == 3: # color = (color[0], color[1], color[2], 1.0 try: alpha = color[3] except IndexError: alpha = 1.0 color = ( int(round(color[0] * 255)), int(round(color[1] * 255)), int(round(color[2] * 255)), ) cache_key = (text, hash(font), font.size, color, alpha) try: self.text_cache_history.remove(cache_key) except ValueError: texture = None else: texture, txtsize = self.text_cache[cache_key] fs_emu_blending(True) fs_emu_texturing(True) gl.glDisable(gl.GL_DEPTH_TEST) if texture: gl.glBindTexture(gl.GL_TEXTURE_2D, texture) else: txtdata, txtsize = TextRenderer(font).render_text(text, color) texture = Render.get().create_texture() gl.glBindTexture(gl.GL_TEXTURE_2D, texture) gl.glTexImage2D( gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, txtsize[0], txtsize[1], 0, gl.GL_BGRA, gl.GL_UNSIGNED_BYTE, txtdata, ) gl.glTexParameteri( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR ) gl.glTexParameteri( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR ) tw, th = ( txtsize[0] * self.ortho_pscalex, txtsize[1] * self.ortho_pscaley, ) tx = x ty = y if w > 0: if tw > w: tw = w else: if halign == 0: tx += (w - tw) / 2 if h > 0: ty += (h - th) / 2 # ts = 4 / cls.display_height # Step # glDisable(GL_TEXTURE_RECTANGLE_ARB) # glTexEnv(GL_TEXTURE_2D, GL_MODULATE) # glDisable(GL_TEXTURE_RECTANGLE) # fs_emu_blending(True) gl.glBegin(gl.GL_QUADS) gl.glColor4f(alpha, alpha, alpha, alpha) gl.glTexCoord2f(0.0, 0.0) gl.glVertex2f(tx, ty + th) gl.glTexCoord2f(1.0, 0.0) gl.glVertex2f(tx + tw, ty + th) gl.glTexCoord2f(1.0, 1.0) gl.glVertex2f(tx + tw, ty) gl.glTexCoord2f(0.0, 1.0) gl.glVertex2f(tx, ty) # glRasterPos2f(tx, ty) # glDrawPixels(txtsize[0], txtsize[1], GL_RGBA, GL_UNSIGNED_BYTE, # txtdata) gl.glEnd() # fs_emu_blending(False) gl.glEnable(gl.GL_DEPTH_TEST) self.text_cache_history.append(cache_key) self.text_cache[cache_key] = texture, txtsize if len(self.text_cache) > TEXT_CACHE_SIZE: cache_key = self.text_cache_history.pop(0) texture, txtsize = self.text_cache.pop(cache_key) Render.get().delete_texture_list.append(texture) # # FIXME: # shadow = False # # glDisable(GL_DEPTH_TEST) # fs_emu_blending(True) # #text = current_menu.selected_item.title # #if shadow: # txtdata, txtsize = TextRenderer(font).render_text(text, shadow_color) # tw, th = txtsize[0] * ortho_pscalex, txtsize[1] * ortho_pscaley # tx = x # ty = y # if w > 0: # tx = tx + (w - tw) / 2 # if h > 0: # ty = ty + (h - th) / 2 # #tx = 0 - tw / 2 # #ty = -0.67 # ts = 4 / State.get().display_height # Step # if shadow: # glPixelTransferf(GL_ALPHA_SCALE, 0.04) # for fx, fy in [(1, 1), (-1, -1), (1, -1), (-1, 1), (1, 0), (-1, # 0), # (0, -1), (0, 1)]: # glRasterPos2f(tx - fx * ts, ty - fy * ts) # glDrawPixels(txtsize[0], txtsize[1], GL_RGBA, # GL_UNSIGNED_BYTE, # txtdata) # glPixelTransferf(GL_ALPHA_SCALE, 0.01) # for fx, fy in [(0, 2), (2, 0), (0, -2), (-2, 0), # (1, 2), (2, 1), (-1, 2), (-2, 1), (1, -2), # (2, -1), (-1, -2), (-2, -1)]: # glRasterPos2f(tx - fx * ts, ty - fy * ts) # glDrawPixels(txtsize[0], txtsize[1], GL_RGBA, # GL_UNSIGNED_BYTE, # txtdata) # glPixelTransferf(GL_ALPHA_SCALE, alpha) # rendered = font.render(text, True, color) # txtsize = rendered.get_size() # txtdata = pygame.image.tostring(rendered, "RGBA", 1) # glRasterPos2f(tx, ty) # glDrawPixels(txtsize[0], txtsize[1], GL_RGBA, GL_UNSIGNED_BYTE, # txtdata) # #glPopAttrib() # glPixelTransferf(GL_ALPHA_SCALE, 1.0) # fs_emu_blending(False) # glEnable(GL_DEPTH_TEST) return tw, th
def load(cls, im, mipmap=False, min_filter=None, wrap_s=gl.GL_CLAMP_TO_EDGE, wrap_t=gl.GL_CLAMP_TO_EDGE, target=gl.GL_TEXTURE_2D, size=None, out_data=None): if size is None: size = [0, 0] # type = "RGB" # gl_type = gl.GL_RGB # if im.mode == "RGBA": # # convert to premultiplied alpha # #pix = im.load() # #for x in range(im.size[0]): # # for y in range(im.size[1]): # # r, g, b, a = pix[x, y] # # if a: # # pix[x, y] = r * 255 // a, g * 255 // a, \ # # b * 255 // a, a # # else: # # pix[x, y] = 0, 0, 0, 0 # a = numpy.fromstring(im.tostring(), dtype=numpy.uint8) # alpha_layer = a[3::4] / 255.0 # a[0::4] *= alpha_layer # a[1::4] *= alpha_layer # a[2::4] *= alpha_layer # #im = Image.fromstring("RGBA", im.size, a.tostring()) # im_data = a.tostring() # # type = "RGBA" # gl_type = gl.GL_RGBA # else: # im_data = im.tostring("raw", "RGB") # # size[0] = im.size[0] # size[1] = im.size[1] # #texture = glGenTextures(1) internal_format = gl.GL_RGBA texture_format = gl.GL_BGRA if im.format() != QImage.Format_ARGB32_Premultiplied: im = im.convertToFormat(QImage.Format_ARGB32_Premultiplied) bits = im.bits() try: pixels = bits.tobytes() except AttributeError: bits.setsize(im.byteCount()) pixels = bytes(bits) size[0] = im.width() size[1] = im.height() from arcade.glui.render import Render texture = Render.get().create_texture() gl.glBindTexture(target, texture) gl.glTexImage2D(target, 0, internal_format, size[0], size[1], 0, texture_format, gl.GL_UNSIGNED_BYTE, pixels) if mipmap: gl.glGenerateMipmap(target) if min_filter is None: min_filter = gl.GL_LINEAR_MIPMAP_LINEAR else: if min_filter is None: min_filter = gl.GL_LINEAR gl.glTexParameteri(target, gl.GL_TEXTURE_MIN_FILTER, min_filter) gl.glTexParameteri(target, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) gl.glTexParameteri(target, gl.GL_TEXTURE_WRAP_S, wrap_s) gl.glTexParameteri(target, gl.GL_TEXTURE_WRAP_T, wrap_t) if out_data is not None: out_data["im_data"] = pixels out_data["type"] = internal_format return texture
def render(self, text, x, y, r=1.0, g=1.0, b=1.0, alpha=1.0): global text_cache if not text: return 0 # find cached text entry, if any for i, item in enumerate(text_cache): if item["text"] == text and item["font"] == self: text_cache.pop(i) break else: item = None if item: fs_emu_blending(True) fs_emu_texturing(True) w = item["w"] h = item["h"] gl.glBindTexture(gl.GL_TEXTURE_2D, item["texture"]) gl.glBegin(gl.GL_QUADS) gl.glColor4f(r * alpha, g * alpha, b * alpha, alpha) gl.glTexCoord2d(0.0, 0.0) gl.glVertex2d(x, y) gl.glTexCoord2d(1.0, 0.0) gl.glVertex2d(x + w, y) gl.glTexCoord2d(1.0, 1.0) gl.glVertex2d(x + w, y + h) gl.glTexCoord2d(0.0, 1.0) gl.glVertex2d(x, y + h) gl.glEnd() # re-insert item at front text_cache.insert(0, item) return w, h # calculate size of text required_width, required_height = self.measure(text) # setup fbo render_texture = gl.glGenTextures(1) gl.glBindTexture(gl.GL_TEXTURE_2D, render_texture) gl.glTexImage2D( gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, required_width, required_height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_INT, None, ) gl.glTexParameteri( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE ) gl.glTexParameteri( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE ) gl.glTexParameteri( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR ) # FIXME: Mipmapping? mip_mapping = 0 if mip_mapping: gl.glTexParameteri( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR_MIPMAP_LINEAR, ) gl.glTexParameteri( gl.GL_TEXTURE_2D, gl.GL_GENERATE_MIPMAP, gl.GL_TRUE ) gl.glGenerateMipmapEXT(gl.GL_TEXTURE_2D) else: gl.glTexParameteri( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR ) gl.glBindTexture(gl.GL_TEXTURE_2D, 0) # Set up some renderbuffer state frame_buffer = gl.GLuint() gl.glGenFramebuffersEXT(1, frame_buffer) gl.glBindFramebufferEXT(gl.GL_FRAMEBUFFER_EXT, frame_buffer) gl.glFramebufferTexture2DEXT( gl.GL_FRAMEBUFFER_EXT, gl.GL_COLOR_ATTACHMENT0_EXT, gl.GL_TEXTURE_2D, render_texture, 0, ) status = gl.glCheckFramebufferStatusEXT(gl.GL_FRAMEBUFFER_EXT) if status != gl.GL_FRAMEBUFFER_COMPLETE_EXT: print("glCheckFramebufferStatusEXT error", status) gl.glPushMatrix() gl.glLoadIdentity() gl.glPushAttrib(int(gl.GL_VIEWPORT_BIT) | int(gl.GL_ENABLE_BIT)) gl.glViewport(0, 0, required_width, required_height) gl.glMatrixMode(gl.GL_PROJECTION) gl.glPushMatrix() gl.glLoadIdentity() gl.gluOrtho2D(0, required_width, 0, required_height) gl.glClearColor(0.0, 0.0, 0.0, 0.0) gl.glClear(gl.GL_COLOR_BUFFER_BIT) gl.glEnable(gl.GL_BLEND) gl.glEnable(gl.GL_TEXTURE_2D) self.texture.bind() tw = self.texture.w th = self.texture.h gl.glBegin(gl.GL_QUADS) gl.glColor4f(1.0, 1.0, 1.0, 1.0) x2 = 0 h = self.h for ch in text: c = ord(ch) w = self.w[c] s1 = self.x[c] / tw s2 = (self.x[c] + w) / tw t1 = (self.y[c]) / th t2 = (self.y[c] + h) / th gl.glTexCoord2d(s1, t2) gl.glVertex2d(x2, 0) gl.glTexCoord2d(s2, t2) gl.glVertex2d(x2 + w, 0) gl.glTexCoord2d(s2, t1) gl.glVertex2d(x2 + w, h) gl.glTexCoord2d(s1, t1) gl.glVertex2d(x2, h) x2 += w gl.glEnd() gl.glPopMatrix() gl.glMatrixMode(gl.GL_MODELVIEW) gl.glPopAttrib() gl.glBindFramebufferEXT(gl.GL_FRAMEBUFFER_EXT, 0) gl.glPopMatrix() gl.glDeleteFramebuffersEXT(1, frame_buffer) if mip_mapping: gl.glBindTexture(gl.GL_TEXTURE_2D, render_texture) gl.glGenerateMipmapEXT(gl.GL_TEXTURE_2D) gl.glBindTexture(gl.GL_TEXTURE_2D, 0) new_item = { "font": self, "text": text, "w": required_width, "h": required_height, "texture": render_texture, } text_cache.insert(0, new_item) item = text_cache.pop() if item["texture"]: gl.glDeleteTextures([item["texture"]]) # now the text is in the cache, so call function again return self.render(text, x, y, r, g, b, alpha)
def load(cls, im, mipmap=False, min_filter=None, wrap_s=gl.GL_CLAMP_TO_EDGE, wrap_t=gl.GL_CLAMP_TO_EDGE, target=gl.GL_TEXTURE_2D, size=None, out_data=None): if size is None: size = [0, 0] # type = "RGB" # gl_type = gl.GL_RGB # if im.mode == "RGBA": # # convert to premultiplied alpha # #pix = im.load() # #for x in range(im.size[0]): # # for y in range(im.size[1]): # # r, g, b, a = pix[x, y] # # if a: # # pix[x, y] = r * 255 // a, g * 255 // a, \ # # b * 255 // a, a # # else: # # pix[x, y] = 0, 0, 0, 0 # a = numpy.fromstring(im.tostring(), dtype=numpy.uint8) # alpha_layer = a[3::4] / 255.0 # a[0::4] *= alpha_layer # a[1::4] *= alpha_layer # a[2::4] *= alpha_layer # #im = Image.fromstring("RGBA", im.size, a.tostring()) # im_data = a.tostring() # # type = "RGBA" # gl_type = gl.GL_RGBA # else: # im_data = im.tostring("raw", "RGB") # # size[0] = im.size[0] # size[1] = im.size[1] # #texture = glGenTextures(1) internal_format = gl.GL_RGBA texture_format = gl.GL_BGRA if im.format() != QImage.Format_ARGB32_Premultiplied: im = im.convertToFormat(QImage.Format_ARGB32_Premultiplied) bits = im.bits() try: pixels = bits.tobytes() except AttributeError: bits.setsize(im.byteCount()) pixels = bytes(bits) size[0] = im.width() size[1] = im.height() from arcade.glui.render import Render texture = Render.get().create_texture() gl.glBindTexture(target, texture) gl.glTexImage2D( target, 0, internal_format, size[0], size[1], 0, texture_format, gl.GL_UNSIGNED_BYTE, pixels) if mipmap: gl.glGenerateMipmap(target) if min_filter is None: min_filter = gl.GL_LINEAR_MIPMAP_LINEAR else: if min_filter is None: min_filter = gl.GL_LINEAR gl.glTexParameteri(target, gl.GL_TEXTURE_MIN_FILTER, min_filter) gl.glTexParameteri(target, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) gl.glTexParameteri(target, gl.GL_TEXTURE_WRAP_S, wrap_s) gl.glTexParameteri(target, gl.GL_TEXTURE_WRAP_T, wrap_t) if out_data is not None: out_data["im_data"] = pixels out_data["type"] = internal_format return texture
def text(self, text, font, x, y, w=0, h=0, color=(1.0, 1.0, 1.0, 1.0), shadow=False, shadow_color=(0, 0, 0), halign=-1): if not text: return 0, 0 # if len(color) == 3: # color = (color[0], color[1], color[2], 1.0 try: alpha = color[3] except IndexError: alpha = 1.0 color = (int(round(color[0] * 255)), int(round(color[1] * 255)), int(round(color[2] * 255))) cache_key = (text, hash(font), font.size, color, alpha) try: self.text_cache_history.remove(cache_key) except ValueError: texture = None else: texture, txtsize = self.text_cache[cache_key] fs_emu_blending(True) fs_emu_texturing(True) gl.glDisable(gl.GL_DEPTH_TEST) if texture: gl.glBindTexture(gl.GL_TEXTURE_2D, texture) else: txtdata, txtsize = TextRenderer(font).render_text(text, color) texture = Render.get().create_texture() gl.glBindTexture(gl.GL_TEXTURE_2D, texture) gl.glTexImage2D( gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, txtsize[0], txtsize[1], 0, gl.GL_BGRA, gl.GL_UNSIGNED_BYTE, txtdata) gl.glTexParameteri( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) gl.glTexParameteri( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) tw, th = (txtsize[0] * self.ortho_pscalex, txtsize[1] * self.ortho_pscaley) tx = x ty = y if w > 0: if tw > w: tw = w else: if halign == 0: tx += (w - tw) / 2 if h > 0: ty += (h - th) / 2 # ts = 4 / cls.display_height # Step # glDisable(GL_TEXTURE_RECTANGLE_ARB) # glTexEnv(GL_TEXTURE_2D, GL_MODULATE) # glDisable(GL_TEXTURE_RECTANGLE) # fs_emu_blending(True) gl.glBegin(gl.GL_QUADS) gl.glColor4f(alpha, alpha, alpha, alpha) gl.glTexCoord2f(0.0, 0.0) gl.glVertex2f(tx, ty + th) gl.glTexCoord2f(1.0, 0.0) gl.glVertex2f(tx + tw, ty + th) gl.glTexCoord2f(1.0, 1.0) gl.glVertex2f(tx + tw, ty) gl.glTexCoord2f(0.0, 1.0) gl.glVertex2f(tx, ty) # glRasterPos2f(tx, ty) # glDrawPixels(txtsize[0], txtsize[1], GL_RGBA, GL_UNSIGNED_BYTE, # txtdata) gl.glEnd() # fs_emu_blending(False) gl.glEnable(gl.GL_DEPTH_TEST) self.text_cache_history.append(cache_key) self.text_cache[cache_key] = texture, txtsize if len(self.text_cache) > TEXT_CACHE_SIZE: cache_key = self.text_cache_history.pop(0) texture, txtsize = self.text_cache.pop(cache_key) Render.get().delete_texture_list.append(texture) # # FIXME: # shadow = False # # glDisable(GL_DEPTH_TEST) # fs_emu_blending(True) # #text = current_menu.selected_item.title # #if shadow: # txtdata, txtsize = TextRenderer(font).render_text(text, shadow_color) # tw, th = txtsize[0] * ortho_pscalex, txtsize[1] * ortho_pscaley # tx = x # ty = y # if w > 0: # tx = tx + (w - tw) / 2 # if h > 0: # ty = ty + (h - th) / 2 # #tx = 0 - tw / 2 # #ty = -0.67 # ts = 4 / State.get().display_height # Step # if shadow: # glPixelTransferf(GL_ALPHA_SCALE, 0.04) # for fx, fy in [(1, 1), (-1, -1), (1, -1), (-1, 1), (1, 0), (-1, # 0), # (0, -1), (0, 1)]: # glRasterPos2f(tx - fx * ts, ty - fy * ts) # glDrawPixels(txtsize[0], txtsize[1], GL_RGBA, # GL_UNSIGNED_BYTE, # txtdata) # glPixelTransferf(GL_ALPHA_SCALE, 0.01) # for fx, fy in [(0, 2), (2, 0), (0, -2), (-2, 0), # (1, 2), (2, 1), (-1, 2), (-2, 1), (1, -2), # (2, -1), (-1, -2), (-2, -1)]: # glRasterPos2f(tx - fx * ts, ty - fy * ts) # glDrawPixels(txtsize[0], txtsize[1], GL_RGBA, # GL_UNSIGNED_BYTE, # txtdata) # glPixelTransferf(GL_ALPHA_SCALE, alpha) # rendered = font.render(text, True, color) # txtsize = rendered.get_size() # txtdata = pygame.image.tostring(rendered, "RGBA", 1) # glRasterPos2f(tx, ty) # glDrawPixels(txtsize[0], txtsize[1], GL_RGBA, GL_UNSIGNED_BYTE, # txtdata) # #glPopAttrib() # glPixelTransferf(GL_ALPHA_SCALE, 1.0) # fs_emu_blending(False) # glEnable(GL_DEPTH_TEST) return tw, th