2017/09/13(水) [n年前の日記]
#1 [python][pi3d] pi3dで画像を表示する
_pi3d
で画像を表示してみたい。画像の表示ができれば、pi3d で2Dゲームを作れそうかちょっと見えてくるかもしれないし。
pi3dのサンプルスクリプト群、 _pi3d_demos の中では…。以下が参考になりそうかなと。
_pi3d_demos/Minimal.py
_pi3d_demos/Minimal_2d.py
_pi3d_demos/Raspberry_Rain.py
_pi3d_demos/Clouds3d.py
_pi3d_demos/SpriteBalls.py
どうやら、pi3d.ImageSprite、あるいは pi3d.Sprite、はたまた pi3d.Points、てなあたりを生成すれば画像を描画できるっぽい。
pi3dのサンプルスクリプト群、 _pi3d_demos の中では…。以下が参考になりそうかなと。
_pi3d_demos/Minimal.py
_pi3d_demos/Minimal_2d.py
_pi3d_demos/Raspberry_Rain.py
_pi3d_demos/Clouds3d.py
_pi3d_demos/SpriteBalls.py
どうやら、pi3d.ImageSprite、あるいは pi3d.Sprite、はたまた pi3d.Points、てなあたりを生成すれば画像を描画できるっぽい。
◎ ImageSpriteを使ってみる。 :
とりあえず、一番簡単に使えそうな ImageSprite を使って描画してみる。
_imagesprite.py
_cutegirl.png
_cutegirl2.png
画像は、 _OpenGameArt.org の、 _Cute Girl - Free Sprites を使わせてもらいました。ありがたや。この画像、可愛いな…。しかもライセンスが CC0 だし…。
_imagesprite.py
_cutegirl.png
_cutegirl2.png
u""" pi3d ImageSprite sample. スプライトを描画するサンプル。 平行投影で描画。 ESCキーで終了する。 Windows10 x64 + Python 2.7.12 32bit + pi3d 2.20 """ from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals import pi3d # ウインドウ生成 display = pi3d.Display.create(w=640, h=480, frames_per_second=60) # シェーダーを生成。uv_flatは照明関係の計算をしない。 shader = pi3d.Shader("uv_flat") # カメラを平行投影に camera = pi3d.Camera(is_3d=False) # テクスチャを読み込み tex = pi3d.Texture("cutegirl.png", blend=False, filter=pi3d.GL_NEAREST) # tex = pi3d.Texture("cutegirl2.png", blend=False, filter=pi3d.GL_NEAREST) # スプライトを生成 sprite0 = pi3d.ImageSprite(tex, shader, w=256.0, h=256.0, x=0.0, y=0.0) sprite1 = pi3d.ImageSprite(tex, shader, w=256.0, h=256.0, x=128.0, y=128.0) print("sprite0.z() = %d" % sprite0.z()) # z=20.0 print("sprite1.z() = %d" % sprite1.z()) # キーボード取得用クラスを生成 keys = pi3d.Keyboard() # メインループ while display.loop_running(): # スプライトを描画 sprite0.draw() sprite1.draw() if keys.read() == 27: # ESCキーが押されたらループを抜けて終了 keys.close() display.destroy() break
画像は、 _OpenGameArt.org の、 _Cute Girl - Free Sprites を使わせてもらいました。ありがたや。この画像、可愛いな…。しかもライセンスが CC0 だし…。
◎ 少し解説。 :
ソースにコメントを書きまくったから、眺めれば分かりそうではあるけど、一応。
画像の色をそのまま出したいときは、uv_flat という種類のシェーダーを使うといいらしい。shader = pi3d.Shader("uv_flat") で用意してる。
_pi3d.Shader - pi3d 2.21 documentation によると、テクスチャ画像を使いたいときはシェーダー種類を示す文字列の頭に「uv_」と付くらしい。「flat」は、照明関係の計算をしないでフラットな状態で描画、ということかなと。
2D描画をしたいので、透視投影ではなく平行投影にする。そのために、カメラを用意して設定する。camera = pi3d.Camera(is_3d=False) で、「このカメラは、3Dっぽく描画しないでくれ=平行投影にしてくれ」と指定してるのだろう…。
画像を描画したいので、テクスチャ画像として読み込む。tex = pi3d.Texture("テクスチャ画像のパス") でテクスチャとして読み込める。
テクスチャ読み込み時の、blend指定の意味は、ちょっとよく分からなかった。filter指定は、拡大縮小時にどんなフィルタをかけるか、だろうけど。 _pi3d.Texture - pi3d 2.21 documentation によれば、フィルタ種類として pi3d.GL_NEAREST や pi3d.GL_LINEAR が指定できるらしい。GL_NEAREST はクッキリだけどジャギジャギ。GL_LINEAR は滑らかだけどぼやける。てな認識でいいんじゃないかな…。 _Textures で紹介されてる画像を眺めれば分かるかなと。
ちなみにドキュメントには、「テクスチャ画像のサイズは、4, 8, 16, 32, 48, 64, 72, 96, 128, 144, 192, 256, 288, 384, 512, 576, 640, 720, 768, 800, 960, 1024, 1080, 1920 てな感じのキリのいい値にしておいてね」と書いてある。
画像を使うスプライトは、以下で生成できる。
pi3d.ImageSprite() のテクスチャのところに、直接、画像のパスを書いても、画像をテクスチャとして読み込んで使ってくれる模様。ただ、同じ画像を他のスプライトでも使いたい場合は、別途テクスチャとして読み込んでソレを指定したほうが確実かもしれず。
と思ったけど、 _pi3d/Sprite.py at master - tipam/pi3d を眺めたら、既にテクスチャが読み込まれているならそっちを流用する、てな実装になってる、ように見えなくもないな…。
画像の色をそのまま出したいときは、uv_flat という種類のシェーダーを使うといいらしい。shader = pi3d.Shader("uv_flat") で用意してる。
_pi3d.Shader - pi3d 2.21 documentation によると、テクスチャ画像を使いたいときはシェーダー種類を示す文字列の頭に「uv_」と付くらしい。「flat」は、照明関係の計算をしないでフラットな状態で描画、ということかなと。
2D描画をしたいので、透視投影ではなく平行投影にする。そのために、カメラを用意して設定する。camera = pi3d.Camera(is_3d=False) で、「このカメラは、3Dっぽく描画しないでくれ=平行投影にしてくれ」と指定してるのだろう…。
画像を描画したいので、テクスチャ画像として読み込む。tex = pi3d.Texture("テクスチャ画像のパス") でテクスチャとして読み込める。
テクスチャ読み込み時の、blend指定の意味は、ちょっとよく分からなかった。filter指定は、拡大縮小時にどんなフィルタをかけるか、だろうけど。 _pi3d.Texture - pi3d 2.21 documentation によれば、フィルタ種類として pi3d.GL_NEAREST や pi3d.GL_LINEAR が指定できるらしい。GL_NEAREST はクッキリだけどジャギジャギ。GL_LINEAR は滑らかだけどぼやける。てな認識でいいんじゃないかな…。 _Textures で紹介されてる画像を眺めれば分かるかなと。
ちなみにドキュメントには、「テクスチャ画像のサイズは、4, 8, 16, 32, 48, 64, 72, 96, 128, 144, 192, 256, 288, 384, 512, 576, 640, 720, 768, 800, 960, 1024, 1080, 1920 てな感じのキリのいい値にしておいてね」と書いてある。
画像を使うスプライトは、以下で生成できる。
sprite0 = pi3d.ImageSprite(テクスチャ, シェーダー, w=幅, h=高さ, x=x座標, y=y座標)そして、この場合は平行投影だから、幅、高さ、座標はドット単位で指定すればいいのだろう…。たぶん。
pi3d.ImageSprite() のテクスチャのところに、直接、画像のパスを書いても、画像をテクスチャとして読み込んで使ってくれる模様。ただ、同じ画像を他のスプライトでも使いたい場合は、別途テクスチャとして読み込んでソレを指定したほうが確実かもしれず。
と思ったけど、 _pi3d/Sprite.py at master - tipam/pi3d を眺めたら、既にテクスチャが読み込まれているならそっちを流用する、てな実装になってる、ように見えなくもないな…。
◎ 透視投影で描画してみる。 :
前述のソースは平行投影で描画してるけど、透視投影でも描画してみる。
_imagesprite2.py
pi3d.Camera(is_3d=True) を指定してるので、平行投影ではなく、透視投影になってる。それと同時に、ImageSprite() 生成時の、幅、高さ、座標値に対して、謎単位な数値を指定している。
また、透視投影の場合、 ImageSprite() 生成時に、z=20.0とか z=30.0 とか指定してやると、描画される大きさが違ってくる。
以下の描画結果は、2つ目のスプライトのz値を、1つ目より大きくした=遠くにしてみた事例。透視投影は、近くにあるものは大きく、遠くにあるものは小さく描画するので、遠くにあるスプライトのほうが小さく描画されてる。
_imagesprite2.py
u""" pi3d ImageSprite sample. スプライトを描画するサンプル。 透視投影で描画。 ESCキーで終了する。 Windows10 x64 + Python 2.7.12 32bit + pi3d 2.20 """ from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals import pi3d # ウインドウ生成 display = pi3d.Display.create(w=640, h=480, frames_per_second=60) # シェーダーを生成。uv_flatは照明関係の計算をしない。 shader = pi3d.Shader("uv_flat") # カメラを透視投影に camera = pi3d.Camera(is_3d=True) # テクスチャを読み込み tex = pi3d.Texture("cutegirl.png", blend=False, filter=pi3d.GL_NEAREST) # tex = pi3d.Texture("cutegirl2.png", blend=False, filter=pi3d.GL_NEAREST) # スプライトを生成 sprite0 = pi3d.ImageSprite(tex, shader, w=10.0, h=10.0, x=0.0, y=0.0) sprite1 = pi3d.ImageSprite(tex, shader, w=10.0, h=10.0, x=5.0, y=5.0) print("sprite0.z() = %f" % sprite0.z()) # z=20.0 print("sprite1.z() = %f" % sprite1.z()) # キーボード取得用クラスを生成 keys = pi3d.Keyboard() # メインループ while display.loop_running(): # スプライトを描画 sprite0.draw() sprite1.draw() if keys.read() == 27: # ESCキーが押されたらループを抜けて終了 keys.close() display.destroy() break
pi3d.Camera(is_3d=True) を指定してるので、平行投影ではなく、透視投影になってる。それと同時に、ImageSprite() 生成時の、幅、高さ、座標値に対して、謎単位な数値を指定している。
また、透視投影の場合、 ImageSprite() 生成時に、z=20.0とか z=30.0 とか指定してやると、描画される大きさが違ってくる。
以下の描画結果は、2つ目のスプライトのz値を、1つ目より大きくした=遠くにしてみた事例。透視投影は、近くにあるものは大きく、遠くにあるものは小さく描画するので、遠くにあるスプライトのほうが小さく描画されてる。
◎ 境界線がおかしい。 :
アルファチャンネルを持った画像を描画した場合、境界部分がちょっと妙な描画になることに気づいた。
お判りいただけるだろうか。
どうやら pi3d は、テクスチャ画像のアルファチャンネルが 0 or 255 の時は問題ないけど、1〜254の時は妙な描画になるっぽいなと…。これはもしかすると、pi3d の問題ではなくて、Open GL ES の問題なのかもしれない。あるいは、使おうとしてるシェーダーの問題だろうか。
_cutegirl.png は境界部分のアルファチャンネルが0〜255になってるけど、 _cutegirl2.png は 0 or 255 の二値にしてあるので、読み込む画像を変えてみると違いが分かるかも。平行投影の場合は _cutegirl2.png を使うと変な境界が出ないけど、透視投影の場合はどちらを使っても変な境界が出ちゃう。みたいな。このあたり、解決策はあるのだろうか…。
お判りいただけるだろうか。
どうやら pi3d は、テクスチャ画像のアルファチャンネルが 0 or 255 の時は問題ないけど、1〜254の時は妙な描画になるっぽいなと…。これはもしかすると、pi3d の問題ではなくて、Open GL ES の問題なのかもしれない。あるいは、使おうとしてるシェーダーの問題だろうか。
_cutegirl.png は境界部分のアルファチャンネルが0〜255になってるけど、 _cutegirl2.png は 0 or 255 の二値にしてあるので、読み込む画像を変えてみると違いが分かるかも。平行投影の場合は _cutegirl2.png を使うと変な境界が出ないけど、透視投影の場合はどちらを使っても変な境界が出ちゃう。みたいな。このあたり、解決策はあるのだろうか…。
[ ツッコむ ]
#2 [pc][neta] CPUは男なのか女なのか
思考メモ。
寝ていたら夢の中で、CPUを女性として分類している光景を何故か目にして。
目が覚めてから、少し考え込んでしまったり。CPUに性別をつけるとしたら、どちらになるんだろう。男なのか、女なのか。「彼」なのか、「彼女」なのか。
まあ、CPUは男扱いされるのが自然、かなと。例えば直系のアーキテクチャ、かつ、機能削減版が出た際などは、「○○の弟分」などと呼ばれたりするし。「○○の妹分」と呼ばれてる場面を見た記憶が無い。つまり、CPUについて語ったり紹介したりしてる人々は、CPUを男として扱うのが感覚的に妥当、と思っているということだろう…。
しかし、8bit PCが普及していた頃、自分の「マイコン」を擬人化するお遊びが一部で流行ってたけど…。その場合は、えてして女性として擬人化されてたような気もするわけで。CPUは男扱いなのに、マイコンは女扱い。さて、何故だろう。
今はどうなんだろうか。例えば、世間の皆様が持ち歩いてる、スマホ、あるいはガラケー。これは男なのか、女なのか。「彼」なのか、「彼女」なのか。
そういえば、スマホだかタブレットだか忘れたけどその手のTVCMで、イケメンの俳優さんがスマホであるかのように演じてた記憶も。すると感覚的には男、ということなのかしらん。女性がスマホやタブレットを演じるという選択肢は…検討されたのだろうか。それとも一切検討されなかったのだろうか。なんだかちょっと気になる。
船は女性扱いされることがあるよな…。電車はどうだろう…。車はどうだろう…。日本刀はどうなのだ…。戦艦は…。一体どのあたりで、自分達は、その機械の性別を推測しているのだろう。
男性ユーザがほとんどなら、そのユーザが扱う機械は女性として見立てられる、というわけではないよな…。だったらCPUも女性扱いされてしかるべきだし。つまり、ユーザの性別で決まるわけでもなさそうな。
もしかして、サイズかな…。手の中に収まるもの、机の上に置くもの、自分が乗り込むもの、つまりは大きさで違ってくるんだろうか。
寝ていたら夢の中で、CPUを女性として分類している光景を何故か目にして。
目が覚めてから、少し考え込んでしまったり。CPUに性別をつけるとしたら、どちらになるんだろう。男なのか、女なのか。「彼」なのか、「彼女」なのか。
まあ、CPUは男扱いされるのが自然、かなと。例えば直系のアーキテクチャ、かつ、機能削減版が出た際などは、「○○の弟分」などと呼ばれたりするし。「○○の妹分」と呼ばれてる場面を見た記憶が無い。つまり、CPUについて語ったり紹介したりしてる人々は、CPUを男として扱うのが感覚的に妥当、と思っているということだろう…。
しかし、8bit PCが普及していた頃、自分の「マイコン」を擬人化するお遊びが一部で流行ってたけど…。その場合は、えてして女性として擬人化されてたような気もするわけで。CPUは男扱いなのに、マイコンは女扱い。さて、何故だろう。
今はどうなんだろうか。例えば、世間の皆様が持ち歩いてる、スマホ、あるいはガラケー。これは男なのか、女なのか。「彼」なのか、「彼女」なのか。
そういえば、スマホだかタブレットだか忘れたけどその手のTVCMで、イケメンの俳優さんがスマホであるかのように演じてた記憶も。すると感覚的には男、ということなのかしらん。女性がスマホやタブレットを演じるという選択肢は…検討されたのだろうか。それとも一切検討されなかったのだろうか。なんだかちょっと気になる。
船は女性扱いされることがあるよな…。電車はどうだろう…。車はどうだろう…。日本刀はどうなのだ…。戦艦は…。一体どのあたりで、自分達は、その機械の性別を推測しているのだろう。
男性ユーザがほとんどなら、そのユーザが扱う機械は女性として見立てられる、というわけではないよな…。だったらCPUも女性扱いされてしかるべきだし。つまり、ユーザの性別で決まるわけでもなさそうな。
もしかして、サイズかな…。手の中に収まるもの、机の上に置くもの、自分が乗り込むもの、つまりは大きさで違ってくるんだろうか。
[ ツッコむ ]
以上、1 日分です。