def test_get_ticks(self): ticks = timer.get_ticks() time.sleep(1) ticks2 = timer.get_ticks() time.sleep(1) ticks3 = timer.get_ticks() # Add some latency, since the final numbers can heavily depend # on the system's context switching behaviour, load, etc., etc., # etc. self.assertTrue(abs(ticks2 - 1000 - ticks) <= 3, "%f is not <= 3 for %f and %f" % (abs(ticks2 - 1000 - ticks), ticks2, ticks)) self.assertTrue(abs(ticks3 - 1000 - ticks2) <= 3, "%f is not <= 3 for %f and %f" % (abs(ticks3 - 1000 - ticks2), ticks3, ticks2)) self.assertTrue(abs(ticks3 - 2000 - ticks) <= 3, "%f is not <= 3 for %f and %f" % (abs(ticks3 - 2000 - ticks2), ticks3, ticks))
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 test_add_remove_timer(self): calls = [] def timerfunc(interval, param): calls.append(param) return interval callback = timer.SDL_TimerCallback(timerfunc) timerid = timer.add_timer(100, callback, "Test") start = timer.get_ticks() end = start while(end - start) < 1100: # One second wait end = timer.get_ticks() # check for <=11, since it can happen that a last call is still # executing self.assertLessEqual(len(calls), 11) timer.remove_timer(timerid) self.assertLessEqual(len(calls), 11) timer.remove_timer(timerid) # Wait a bit, so the last executing handlers can finish timer.delay(10)
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 render(self, frame_no): bgc = GLColor( 0.0, 0.5, 0.0, 1 ) t_render_enter = sdltimer.get_ticks() win_mouse_pos = Coord2._make(sdlmouse.get_mouse_state()[1:]) fbo_mouse_pos = self.win2glfb(win_mouse_pos) grid_mouse_pos_f = self.win2dffb(win_mouse_pos) grid_mouse_pos = Coord2(int(grid_mouse_pos_f.x), int(grid_mouse_pos_f.y)) map_mouse_pos = Coord3(self.render_origin.x + grid_mouse_pos.x, self.render_origin.y + grid_mouse_pos.y, self.render_origin.z) mc = abs( 2*(t_render_enter - math.floor(t_render_enter)) - 1) mouse_color = ( mc, mc, mc, 1.0) if self.hp_debug.active: # todo: render debug data in single pass instead of what's below # outputting a second color output to a separate fbo black = (0,0,0,1) fbosz = Size2(self.fbo.size.w, self.fbo.size.h) self.debug_fbo.resize(fbosz) self.debug_fbo.bind(clear = black) nomouse = Coord2(-1, -1) self._render_one_grid(self.render_origin, nomouse, black, 1.0, frame_no, debug = True) # the tile under the mouse trect = Rect((fbo_mouse_pos.x//self.psz.x) * self.psz.x, (fbo_mouse_pos.y//self.psz.y) * self.psz.y, self.psz.x, self.psz.y) # read it back pixels = self.debug_fbo.readpixels(trect) self.hp_debug.update(self.winsize, pixels, self.psz, trect) self.fbo.bind(clear = bgc) zed = self.render_origin.z zeddown = min(self.zeddown, zed+1) zd = list((zeddown-z)/zeddown for z in range(zeddown)) # linear darkening for i in range(1-len(zd), 1): # draw starting from -zeddown zlevels and up # draw the map. if i + zed < 0: continue render_origin = self.render_origin._replace(z = i + zed) darken = zd[-i] self._render_one_grid(render_origin, grid_mouse_pos, mouse_color, darken, frame_no, hidden = self.show_hidden) self.fbo.blit(self.map_viewport) t_hud_start = sdltimer.get_ticks() panels = [ self.hp_renderer, self.hp_mouse, self.hp_cheat, self.hp_debug ] self.hp_renderer.update(self.winsize, self.map_viewport, hud_time = self.last_hud_time, loop_time = self.last_loop_time, zeddown = zeddown, anim_fps = self.anim_fps, frame_no = frame_no, origin = self.render_origin, grid = self.grid.size, map = self.gamedata.dim, pszar = self.Pszar, psz = self.psz, winsize = self.winsize, fbosize = self.fbo.size, show_hidden = self.show_hidden) self.hp_mouse.update(self.winsize, self.hp_renderer, self, win_mouse_pos, fbo_mouse_pos, grid_mouse_pos, grid_mouse_pos_f, map_mouse_pos) self.hp_cheat.update(self.winsize) self.hud.reshape(self.winsize) self.hud.render(panels) self.last_hud_time = sdltimer.get_ticks() - t_hud_start sdl_flip(self.window) self.last_render_time = sdltimer.get_ticks() - t_render_enter
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)