FPSを作ってみる@wiki
05)
最終更新:
slice
-
view
(2013/05/25)
更新休止
お世辞にもプレビュー数が多いとは言えないページではあるが進捗を淡々と記すのは一応自分で決めた事なので。
身内に不幸があった関係でしばらく更新を休止する。
再開は・・ちょっと今はわからない。すぐかもしれないし一ヶ月後かもしれない。
身内に不幸があった関係でしばらく更新を休止する。
再開は・・ちょっと今はわからない。すぐかもしれないし一ヶ月後かもしれない。
あとこれはお願い。一言でいいからトップページにコメントとか貰えると有難い。
ではまた。
ではまた。
(2013/05/22)
行列クラス公開
といってもまだバグチェックとかはしてない。もちろんGitHub。
しかし・・・・boost::preprocessorを使って色々してると、やはりコンパイラが出すエラーが分かりにくいのが気になる。
もっともboost::spirit程ではないが。今思えばアレはやばかった。
別に無理にBNF記法に合わせなくていいからもうちょっとコンパイル時間が短くてエラーが解りやすい、
なおかつ外部ツールのプリプロセスが不要な文法解析ライブラリとか無いものか。
しかし・・・・boost::preprocessorを使って色々してると、やはりコンパイラが出すエラーが分かりにくいのが気になる。
もっともboost::spirit程ではないが。今思えばアレはやばかった。
別に無理にBNF記法に合わせなくていいからもうちょっとコンパイル時間が短くてエラーが解りやすい、
なおかつ外部ツールのプリプロセスが不要な文法解析ライブラリとか無いものか。
話を戻して
まぁ何だね。これだけマクロで無駄な苦労してるといっそ
「デバッグ時は外部DLLをリンクする」
「リリース時は別のヘッダをインクルードしてインライン展開をしてもらう」
形でライブラリ構成するのもアリかもしれんね。
まぁ何だね。これだけマクロで無駄な苦労してるといっそ
「デバッグ時は外部DLLをリンクする」
「リリース時は別のヘッダをインクルードしてインライン展開をしてもらう」
形でライブラリ構成するのもアリかもしれんね。
とはいえ今作ってるのも中途半端だけは避けたいから
前に自分が作ってたライブラリの機能くらいは移植してから終わりたい。
変にテンプレート使ってデバッグが遅いとはいえクォータニオンや平面クラスとか用意してあって、一応動いたので。
現に公開してるデモプログラムは数学クラス全部自前実装だし。
前に自分が作ってたライブラリの機能くらいは移植してから終わりたい。
変にテンプレート使ってデバッグが遅いとはいえクォータニオンや平面クラスとか用意してあって、一応動いたので。
現に公開してるデモプログラムは数学クラス全部自前実装だし。
一からゲームを組みたいんだっていう奇特な人で無ければ普通にD3DX関数(廃止するんだっけ?)やEigenとか使っておけばいいと思う。
Eigenは最近になってライセンスがLGPLからMPL2.0に変わったようなのでより使いやすくなってる。
ちなみに自分がGitHubで公開してるコードはMITライセンス・・・という程大層なものでもないが、形から入る方なのでそうしてみた。
Eigenは最近になってライセンスがLGPLからMPL2.0に変わったようなのでより使いやすくなってる。
ちなみに自分がGitHubで公開してるコードはMITライセンス・・・という程大層なものでもないが、形から入る方なのでそうしてみた。
(2013/05/15)
ベクトルクラス公開
前にちょこっと書いて触れずに放置していたSSE命令を使ったベクトルクラスを
boost preprocessorの助けを借りた形で前よりスマートに書きなおした。
まだベクトルクラスだけしか無いが、とりあえず公開とする。詳しくはいつものGitHubにて。
リポジトリ名はSpinner。もちろん適当につけた。
boost preprocessorの助けを借りた形で前よりスマートに書きなおした。
まだベクトルクラスだけしか無いが、とりあえず公開とする。詳しくはいつものGitHubにて。
リポジトリ名はSpinner。もちろん適当につけた。
実の所wikiを更新してないけど裏では作業してるんですよーという事を示したかったのもある。
GitHubのフィードをwikiに載せれば・・とも思ったがAtWikiの機能が本当にただ「表示するだけ」で、
何件までとかのフィルタさえ無くて微妙過ぎた。
GitHubのフィードをwikiに載せれば・・とも思ったがAtWikiの機能が本当にただ「表示するだけ」で、
何件までとかのフィルタさえ無くて微妙過ぎた。
そんな訳でこれから行列クラスに取り掛かる
(2013/05/13)
シェーダーが使えない
書きかけの記事を置いたまんま放置してた件。
とりあえず体調不良だったのもあるけど理由として一番でかいのは
OpenGLが何故かver1.4で初期化されてしまう問題。
自分が詰まってたのはQtでのOpenGLなのだが、原因からすればXWindowで自前初期化したケースと変わらないだろうと。
とりあえず体調不良だったのもあるけど理由として一番でかいのは
OpenGLが何故かver1.4で初期化されてしまう問題。
自分が詰まってたのはQtでのOpenGLなのだが、原因からすればXWindowで自前初期化したケースと変わらないだろうと。
日にちも経ってしまった事だし概要だけ述べる
1. シェーダーの初期化やVertexBufferObjectの動作を確かめるためにQtのQGLWidgetを用いた時に
glGenBuffers()を呼んでも本来メモリにセットされるはずの値がセットされてない事に気づき、原因を探す
(glGetError()ではGL_NO_ERRORが返る)
2. QGLWidgetが悪いのかと踏んでQGuiApplicationとQWindowを使った実装に変更するも、改善されず
3. シェーダー管理クラスのQGLShaderProgramを使ってシェーダーを読み込むと「このバージョンのOpenGLでは対応してない云々」と言われ、QOpenGLContextにて初期化されたバージョンを見ると1.4になっている。初期化パラメータをどういじっても2.0以上にはならず
4. ドライバを入れなおすも、変わらない(RadeonなのでCatalyst 13.4を導入)
5. ふと、lddで依存ファイルを調べると・・libGL.so.1のパスにmesaとかいうのが(確かオープンソースドライバ)
glGenBuffers()を呼んでも本来メモリにセットされるはずの値がセットされてない事に気づき、原因を探す
(glGetError()ではGL_NO_ERRORが返る)
2. QGLWidgetが悪いのかと踏んでQGuiApplicationとQWindowを使った実装に変更するも、改善されず
3. シェーダー管理クラスのQGLShaderProgramを使ってシェーダーを読み込むと「このバージョンのOpenGLでは対応してない云々」と言われ、QOpenGLContextにて初期化されたバージョンを見ると1.4になっている。初期化パラメータをどういじっても2.0以上にはならず
4. ドライバを入れなおすも、変わらない(RadeonなのでCatalyst 13.4を導入)
5. ふと、lddで依存ファイルを調べると・・libGL.so.1のパスにmesaとかいうのが(確かオープンソースドライバ)
6. どうも普通にlibGLをリンクするとmesaドライバが読み込まれる設定になってる。で、fglrxがプロプライエタリ=catalystのドライバ
7. soファイルのパス設定はどうだったっけ?と思い、見てみると見慣れないリンクが・・(水色の2つ)
8. とりあず水色の2つは除外してldconfigを実行して自プログラムをコンパイル後、再度ldd
mesaじゃない方をリンクしている
バージョンを見ると無事4.2になっていた。glGenBuffersその他シェーダー関連の関数も普通に動く。
出力される対応エクステンションの数がmesaと比べて桁違いであった。
出力される対応エクステンションの数がmesaと比べて桁違いであった。
前にドライバの導入に手間取ってオープンソースのに戻したりまたcatalyst入れたりを繰り返していたんで、その辺かなぁ・・
その後
本当は3Dでポリゴンぐりぐり動かしてる予定がシェーダー云々以前で手間取り、見事に調子が狂ってしまったんで
気分転換ついでに別の事をしていた。勉強タイム。
今回取り組んだのはboost::asioで、名の通り非同期(asynchronous)に入出力(input/output)をするライブラリである。
具体的にはネットワーク通信やシリアルポート?なんかの、時間がかかる処理に対しイベントハンドラを設定し各種処理が終わり次第呼び出すような仕組み。
通信に限らず別スレッドで重い画像処理をさせるとかにも使えるが、基本はtcpやudpな気はする。
気分転換ついでに別の事をしていた。勉強タイム。
今回取り組んだのはboost::asioで、名の通り非同期(asynchronous)に入出力(input/output)をするライブラリである。
具体的にはネットワーク通信やシリアルポート?なんかの、時間がかかる処理に対しイベントハンドラを設定し各種処理が終わり次第呼び出すような仕組み。
通信に限らず別スレッドで重い画像処理をさせるとかにも使えるが、基本はtcpやudpな気はする。
イベントハンドラが実行されるスレッドはboost::asio::io_serviceのrun()を呼び出したスレッドと保証されてるんで
処理の完了通知を取り扱う上でいちいち同期をとらなくてもいい。
チュートリアルをひと通り終えた程度の知識じゃこんなとこですねはい。
処理の完了通知を取り扱う上でいちいち同期をとらなくてもいい。
チュートリアルをひと通り終えた程度の知識じゃこんなとこですねはい。
チュートリアルでやってたようにdaytimeサーバーに繋いでテキスト一行受け取って終了のようなケースだと
プログラムの行数的にはwinsockでチマチマやった時と変わらんからまだ「boost便利!」とは行かないのが実情。
複数同時リクエストしたりキャンセル処理が入れば違ってくるとは思う。
プログラムの行数的にはwinsockでチマチマやった時と変わらんからまだ「boost便利!」とは行かないのが実情。
複数同時リクエストしたりキャンセル処理が入れば違ってくるとは思う。
前回の記事
書きかけ記事は引き続き放置で。
近日中にリファインして再公開したいが、気力がない。
近日中にリファインして再公開したいが、気力がない。
(2013/05/09)
[書きかけ記事]
またもや空いてしまって申し訳ない。
訂正
とりあえず・・
前回「OpenGLのセッティング関数云々はこんな感じ」等と書いたな。あれは嘘だ。(アアアァァァァァァァァ....
前回「OpenGLのセッティング関数云々はこんな感じ」等と書いたな。あれは嘘だ。(アアアァァァァァァァァ....
実は上手く動かないことに5月入る前には気づき、考え直して再実装したものの
肝心な記事の間違い訂正を面倒臭がってズルズルと今日に至る。
詳しいことはソースを見てもらったほうが早い。
肝心な記事の間違い訂正を面倒臭がってズルズルと今日に至る。
詳しいことはソースを見てもらったほうが早い。
[---- ソース載せる欄(後日)----]
要点だけ説明すると(linewidth,glLineWidth,1)という風に引数の数だけ指定して
intだろうがboolだろうが全部floatでまかなっていた所をちゃんとboost::variantを使って分離。
従って(linewidth,glLineWidth,float)と引数型を記述するようにした。
ウィンドウへの描画範囲(四隅)を指定するglViewportだったら(viewport,glViewport,int,int,int,int)という感じ。
intだろうがboolだろうが全部floatでまかなっていた所をちゃんとboost::variantを使って分離。
従って(linewidth,glLineWidth,float)と引数型を記述するようにした。
ウィンドウへの描画範囲(四隅)を指定するglViewportだったら(viewport,glViewport,int,int,int,int)という感じ。
ところでboost::variantから値を取り出すboost::getはテンプレート引数に数値を使えないのだろうか?
例えば
boost::variant<bool,int,float> value;
という変数があって、ここにintが格納されているとしたら値を取り出すのに1番目の型という事で
boost::get<1>(value)と書きたかったのだがコンパイルが通らず。
実際はboost::get<int>(value)という風に型を指定する。
例えば
boost::variant<bool,int,float> value;
という変数があって、ここにintが格納されているとしたら値を取り出すのに1番目の型という事で
boost::get<1>(value)と書きたかったのだがコンパイルが通らず。
実際はboost::get<int>(value)という風に型を指定する。
なんだかな、内部にタイプリストを持っておけばインデックスで型を特定できそうな物だがな。
自分は偉い人じゃないので理由はわからない。
自分は偉い人じゃないので理由はわからない。
進捗状況
まぁ、Gitのコミット履歴を見るに・・
4日までは自前エフェクトフォーマットの仕様変更を繰り返してたようだ。
5日でエフェクト記述から頂点、ピクセルシェーダーそれぞれを関連する変数ブロックと一緒に出力し、OpenGLドライバでコンパイルまで行けたらしい。
その後はOpenGLの頂点バッファの管理クラス、シェーダークラス、間合せの行列クラス、OpenGLAPIのエラーチェックアサートマクロ・・・と、実装は月並みなので省略。
4日までは自前エフェクトフォーマットの仕様変更を繰り返してたようだ。
5日でエフェクト記述から頂点、ピクセルシェーダーそれぞれを関連する変数ブロックと一緒に出力し、OpenGLドライバでコンパイルまで行けたらしい。
その後はOpenGLの頂点バッファの管理クラス、シェーダークラス、間合せの行列クラス、OpenGLAPIのエラーチェックアサートマクロ・・・と、実装は月並みなので省略。
昨日までは頂点ポインタの関連付け機構なんぞをやっていた。
これはDirectXと同様に頂点ストリームとオフセットとセマンティクスを事前に設定しておき
実行時はストリームに頂点配列ポインタを渡すだけでシェーダー変数の設定(glVertexAttribPointerとか)をやってくれる物。
例として3次元の座標と2次元のテクスチャ座標を持つ頂点ならば
これはDirectXと同様に頂点ストリームとオフセットとセマンティクスを事前に設定しておき
実行時はストリームに頂点配列ポインタを渡すだけでシェーダー変数の設定(glVertexAttribPointerとか)をやってくれる物。
例として3次元の座標と2次元のテクスチャ座標を持つ頂点ならば
// 頂点を表す構造体
struct Vert {
vec3 pos;
vec2 tex;
};
// 頂点オフセット定義 {ストリーム番号、バイトオフセット、正規化フラグ、要素数、セマンティクス}
VertexDecl vDecl[] = {
{0, 0, GL_FLOAT,GL_FALSE, 3, (GLuint)VSem::POSITION},
{0, 12, GL_FLOAT, GL_FALSE, 2, (GLuint)VSem::TEXCOORD0}
};
Vert vert[] = {
{
{-1,-1,-1},
{0,0}
},
{
{-1,1,-1},
{0,1}
},
{
{1,1,-1},
{1,1}
},
{
{1,-1,-1},
{1,0}
}
};
GLVBuffer vbuff;
vbuff.setData(vert, countof(vert)); // 頂点バッファの作成
GLEffect glx("file.fx"); // エフェクトファイルの読み込み
glx.setVStream(0, vbuff); // 頂点ストリームの設定
頂点バッファの作成とかは疑似コードなんだけど、大体このように書く。
後は内部でglEnableVertexAttribArrayやglglVertexAttribPointerを呼んでくれて描画の準備が整う(予定。まだテクスチャとかやってないし)
後は内部でglEnableVertexAttribArrayやglglVertexAttribPointerを呼んでくれて描画の準備が整う(予定。まだテクスチャとかやってないし)