#!python # -*- mode: python; Encoding: utf-8; coding: utf-8 -*- # Last updated: <2017/04/25 17:13:04 +0900> u""" PySDL2のテスト. SDL_Texture と SD_Renderer を使うと高速描画できるらしいので試す。 でも、本当に速くなっているのかな…? 動作確認環境: Windows10 x64 + Python 2.7.13 32bit版 + PySDL2 0.9.5 """ import os import sdl2 import sdl2.sdlimage import ctypes import math SCREEN_SIZE = (640, 480) # SCREEN_SIZE = (1280, 720) def main(): u"""メイン処理.""" # PySDL2 の初期化 sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO) # ウインドウを作成して表示。 # タイトル文字列、表示位置、ウインドウサイズを指定している window = sdl2.SDL_CreateWindow(b"render test", sdl2.SDL_WINDOWPOS_CENTERED, sdl2.SDL_WINDOWPOS_CENTERED, SCREEN_SIZE[0], SCREEN_SIZE[1], sdl2.SDL_WINDOW_SHOWN) # ウインドウから renderer を取得。ウインドウ、インデックス、フラグを渡す # インデックスが-1なら初期化 # fg = 0 # fg = sdl2.SDL_RENDERER_PRESENTVSYNC | sdl2.SDL_RENDERER_ACCELERATED fg = sdl2.SDL_RENDERER_ACCELERATED renderer = sdl2.SDL_CreateRenderer(window, -1, fg) # 画像ファイルのパスを取得 filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)), "res", "hello.png") # 画像をサーフェイスとして読み込み # png等の読み込みには SDL2_image を利用する surface = sdl2.sdlimage.IMG_Load(filepath.encode("utf-8")) # 画像サイズを取得しておく w = surface.contents.w h = surface.contents.h print("w,h = %d,%d" % (w, h)) # サーフェイスをテクスチャに変換 # SDL_CreateTextureFromSurface() を使えば変換できる texture = sdl2.SDL_CreateTextureFromSurface(renderer, surface) # テクスチャに変換したからサーフェイスは用済み。解放してやる sdl2.SDL_FreeSurface(surface) ang = 0 interval = sdl2.SDL_GetPerformanceFrequency() / 60 oldtime = sdl2.SDL_GetPerformanceCounter() running = True while running: # メインループ # イベントを調べる # 閉じるボタンのクリック or ESCキーが押されたらメインループを終了 event = sdl2.SDL_Event() while sdl2.SDL_PollEvent(ctypes.byref(event)) != 0: if event.type == sdl2.SDL_QUIT: # 閉じるボタンがクリックされた running = False break if event.type == sdl2.SDL_KEYDOWN: # 何かのキーが押し下げられた if event.key.keysym.sym == sdl2.SDLK_ESCAPE: # ESCキーが押された running = False break # テクスチャの表示位置を算出。円運動をさせている rad = math.radians(ang) r = SCREEN_SIZE[0] / 6 x = int(r * math.cos(rad) + (SCREEN_SIZE[0] / 2) - (w / 2)) y = int(r * math.sin(rad) + (SCREEN_SIZE[1] / 2) - (h / 2)) ang = (ang + 3) % 360 # 画面をクリア sdl2.SDL_RenderClear(renderer) # テクスチャの転送元領域を設定 src_rect = sdl2.SDL_Rect(0, 0, w, h) # テクスチャの転送先領域を設定 dst_rect = sdl2.SDL_Rect(x, y, w, h) # テクスチャをウインドウの renderer に転送 # 転送元領域に NULL を指定すれば、全体を指定できる、はずなのだが… # sdl2.SDL_RenderCopy(renderer, texture, None, dst_rect) sdl2.SDL_RenderCopy(renderer, texture, src_rect, dst_rect) # ウインドウ(renderer)の内容を更新 sdl2.SDL_RenderPresent(renderer) # ループの時間待ち while True: if sdl2.SDL_GetPerformanceCounter() - oldtime >= interval: break sdl2.SDL_Delay(0) oldtime = sdl2.SDL_GetPerformanceCounter() # メインループ終了 # テクスチャ、renderer、ウインドウの解放 sdl2.SDL_DestroyTexture(texture) sdl2.SDL_DestroyRenderer(renderer) sdl2.SDL_DestroyWindow(window) # sdl2を終了 sdl2.SDL_Quit() if __name__ == '__main__': main()