3

私はピグレットで小さなゲームを開発しています。もちろん、目玉の 1 つは、色付きの長方形を描くことです。私は最初、メモリ内に画像を作成してblit()ing することでこれを行いましたが、うまくいきました。いかに醜く、遠回しで非効率的であるかに気付いた後 (はい、私はプロファイリングしました -ColorRect.draw()かなりの時間がかかり、この変更により 10 倍効率的になりました) これが代わりに頂点リストの作成を開始しましたpyglet.graphics.Batch。例)。それ以来、いくつかの低レベルの OpenGL コードで奇妙な例外が発生しましたが、その原因を見つけられなかったり、確実に再現できなかったりしました。

ゲームプレイ イベントとの明確な関係はありません。たとえば、直前に特別なことが起こらなかったか、常に見逃しています。エラーはイベント ループのどこかで発生するため、どの位置更新が原因であるかを簡単に突き止めることができません。正直なところ、私は困惑しています。したがって、私は発見したことをブレインダンプし、ある種の超能力者に期待します.

私はWindows 7 32ビット(すぐにUbuntu 11.10で試してみるかもしれません)でPython 3.2.2を試してみました. 2to3 を自動的に実行しないため、インストールが難しくなりますが、同様に py3k に対応しているように見えます)。次回はおそらく最新の mercurial バージョンに更新する予定ですが、それはほんの数回のコミットであり、変更はまったく無関係のようです。

完全なトレースバック (一部のパスは原則として検閲されていますが、独自の virtualenv にあることに注意してください):

Traceback (most recent call last):
  File "<my main file>", line 152, in <module>
    main()
  File "<my main file>", line 148, in main
    run()
  File "<my main file>", line 125, in run
    pyglet.app.run()
  File "<virtualenv>\Lib\site-packages\pyglet\app\__init__.py", line 123, in run
    event_loop.run()
  File "<virtualenv>\Lib\site-packages\pyglet\app\base.py", line 135, in run
    self._run_estimated()
  File "<virtualenv>\Lib\site-packages\pyglet\app\base.py", line 164, in _run_estimated
    timeout = self.idle()
  File "<virtualenv>\Lib\site-packages\pyglet\app\base.py", line 278, in idle
    window.switch_to()
  File "<virtualenv>\Lib\site-packages\pyglet\window\win32\__init__.py", line 305, in switch_to
    self.context.set_current()
  File "<virtualenv>\Lib\site-packages\pyglet\gl\win32.py", line 213, in set_current
    super(Win32Context, self).set_current()
  File "<virtualenv>\Lib\site-packages\pyglet\gl\base.py", line 320, in set_current
    buffers = (gl.GLuint * len(buffers))(*buffers)
IndexError: invalid index

事後分析 (FPS が 60 から 7 に低下したため、実行不可能になるまで積極的にコードを実行する) を実行すると、次のようになりpdbます。

  • buffersint のリストです。これらが何を表しているのか、どこから来たのかはわかりませんが、self.object_space._doomed_textures(where selfis a window object) と呼ばれるリストから取得されます。関連するコメントには、このコード ブロックは、削除予定のテクスチャを解放すると書かれています。どこでもテクスチャを明示的に使用しているとは思いませんが、pyglet がフードの下で何をしているのかは誰にもわかりません。これらの整数は、ID または破棄されるテクスチャの一部であると想定しています。
  • gl.GLuintのエイリアスですctypes.c_ulong。したがって、同じ長さと内容(gl.GLuint * len(buffers))(*buffers)の配列を作成しますulong
  • pdbエラーやデータの破損なしに、プロンプトでまったく同じ式を評価できます。

ctypes を使用した独立した実験 (virtualenv の外部で、pyglet をインポートせずに) はIndexError、配列コンストラクターに与えられた引数が多すぎる場合に発生することを示しています。これは意味がありません。実験と論理の両方が、長さと引数の数が常に一致する必要があることを示唆しています。

  1. この例外が発生する可能性がある他のケースはありますか? これは pyglet のバグでしょうか、それともライブラリを誤用して関連する警告を見逃したのでしょうか?
  2. 頂点リストを作成および維持するコードは、これをデバッグするのに役立ちますか? おそらく何か問題があります。私はすでにそれをじっと見つめていましたが、私は の経験がほとんどないのでpyglet.graphics、これは限られた用途でした. ColorRectコードを見たい場合は、コメントを残してください。
  3. これを引き起こす可能性のある他のアイデアはありますか?
4

1 に答える 1

0

コードが提供されていないため、実際に関連する回答を提供するのは少し難しいですが、エラー出力からわかることからです。

buffers = (gl.GLuint * len(buffers))(*buffers)

したがって、私が正しく理解していれば、GLuint のサイズ (4 バイト) に実際のバッファーの長さ (初期化されている場合) を掛けています。インデックスが高すぎるため、インデックスが無効になっているのはそのためでしょうか?

バッファーはバイト単位なので、通常は問題ありませんが、int のリストだとおっしゃいましたか?

それが役に立てば幸い

于 2012-03-08T07:50:31.637 に答える