2013/05/10(金) [n年前の日記]
#3 [prog] pygame + PyOpenGLでフルスクリーン表示が上手くいかない
色々試してるけど、どうにも…。
◎ pygame + PyOpenGLでフルスクリーン表示できない問題。 :
フルスクリーン表示をすると、画面の上部にウインドウ枠が残ったり、そこだけ黒い表示のままになったりする。メインPC上では症状が発生しないが、録画用PC上ではそういう症状が起きる。
以下の2点を加えたところ、症状は見られなくなったけど…。
glut32.dll がバグ持ちなのかと思って、glut32.dll を freeglut.dll で差し替えてみたけど、これは関係なかった模様。ただ、freeglut.dll で置き換えた際に、「glutBitmapCharacter() を使いたかったら glutInit() を事前に呼んでおけ」とエラーが表示されたので、glutInit() を呼べるなら呼んでおいたほうがいいのだろう。たぶん。
ちなみに、freeglut.dll は、 _freeglut Windows Development Libraries から入手できる。freeglut.dll を glut32.dll にリネームしてスクリプトのあるフォルダに置けば使えるみたい。
以下の2点を加えたところ、症状は見られなくなったけど…。
- フルスクリーン表示とウインドウ表示を切り替える際、pygame.display.set_mode() を呼ぶ直前に、pygame.display.quit()、pygame.display.init() を呼んでおく。
- pygame.display.set_mode() を呼んだ後、glutInit() を呼んでおく。
glut32.dll がバグ持ちなのかと思って、glut32.dll を freeglut.dll で差し替えてみたけど、これは関係なかった模様。ただ、freeglut.dll で置き換えた際に、「glutBitmapCharacter() を使いたかったら glutInit() を事前に呼んでおけ」とエラーが表示されたので、glutInit() を呼べるなら呼んでおいたほうがいいのだろう。たぶん。
ちなみに、freeglut.dll は、 _freeglut Windows Development Libraries から入手できる。freeglut.dll を glut32.dll にリネームしてスクリプトのあるフォルダに置けば使えるみたい。
◎ フルスクリーン表示すると画面の書き換えの様子が見えてしまう問題。 :
pygame + PyOpenGL でフルスクリーン表示をすると、画面内に横線が入っているかのような見た目になることに気付いた。おそらく、ダブルバッファを切り替えるタイミングが見えているのではないかと。ティアリングと呼ぶのでしたっけ?
メインループの書き方がよろしくないのだろうか。それとも、垂直帰線期間だか vsync だかそのへんが関係しているのだろうか。OpenGL関係でフルスクリーン表示をすると、画面書き換え(バッファ切り替え?)のタイミングが vsync で固定される、てな話を海外掲示板で見かけたりもしたわけで。
症状が出ている録画用PCは、液晶ディスプレイにHDMI接続しているのだけど、まさか、HDMI接続の場合はvsyncが正確に得られない、等の問題があったり…したら手の打ちようがないのだろうな…。そもそも液晶ディスプレイでvsyncがどうこうってのもなんだかおかしい気もするけど。ブラウン管なら原理からして、そのへんが絡んでくるけれど…。液晶ディスプレイの場合は、どういう仕組み・やり取りになってるんだろうか…。
メインループの書き方がよろしくないのだろうか。それとも、垂直帰線期間だか vsync だかそのへんが関係しているのだろうか。OpenGL関係でフルスクリーン表示をすると、画面書き換え(バッファ切り替え?)のタイミングが vsync で固定される、てな話を海外掲示板で見かけたりもしたわけで。
症状が出ている録画用PCは、液晶ディスプレイにHDMI接続しているのだけど、まさか、HDMI接続の場合はvsyncが正確に得られない、等の問題があったり…したら手の打ちようがないのだろうな…。そもそも液晶ディスプレイでvsyncがどうこうってのもなんだかおかしい気もするけど。ブラウン管なら原理からして、そのへんが絡んでくるけれど…。液晶ディスプレイの場合は、どういう仕組み・やり取りになってるんだろうか…。
◎ pygame + DirectX利用時に不正終了する問題。 :
pygame は SDL を使って描画している。その SDL は、Windows 上で動く際、windib とやらを使って描画している。環境変数 SDL_VIDEODRIVER に 'directx' を指定することで、windib ではなく、DirectX が使われるはず、なのだけど…。
Ruby/SDL上ではそのあたりの切り替えが上手くいかなかったのだけど、pygame 上では反映されるようで、喜んで(?)設定してみたり。しかし、ウインドウ表示中はともかく、directx で一度でもフルスクリーン表示をすると、その後、スクリプトの終了時に、必ず不正終了してしまう。
検索してみたところ、海外掲示板でも同様の不具合報告を見かけた。しかし、どの報告でも、「pygameでDirectXを使うな。OpenGL使え」で話が打ち切られてるようで。…たしかに、マルチプラットフォームを意識すれば、DirectXを選択肢に入れるのはおかしい。でも、ちょっと前までは、SDLもDirectXを活用してた記憶があるわけで。
pygame の標準描画(= SDL = windib による描画)は結構遅いので、directx にして速くなるなら使ってみたい。が、directx にすれば必ず速くなるわけでもないようで。自分のメインPC上で、directx + フルスクリーン表示をすると、画面の書き換えが「ペロン、ペロン」という状態に。たぶん、1FPSすら出ていない…。pygame.HWSURFACE や pygame.DOUBLEBUF を指定してみても劇的変化は無く。
pygame だけで60FPSのゲームを、と考えること自体が無謀なのだろうか。かもしれん…。
pyglet とやらを使えば、また違ってくるのかな。どうなんだろ。
Ruby/SDL上ではそのあたりの切り替えが上手くいかなかったのだけど、pygame 上では反映されるようで、喜んで(?)設定してみたり。しかし、ウインドウ表示中はともかく、directx で一度でもフルスクリーン表示をすると、その後、スクリプトの終了時に、必ず不正終了してしまう。
検索してみたところ、海外掲示板でも同様の不具合報告を見かけた。しかし、どの報告でも、「pygameでDirectXを使うな。OpenGL使え」で話が打ち切られてるようで。…たしかに、マルチプラットフォームを意識すれば、DirectXを選択肢に入れるのはおかしい。でも、ちょっと前までは、SDLもDirectXを活用してた記憶があるわけで。
pygame の標準描画(= SDL = windib による描画)は結構遅いので、directx にして速くなるなら使ってみたい。が、directx にすれば必ず速くなるわけでもないようで。自分のメインPC上で、directx + フルスクリーン表示をすると、画面の書き換えが「ペロン、ペロン」という状態に。たぶん、1FPSすら出ていない…。pygame.HWSURFACE や pygame.DOUBLEBUF を指定してみても劇的変化は無く。
pygame だけで60FPSのゲームを、と考えること自体が無謀なのだろうか。かもしれん…。
pyglet とやらを使えば、また違ってくるのかな。どうなんだろ。
[ ツッコむ ]
以上です。