def __init__(self, font, string, camera=None, color=(255, 255, 255, 255), shadow=(0, 0, 0, 255), shadow_radius=0, font_size=24, margin=5.0, justify='C', background_color=None, shader=None, f_type='', mipmap=True): """Arguments: *font*: File path/name to a TrueType font file. *string*: String to write. *camera*: Camera object passed on to constructor of sprite *color*: Color in format '#RRGGBB', (255,0,0,255), 'orange' etc (as accepted by PIL.ImageDraw) default (255, 255, 255, 255) i.e. white 100% alpha *shadow*: Color of shadow, default black. *shadow_radius*: Gaussian blur radius applied to shadow layer, default 0 (no shadow) *font_size*: Point size for drawing the letters on the internal Texture. default 24 *margin*: Offsets from the top left corner for the text and space on right and bottom. default 5.0 *justify*: L(eft), C(entre), R(ight) default C *background_color*: filled background in ImageDraw format as above. default None i.e. transparent. *shader*: can be passed to init otherwise needs to be set in set_shader or draw. default None *f_type*: filter type. BUMP will generate a normal map (indented by default, +BUMP or BUMP+ will make it stick out), EMBOSS, CONTOUR, BLUR and SMOOTH do what they sound like they will do. """ super(FixedString, self).__init__(font, mipmap=mipmap) self.font = font try: imgfont = ImageFont.truetype(font, font_size) except IOError: abspath = os.path.abspath(font) msg = "Couldn't find font file '%s'" % font if font != abspath: msg = "%s - absolute path is '%s'" % (msg, abspath) raise Exception(msg) justify = justify.upper() f_type = f_type.upper() ascent, descent = imgfont.getmetrics() height = ascent + descent lines = string.split('\n') nlines = len(lines) maxwid = 0 for l in lines: line_wid = imgfont.getsize(l)[0] if line_wid > maxwid: maxwid = line_wid maxwid += 2.0 * margin texture_wid = WIDTHS[0] for l in WIDTHS: if l > maxwid: texture_wid = l break texture_wid = l texture_hgt = int(nlines * height + 2 * margin) self.im = Image.new("RGBA", (texture_wid, texture_hgt), background_color) self.ix, self.iy = texture_wid, texture_hgt draw = ImageDraw.Draw(self.im) if shadow_radius > 0: from PIL import ImageFilter self._render_text(lines, justify, margin, imgfont, maxwid, height, shadow, draw) self.im = self.im.filter( ImageFilter.GaussianBlur(radius=shadow_radius)) if background_color == None: im_arr = self._force_color(np.array(self.im), shadow) try: # numpy not quite working fully in pypy so have to convert tobytes self.im = Image.fromarray(im_arr) except: h, w, c = im_arr.shape rgb = 'RGB' if c == 3 else 'RGBA' self.im = Image.frombytes(rgb, (w, h), im_arr.tobytes()) draw = ImageDraw.Draw(self.im) self._render_text(lines, justify, margin, imgfont, maxwid, height, color, draw) force_color = background_color is None and shadow_radius == 0 if f_type == '': self.image = np.array(self.im) elif 'BUMP' in f_type: amount = -1.0 if '+' in f_type else 1.0 self.image = self._normal_map(np.array(self.im, dtype=np.uint8), amount) force_color = False else: from PIL import ImageFilter if f_type == 'EMBOSS': self.im = self.im.filter(ImageFilter.EMBOSS) elif f_type == 'CONTOUR': self.im = self.im.filter(ImageFilter.CONTOUR) elif f_type == 'BLUR': self.im = self.im.filter(ImageFilter.BLUR) elif f_type == 'SMOOTH': self.im = self.im.filter(ImageFilter.SMOOTH_MORE) self.image = np.array(self.im) if force_color: self.image = self._force_color(self.image, color) self._tex = ctypes.c_uint() bmedge = nlines * height + 2.0 * margin self.sprite = Sprite(camera=camera, w=maxwid, h=bmedge) buf = self.sprite.buf[0] #convenience alias buf.textures = [self] if shader != None: self.sprite.shader = shader buf.shader = shader buf.unib[6] = float(maxwid / texture_wid) #scale to fit buf.unib[7] = float(bmedge / texture_hgt)
def __init__(self, font, string, camera=None, color=(255, 255, 255, 255), outline=(0, 0, 0, 255), outline_size=0, font_size=24, margin=5.0, justify='C', background_color=None, shader=None, f_type='', mipmap=True): """Arguments: *font*: File path/name to a TrueType font file. *string*: String to write. *camera*: Camera object passed on to constructor of sprite *color*: Color in format #RRGGBB, (255,0,0,255) etc (as accepted by PIL.ImageDraw) default (255, 255, 255, 255) i.e. white 100% alpha *font_size*: Point size for drawing the letters on the internal Texture. default 24 *margin*: Offsets from the top left corner for the text and space on right and bottom. default 5.0 *justify*: L(eft), C(entre), R(ight) default C *background_color*: filled background in ImageDraw format as above. default None i.e. transparent. *shader*: can be passed to init otherwise needs to be set in set_shader or draw. default None *f_type*: filter type. BUMP will generate a normal map (indented), EMBOSS, CONTOUR, BLUR and SMOOTH do what they sound like they will do. """ super(FixedOutlineString, self).__init__(font, mipmap=mipmap) self.font = font try: imgfont = ImageFont.truetype(font, font_size) except IOError: abspath = os.path.abspath(font) msg = "Couldn't find font file '%s'" % font if font != abspath: msg = "%s - absolute path is '%s'" % (msg, abspath) raise Exception(msg) justify = justify.upper() f_type = f_type.upper() ascent, descent = imgfont.getmetrics() height = ascent + descent lines = string.split('\n') nlines = len(lines) maxwid = 0 for l in lines: line_wid = imgfont.getsize(l)[0] if line_wid > maxwid: maxwid = line_wid maxwid += 2.0 * margin texture_wid = WIDTHS[0] for l in WIDTHS: if l > maxwid: texture_wid = l break texture_wid = l texture_hgt = int(nlines * height + 2 * margin) self.im = Image.new("RGBA", (texture_wid, texture_hgt), background_color) self.alpha = True self.ix, self.iy = texture_wid, texture_hgt draw = ImageDraw.Draw(self.im) for i, line in enumerate(lines): line_len = imgfont.getsize(line)[0] if justify == "C": xoff = (maxwid - line_len) / 2.0 elif justify == "L": xoff = margin else: xoff = maxwid - line_len # draw the outline by drawing the displaced text repeatedly if outline_size > 0: for xi in range(-outline_size, outline_size + 1): for yi in range(-outline_size, outline_size + 1): if xi != 0 and yi != 0: draw.text((xoff + xi, margin + i * height + yi), line, font=imgfont, fill=outline) draw.text((xoff, margin + i * height), line, font=imgfont, fill=color) if f_type == '': pass elif f_type == 'BUMP': self.im = self.make_bump_map() else: from PIL import ImageFilter if f_type == 'EMBOSS': self.im = self.im.filter(ImageFilter.EMBOSS) elif f_type == 'CONTOUR': self.im = self.im.filter(ImageFilter.CONTOUR) elif f_type == 'BLUR': self.im = self.im.filter(ImageFilter.BLUR) elif f_type == 'SMOOTH': self.im = self.im.filter(ImageFilter.SMOOTH_MORE) #self.image = self.im.convert('RGBA').tostring('raw', 'RGBA') self.im = self.im.convert('RGBA') self.image = np.array(self.im) self._tex = ctypes.c_int() bmedge = nlines * height + 2.0 * margin self.sprite = Sprite(camera=camera, w=maxwid, h=bmedge) buf = self.sprite.buf[0] #convenience alias buf.textures = [self] if shader != None: self.sprite.shader = shader buf.shader = shader buf.unib[6] = float(maxwid / texture_wid) #scale to fit buf.unib[7] = float(bmedge / texture_hgt)
flatsh = Shader("shaders/uv_flat") defocus = Defocus() #Create textures shapeimg = Texture("textures/straw1.jpg") shapebump = Texture("textures/floor_nm.jpg", True) shapeshine = Texture("textures/pong3.png") #Create shape myshape = MergeShape(camera=persp_cam) #specify perspective view asphere = Sphere(sides=16, slices=16) myshape.radialCopy(asphere, step=72) myshape.position(0.0, 0.0, 5.0) myshape.set_draw_details(shader, [shapeimg, shapebump, shapeshine], 8.0, 0.1) mysprite = Sprite(w=10.0, h=10.0, camera=persp_cam) mysprite.position(0.0, 0.0, 15.0) mysprite.set_draw_details(flatsh, [shapebump]) tick = 0 next_time = time.time() + 2.0 #load ttf font and set the font colour to 'raspberry' arialFont = Ttffont("fonts/FreeMonoBoldOblique.ttf", "#dd00aa") mystring = String(font=arialFont, string="blurring with distance!", camera=ortho_cam, z=1.0, is_3d=False) # orthographic view mystring.set_shader(flatsh)
def __init__(self, shader="uv_flat", mipmap=False, separation=0.4, interlace=0): """ calls Texture.__init__ but doesn't need to set file name as texture generated from the framebuffer. Keyword Arguments: *shader* to use when drawing sprite, defaults to uv_flat. *mipmap* can be set to True with slight cost to speed, or use fxaa shader *separation* distance between the two camera positions - how wide apart the eye views are. *interlace* if interlace > 0 then the images are not taken with glScissor and must be drawn with a special interlacing shader. """ # load shader if interlace <= 0: # i.e. default side by side behaviour self.shader = Shader.create(shader) else: self.shader = Shader(vshader_source = """ precision mediump float; attribute vec3 vertex; attribute vec2 texcoord; uniform mat4 modelviewmatrix[2]; varying vec2 texcoordout; void main(void) { texcoordout = texcoord; gl_Position = modelviewmatrix[1] * vec4(vertex,1.0); } """, fshader_source = """ precision mediump float; uniform sampler2D tex0; uniform sampler2D tex1; varying vec2 texcoordout; void main(void) {{ vec4 texc0 = texture2D(tex0, texcoordout); vec4 texc1 = texture2D(tex1, texcoordout); vec2 coord = vec2(gl_FragCoord); gl_FragColor = mix(texc0, texc1, step(0.5, fract(coord.x / {:f}))); }} """.format(interlace * 2.0)) self.camera_3d = Camera() # create 3d cam first so it becomes default instance self.forMtrx = np.identity(4, dtype='float32') # initially not rotated self.position = [0.0, 0.0, 0.0] self.camera_2d = Camera(is_3d=False) self.offs = separation / 2.0 self.interlace = interlace self.textures = [] self.sprites = [] self.tex_list = [] for i in range(2): self.textures.append(OffScreenTexture(name="stereo")) ix, iy = self.textures[i].ix, self.textures[i].iy #two sprites full width but moved so that they are centred on the #left and right edges. The offset values then move the uv mapping #so the image is on the right of the left sprite and left of the #right sprite self.sprites.append(Sprite(z=20.0, w=ix, h=iy, flip=True)) if interlace <= 0: self.sprites[i].positionX(-ix/2.0 + i*ix) self.sprites[i].set_offset((i * 0.5 - 0.25, 0.0)) else: self.sprites[i].set_2d_size(w=ix, h=iy) self.textures[i].blend = True self.textures[i].mipmap = mipmap self.tex_list.append(self.textures[i]) opengles.glColorMask(1, 1, 1, 1)
cloudTex = [] cloudTex.append(Texture("textures/cloud2.png", True)) cloudTex.append(Texture("textures/cloud3.png", True)) cloudTex.append(Texture("textures/cloud4.png", True)) cloudTex.append(Texture("textures/cloud5.png", True)) cloudTex.append(Texture("textures/cloud6.png", True)) # Setup cloud positions and cloud image refs cz = 0.0 clouds = [] # an array for the clouds for b in range(0, cloudno): size = 0.5 + random.random() / 2.0 cloud = Sprite(w=size * widex, h=size * widey, x=150.0 * (random.random() - 0.5), y=0.0, z=cloud_depth - cz) cloud.set_draw_details(shader, [cloudTex[int(random.random() * 4.99999)]], 0.0, 0.0) clouds.append(cloud) cz = cz + zd CAMERA = Camera.instance() CAMERA.position((0.0, 0.0, 50.0)) CAMERA.was_moved = False # Fetch key presses mykeys = Keyboard() while DISPLAY.loop_running(): # the z position of each cloud is held in clouds[i].unif[2] returned by cloud.z()