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 create_texture(self): if len(self.unused_texture_list) == 0: self.unused_texture_list.extend(gl.glGenTextures(50)) return self.unused_texture_list.pop()
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)