def run(self, window): """Starts an event loop without actually processing any event. """ running = True while running: event = events.poll_event(True) while event is not None: if event.type == events.SDL_QUIT: running = False break window.refresh() timer.delay(10)
def loop(window, bg_color, fbo_color, grid, hud, panels, choke): fbo = FBO(Size2(window._w, window._h)) choke_ms = 0 if choke == 0 else 1000 // choke while True: loopstart = sdltimer.get_ticks() while True: event = sdlevents.poll_event(True) if event is None: break elif event.type == sdlevents.SDL_QUIT: return elif event.type == sdlevents.SDL_KEYUP: if event.key.keysym.sym == sdlkeys.SDLK_ESCAPE: return elif event.type == sdlevents.SDL_WINDOWEVENT: if event.window.event == sdlvideo.SDL_WINDOWEVENT_RESIZED: sz = Size2(event.window.data1, event.window.data2) fbo.resize(sz) grid.reshape(sz) hud.reshape(sz) elif event.type == sdlevents.SDL_MOUSEBUTTONDOWN: return glcalltrace("frame") glClearColor(*bg_color) glClear(GL_COLOR_BUFFER_BIT) glcalltrace("fbo.bind()") fbo.bind(fbo_color) glcalltrace("grid.render()") grid.render() glcalltrace("fbo.blit()") fbo.blit(Rect(0, 0, window._w, window._h)) glcalltrace("hud.render()") hud.render(panels) sdl_flip(window) elapsed = sdltimer.get_ticks() - loopstart if choke_ms > elapsed: sdltimer.delay(choke_ms - elapsed)
def loop(self, window, bg_color, choke): self.resize(Size2(window._w, window._h)) blit = Blitter() choke_ms = 0 if choke == 0 else 1000//choke while True: loopstart = sdltimer.get_ticks() while True: event = sdlevents.poll_event(True) if event is None: break elif event.type == sdlevents.SDL_QUIT: return elif event.type == sdlevents.SDL_KEYUP: if event.key.keysym.sym == sdlkeys.SDLK_ESCAPE: return elif event.type == sdlevents.SDL_WINDOWEVENT: if event.window.event == sdlvideo.SDL_WINDOWEVENT_RESIZED: self.resize(Size2(event.window.data1, event.window.data2)) elif event.type == sdlevents.SDL_MOUSEBUTTONDOWN: return glcalltrace("frame") renderlist = self.gather() #pprint.pprint(renderlist) text_sizes = {} map_sizes = {} for what, rect in renderlist: if isinstance(what, Text): text_sizes[what] = what.size elif isinstance(what, Mapview0): glcalltrace("create mapview fbo") map_sizes[what] = TexFBO(what.size) glcalltrace("create text surfbunchpbo") text_surf_bunch = SurfBunchPBO(text_sizes, FtBitmap) # 1. submit text_surf_bunch for text rendering for what, ts in text_surf_bunch.items(): what.render(ts.surface) # 2. render maps for what, where in map_sizes.items(): glcalltrace("render mapview") with where.as_target(): what.render() # 3. wait for text rendering to be complete pass glcalltrace("upload text textures") text_surf_bunch.upload() # 3. compose vpsize = Size2(window._w, window._h) glcalltrace("compose") glBindFramebuffer(GL_FRAMEBUFFER, 0) glViewport(0, 0, *vpsize) glClearColor(*bg_color) glClear(GL_COLOR_BUFFER_BIT) for what, rect in renderlist: if what in text_surf_bunch: glcalltrace("blit text") glActiveTexture(GL_TEXTURE0) # in fact here we can get away # with calling this outside the loop # but only here. It's noop after # the first call (in mesa) anyway. glBindTexture(GL_TEXTURE_2D, text_surf_bunch[what].texname) blit.ralpha(rect, vpsize, color=(1.0,1.0,1.0,1.0)) elif isinstance(what, Panel): glcalltrace("blit panel") blit.fill(rect, vpsize, what.color) elif what in map_sizes: glcalltrace("blit mapview") with map_sizes[what].as_texture(GL_TEXTURE0): blit.texblend(rect, vpsize) sdl_flip(window) text_surf_bunch.fini() for tf in map_sizes.values(): tf.fini() #return elapsed = sdltimer.get_ticks() - loopstart if choke_ms > elapsed: sdltimer.delay(choke_ms - elapsed)
def loop(self, choke): frame_no = 0 last_loop_ts = last_animflip_ts = sdltimer.get_ticks() - 1 render_choke = 1000/choke if choke > 0 else 0 # ala G_FPS_CAP anim_period = 1000/self.anim_fps paused = False finished = False panning = False scrolldict = { SDLK_LEFT: ( 1, 0), SDLK_RIGHT: ( -1, 0), SDLK_UP: ( 0, 1), SDLK_DOWN: ( 0, -1), SDLK_HOME: ( 1, 1), SDLK_PAGEUP: ( -1, 1), SDLK_END: ( 1, -1), SDLK_PAGEDOWN: ( -1, -1), } def had_input(): if not self.had_input: self.had_input = True self.hp_cheat.active = False while not finished: loop_start = sdltimer.get_ticks() self.last_loop_time = loop_start - last_loop_ts last_loop_ts = loop_start if not paused: if loop_start - last_animflip_ts > anim_period: frame_no += 1 last_animflip_ts = loop_start if frame_no > self.gamedata.maxframes-1: frame_no = 0 self.render(frame_no) while not finished: # hang around in case fps is user-limited while True: # eat events ev = sdlevents.poll_event(True) kmodstate = sdlkeyboard.get_mod_state() if ev is None: break elif ev.type == SDL_KEYDOWN: kcode = ev.key.keysym.sym if kcode == SDLK_SPACE: paused = not paused elif kcode == SDLK_F1: self.hp_cheat.active = not self.hp_cheat.active elif kcode == SDLK_F2: self.dump_fbos() elif kcode == SDLK_ESCAPE: if self.had_input: finished = True break else: self.hp_cheat.active = False elif kcode == SDLK_KP_MULTIPLY: self.show_hidden = False if self.show_hidden else True elif kcode in (SDLK_KP_DIVIDE, SDLK_BACKQUOTE): self.hp_debug.active = False if self.hp_debug.active else True elif kcode == SDLK_PERIOD and ev.mod & KMOD_SHIFT: self.zpan(-1) elif kcode == SDLK_COMMA and ev.mod & KMOD_SHIFT: self.zpan(1) elif kcode in scrolldict: boost = 10 if kmodstate & KMOD_SHIFT else 1 self.pan(Coord2(scrolldict[kcode][0] * boost * self.psz.x, scrolldict[kcode][1] * boost * self.psz.y)) elif kcode == SDLK_BACKSPACE: self.render_origin = self.gamedata.window elif kcode == SDLK_KP_PLUS: if self.anim_fps > 1: self.anim_fps += 1 elif self.anim_fps > 0.5: self.anim_fps = 1 else: self.anim_fps *= 2 anim_period = 1000.0 / self.anim_fps elif kcode == SDLK_KP_MINUS: if self.anim_fps > 1: self.anim_fps -= 1 else: self.anim_fps /= 2 anim_period = 1000.0 / self.anim_fps elif kcode == SDLK_MINUS: if self.zeddown > 1: self.zeddown -= 1 elif kcode == SDLK_EQUALS: if self.zeddown < self.gamedata.dim.z - 1: self.zeddown += 1 had_input() elif ev.type == SDL_QUIT: finished = True break elif ev.type == SDL_WINDOWEVENT: if ev.window.event == sdlvideo.SDL_WINDOWEVENT_RESIZED: self.reshape(Size2(ev.window.data1, ev.window.data2)) elif ev.type == SDL_MOUSEBUTTONDOWN: had_input() if ev.button.button == SDL_BUTTON_RIGHT: # RMB panning = True elif ev.button.button == SDL_BUTTON_LEFT: paused = not paused elif ev.type == SDL_MOUSEBUTTONUP: if ev.button.button == SDL_BUTTON_RIGHT: panning = False elif ev.type == SDL_MOUSEMOTION: if panning: self.pan(Coord2(ev.motion.xrel, ev.motion.yrel)) elif ev.type == SDL_MOUSEWHEEL: had_input() amount = -ev.wheel.y mpos = Coord2._make(sdlmouse.get_mouse_state()[1:]) if kmodstate & KMOD_CTRL: if amount > 0: self.zoom("zoom_in", mpos) else: self.zoom("zoom_out", mpos) elif kmodstate & KMOD_SHIFT: self.zpan(10 * amount) else: self.zpan(1 * amount) elapsed_time = sdltimer.get_ticks() - last_loop_ts if elapsed_time > render_choke: break sdltimer.delay(10)
def run(): # You know those from the helloworld.py example. # Initialize the video subsystem, create a window and make it visible. video.init() window = video.Window("UI Elements", size=(800, 600)) window.show() spritefactory = video.SpriteFactory(video.SOFTWARE) # If you want hardware-accelerated rendering, use video.TEXTURE instead # and pass a renderer along: # # renderer = video.RenderContext(window) # factory = video.SpriteFactory(video.TEXTURE, renderer=renderer) # # Create a UI factory, which will handle several defaults for # us. Also, the UIFactory can utilises software-based UI elements as # well as hardware-accelerated ones; this allows us to keep the UI # creation code clean. uifactory = video.UIFactory(spritefactory) # Create a simple Button sprite, which reacts on mouse movements and # button presses and fill it with a white color. All UI elements # inherit directly from the TextureSprite (for TEXTURE) or SoftwareSprite # (for SOFTWARE), so everything you can do with those classes is also # possible for the UI elements. button = uifactory.from_image \ (video.BUTTON, RESOURCES.get_path("button.bmp")) button.position = 50, 50 # Create a TextEntry sprite, which reacts on keyboard presses and # text input. entry = uifactory.from_image \ (video.TEXTENTRY, RESOURCES.get_path("textentry.bmp")) entry.position = 50, 200 # Create a CheckButton sprite. The CheckButton is a specialised # Button, which can switch its state, identified by the 'checked' # attribute by clicking. checkbutton = uifactory.from_image \ (video.CHECKBUTTON, RESOURCES.get_path("button.bmp")) checkbutton.position = 200, 50 # Bind some actions to the button's event handlers. Whenever a click # (combination of a mouse button press and mouse button release), the # onclick() function will be called. # Whenever the mouse moves around in the area occupied by the button, the # onmotion() function will be called. # The event handlers receive the issuer of the event as first argument # (the button is the issuer of that event) and the SDL event data as second # argument for further processing, if necessary. button.click += onclick button.motion += onmotion # Bind some actions to the entry's event handlers. The TextEntry # receives input events, once it has been activated by a mouse # button press on its designated area. The UIProcessor class takes # care of this internally through its activate() method. If the # TextEntry is activated, SDL_TEXTINPUT events are enabled by the # relevant SDL2 functions, causing input events to occur, that are # handled by the TextEntry. entry.input += oninput entry.editing += onedit # Since all gui elements are sprites, we can use the # SpriteRenderer class, we learned about in helloworld.py, to # draw them on the Window. spriterenderer = spritefactory.create_sprite_renderer(window) # Create a new UIProcessor, which will handle the user input events # and pass them on to the relevant user interface elements. uiprocessor = video.UIProcessor() running = True while running: events = video.get_events() for event in events: if event.type == sdlevents.SDL_QUIT: running = False break # Pass the SDL2 events to the UIProcessor, which takes care of # the user interface logic. uiprocessor.dispatch([button, checkbutton, entry], event) event = sdlevents.poll_event(True) # Render all user interface elements on the window. spriterenderer.render((button, entry, checkbutton)) video.quit() return 0