2Dゲームエンジンでサポートされているスプライトの半透明性の一部として、フレームごとに行う必要があることの1つは、z_index
プロパティですべてのスプライトを並べ替えることです情報here)。次のように現在、私のcdef class RenderSystem
に関連する骨格が見えます:cythonのcdefクラスプロパティによる高速ソート
#lots of imports...
cdef class RenderSystem:
def __init__(self):
#other irrelevant initialization stuff here
self.sprites = []
def add_sprite(self, Sprite sprite):
self.sprites.append(sprite)
def remove_sprite(self, Sprite, sprite):
self.sprites.remove(sprite)
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.initializedcheck(False)
@cython.cdivision(True)
@cython.infer_types(True)
@cython.binding(False)
def update(self):
self.sprites.sort(key=op.attrgetter("z_index"))#op = operator
#render-y OpenGL stuff goes here...
基本的には、RenderSystem
オブジェクトがcdef class Sprite
オブジェクトののpython-隠されたリストを保持しています。ユーザーはこのリストから間接的にSprite
オブジェクトを追加または削除できます。私のSprite
クラスは、ユーザーが(-1.0, 1.0]
の範囲で設定するcdef public float z_index
プロパティを持っています。 Sprite
z_index
の値を持つオブジェクトは、シーン内でより高い値のz_index
を持つオブジェクトの背後に表示されます。
sort
機能だけでは、CPU使用量のかなりの部分(レンダリングなしで13%、レンダリングで> 25%(フルコア))が実現したことに気付きました。私はcythonで、代わりに(from libc.stdlib cimport qsort
経由で)使用できるqsort
c関数があることを知っています。しかし、qsort
hereを読むと、それはのように見えます。それはfloat *z_index_list
で渡されたものを注文し、Sprite
オブジェクトとそのz_indices
の間の関連付けを失います。
TL; DR:cpythonの組み込みソート関数を実行できない特定の属性によってcdefクラスオブジェクトのリストをソートするための、いくつかの方法があります。
いつものようにありがとう!あなたの 'key_func'を使っていくつかのCPU%を削りました(今は9%はレンダリングなし、同じ25%はレンダリングで)。代わりにnumpyを使用するようにコードを再構築しようとします。私が気が狂ったルートに行くと、これは私の 'Sprite'クラスをそのまま保つことができますか?私の 'Sprite'クラスは多くの数値プロパティと固定サイズの浮動小数点配列を持っていますが、OpenGLと大きく相互作用する' Texture'クラスにも依存しています。私はおそらく、これらのオブジェクト( 'Sprite'オブジェクトとその子' Texture')へのuint32_tポインタをnumpy配列に格納することを考えていました。 – CodeSurgeon
他のPython/Cythonクラスへのポインタを格納している場合は、おそらく良いソリューションではありません。 – DavidW
ちょうど好奇心からnumpyを試してみましたが、ソートのパフォーマンスは 'key_func'とほぼ同じですが、スプライトの追加と削除(特に)は遅いです(配列が固定サイズであるため、要素を中間に追加し、最後に新しい要素を追加して配列内の「穴」を避ける)。その他の提案はありますか? – CodeSurgeon