def __init__(self, **kwargs): Widget.__init__(self, **kwargs) self.canvas = RenderContext(use_parent_projection=True) self.canvas.shader.source = 'starfield.glsl' self.vfmt = ( ('vCenter', 2, 'float'), ('vScale', 1, 'float'), ('vPosition', 2, 'float'), ('vTexCoords0', 2, 'float'), ) self.vsize = sum(attr[1] for attr in self.vfmt) self.indices = [] for i in xrange(0, 4 * NSTARS, 4): self.indices.extend(( i, i + 1, i + 2, i + 2, i + 3, i)) self.vertices = [] for i in xrange(NSTARS): self.vertices.extend(( 0, 0, 1, -24, -24, 0, 1, 0, 0, 1, 24, -24, 1, 1, 0, 0, 1, 24, 24, 1, 0, 0, 0, 1, -24, 24, 0, 0, )) self.texture = Image('star.png').texture self.stars = [Star(self, i) for i in xrange(NSTARS)]
def __init__(self, **kwargs): # Make sure opengl context exists EventLoop.ensure_window() self.canvas = RenderContext(use_parent_projection=True, use_parent_modelview=True) self._callbacks = {} with self.canvas: self.fbo = Fbo(size=self.size) with self.fbo.before: # noqa PushMatrix() with self.fbo: ClearColor(0, 0, 0, 0) ClearBuffers() self._background_color = Color(*self.background_color) self.fbo_rectangle = Rectangle(size=self.size) with self.fbo.after: # noqa PopMatrix() super(EffectWidget, self).__init__(**kwargs) fbind = self.fbind fbo_setup = self.refresh_fbo_setup fbind('size', fbo_setup) fbind('effects', fbo_setup) fbind('background_color', self._refresh_background_color) self.refresh_fbo_setup() self._refresh_background_color() # In case thi was changed in kwargs
def __init__(self, **kwargs): self.canvas = RenderContext() self.pressed_keys = set() Window.bind(on_key_down=self.key_down) Window.bind(on_key_up=self.key_up) super().__init__(**kwargs)
class Starfield(Widget): def __init__(self, **kwargs): Widget.__init__(self, **kwargs) self.canvas = RenderContext(use_parent_projection=True) self.canvas.shader.source = 'starfield.glsl' self.vfmt = ( ('vCenter', 2, 'float'), ('vScale', 1, 'float'), ('vPosition', 2, 'float'), ('vTexCoords0', 2, 'float'), ) self.vsize = sum(attr[1] for attr in self.vfmt) self.indices = [] for i in xrange(0, 4 * NSTARS, 4): self.indices.extend(( i, i + 1, i + 2, i + 2, i + 3, i)) self.vertices = [] for i in xrange(NSTARS): self.vertices.extend(( 0, 0, 1, -24, -24, 0, 1, 0, 0, 1, 24, -24, 1, 1, 0, 0, 1, 24, 24, 1, 0, 0, 0, 1, -24, 24, 0, 0, )) self.texture = Image('star.png').texture self.stars = [Star(self, i) for i in xrange(NSTARS)] def update_glsl(self, nap): x0, y0 = self.center max_distance = 1.1 * max(x0, y0) for i in xrange(NSTARS): star = self.stars[i] star.distance *= 2 * nap + 1 star.size += 0.25 * nap if (star.distance > max_distance): star.reset() else: star.update(x0, y0) self.canvas.clear() with self.canvas: Mesh(fmt=self.vfmt, mode='triangles', indices=self.indices, vertices=self.vertices, texture=self.texture)
class PSWidget(Widget): indices = [] vertices = [] particles = [] def __init__(self, **kwargs): Widget.__init__(self, **kwargs) self.canvas = RenderContext(use_parent_projection=True) self.canvas.shader.source = self.glsl self.vfmt = ( ('vCenter', 2, 'float'), ('vScale', 1, 'float'), ('vPosition', 2, 'float'), ('vTexCoords0', 2, 'float'), ) self.vsize = sum(attr[1] for attr in self.vfmt) self.texture, self.uvmap = load_atlas(self.atlas) def make_particles(self, Cls, num): count = len(self.particles) uv = self.uvmap[Cls.tex_name] for i in xrange(count, count + num): j = 4 * i self.indices.extend(( j, j + 1, j + 2, j + 2, j + 3, j)) self.vertices.extend(( 0, 0, 1, -uv.su, -uv.sv, uv.u0, uv.v1, 0, 0, 1, uv.su, -uv.sv, uv.u1, uv.v1, 0, 0, 1, uv.su, uv.sv, uv.u1, uv.v0, 0, 0, 1, -uv.su, uv.sv, uv.u0, uv.v0, )) p = Cls(self, i) self.particles.append(p) def update_glsl(self, nap): for p in self.particles: p.advance(nap) p.update() self.canvas.clear() with self.canvas: Mesh(fmt=self.vfmt, mode='triangles', indices=self.indices, vertices=self.vertices, texture=self.texture)
def __init__(self, **kwargs): Widget.__init__(self, **kwargs) self.canvas = RenderContext(use_parent_projection=True) self.canvas.shader.source = self.glsl self.vfmt = ( ('vCenter', 2, 'float'), ('vScale', 1, 'float'), ('vPosition', 2, 'float'), ('vTexCoords0', 2, 'float'), ) self.vsize = sum(attr[1] for attr in self.vfmt) self.texture, self.uvmap = load_atlas(self.atlas)
class Screen(Widget): def __init__(self, **kwargs): self.canvas = RenderContext() self.pressed_keys = set() Window.bind(on_key_down=self.key_down) Window.bind(on_key_up=self.key_up) super().__init__(**kwargs) def key_down(self, _, key, *args): self.pressed_keys.add(key) def key_up(self, _, key, *args): self.pressed_keys.discard(key) def render(self, delta): """Override this method and render graphics""" def update(self, delta): """Override this method for updating state""" def on_create(self): """Called when initialized from screen manager""" def on_destroy(self): """Called when removed from screen manager""" def on_open(self): """Called when the screen is opened""" def on_close(self): """Called when the screen is closed""" def on_resize(self, width: int, height: int): """Called on window resize""" def clear(self): self.canvas.clear() def set_projection_matrix(self, matrices): self.canvas['projection_mat'] = matrices[0] self.canvas['modelview_mat'] = matrices[1] def render_screen(self, delta): """Wrapper method for render, should not be overrided""" with self.canvas: self.render(delta)
def __init__(self, **kwargs): self.canvas = RenderContext(use_parent_modelview=True, use_parent_projection=True) self.canvas.shader.source = resource_find('game.glsl') Widget.__init__(self, **kwargs) self.blending_is_broken = blending_is_broken() self.tex, self.tex_uv = load_tex_uv('a.atlas') update_tex_uv(self.tex_uv) self.root_note = NOTES[0] self.scale_class = SCALES[0] self.scale = self.scale_class(self.root_note) self.tuning = TUNING_DEFAULT self.build(False) from kivy.core.window import Window global g_window g_window = Window
def __init__(self, screen_size, font_source=None, font_size=None, fg_color=None, bg_color=None, **kwargs): super().__init__(**kwargs) self.screen_size = screen_size self.fg_color = fg_color or self._fg_color self.bg_color = bg_color or self._bg_color self.font_source = font_source or self._font_source self.font_size = font_size or self._font_size self.font_tex, self.font_map = load_font(self.font_source, self.font_size) self.canvas = RenderContext(use_parent_projection=True) self.canvas.shader.source = self._shader self.console_bg_color()
def __init__(self): super().__init__() self.canvas = RenderContext() self.canvas.shader.source = 'hello_cube.glsl' ff = ((b'my_vertex_position', 3, 'float'), ) vv = (0, 0, 0, 1., 0, 0, 1., 1., 0, 0, 1., 0, 0, 0, 1., 1., 0, 1., 1., 1., 1., 0, 1., 1.) ii = (0, 1, 1, 2, 2, 3, 3, 0, 0, 4, 1, 5, 2, 6, 3, 7, 4, 5, 5, 6, 6, 7, 7, 4) with self.canvas: Mesh(fmt=ff, vertices=vv, indices=ii, mode='lines') self.canvas['center_the_cube'] = Matrix().translate(-.5, -.5, -.5) self.canvas['my_view'] = Matrix().look_at(3, 3, 2, 0, 0, 0, 0, 0, 1) self.canvas['my_proj'] = Matrix() aspect = Window.size[0] / Window.size[1] self.canvas['my_proj'].perspective(30, aspect, .1, 100) Clock.schedule_interval(self.increase_angle, 1 / 60)
def __init__(self, zs, ps, **kwargs): super(Renderer, self).__init__(**kwargs) self.canvas = RenderContext(compute_normal_mat=True) self.canvas.shader.source = resource_find('simple.glsl') #self._keyboard = Window.request_keyboard(self._keyboard_closed, self) self.zs = zs self.ps = ps #self._keyboard.bind(on_key_down=self._on_keyboard_down) #self._keyboard.bind(on_key_up=self._on_keyboard_up) self.shiftDown = False #self.scene = ObjFile(resource_find("monkey.obj")) with self.canvas: self.cb = Callback(self.setup_gl_context) PushMatrix() self.setup_scene() PopMatrix() self.cb = Callback(self.reset_gl_context) Clock.schedule_interval(self.update_glsl, 1 / 60.)
def __init__(self, **kwargs): super(Starfield, self).__init__(**kwargs) self.canvas = RenderContext(use_parent_projection=True) self.canvas.shader.source = 'starfield.glsl' self.vfmt = ( (b'vCenter', 2, 'float'), # Denotes the star's center point on # the screen. (b'vScale', 1, 'float'), # The star's scale factor. 1 being # the original size (48x48 px) (b'vPosition', 2, 'float'), # Position of each vertex relative # to the star's center point. (b'vTexCoords0', 2, 'float'), # Refers to texture coordinates. ) # Note the length of a single vertex in the array of vertices self.vsize = sum(attr[1] for attr in self.vfmt) self.indices = [] for i in range(0, 4 * NSTARS, 4): self.indices.extend(( i, i + 1, i + 2, i + 2, i + 2, i + 3, i )) # Essentially, the vertices contain all the data about our stars that # we need to retain, however this is not ideal to operate on. # So instead, we create a `Star()` class to encapsulate the operations # and computations. It will also contain additional properties such as # size, angle, distance from center, etc. self.vertices = [] for i in range(NSTARS): self.vertices.extend(( 0, 0, 1, -24, -24, 0, 1, 0, 0, 1, 24, -24, 1, 1, 0, 0, 1, 24, 24, 1, 0, 0, 0, 1, -24, 24, 0, 0, )) self.texture = Image('assets/star.png').texture self.stars = [Star(self, i) for i in range(NSTARS)]
def __init__(self, **kwargs): super(Con, self).__init__(**kwargs) self.canvas = RenderContext(use_parent_projection=True) self.canvas.shader.source = 'font_render.glsl' self.scale = 1.0 self.font_size = (8, 12) self.texture, self.uvmap = load_font('terminal8x12_gs_ro.png', self.font_size) self.vfmt = ( (b'vCenter', 2, 'float'), (b'vScale', 1, 'float'), (b'vPosition', 2, 'float'), (b'vTexCoords0', 2, 'float'), (b'vColor', 3, 'float'), ) self.render()
def __init__(self, **kwargs): Widget.__init__(self, **kwargs) self.canvas = RenderContext(use_parent_projection=True) self.canvas.shader.source = 'basic.glsl' fmt = ((b'vPosition', 2, 'float'), ) indices = (0, 1, 2, 2, 3, 0) vertices = ( 0, 0, 255, 0, 255, 255, 0, 255, ) with self.canvas: Mesh(fmt=fmt, mode='triangles', indices=indices, vertices=vertices)
def __init__(self, **kwargs): Widget.__init__(self, **kwargs) self.canvas = RenderContext(use_parent_projection=True) self.canvas.shader.source = 'tex_image.glsl' fmt = ( ('vPosition', 2, 'float'), ('vTexCoords0', 2, 'float'), ) indices = (0, 1, 2, 2, 3, 0) vertices = ( 0, 0, 0, 1, 255, 0, 1, 1, 255, 255, 1, 0, 0, 255, 0, 0, ) with self.canvas: Mesh(fmt=fmt, mode='triangles', indices=indices, vertices=vertices, texture=Image('kivy.png').texture)
def __init__(self, **kwargs): Widget.__init__(self, **kwargs) self.canvas = RenderContext(use_parent_projection=True) self.canvas.shader.source = 'color.glsl' fmt = ( (b'vPosition', 2, 'float'), (b'vColor', 3, 'float'), ) indices = (0, 1, 2, 2, 3, 0) vertices = ( 0, 0, 0.463, 0.839, 1, 255, 0, 0.831, 0.984, 0.474, 255, 255, 1, 0.541, 0.847, 0, 255, 1, 0.988, 0.474, ) with self.canvas: Mesh(fmt=fmt, mode='triangles', indices=indices, vertices=vertices)
def draw(self, canvas: RenderContext): canvas.add(self.color) canvas.add(self.rect) canvas.add(Color(1, 1, 1, 1))
def draw(self, canvas: RenderContext): for row in self.terrain_instructions: for terrain in row: terrain.draw(canvas) canvas.add(self.world_group)
def __init__(self, **kwargs): self.canvas = RenderContext() self.disable = False self.engine = None super().__init__(**kwargs)
class Game(Widget): '''Game renderer''' REPLACE_CURSOR = False def __init__(self, **kwargs): self.canvas = RenderContext(use_parent_modelview=True, use_parent_projection=True) self.canvas.shader.source = resource_find('game.glsl') Widget.__init__(self, **kwargs) self.blending_is_broken = blending_is_broken() self.tex, self.tex_uv = load_tex_uv('a.atlas') update_tex_uv(self.tex_uv) self.root_note = NOTES[0] self.scale_class = SCALES[0] self.scale = self.scale_class(self.root_note) self.tuning = TUNING_DEFAULT self.build(False) from kivy.core.window import Window global g_window g_window = Window def build(self, updating=True): fretboard = build_fretboard(self.scale, self.tuning) if Game.REPLACE_CURSOR: self.begin_cursor = len(fretboard) * VERTEX_SIZE * 4 fretboard += [Quad(x=0, y=0, size=1, tex='cursor')] self.indices = [] ix = self.indices.extend for c in range(0, len(fretboard) << 2, 4): ix((c, c + 1, c + 2, c + 2, c + 3, c)) self.vertices = [] vx = self.vertices.extend self.animate = set() for i, o in enumerate(fretboard): uv = self.tex_uv[o[3]] vx(( o[0], o[1], o[2], -uv[4], -uv[5], uv[0], uv[1], o[0], o[1], o[2], uv[4], -uv[5], uv[2], uv[1], o[0], o[1], o[2], uv[4], uv[5], uv[2], uv[3], o[0], o[1], o[2], -uv[4], uv[5], uv[0], uv[3], )) if o[2] < 1: self.animate.add(i) if updating: self.set_updating() self.update_heading() def set_updating(self): Clock.unschedule(self.update_glsl) Clock.schedule_interval(self.update_glsl, 60 ** -1) on_start = set_updating def update_glsl(self, nap): ''' https://github.com/kivy/kivy/issues/2178 if Game.REPLACE_CURSOR: cur_x, cur_y = g_window.mouse_pos cur_x += CURSOR_OFFSET_X cur_y += CURSOR_OFFSET_Y for c in (self.begin_cursor, self.begin_cursor + VERTEX_SIZE, self.begin_cursor + VERTEX_SIZE * 2, self.begin_cursor + VERTEX_SIZE * 3): self.vertices[c] = cur_x self.vertices[c + 1] = cur_y ''' if self.animate: for i in self.animate.copy(): idx = i * VERTEX_SIZE * 4 + 2 val = self.vertices[idx] * (nap * 25 + 1) if val >= 1: val = 1 self.animate.remove(i) for c in (idx, idx + VERTEX_SIZE, idx + VERTEX_SIZE * 2, idx + VERTEX_SIZE * 3): self.vertices[c] = val if not self.animate and not Game.REPLACE_CURSOR: Clock.unschedule(self.update_glsl) self.canvas.clear() if self.blending_is_broken: self.canvas.before.add(select_blend_func) self.canvas.after.add(reset_blend_func) self.canvas.add(Mesh(indices=self.indices, vertices=self.vertices, fmt=VERTEX_FORMAT, mode='triangles', texture=self.tex)) def set_root_note(self, root_note): self.root_note = root_note self.scale = self.scale_class(self.root_note) self.build() def set_scale_class(self, scale_class): self.scale_class = scale_class self.scale = self.scale_class(self.root_note) self.build() def set_tuning(self, tuning): self.tuning = tuning self.build() _heading = None def update_heading(self): if self._heading: self._heading.text = u'%s \u2013 %s tuning' % (unicode(self.scale), self.tuning['name']) set_animooted = lambda self, val: set_ani(val)
class Starfield(Widget): def __init__(self, **kwargs): super(Starfield, self).__init__(**kwargs) self.canvas = RenderContext(use_parent_projection=True) self.canvas.shader.source = 'starfield.glsl' self.vfmt = ( (b'vCenter', 2, 'float'), # Denotes the star's center point on # the screen. (b'vScale', 1, 'float'), # The star's scale factor. 1 being # the original size (48x48 px) (b'vPosition', 2, 'float'), # Position of each vertex relative # to the star's center point. (b'vTexCoords0', 2, 'float'), # Refers to texture coordinates. ) # Note the length of a single vertex in the array of vertices self.vsize = sum(attr[1] for attr in self.vfmt) self.indices = [] for i in range(0, 4 * NSTARS, 4): self.indices.extend(( i, i + 1, i + 2, i + 2, i + 2, i + 3, i )) # Essentially, the vertices contain all the data about our stars that # we need to retain, however this is not ideal to operate on. # So instead, we create a `Star()` class to encapsulate the operations # and computations. It will also contain additional properties such as # size, angle, distance from center, etc. self.vertices = [] for i in range(NSTARS): self.vertices.extend(( 0, 0, 1, -24, -24, 0, 1, 0, 0, 1, 24, -24, 1, 1, 0, 0, 1, 24, 24, 1, 0, 0, 0, 1, -24, 24, 0, 0, )) self.texture = Image('assets/star.png').texture self.stars = [Star(self, i) for i in range(NSTARS)] def update_glsl(self, nap): """ Implement the starfield motion algorithm. """ # Determine the max distance a star will travel based on the starfield # widget's center. x0, y0 = self.center max_distance = 1.1 * max(x0, y0) for star in self.stars: # We then move the stars towards the max_distance, enlarging it at # the same time. When it reaches the max_distance, we reset it. star.distance *= 2 * nap + 1 star.size += 0.25 * nap if star.distance > max_distance: star.reset() else: star.update(x0, y0) # Finally we draw them on the canvas self.canvas.clear() with self.canvas: Mesh(fmt=self.vfmt, mode='triangles', indices=self.indices, vertices=self.vertices, texture=self.texture)
def __init__(self, **kwargs): Widget.__init__(self, **kwargs) self.canvas = RenderContext(use_parent_projection=True) self.canvas.shader.source = 'tex_atlas.glsl' fmt = ( (b'vCenter', 2, 'float'), (b'vPosition', 2, 'float'), (b'vTexCoords0', 2, 'float'), ) texture, uvmap = load_atlas('icons.atlas') a = uvmap['icon_clock'] vertices = ( 128, 128, -a.su, -a.sv, a.u0, a.v1, 128, 128, a.su, -a.sv, a.u1, a.v1, 128, 128, a.su, a.sv, a.u1, a.v0, 128, 128, -a.su, a.sv, a.u0, a.v0, ) indices = (0, 1, 2, 2, 3, 0) b = uvmap['icon_paint'] vertices += ( 256, 256, -b.su, -b.sv, b.u0, b.v1, 256, 256, b.su, -b.sv, b.u1, b.v1, 256, 256, b.su, b.sv, b.u1, b.v0, 256, 256, -b.su, b.sv, b.u0, b.v0, ) indices += (4, 5, 6, 6, 7, 4) with self.canvas: Mesh(fmt=fmt, mode='triangles', vertices=vertices, indices=indices, texture=texture)
class PSWidget(Widget): """ Abstract class to handle all sprite rendering An instance of this renderer will only hold a single source of texture. """ indices = [] vertices = [] particles = [] def __init__(self, **kwargs): super(PSWidget, self).__init__(**kwargs) self.canvas = RenderContext(use_parent_projection=True) self.canvas.shader.source = self.glsl self.vfmt = ( (b'vCenter', 2, 'float'), (b'vScale', 1, 'float'), (b'vPosition', 2, 'float'), (b'vTexCoords0', 2, 'float'), ) self.vsize = sum(attr[1] for attr in self.vfmt) self.texture, self.uvmap = load_atlas(self.atlas) def make_particles(self, Cls, num): """ Convenience method to add a large number (`num`) of similar particles Parameters ---------- Cls (obj) - Particle class instance. This should implement a `tex_name` property to lookup the correct sprite in the UV mapping. num (int) - Number of particles to add. """ count = len(self.particles) uv = self.uvmap[Cls.tex_name] for i in range(count, count + num): j = 4 * i self.indices.extend(( j, j + 1, j + 2, j + 2, j + 3, j)) self.vertices.extend(( 0, 0, 1, -uv.su, -uv.sv, uv.u0, uv.v1, 0, 0, 1, uv.su, -uv.sv, uv.u1, uv.v1, 0, 0, 1, uv.su, uv.sv, uv.u1, uv.v0, 0, 0, 1, -uv.su, uv.sv, uv.u0, uv.v0, )) p = Cls(self, i) self.particles.append(p) def update_glsl(self, nap): """ Update the canvas. NOTES: Take the ff. into consideration when optimization is necessary: The particles update loop: - This loop should parallelized in full or partially. - This could also be run on another thread completely, and not update on every frame. This may apply to selected particle sub-classes, i.e. stuff in the background that doesn't affect program flow. Parameters ---------- nap (float) - TODO """ # Update the state of all particles for p in self.particles: p.advance(nap) p.update() # Draw the changes self.canvas.clear() with self.canvas: Mesh(fmt=self.vfmt, mode='triangles', indices=self.indices, vertices=self.vertices, texture=self.texture)
def __init__(self, **kwargs): self.canvas = RenderContext(use_parent_projection=True, use_parent_modelview=True, use_parent_frag_modelview=True) super(RootLayout, self).__init__(**kwargs)
class PSWidget(Widget): #widget sınıfı oluşturuldu. indices = [] #indis listesi vertices = [] #köşe listesi particles = [] #particles listesi def __init__(self, **kwargs): #Pencere ayarlaması yapıldı. Widget.__init__(self, **kwargs) self.canvas = RenderContext(use_parent_projection=True) self.canvas.shader.source = self.glsl self.vfmt = ( (b'vCenter', 2, 'float'), (b'vScale', 1, 'float'), (b'vPosition', 2, 'float'), (b'vTexCoords0', 2, 'float'), ) self.vsize = sum(attr[1] for attr in self.vfmt) self.texture, self.uvmap = load_atlas(self.atlas) def make_particles(self, Cls, num): #Particle oluşturma fonksiyonu tanımlandı. count = len(self.particles) uv = self.uvmap[Cls.tex_name] for i in range(count, count + num): j = 4 * i self.indices.extend((j, j + 1, j + 2, j + 2, j + 3, j)) self.vertices.extend(( #particle konumlanması amaçlandı. 0, 0, 1, -uv.su, -uv.sv, uv.u0, uv.v1, 0, 0, 1, uv.su, -uv.sv, uv.u1, uv.v1, 0, 0, 1, uv.su, uv.sv, uv.u1, uv.v0, 0, 0, 1, -uv.su, uv.sv, uv.u0, uv.v0, )) p = Cls(self, i) self.particles.append(p) def update_glsl(self, nap): #update fonksiyonu oluşturuldu. for p in self.particles: p.advance(nap) #advance fonksiyonu çağırıldı. p.update() #update fonksiyonu çağırıldı. self.canvas.clear() #pencerenin temizlenmesi sağlandı. with self.canvas: Mesh(fmt=self.vfmt, mode='triangles', indices=self.indices, vertices=self.vertices, texture=self.texture)
class EffectWidget(RelativeLayout): ''' Widget with the ability to apply a series of graphical effects to its children. See the module documentation for more information on setting effects and creating your own. ''' background_color = ListProperty((0, 0, 0, 0)) '''This defines the background color to be used for the fbo in the EffectWidget. :attr:`background_color` is a :class:`ListProperty` defaults to (0, 0, 0, 0) ''' texture = ObjectProperty(None) '''The output texture of the final :class:`~kivy.graphics.Fbo` after all effects have been applied. texture is an :class:`~kivy.properties.ObjectProperty` and defaults to None. ''' effects = ListProperty([]) '''List of all the effects to be applied. These should all be instances or subclasses of :class:`EffectBase`. effects is a :class:`ListProperty` and defaults to []. ''' fbo_list = ListProperty([]) '''(internal) List of all the fbos that are being used to apply the effects. fbo_list is a :class:`ListProperty` and defaults to []. ''' _bound_effects = ListProperty([]) '''(internal) List of effect classes that have been given an fbo to manage. This is necessary so that the fbo can be removed if the effect is no longer in use. _bound_effects is a :class:`ListProperty` and defaults to []. ''' def __init__(self, **kwargs): # Make sure opengl context exists EventLoop.ensure_window() self.canvas = RenderContext(use_parent_projection=True, use_parent_modelview=True) self._callbacks = {} with self.canvas: self.fbo = Fbo(size=self.size) with self.fbo.before: # noqa PushMatrix() with self.fbo: ClearColor(0, 0, 0, 0) ClearBuffers() self._background_color = Color(*self.background_color) self.fbo_rectangle = Rectangle(size=self.size) with self.fbo.after: # noqa PopMatrix() super(EffectWidget, self).__init__(**kwargs) fbind = self.fbind fbo_setup = self.refresh_fbo_setup fbind('size', fbo_setup) fbind('effects', fbo_setup) fbind('background_color', self._refresh_background_color) self.refresh_fbo_setup() self._refresh_background_color() # In case thi was changed in kwargs def _refresh_background_color(self, *args): # noqa self._background_color.rgba = self.background_color def _propagate_updates(self, *largs): """Propagate updates from widgets.""" del largs for fbo in self.fbo_list: fbo.ask_update() def refresh_fbo_setup(self, *args): # noqa '''(internal) Creates and assigns one :class:`~kivy.graphics.Fbo` per effect, and makes sure all sizes etc. are correct and consistent. ''' # Add/remove fbos until there is one per effect while len(self.fbo_list) < len(self.effects): with self.canvas: new_fbo = EffectFbo(size=self.size) with new_fbo: ClearColor(0, 0, 0, 0) ClearBuffers() Color(1, 1, 1, 1) new_fbo.texture_rectangle = Rectangle(size=self.size) new_fbo.texture_rectangle.size = self.size self.fbo_list.append(new_fbo) while len(self.fbo_list) > len(self.effects): old_fbo = self.fbo_list.pop() self.canvas.remove(old_fbo) # Remove fbos from unused effects for effect in self._bound_effects: if effect not in self.effects: effect.fbo = None self._bound_effects = self.effects # Do resizing etc. self.fbo.size = self.size self.fbo_rectangle.size = self.size for i in range(len(self.fbo_list)): self.fbo_list[i].size = self.size self.fbo_list[i].texture_rectangle.size = self.size # If there are no effects, just draw our main fbo if len(self.fbo_list) == 0: # noqa self.texture = self.fbo.texture return for i in range(1, len(self.fbo_list)): fbo = self.fbo_list[i] fbo.texture_rectangle.texture = self.fbo_list[i - 1].texture # Build effect shaders for effect, fbo in zip(self.effects, self.fbo_list): effect.fbo = fbo self.fbo_list[0].texture_rectangle.texture = self.fbo.texture self.texture = self.fbo_list[-1].texture for fbo in self.fbo_list: fbo.draw() self.fbo.draw() def add_widget(self, widget): # noqa # Add the widget to our Fbo instead of the normal canvas c = self.canvas self.canvas = self.fbo with widget.canvas: self._callbacks[widget.canvas] = Callback(self._propagate_updates) super(EffectWidget, self).add_widget(widget) self.canvas = c def remove_widget(self, widget): # Remove the widget from our Fbo instead of the normal canvas c = self.canvas widget.canvas.remove(self._callbacks[widget.canvas]) del self._callbacks[widget.canvas] self.canvas = self.fbo super(EffectWidget, self).remove_widget(widget) self.canvas = c def clear_widgets(self, children=None): # Clear widgets from our Fbo instead of the normal canvas c = self.canvas self.canvas = self.fbo for canvas, callback in self._callbacks.items(): canvas.remove(callback) self._callbacks = {} super(EffectWidget, self).clear_widgets(children) self.canvas = c
class Console(Widget): _vertices = [] _indices = [] _vfmt = ( (b'vCenter', 2, 'float'), (b'vPosition', 2, 'float'), (b'vTexCoords0', 2, 'float'), (b'vColor', 3, 'float'), (b'isTexFlag', 1, 'float'), ) _vsize = sum(i[1] for i in _vfmt) _fg_color = (1.0, 1.0, 1.0) _bg_color = (0.0, 0.0, 0.0) _shader = 'console.glsl' _font_source = 'terminal8x12_gs_ro.png' _font_size = (8, 12) def __init__(self, screen_size, font_source=None, font_size=None, fg_color=None, bg_color=None, **kwargs): super().__init__(**kwargs) self.screen_size = screen_size self.fg_color = fg_color or self._fg_color self.bg_color = bg_color or self._bg_color self.font_source = font_source or self._font_source self.font_size = font_size or self._font_size self.font_tex, self.font_map = load_font(self.font_source, self.font_size) self.canvas = RenderContext(use_parent_projection=True) self.canvas.shader.source = self._shader self.console_bg_color() @property def max_indice(self): return max(self._indices) + 1 if self._indices else 0 def get_pixel_pos(self, pos, is_bg=False): font_w, font_h = self.font_size tx, ty = pos w, h = font_w * 0.5, font_h * 0.5 x, y = (tx * font_w) + w, (ty * font_h) + h if is_bg: x, y = tx * font_w, ty * font_h return x, y def get_console_pos(self, pos): # TODO: Assuming that the pos coords could be referring to any pixel # within the font size, I need to get the relative bottom right # coords and use that for the tx, ty values instead. This will # increase the accuracy of the translation. font_w, font_h = self.font_size tx, ty = pos x, y = tx / font_w, ty / font_h return round(x, 0), round(y, 0) def console_bg_color(self): self.put_rect((0, 0), self.screen_size, self.bg_color) def put_char(self, char, pos, color=None): x, y = self.get_pixel_pos(pos) r, g, b = color or self.fg_color idx = self.max_indice uv = self.font_map.get(ord(char)) or self.uvmap.get(ord(' ')) self._vertices.extend(( x, y, -uv.su, -uv.sv, uv.u0, uv.v1, r, g, b, 1, x, y, uv.su, -uv.sv, uv.u1, uv.v1, r, g, b, 1, x, y, uv.su, uv.sv, uv.u1, uv.v0, r, g, b, 1, x, y, -uv.su, uv.sv, uv.u0, uv.v0, r, g, b, 1, )) self._indices.extend(( idx, idx + 1, idx + 2, idx + 2, idx + 3, idx )) def put_bg_color(self, pos, color): font_w, font_h = self.font_size x, y = self.get_pixel_pos(pos, is_bg=True) r, g, b = color idx = self.max_indice self._vertices.extend(( x, y, 0, 0, 0, 0, r, g, b, 0, x, y, font_w, 0, 0, 0, r, g, b, 0, x, y, font_w, font_h, 0, 0, r, g, b, 0, x, y, 0, font_h, 0, 0, r, g, b, 0, )) self._indices.extend(( idx, idx + 1, idx + 2, idx + 2, idx + 3, idx )) def put_text(self, text, pos, color=None, wrap=None): x, y = pos start_x = x ctr = 0 for char in iter(text): if isinstance(wrap, int) and ctr >= wrap: ctr = 0 x = start_x y -= 1 if not char.strip() and x == start_x: continue self.put_char(char, pos=(x, y), color=color) x += 1 ctr += 1 def put_rect(self, pos, size, color): font_w, font_h = self.font_size w, h = size x, y = self.get_pixel_pos(pos, is_bg=True) r, g, b = color idx = self.max_indice self._vertices.extend(( x, y, 0, 0, 0, 0, r, g, b, 0, x, y, w * font_w, 0, 0, 0, r, g, b, 0, x, y, w * font_w, h * font_h, 0, 0, r, g, b, 0, x, y, 0, h * font_h, 0, 0, r, g, b, 0, )) self._indices.extend(( idx, idx + 1, idx + 2, idx + 2, idx + 3, idx )) def flush(self): self.canvas.clear() with self.canvas: Mesh(fmt=self._vfmt, mode='triangles', indices=self._indices, vertices=self._vertices, texture=self.font_tex)
def draw_top(self, canvas: RenderContext): canvas.add(self.top_group)
class PSWidget(Widget): indices = [] vertices = [] particles = [] def __init__(self, **kwargs): Widget.__init__(self, **kwargs) self.canvas = RenderContext(use_parent_projection=True) self.canvas.shader.source = self.glsl self.vfmt = ( ('vCenter', 2, 'float'), ('vScale', 1, 'float'), ('vPosition', 2, 'float'), ('vTexCoords0', 2, 'float'), ) self.vsize = sum(attr[1] for attr in self.vfmt) self.texture, self.uvmap = load_atlas(self.atlas) def make_particles(self, Cls, num): count = len(self.particles) uv = self.uvmap[Cls.tex_name] for i in xrange(count, count + num): j = 4 * i self.indices.extend((j, j + 1, j + 2, j + 2, j + 3, j)) self.vertices.extend(( 0, 0, 1, -uv.su, -uv.sv, uv.u0, uv.v1, 0, 0, 1, uv.su, -uv.sv, uv.u1, uv.v1, 0, 0, 1, uv.su, uv.sv, uv.u1, uv.v0, 0, 0, 1, -uv.su, uv.sv, uv.u0, uv.v0, )) p = Cls(self, i) self.particles.append(p) def update_glsl(self, nap): for p in self.particles: p.advance(nap) p.update() self.canvas.clear() with self.canvas: Mesh(fmt=self.vfmt, mode='triangles', indices=self.indices, vertices=self.vertices, texture=self.texture)
def clear(self, canvas: RenderContext): canvas.clear()
class Game(Widget): '''Game renderer''' REPLACE_CURSOR = False def __init__(self, **kwargs): self.canvas = RenderContext(use_parent_modelview=True, use_parent_projection=True) self.canvas.shader.source = resource_find('game.glsl') Widget.__init__(self, **kwargs) self.blending_is_broken = blending_is_broken() self.tex, self.tex_uv = load_tex_uv('a.atlas') update_tex_uv(self.tex_uv) self.root_note = NOTES[0] self.scale_class = SCALES[0] self.scale = self.scale_class(self.root_note) self.tuning = TUNING_DEFAULT self.build(False) from kivy.core.window import Window global g_window g_window = Window def build(self, updating=True): fretboard = build_fretboard(self.scale, self.tuning) if Game.REPLACE_CURSOR: self.begin_cursor = len(fretboard) * VERTEX_SIZE * 4 fretboard += [Quad(x=0, y=0, size=1, tex='cursor')] self.indices = [] ix = self.indices.extend for c in range(0, len(fretboard) << 2, 4): ix((c, c + 1, c + 2, c + 2, c + 3, c)) self.vertices = [] vx = self.vertices.extend self.animate = set() for i, o in enumerate(fretboard): uv = self.tex_uv[o[3]] vx(( o[0], o[1], o[2], -uv[4], -uv[5], uv[0], uv[1], o[0], o[1], o[2], uv[4], -uv[5], uv[2], uv[1], o[0], o[1], o[2], uv[4], uv[5], uv[2], uv[3], o[0], o[1], o[2], -uv[4], uv[5], uv[0], uv[3], )) if o[2] < 1: self.animate.add(i) if updating: self.set_updating() self.update_heading() def set_updating(self): Clock.unschedule(self.update_glsl) Clock.schedule_interval(self.update_glsl, 60**-1) on_start = set_updating def update_glsl(self, nap): ''' https://github.com/kivy/kivy/issues/2178 if Game.REPLACE_CURSOR: cur_x, cur_y = g_window.mouse_pos cur_x += CURSOR_OFFSET_X cur_y += CURSOR_OFFSET_Y for c in (self.begin_cursor, self.begin_cursor + VERTEX_SIZE, self.begin_cursor + VERTEX_SIZE * 2, self.begin_cursor + VERTEX_SIZE * 3): self.vertices[c] = cur_x self.vertices[c + 1] = cur_y ''' if self.animate: for i in self.animate.copy(): idx = i * VERTEX_SIZE * 4 + 2 val = self.vertices[idx] * (nap * 25 + 1) if val >= 1: val = 1 self.animate.remove(i) for c in (idx, idx + VERTEX_SIZE, idx + VERTEX_SIZE * 2, idx + VERTEX_SIZE * 3): self.vertices[c] = val if not self.animate and not Game.REPLACE_CURSOR: Clock.unschedule(self.update_glsl) self.canvas.clear() if self.blending_is_broken: self.canvas.before.add(select_blend_func) self.canvas.after.add(reset_blend_func) self.canvas.add( Mesh(indices=self.indices, vertices=self.vertices, fmt=VERTEX_FORMAT, mode='triangles', texture=self.tex)) def set_root_note(self, root_note): self.root_note = root_note self.scale = self.scale_class(self.root_note) self.build() def set_scale_class(self, scale_class): self.scale_class = scale_class self.scale = self.scale_class(self.root_note) self.build() def set_tuning(self, tuning): self.tuning = tuning self.build() _heading = None def update_heading(self): if self._heading: self._heading.text = u'%s \u2013 %s tuning' % (unicode( self.scale), self.tuning['name']) set_animooted = lambda self, val: set_ani(val)
def __init__(self, **kwargs): super().__init__(**kwargs) self.prog = RenderContext() self.prog.shader.vs = vs self.prog.shader.fs = fs self.canvas = self.prog