FPSを作ってみる@wiki
07)
最終更新:
slice
-
view
(2012/07/30)
BTS
前々から気になっていたシリーズ.BTS(bug tracking system)だかITS(issue tracking system)とはなんぞや?
一言で言えばバグや要望の案件(の内容や状態)をチケットとして管理するシステム.
ぶっちゃけBTSを1人で使っても殆ど意味無さそうだが将来誰か加わった時や加わる時の為とか
いちいちwikiを更新せずとも進んでいる雰囲気を醸し出せるかもしれないとの目論見でちょっと調べていた.
今の所タスクや仕様等はメモ帳に書き留めているだけなので時々新旧のエントリが混乱したりする.その辺もマシになればと.
一言で言えばバグや要望の案件(の内容や状態)をチケットとして管理するシステム.
ぶっちゃけBTSを1人で使っても殆ど意味無さそうだが将来誰か加わった時や加わる時の為とか
いちいちwikiを更新せずとも進んでいる雰囲気を醸し出せるかもしれないとの目論見でちょっと調べていた.
今の所タスクや仕様等はメモ帳に書き留めているだけなので時々新旧のエントリが混乱したりする.その辺もマシになればと.
BTS自体の説明は他に譲るとして
一口にBTSといっても純粋にバグ管理だけの物からプロジェクト管理までカバーした物,有料無料が存在する訳で
自分の場合はバグ管理にちょっと使ってみたい程度なので勿論無料,機能もバグ管理オンリーの
なるべくシンプルなシステムを選びたい.
具体的にはBugzilla, Redmine, Mantis, Trac.. ASP系ならSimpleBugTrackerやubicast projectsなどが候補に挙がった.
一口にBTSといっても純粋にバグ管理だけの物からプロジェクト管理までカバーした物,有料無料が存在する訳で
自分の場合はバグ管理にちょっと使ってみたい程度なので勿論無料,機能もバグ管理オンリーの
なるべくシンプルなシステムを選びたい.
具体的にはBugzilla, Redmine, Mantis, Trac.. ASP系ならSimpleBugTrackerやubicast projectsなどが候補に挙がった.
と.ここまで書いておいてアレだがコードホスティングサービスのGitHubやBitbucketにも
簡易なBTSらしき物がついていたのでコレでいいやという結果に.
ApacheにインストールするタイプのBTSもそのうち挑戦したいな.
簡易なBTSらしき物がついていたのでコレでいいやという結果に.
ApacheにインストールするタイプのBTSもそのうち挑戦したいな.
それはそれとして.
ゲームの方はキャラクタモデルのジョイントに従って手足を動かす処理を組み込んでいた.所謂スキンメッシュ.
まぁ数年前の動画でやってたから特に目新しい事は無し,詰まった箇所は大半が単なる記述ミス(コンパイルエラー)である.
バグらしいバグと言えばシェーダーへの配列変数の設定を勘違いしていて全てSetValueで済ませようとしていた.
あれ?これで動かないんなら動画の時も動かなかったのでは?と思ったがアレは2世代前(3代目.現在5代目)のエンジンだった.
4代目が日の目を見たのはTwitterクライアントくらいか・・
ゲームの方はキャラクタモデルのジョイントに従って手足を動かす処理を組み込んでいた.所謂スキンメッシュ.
まぁ数年前の動画でやってたから特に目新しい事は無し,詰まった箇所は大半が単なる記述ミス(コンパイルエラー)である.
バグらしいバグと言えばシェーダーへの配列変数の設定を勘違いしていて全てSetValueで済ませようとしていた.
あれ?これで動かないんなら動画の時も動かなかったのでは?と思ったがアレは2世代前(3代目.現在5代目)のエンジンだった.
4代目が日の目を見たのはTwitterクライアントくらいか・・
(2012/07/26)
ゲームエンジンの作業に若干飽きてしまったのと前々から思ってたのと
Linuxに最近触ってないからMakefileの書き方とか忘れかけてる!やばい.との事で
GitHubにTLSFアロケータの出来かけをアップしてみた.メモリ効率と速度は非常にアレだが.コメントも日本語でしか書いてないし・・
一応オープンソースなのでコンパイラがvisualC++オンリーでは懐が狭いと思い,gcc用にインラインアセンブラ等修正.
テンプレート関連でvisualC++だと問題ない記述がgccだとエラーになる部分もあったりして幾らか手直しした.
具体的には
template <class T>
struct Base {
Base(T t) {}
};
template <class B>
struct Someone : Base<B> {
Someone(B b): Base(b) {}
};
のようなコードをgccでコンパイルしようとするとBaseのテンプレート引数がねぇよ!と怒られてしまう.
visualC++では単にBaseと書いた場合は暗黙にBase<B>のことを指すのだが.
Linuxに最近触ってないからMakefileの書き方とか忘れかけてる!やばい.との事で
GitHubにTLSFアロケータの出来かけをアップしてみた.メモリ効率と速度は非常にアレだが.コメントも日本語でしか書いてないし・・
一応オープンソースなのでコンパイラがvisualC++オンリーでは懐が狭いと思い,gcc用にインラインアセンブラ等修正.
テンプレート関連でvisualC++だと問題ない記述がgccだとエラーになる部分もあったりして幾らか手直しした.
具体的には
template <class T>
struct Base {
Base(T t) {}
};
template <class B>
struct Someone : Base<B> {
Someone(B b): Base(b) {}
};
のようなコードをgccでコンパイルしようとするとBaseのテンプレート引数がねぇよ!と怒られてしまう.
visualC++では単にBaseと書いた場合は暗黙にBase<B>のことを指すのだが.
(2012/07/23)
さりげにweb拍手のカウントが増えてる.
特に大規模な更新したわけでも無いがなんか,あったんだろうか.
只のカウンタとはいえモチベーションの維持に少なからず役立つからいいっちゃあいいんだけど.
特に大規模な更新したわけでも無いがなんか,あったんだろうか.
只のカウンタとはいえモチベーションの維持に少なからず役立つからいいっちゃあいいんだけど.
基礎固めその11: モデル読み込み
文字通り.フォーマットはデータを目視で確認 & 手入力し易いJsonである(ちなみにその前はXMLだった).
ただやっぱり数千頂点,ポリゴンあるモデルの読み込みで1秒程度かかってしまうからリリース時には
バイナリにする必要がありそう.まぁその辺ゲームできてから悩めばいい話なので・・
バンプマップに対応する際に頂点座標とUVから従法線を計算する必要が生ずるのだが
これをモデルデータに含めるかモデルを読み込んでから計算するかで迷った.
即ち速度とデータサイズのどちらを重視するか.
とりあえず開発中だしぶっちゃけどっちでもいいって事でモデル読み込んでからにした.
ただやっぱり数千頂点,ポリゴンあるモデルの読み込みで1秒程度かかってしまうからリリース時には
バイナリにする必要がありそう.まぁその辺ゲームできてから悩めばいい話なので・・
バンプマップに対応する際に頂点座標とUVから従法線を計算する必要が生ずるのだが
これをモデルデータに含めるかモデルを読み込んでから計算するかで迷った.
即ち速度とデータサイズのどちらを重視するか.
とりあえず開発中だしぶっちゃけどっちでもいいって事でモデル読み込んでからにした.
さて.モデル読み込みまで来たんだからそろそろデモが出せて然るべきなのだが
前に考えてた描画の仕組みじゃDeferredRenderingをしようとした時に上手くいかない事が判明して設計し直している・・
前に考えてた描画の仕組みじゃDeferredRenderingをしようとした時に上手くいかない事が判明して設計し直している・・
それが終わったら
モデル1つ表示のバンプマップ,セルフシャドウ無し,光源は1つで一発出してみようか.
モデル1つ表示のバンプマップ,セルフシャドウ無し,光源は1つで一発出してみようか.
(2012/07/18)
う~む.コンテナによってメモリ領域を分ける必要性が・・・・?という至極真っ当な疑問が払拭できず
「そもそもゲーム(機)でのSTLの是非」についてなんかも調べながら2時間程考えた.
いっそグローバルなnewを置き換えれば一番簡単かつ見方によっては美しい実装だろう.
しかしゲーム機でもないのにそれをするのは依然として抵抗がある.
「そもそもゲーム(機)でのSTLの是非」についてなんかも調べながら2時間程考えた.
いっそグローバルなnewを置き換えれば一番簡単かつ見方によっては美しい実装だろう.
しかしゲーム機でもないのにそれをするのは依然として抵抗がある.
まず型でアロケータを分けるのは自分で言っておいて難だが意味がわからないのでボツ.
分けるとしたらフラグメントを避ける目的か.
すなわちずっと確保しておくメモリとそうでないメモリを区別する位なら面倒じゃないし複数種類のコンテナで同じアロケータを使い回せる.
ざっと思いついた所では・・
分けるとしたらフラグメントを避ける目的か.
すなわちずっと確保しておくメモリとそうでないメモリを区別する位なら面倒じゃないし複数種類のコンテナで同じアロケータを使い回せる.
ざっと思いついた所では・・
- 長くとも1フレーム以内に解放される可変バッファ(関数内で計算結果を一時的に保存するなど)
- 数秒から数十秒(弾丸やパーティクル)
- 数分以上(モデルやサウンドなど)
こんなとこか.まぁ3種類でも無駄に多く感じるから上の2つは纏めてしまおう.
長々書いておいてアレだがPCで動かす分には普通のnew/deleteで全く問題ないと思う.だからこれは殆ど趣味みたいなもん.
いずれは非PCで動かすゲームを書いてみたいからその練習.
いずれは非PCで動かすゲームを書いてみたいからその練習.
(2012/07/17)
自前のアロケータ(というかTLSF)を用意したは良い物の実際使ってる場所が
やはり自前のリソースマネージャと明示的に配列を確保してる一部のクラスに留まっていて
普通にstd::vectorなんかはデフォルトアロケータ,つまり::operator newであり
非常に中途半端臭がしてたので対策を考える.
やはり自前のリソースマネージャと明示的に配列を確保してる一部のクラスに留まっていて
普通にstd::vectorなんかはデフォルトアロケータ,つまり::operator newであり
非常に中途半端臭がしてたので対策を考える.
といってもnewをオーバーロードとかはしない.組み込みでもない限り後々面倒だろうから.
要するにメモリの動的確保をするのは主にSTLのコンテナなのだから
そこで使うアロケータを用意しようと.
以前にちょっと調べたこともあったが注意事項など読んでいる内に
「なんだか小難しいからデフォルトを使おう」という話になってたか.
要するにメモリの動的確保をするのは主にSTLのコンテナなのだから
そこで使うアロケータを用意しようと.
以前にちょっと調べたこともあったが注意事項など読んでいる内に
「なんだか小難しいからデフォルトを使おう」という話になってたか.
改めて調べると実装自体は既にあるテンプレをコピーしてきて数カ所書き換えるだけであった.
注意事項というのは単に「staticなメンバ変数を持ってはいけない」という物.
何でかというと自分でも完全に理解してないがどうやらC++の規格として
「アロケータは同じ型なら交換できなければならない」というのがあるらしい.
内部に変数なんぞもってたら確保した時と違うアロケータで解放したら不具合起こりそうだ.
注意事項というのは単に「staticなメンバ変数を持ってはいけない」という物.
何でかというと自分でも完全に理解してないがどうやらC++の規格として
「アロケータは同じ型なら交換できなければならない」というのがあるらしい.
内部に変数なんぞもってたら確保した時と違うアロケータで解放したら不具合起こりそうだ.
あともう一つ.
STL アロケータ とググッて一番に出てくるページなんかではstd::vectorはともかくstd::mapやstd::listは
”ユーザーが自分で用意したアロケータが使われるとは限らないから結局デフォルトが~”とか書いてあるが
これは少々不正確ではないか.
確かにmapやlistはデータ本体の他に前後のノードへのポインタを持つ必要があるのでコンテナの型のアロケータはそのまま使われないと思う.
じゃあ代わりに何で確保するのかという問題になるが仮にここで”勝手に”標準のnewなんて使ってたらアロケータの意味が全くない.
ググッて出てきた他のページを読めばわかるがtemplate <class U> rebind;という構造体がアロケータ内部に定義される事になっていて
その内部型であるrebind<U>::otherがUのアロケータを示す事で他の型のメモリを確保する仕様のようだ.
STL アロケータ とググッて一番に出てくるページなんかではstd::vectorはともかくstd::mapやstd::listは
”ユーザーが自分で用意したアロケータが使われるとは限らないから結局デフォルトが~”とか書いてあるが
これは少々不正確ではないか.
確かにmapやlistはデータ本体の他に前後のノードへのポインタを持つ必要があるのでコンテナの型のアロケータはそのまま使われないと思う.
じゃあ代わりに何で確保するのかという問題になるが仮にここで”勝手に”標準のnewなんて使ってたらアロケータの意味が全くない.
ググッて出てきた他のページを読めばわかるがtemplate <class U> rebind;という構造体がアロケータ内部に定義される事になっていて
その内部型であるrebind<U>::otherがUのアロケータを示す事で他の型のメモリを確保する仕様のようだ.
ま,そんな訳でメモリプールを分けたいと思ったら型で区別するしか無さそうである.
だがC++のtypedefは単なる別名定義に過ぎない.
うっかり頂点インデックスで使うunsigned shortを置き換えようものならプログラムの他の箇所で暴発するのは想像に難くない・・
要するに型が違えばいいのだから最悪
template <class T, class ID>
struct MyInt {
T value;
だがC++のtypedefは単なる別名定義に過ぎない.
うっかり頂点インデックスで使うunsigned shortを置き換えようものならプログラムの他の箇所で暴発するのは想像に難くない・・
要するに型が違えばいいのだから最悪
template <class T, class ID>
struct MyInt {
T value;
MyInt() {}
MyInt(T v): value(v) {}
MyInt& operator = (T v) { value=v; return *this; }
bool operator == const (T v) { return value==v; }
operator T() const { return value; }
...あと色々定義
};
struct _VIndex {}; // 区別用にユニークな型を定義
typedef MyInt<int, _VIndex> VIndex; // 頂点インデックス
とかでいいか?
MyInt(T v): value(v) {}
MyInt& operator = (T v) { value=v; return *this; }
bool operator == const (T v) { return value==v; }
operator T() const { return value; }
...あと色々定義
};
struct _VIndex {}; // 区別用にユニークな型を定義
typedef MyInt<int, _VIndex> VIndex; // 頂点インデックス
とかでいいか?
あとは簡単なメタプログラミングで型を渡したら対応するアロケータクラスのポインタを返すグローバル関数を定義しておけば,どうだろうか
(2012/07/14)
やっぱり,一人でイチから作るなんて無理があったのかねぇ・・
正直言って完成させる自信ない.
正直言って完成させる自信ない.
基礎固めその10: レンダリング & アップデート機構
とりあえず動かさなければという事で単純にタスクの優先度でソートしシーン上のオブジェクトをアップデート(毎フレームの処理)
するUpdatorクラスを実装.
描画に関しても同じく優先度ソートで.
一応,後からクラスを実装すればマップの同じ部屋に居る敵だけ更新なども出来る筈.実際やってみないと説得力無いが.
非頂点バッファのポリゴンや同じテクスチャのオブジェクトは纏めて描画する等の部分は移植がメイン.
するUpdatorクラスを実装.
描画に関しても同じく優先度ソートで.
一応,後からクラスを実装すればマップの同じ部屋に居る敵だけ更新なども出来る筈.実際やってみないと説得力無いが.
非頂点バッファのポリゴンや同じテクスチャのオブジェクトは纏めて描画する等の部分は移植がメイン.
ま,そんなこんなで四角ポリゴンにテクスチャを張り付けてカーソルキーで移動
スペース押す毎に四角ポリゴンが生成され,優先度でソートされ,描画・・・
といったスクリプトなんぞ書いて動かしていたが
流石にこれで喜ぶ年ではないなぁ.
そりゃ前と比べたら内部はかなりスッキリしてるけれど.拡張性も含め.
スペース押す毎に四角ポリゴンが生成され,優先度でソートされ,描画・・・
といったスクリプトなんぞ書いて動かしていたが
流石にこれで喜ぶ年ではないなぁ.
そりゃ前と比べたら内部はかなりスッキリしてるけれど.拡張性も含め.
次の課題は当たり判定をどうするか.
前までは何となくアップデートフェーズ,描画フェーズ,コリジョンフェーズと分けて処理していたのだが
別に明確にアップデートと分けなくても良いような(実際アップデートの時にコリジョン関数呼びまくってた)
けど当たり判定は一気にやってしまってアップデートの時に結果を各オブジェクトで参照しつつ分岐・・・っていうのも
その都度関数呼ぶよりシンプルでわかりやすいし・・(続く)
前までは何となくアップデートフェーズ,描画フェーズ,コリジョンフェーズと分けて処理していたのだが
別に明確にアップデートと分けなくても良いような(実際アップデートの時にコリジョン関数呼びまくってた)
けど当たり判定は一気にやってしまってアップデートの時に結果を各オブジェクトで参照しつつ分岐・・・っていうのも
その都度関数呼ぶよりシンプルでわかりやすいし・・(続く)
(2012/07/10)
後日とか言っておきながら平気で1週間過ぎる訳で.
えっと,このように(?)毎度毎度間隔が空いてしまう原因は
「キリが良い所まで進んだら進捗を書こう」とするからであって動画も然りなのである.
自問自答するようだが「キリの良い所」なんて無いのにね.完成したらか?
否,自分のことだからそれでも細かなアラが気になって仕方ないだろう.
えっと,このように(?)毎度毎度間隔が空いてしまう原因は
「キリが良い所まで進んだら進捗を書こう」とするからであって動画も然りなのである.
自問自答するようだが「キリの良い所」なんて無いのにね.完成したらか?
否,自分のことだからそれでも細かなアラが気になって仕方ないだろう.
御託はここまで.とりあえず書く.
基礎固めその9: デバイスロスト対応
今までDirect3Dを触っていた癖にずっと放置していたデバイスロストにやっとこさ対応.
何のリソースを確保し直すのか等を調査してリソースマネージャにデバイスロストを通知すれば
予め登録しておいた「ロスト対応が必要なリソース」が順に処理を行うようにした.
これ自体は配列にポインタ登録して呼び出すだけなんでどうって事ないのだが
少し迷ったのがテクスチャにD3DPOOL_MANAGEDフラグを指定しておけばドライバが復帰処理をしてくれる点.
頼ろうか,どうしようか・・
何のリソースを確保し直すのか等を調査してリソースマネージャにデバイスロストを通知すれば
予め登録しておいた「ロスト対応が必要なリソース」が順に処理を行うようにした.
これ自体は配列にポインタ登録して呼び出すだけなんでどうって事ないのだが
少し迷ったのがテクスチャにD3DPOOL_MANAGEDフラグを指定しておけばドライバが復帰処理をしてくれる点.
頼ろうか,どうしようか・・
しかしよくよく考えてみたらD3DPOOL_MANAGEDに出来ないRenderTargetはどのみち自前でやらなきゃいけないし
ちょいとググればドライバの復帰処理というのも単にシステムメモリに1つコピーを取っておいて書き戻してるだけっぽいのだ.
つまりメモリを余計に食う.
「ファイルから読む静的テクスチャ」なんかはまたファイルから読めばいいし,軽いプロシージャル生成ならまた走らせればいい.
フルスクリーン状態から最小化して数秒の復帰時間がかかった所で誰も文句を言わないだろうとの判断で
どうしても直前の内容を復元しないと困る場合のみMANAGEDを指定する方針にした.
(でもやりすぎるとsourceエンジンみたいになっちゃうんだろうか)
ちょいとググればドライバの復帰処理というのも単にシステムメモリに1つコピーを取っておいて書き戻してるだけっぽいのだ.
つまりメモリを余計に食う.
「ファイルから読む静的テクスチャ」なんかはまたファイルから読めばいいし,軽いプロシージャル生成ならまた走らせればいい.
フルスクリーン状態から最小化して数秒の復帰時間がかかった所で誰も文句を言わないだろうとの判断で
どうしても直前の内容を復元しないと困る場合のみMANAGEDを指定する方針にした.
(でもやりすぎるとsourceエンジンみたいになっちゃうんだろうか)
後はカメラ,頂点・インデックスバッファ,当たり判定,姿勢管理 などのクラスを地道に移植しているのと
オブジェクト間メッセージ通信の部分を煮詰めたりしている.
アップデートと描画の管理については幾分纏まって来たから行けるか・・・?
オブジェクト間メッセージ通信の部分を煮詰めたりしている.
アップデートと描画の管理については幾分纏まって来たから行けるか・・・?
これらとは別に描画アルゴリズムの調査も少々.
具体的には屋外シーンで使うシャドウマップ(LiSPSMやカスケード手法)
水面下コースティクスなど <= 海面描画に未だに満足してない
具体的には屋外シーンで使うシャドウマップ(LiSPSMやカスケード手法)
水面下コースティクスなど <= 海面描画に未だに満足してない
(2012/07/04)
さて5月にも書いたが,何かあったわけじゃないけど今月から更に気を引き締めて行こうか・・
とりあえず来月までTwitterを自粛する.
とりあえず来月までTwitterを自粛する.
まず結構前に書いた動画の件.
ある程度新エンジンが出来てきたらわざわざ古いソースをいじってまで動画を撮るのが億劫になってしまったので
「モデル表示&視点操作するだけのデモ」で代えさせて貰う.
今思えば海面描画が一段落した時点で動画にすべきだった.
ある程度新エンジンが出来てきたらわざわざ古いソースをいじってまで動画を撮るのが億劫になってしまったので
「モデル表示&視点操作するだけのデモ」で代えさせて貰う.
今思えば海面描画が一段落した時点で動画にすべきだった.
次にQtで作ってみたTwitterクライアントのGitHub公開.
これはソースに少し修正を加えた後,なるべく早くする.具体的にはユーザーの情報を管理する部分が未完成で
現状はどんなにユーザー情報が参照されなくなっても解放されずメモリを食い尽くす一方である.
ゲームエンジンで使っているメモリアロケータとリソースマネージャを組み込めば何とかなるだろうか・・
とはいえ高々1人数キロバイト程度
ことメモリが潤沢な今日では例えスマフォだろうが(恐らく512mbとか積んでるんだろう)
問題になるとは思えない関係で長年放置されてきたのだった.
これはソースに少し修正を加えた後,なるべく早くする.具体的にはユーザーの情報を管理する部分が未完成で
現状はどんなにユーザー情報が参照されなくなっても解放されずメモリを食い尽くす一方である.
ゲームエンジンで使っているメモリアロケータとリソースマネージャを組み込めば何とかなるだろうか・・
とはいえ高々1人数キロバイト程度
ことメモリが潤沢な今日では例えスマフォだろうが(恐らく512mbとか積んでるんだろう)
問題になるとは思えない関係で長年放置されてきたのだった.
前にちょっとweb関連を勉強したときの名残であるスクショギャラリー (Media -> Gallery -> ShotGallery).
配信の時にガイジンから
配信の時にガイジンから
- 「毎回PHPでスクショのディレクトリを走査する」んでなくてキャッシュした方がいいよ
- 画像読み込み完了待ちはポーリングじゃなくてjQueryの.load()を使った方が(略
と突っ込みが入った.
後者はともかく前者は毎日サイトに100人程度アクセスが来るようになったら考える.
アクセス頻度高くないのに最適化をするモチベーションは,ちょっと・・
途中まで作ってあるアンケートや投票フォームとかも気が向いたらという事で.
後者はともかく前者は毎日サイトに100人程度アクセスが来るようになったら考える.
アクセス頻度高くないのに最適化をするモチベーションは,ちょっと・・
途中まで作ってあるアンケートや投票フォームとかも気が向いたらという事で.
ゲームの進捗についてはまた後日