FPSを作ってみる@wiki
07)
最終更新:
slice
-
view
(2014/07/28)
とりいそぎ
急いでないけど絵だけ公開
Drawing(analog)
Drawing(analog)
(2014/07/19)
テストフレームワーク
BoostTestとGoogleTestのどっち使おうかという話。
一応両方試した。身構える程難しくなかった。
一応両方試した。身構える程難しくなかった。
結論としては「どっちでもいいんじゃないの?」と。
かなりマニアックな事をすれば違ってくるんだろうけども、普通にテスト書く分にゃほぼ同じ。
どっちでもいいとなれば新しい方を使おうという事でGoogleTestに決定。
ただ、BoostTestはヘッダのインクルードだけで使えるバージョンもあるから
ちょっと書いてみたアプリケーションを手軽にテストしたい時に便利かも。
かなりマニアックな事をすれば違ってくるんだろうけども、普通にテスト書く分にゃほぼ同じ。
どっちでもいいとなれば新しい方を使おうという事でGoogleTestに決定。
ただ、BoostTestはヘッダのインクルードだけで使えるバージョンもあるから
ちょっと書いてみたアプリケーションを手軽にテストしたい時に便利かも。
ULPs
GoogleTestのリファレンス
を読んでいた時に浮動小数点数の比較が詳しく載ってたのでついでに。
浮動小数点数(以下floatと呼ぶ)の計算には誤差がつきものだが
大抵のプログラミング入門的なwebページや参考書は「誤差が出る」ことと
「だから比較には許容値(epsilon)を設けましょう」までしか書いてない気がする。
を読んでいた時に浮動小数点数の比較が詳しく載ってたのでついでに。
浮動小数点数(以下floatと呼ぶ)の計算には誤差がつきものだが
大抵のプログラミング入門的なwebページや参考書は「誤差が出る」ことと
「だから比較には許容値(epsilon)を設けましょう」までしか書いてない気がする。
いや、epsilon自体はともかくこれを何の策もなく絶対値にしてしまう事が問題で
一口に値と言っても0付近の小さい値か1000000.0のような大きい値かでfloatの分解能が異なる。
もちろん弾丸の当たり判定でこの位の大きさを扱うからこの誤差、キャラクター同士の判定にはこれと決めれば
ある程度カバーできるが、どうにも柔軟性に欠ける訳で。
一口に値と言っても0付近の小さい値か1000000.0のような大きい値かでfloatの分解能が異なる。
もちろん弾丸の当たり判定でこの位の大きさを扱うからこの誤差、キャラクター同士の判定にはこれと決めれば
ある程度カバーできるが、どうにも柔軟性に欠ける訳で。
ではと、比較する時に値をチェックし小さい値なら小さい誤差、
大きければ大きい誤差という風にepsilonを相対的にすれば良さそうに思える。
これは絶対値よりはマシなものの、余程上手く調整しないと0付近の比較が細かすぎたりして上手く行かない。
余計な処理が増えて結局調整が必要なら絶対値でいいじゃんという気も。
大きければ大きい誤差という風にepsilonを相対的にすれば良さそうに思える。
これは絶対値よりはマシなものの、余程上手く調整しないと0付近の比較が細かすぎたりして上手く行かない。
余計な処理が増えて結局調整が必要なら絶対値でいいじゃんという気も。
当てずっぽうにそれらしい誤差値を使うのではなく
要はfloatで表現できる最小の刻み幾つ分を許容するっていうのがやりたい。
こういうのは割とメジャーな話題のようで、その辺が
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
ここに詳しく書かれている。
乱暴に言ってしまえばfloatをin32_tにreinterpret_castして
それをインクリメントするとfloatで表現可能な最小単位(Unit in the last place = ULP)で1だけ0から離れる方向へ、
デクリメントすれば0に近づく方向へずらせるというもの。
負数と正数の場合でちょいと工夫してやれば2つの値のULPsが求まるので、
同じくULPsで指定された許容誤差と比べれば目的の挙動が達成出来る寸法。
要はfloatで表現できる最小の刻み幾つ分を許容するっていうのがやりたい。
こういうのは割とメジャーな話題のようで、その辺が
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
ここに詳しく書かれている。
乱暴に言ってしまえばfloatをin32_tにreinterpret_castして
それをインクリメントするとfloatで表現可能な最小単位(Unit in the last place = ULP)で1だけ0から離れる方向へ、
デクリメントすれば0に近づく方向へずらせるというもの。
負数と正数の場合でちょいと工夫してやれば2つの値のULPsが求まるので、
同じくULPsで指定された許容誤差と比べれば目的の挙動が達成出来る寸法。
ところでここまで書いておいてアレだが
ベクトルや平面、行列など使って色々していると
長さが1のはずのベクトルが0.997だったり、その程度の誤差はすぐ出てしまうので
やはり用途に合った許容誤差は必要なのだという結論に。しかも大抵は大小比較があれば事足りるし。
だからあまり触れられないのか・・
ベクトルや平面、行列など使って色々していると
長さが1のはずのベクトルが0.997だったり、その程度の誤差はすぐ出てしまうので
やはり用途に合った許容誤差は必要なのだという結論に。しかも大抵は大小比較があれば事足りるし。
だからあまり触れられないのか・・
最終的に自分のライブラリでは
// float定数のULPs単位での差をコンパイル時計算するルーチン constexpr int32_t ULPs_C(float val0, float val1); // ULPsを実行時計算するルーチン int32_t ULPs(float val0, float val1); // ULPsで誤差を指定するfloat値比較 bool EqULPs(float val0, float val1, int32_t ulps);
を用意し、例えばfloat精度で1.0が1.001だったりする位の誤差なら許容する場合
constexpr int32_t ulps1_0 = ULPs_C(1.0f, 1.0f+1e-3f); EqULPs(val0, val1, ulps1_0);
のように書く形で落ち着いた。
従来度通り絶対値で誤差を指定したければEqAbs(val0, val1, 1e-3f)など。
従来度通り絶対値で誤差を指定したければEqAbs(val0, val1, 1e-3f)など。
絵
あくまでメインはプログラミングなので気が向いた時に気が向いた対象を描く方針。
下書き(?)が終わり次回の更新でアップできればいいなという感じで、マッタリと。
下書き(?)が終わり次回の更新でアップできればいいなという感じで、マッタリと。
(2014/07/15)
プログラムが思うように進まないのでスクリーンショットの代わりに絵でお茶を濁す。
自分の左手。今回は陰影を付けずにイラスト風でやってみた。
グラデーションの作業は要らなくなるがどの線を残すか(強調するか)っていう勘所がよくわかんなくて
これはこれで難しい。
模写とか実物を見ながら描く絵は全体のバランスにさえ気をつければ結構それっぽくなっちゃうもんだね。
人の顔はそうもいかなそうだけども。
グラデーションの作業は要らなくなるがどの線を残すか(強調するか)っていう勘所がよくわかんなくて
これはこれで難しい。
模写とか実物を見ながら描く絵は全体のバランスにさえ気をつければ結構それっぽくなっちゃうもんだね。
人の顔はそうもいかなそうだけども。
問題は想像しながら描く時のパースで、歪ませるといっても自分にはどうやっていいのかさっぱり。
3DCGには少し覚えがあるという事でまずバウンディングボックスを描いて、それから中を・・とやってみても
箱自体は確かにパースがかかって立体的、だがしかし。みたいな。
3DCGには少し覚えがあるという事でまずバウンディングボックスを描いて、それから中を・・とやってみても
箱自体は確かにパースがかかって立体的、だがしかし。みたいな。
自分のボキャブラリじゃ上手く表現できないのが残念だが、強いて言えば
絵の初心者にありがちと思われる、左右をなるべく対称に描かないと不安になるとか
物が重なる(後ろの物が隠れて一部見えなくなる)構図を無意識に避けようとする現象。
絵の初心者にありがちと思われる、左右をなるべく対称に描かないと不安になるとか
物が重なる(後ろの物が隠れて一部見えなくなる)構図を無意識に避けようとする現象。
ま、地道に行くしかないか。
プログラムの方はテクスチャで詰まる
今の実装ではモデルのテクスチャをSDL_imageで行っている関係で
ファイルを一旦SDL_Surfaceに落としてから改めてglTexImage2D等を呼びGPUに転送している。
SDL_Surfaceを経由するという事は、当然SDLのピクセルフォーマット -> OpenGLのテクスチャフォーマットの関連付けが必要となる。
どうするか?と、問われてもSDLはともかくOpenGLの定数はフォーマットと中身の値に関連性が無いので
仕方なくリスト化してポチポチ打ち込んでた。
ファイルを一旦SDL_Surfaceに落としてから改めてglTexImage2D等を呼びGPUに転送している。
SDL_Surfaceを経由するという事は、当然SDLのピクセルフォーマット -> OpenGLのテクスチャフォーマットの関連付けが必要となる。
どうするか?と、問われてもSDLはともかくOpenGLの定数はフォーマットと中身の値に関連性が無いので
仕方なくリスト化してポチポチ打ち込んでた。
SDLのピクセルフォーマットにはヘッダを見るに16bit(float or int)や32bit floatを示す定数があって、
てっきりSDL_SurfaceにRGB16(Red,Green,Blue(16bits))なんかも扱えるものだと思って組んでいたら
どうもRGBA合わせて32bitまでの整数フォーマットしか受け付けないご様子で色々と組み直しになったり。
試しにSDL_ConvertSurface()の引数にRGBA(float)なんかを食わせるとunknown formatと怒られてしまう。
将来的にサポートするつもりという事だろうか・・
てっきりSDL_SurfaceにRGB16(Red,Green,Blue(16bits))なんかも扱えるものだと思って組んでいたら
どうもRGBA合わせて32bitまでの整数フォーマットしか受け付けないご様子で色々と組み直しになったり。
試しにSDL_ConvertSurface()の引数にRGBA(float)なんかを食わせるとunknown formatと怒られてしまう。
将来的にサポートするつもりという事だろうか・・
あとSDLのピクセルフォーマットの表記でも引っかかった
Red=0xff, Green=0x80, Blue=0x3fだったとすると
SDL_PIXELFORMAT_RGB24はメモリ上に
Red=0xff, Green=0x80, Blue=0x3fだったとすると
SDL_PIXELFORMAT_RGB24はメモリ上に
0xff, 0x80, 0x3f
と並ぶが
SDL_PIXELFORMAT_RGB888では
SDL_PIXELFORMAT_RGB888では
0x3f, 0x80, 0xff
なのだ。
これはどういうことかと言うとヘッダを見るとわかるがSDL_PIXELFORMAT_RGB24は
SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_RGBとなっており
意味は中身がuint8_tの配列で、要素の並び順はR -> G -> B
対してSDL_PIXELFORMAT_RGB888は
SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XRGBで
中身は32bit値にhigh bitからX -> R -> G -> Bの順でパックされている
という意味になる。Xのところは使われない。
これはどういうことかと言うとヘッダを見るとわかるがSDL_PIXELFORMAT_RGB24は
SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_RGBとなっており
意味は中身がuint8_tの配列で、要素の並び順はR -> G -> B
対してSDL_PIXELFORMAT_RGB888は
SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XRGBで
中身は32bit値にhigh bitからX -> R -> G -> Bの順でパックされている
という意味になる。Xのところは使われない。
もしかしてCPUがビッグエンディアンだったりすると違うのかもしれないが
とりあえずリトルエンディアンの環境だと上記の例は
とりあえずリトルエンディアンの環境だと上記の例は
0x00ff803f [32bitパックされた状態] 0x3f, 0x80, 0xff, (0x00) [メモリの配置]
長くなってしまったが、要するに名前が似てるのに配置が逆なのだ。紛らわしい。
これを知った上で改めてPIXELFORMATを眺めると
RGBA8888のように要素ごとのbit数が並んでる物はパックされていてメモリ上では表記と逆の配置、
RGB24のように全体のbit数が1つだけ書いてあればそれは配列形式でメモリ上でもそのまま。
という事に気づく。けど、パッと見てこうだ!とは、ならんよなぁ。
これを知った上で改めてPIXELFORMATを眺めると
RGBA8888のように要素ごとのbit数が並んでる物はパックされていてメモリ上では表記と逆の配置、
RGB24のように全体のbit数が1つだけ書いてあればそれは配列形式でメモリ上でもそのまま。
という事に気づく。けど、パッと見てこうだ!とは、ならんよなぁ。
テスト
行列とかベクトルなんかの計算をするクラスはテストコードが必須、
でも漠然とランダムデータを生成してエラーチェックしていてもなんだか釈然としない。
(それ以前にまともなテストコード書いてないのはともかく)
テストコードにはそれ用の書き方がある筈だし
チームで開発しなくても普通はテスト用のフレームワーク使うよな。
と思ったのでこれを機に調べて使ってみたい。
でも漠然とランダムデータを生成してエラーチェックしていてもなんだか釈然としない。
(それ以前にまともなテストコード書いてないのはともかく)
テストコードにはそれ用の書き方がある筈だし
チームで開発しなくても普通はテスト用のフレームワーク使うよな。
と思ったのでこれを機に調べて使ってみたい。
候補はGoogle TestとBoost Test。
Boostが既に導入済みなのでとりあえずBoost Testから試す所存。
Boostが既に導入済みなのでとりあえずBoost Testから試す所存。
(2014/07/06)
FBXとモデル
相変わらずモデルの読み込みや描画を詰めている(煮詰まっているともいう)
コード書き直しばっかりでページに乗せられるような画像が上がってこない。
コード書き直しばっかりでページに乗せられるような画像が上がってこない。
前にも書いたかもしれないが、FBXはあくまでもモデラー間のデータ受け渡し用であって
ゲームにそのまま使える代物じゃないだろって思う。
プログラミング解説のサイトなんかで
DirectX9までで使われてたXファイルが廃止されちゃったから代わりに使えそうなのはFBXだーみたいな記述を割と目にするけど
汎用的すぎてゲームに無用な情報が多い。
デバッグ時にモデラーから出力したFBXを直接読み込ませたいならともかく
自分はゲーム本体にFBXライブラリをリンクしたくはないかなぁ。
ライセンスの問題もありそうだし、それ以前にAndroid向けのライブラリが用意されてないとか。
ゲームにそのまま使える代物じゃないだろって思う。
プログラミング解説のサイトなんかで
DirectX9までで使われてたXファイルが廃止されちゃったから代わりに使えそうなのはFBXだーみたいな記述を割と目にするけど
汎用的すぎてゲームに無用な情報が多い。
デバッグ時にモデラーから出力したFBXを直接読み込ませたいならともかく
自分はゲーム本体にFBXライブラリをリンクしたくはないかなぁ。
ライセンスの問題もありそうだし、それ以前にAndroid向けのライブラリが用意されてないとか。
プログラミング以外の・・
ところで長らく殺風景だったWeb拍手のお礼画面の画像、またはtwitterの投稿からわかる通り
プログラミングの他に取り組んでる事というのは絵の練習。
何故かと言うと、それをここに書くにはスペースが足りないので詳細は省くが言ってみれば
「描けると楽しそうだから」
に尽きる。
例えば何かネタを思いついたとしてそれを面白おかしくtwitterで伝える為に文章だけというのは結構難易度が高い。
したがって百聞は一見に如かず、画像でとなり
自分の場合2Dの絵は描けないから3DCGでやろうとすると後ろ側までモデリングした後にテクスチャとエフェクトを作らなければならないし、
ネタは鮮度が命なのにそんな悠長なことをやっていては作る側としても気分が覚める。
第一視点を変更して何回も描画する訳でもないのにわざわざ3Dで作る利点って何よ?とか。
自作ツールに使うアイコン等の小さい画像にしても3DCGで作って縮小すると大抵メリハリついてなくて微妙になったりするので
描けないからとも言ってられず、必要性を感じた次第である。
プログラミングの他に取り組んでる事というのは絵の練習。
何故かと言うと、それをここに書くにはスペースが足りないので詳細は省くが言ってみれば
「描けると楽しそうだから」
に尽きる。
例えば何かネタを思いついたとしてそれを面白おかしくtwitterで伝える為に文章だけというのは結構難易度が高い。
したがって百聞は一見に如かず、画像でとなり
自分の場合2Dの絵は描けないから3DCGでやろうとすると後ろ側までモデリングした後にテクスチャとエフェクトを作らなければならないし、
ネタは鮮度が命なのにそんな悠長なことをやっていては作る側としても気分が覚める。
第一視点を変更して何回も描画する訳でもないのにわざわざ3Dで作る利点って何よ?とか。
自作ツールに使うアイコン等の小さい画像にしても3DCGで作って縮小すると大抵メリハリついてなくて微妙になったりするので
描けないからとも言ってられず、必要性を感じた次第である。
そこですぐに始められる第一歩として鉛筆またはシャーペンと紙で写真やイラストの模写なんかをやっている。
方法論はよく知らんけど見よう見まねでやってればちょっとくらい出来るようになるだろうとの目論見。
絵の練習は下手くそでも描き終われば一区切りつくし前回との差異もわかりやすく
何かしら目に見える形で成果が残せて、ぶっちゃけ今の所プログラミングなんかよりずっと楽しく
余計にプログラミングが進まない格好に。
方法論はよく知らんけど見よう見まねでやってればちょっとくらい出来るようになるだろうとの目論見。
絵の練習は下手くそでも描き終われば一区切りつくし前回との差異もわかりやすく
何かしら目に見える形で成果が残せて、ぶっちゃけ今の所プログラミングなんかよりずっと楽しく
余計にプログラミングが進まない格好に。
こうなると近々ペンタブが必要になってくるのかもしれないが、まだ何とも。
(とか言いつつamazonをチラチラ)
(とか言いつつamazonをチラチラ)
添付ファイル