FPSを作ってみる@wiki
08)
最終更新:
slice
-
view
(2013/08/31)
フォント
ま、何時までやってんだという感じだけど。一応。文章は青空文庫から適当に取ってきたのと自分のソースコードの一部。
確認の為にアルファ抜きは無しでやってる。
確認の為にアルファ抜きは無しでやってる。

で、こっちがキャッシュ。

別段面白いことは無い。キャッシュが複数枚に渡った時の対処だけ書いて終了としたい。
意外だったのはキャッシュをこんなギチギチに詰めても隣のフォントが半ピクセル映り込んだりしてないなーという事。
予定
はい。途中までアルゴリズム考えてしまったんでメガテクスチャします。
個人制作の範囲でメガテクスチャって用途がイマイチわからん気もするけどランダムマップでプロシージャルにテクスチャを生成する場合に
何か役に立つかもしれない。
キャラクターを描画する際に使用するテクスチャを一枚に収めなくてOKなので作業する人(というか恐らく自分)は楽になるかも。
個人制作の範囲でメガテクスチャって用途がイマイチわからん気もするけどランダムマップでプロシージャルにテクスチャを生成する場合に
何か役に立つかもしれない。
キャラクターを描画する際に使用するテクスチャを一枚に収めなくてOKなので作業する人(というか恐らく自分)は楽になるかも。
メガテクスチャが「実はアルゴリズムが使えない」だとかでおじゃんになるか一区切りついたらまずは今までDirectXでやってたDifferedShadingをOpenGLへ移植。
その次は、まずは普通のシャドウマップ。
更にその後は後になってから考える。
その次は、まずは普通のシャドウマップ。
更にその後は後になってから考える。
(2013/08/27)
とりあえずグラフィック強化を始める前に8月が終わるのだけは避けたい。
現状
相変わらずフォント関連。結局の所シンプルじゃなくなった。
テクスチャにフォントを詰めて行く所はフォントの縦幅だけ固定で横は文字ごとにばらつきがあるんで
可変で。
前に作ったTLSFアロケータみたいに空き領域の広さで分けて格納しておいて
確保時にはビット演算で適した空き領域(テクスチャ位置)を一発で求める。
今思えば別に線形探索でえーやんという感じなのだが。
テクスチャにフォントを詰めて行く所はフォントの縦幅だけ固定で横は文字ごとにばらつきがあるんで
可変で。
前に作ったTLSFアロケータみたいに空き領域の広さで分けて格納しておいて
確保時にはビット演算で適した空き領域(テクスチャ位置)を一発で求める。
今思えば別に線形探索でえーやんという感じなのだが。
あと文字列の頂点配置と頂点フォーマットの管理を詰めれば、行けるか?といった所。
グラフィック強化について
前にシャドウマップやらSSAOだのと言ってた気がするがここに来てメガテクスチャに興味が出始めている。
id softwareのRAGEで有名になった、巨大なテクスチャに複数の画像を書き込んでマップ全体で
一枚のテクスチャを使いまわしましょうという技術(あってる?)
この時見える部分のテクスチャだけをメガテクスチャに置く事で
「従来マップで使われているテクスチャは全てVRAMに収まっているべき」という制限が緩和される。
まぁ、理想的にはの話で当初はテクスチャの貼り遅れが目立つなどあったみたいだけど。
言ってみればVRAMの手動管理だね。
id softwareのRAGEで有名になった、巨大なテクスチャに複数の画像を書き込んでマップ全体で
一枚のテクスチャを使いまわしましょうという技術(あってる?)
この時見える部分のテクスチャだけをメガテクスチャに置く事で
「従来マップで使われているテクスチャは全てVRAMに収まっているべき」という制限が緩和される。
まぁ、理想的にはの話で当初はテクスチャの貼り遅れが目立つなどあったみたいだけど。
言ってみればVRAMの手動管理だね。
ちなみにこの機能はOpenGL4.3やDirectX11.2でハードウェア対応されて自前でやらずとも手軽に使えるようになってる。
でもメインで使えるようになるまで2〜3年はかかりそうだ・・
でもメインで使えるようになるまで2〜3年はかかりそうだ・・
(2013/08/23)
rigid2d-test_v0.0.2-2wを公開
何はともあれOpenGL4以上でしか動かなかったっぽい問題を修正
余計な関数読み込みを排除したので
OpenGL2.0までとARB_framebuffer_object拡張をサポートしてるカードであれば起動出来る筈。
正確にはARB_framebuffer_objectは必須ではないが今後の為にそういうクラスを実装した関係上。
linuxの方は・・メンドイから放置
余計な関数読み込みを排除したので
OpenGL2.0までとARB_framebuffer_object拡張をサポートしてるカードであれば起動出来る筈。
正確にはARB_framebuffer_objectは必須ではないが今後の為にそういうクラスを実装した関係上。
linuxの方は・・メンドイから放置
単なるリリース番号の違いなので見た目の動作は全く変わらない。
しかしながら内部では結構変更箇所がある。
大きな点は「スマートフォン等でバックグラウンドに回したら使用リソースを最小限にする」機能のテストとして
シーンのリセット時に全てのOpenGLリソースを一旦開放してから再確保している。
ファイルから読み込んだテクスチャなら再度ファイルから読むし、ユーザー定義のテクスチャはフラグで
直前の内容をメモリに持っておいて復元するのか、何もしなくていいのかを選べるようにしたり。
framebufferやrenderbufferに対しても同様の処理を実装しているものの
今回のプログラムではframebufferを使っていないから従ってその辺はテストになってない。
しかしながら内部では結構変更箇所がある。
大きな点は「スマートフォン等でバックグラウンドに回したら使用リソースを最小限にする」機能のテストとして
シーンのリセット時に全てのOpenGLリソースを一旦開放してから再確保している。
ファイルから読み込んだテクスチャなら再度ファイルから読むし、ユーザー定義のテクスチャはフラグで
直前の内容をメモリに持っておいて復元するのか、何もしなくていいのかを選べるようにしたり。
framebufferやrenderbufferに対しても同様の処理を実装しているものの
今回のプログラムではframebufferを使っていないから従ってその辺はテストになってない。
そんな感じ。
(2013/08/22)
codecvt
要はUTF8, UTF16, UTF32の相互変換をどうしましょうかという事なのだけど。
前回までは自前でやってて、速度はともかく大したコード量でもないし信頼性も別にゲームだしって感じで問題なかった。
とはいえあまりスマートなコードではないので何とかしたい。
C++11は標準ライブラリに(ようやく?)備わっているらしいのでちょっと調べてこれを使うことにした。
前回までは自前でやってて、速度はともかく大したコード量でもないし信頼性も別にゲームだしって感じで問題なかった。
とはいえあまりスマートなコードではないので何とかしたい。
C++11は標準ライブラリに(ようやく?)備わっているらしいのでちょっと調べてこれを使うことにした。
そしたらlibstdc++にはまだ実装されてないって言う話じゃないですか。
ついでに言えばregexも無いじゃないですか。
ついでに言えばregexも無いじゃないですか。
聞けばlibc++にはある様なので、ちょいとビルドしてそれを使う。c++のABI実装は互換性を考慮してlibsupc++とした。
だがしかし
そういやOpenGL4のカードでしか起動しない問題を直さなきゃなー。
意気揚々と作業に取り掛かるもコンパイルが通らない。ぐぐると
「MinGWにゃまだlibc++対応してないよー」みたいな事が書かれててアレ。
意気揚々と作業に取り掛かるもコンパイルが通らない。ぐぐると
「MinGWにゃまだlibc++対応してないよー」みたいな事が書かれててアレ。
結局libstdc++に戻した。libc++移行の動機だったUnicode変換に関しては以前のルーチンを移植する事に。
中々思うように進まない。
中々思うように進まない。
(2013/08/20)
ふとした懸念
先日公開した2D物理サンプル。
OpenGLの利用に関して既存のGLEWや、GULT、はたまたQt5を使用しているのに用意された関数群を使わず
自前で関数のアドレスを取得しているんだけど
その時に「アドレスが取得できなかったらエラーを吐いて落ちる」ようにしてた事に今気づいた。
OpenGLの利用に関して既存のGLEWや、GULT、はたまたQt5を使用しているのに用意された関数群を使わず
自前で関数のアドレスを取得しているんだけど
その時に「アドレスが取得できなかったらエラーを吐いて落ちる」ようにしてた事に今気づいた。
具体的には
http://www.opengl.org/registry/
から"Core API and Extension Header Files"のリンクで最新のOpenGLヘッダを取ってきて
https://gist.github.com/degarashi/5203986
にあるような簡単なプログラムで関数宣言(プロトタイプ)を列挙したものを使ってwglGetProcAddressかglxGetProcAddressを呼んでいる。
http://www.opengl.org/registry/
から"Core API and Extension Header Files"のリンクで最新のOpenGLヘッダを取ってきて
https://gist.github.com/degarashi/5203986
にあるような簡単なプログラムで関数宣言(プロトタイプ)を列挙したものを使ってwglGetProcAddressかglxGetProcAddressを呼んでいる。
で、この関数の列挙の時に特にバージョンで制限を掛けなかったんで多分
OpenGL4.0か3.3あたりに対応してるボードじゃないとエラーで落ちるんじゃなかろうか?と。
っていうか自分の予測では例外を投げてmain関数のcatchで捕捉されるが
そこは単にどっかでコケた際にエラー文章のメッセージボックスを表示する目的でしか使ってないので「××のエラーが起きた」とだけ出てプログラムが終了する。
実際に使用したOpenGLの関数はバージョン2.0の範囲だからこれは直すべきなのだろう。そのうち。
OpenGL4.0か3.3あたりに対応してるボードじゃないとエラーで落ちるんじゃなかろうか?と。
っていうか自分の予測では例外を投げてmain関数のcatchで捕捉されるが
そこは単にどっかでコケた際にエラー文章のメッセージボックスを表示する目的でしか使ってないので「××のエラーが起きた」とだけ出てプログラムが終了する。
実際に使用したOpenGLの関数はバージョン2.0の範囲だからこれは直すべきなのだろう。そのうち。
(2013/08/17)
OpenGLのフォーマット
フォントクラスは実装の目処が立ったのでさあと思ったらテクスチャクラスの実装がスカスカだったので
それとかFramebuffer(D3Dで言うRenderTarget)の勉強をしていた。要するに足踏み状態。
それとかFramebuffer(D3Dで言うRenderTarget)の勉強をしていた。要するに足踏み状態。
いや、何に一番時間を取られたかといえばAndroidでデバイスロストみたいな状態になった際にテクスチャの再確保をするんだけど
ファイルからまた読めばいい物もあれば直前の内容をキッチリ復元したいものもある訳で。
もちろん問題は後者のほう。
OpenGLテクスチャのフォーマットは定数で管理されていてそれ単体じゃRの要素しか無いのか、形式は8bitなのかfloatなのかとかがわからない。
要素の数と形式が分からなければサーフェスの保存に必要な容量もわからない。
どうするか?
また、D3DではサーフェスのフォーマットがR8G8B8だった場合バッファをロックして読み込んだらBlue, Green, Redの順に各8bitで色情報が並んでいるし、floatならfloatだったんだが
OpenGLの場合は別途読み出すフォーマットを与える形になるので例えばRGB888のサーフェスをGL_FLOATで読むとしたらR,G,Bをそれぞれfloatに直して返してくる仕様であり
この読むフォーマットが不適切だと精度が落ちたり無駄に容量を食ってしまう結果となる。
ファイルからまた読めばいい物もあれば直前の内容をキッチリ復元したいものもある訳で。
もちろん問題は後者のほう。
OpenGLテクスチャのフォーマットは定数で管理されていてそれ単体じゃRの要素しか無いのか、形式は8bitなのかfloatなのかとかがわからない。
要素の数と形式が分からなければサーフェスの保存に必要な容量もわからない。
どうするか?
また、D3DではサーフェスのフォーマットがR8G8B8だった場合バッファをロックして読み込んだらBlue, Green, Redの順に各8bitで色情報が並んでいるし、floatならfloatだったんだが
OpenGLの場合は別途読み出すフォーマットを与える形になるので例えばRGB888のサーフェスをGL_FLOATで読むとしたらR,G,Bをそれぞれfloatに直して返してくる仕様であり
この読むフォーマットが不適切だと精度が落ちたり無駄に容量を食ってしまう結果となる。
要するに精度を落とさずに無駄に容量を食うこともなく保存したい。glGet()系の関数で色成分毎の使用ビット数を取得は出来るが
intなのかuintか、はたまたhalf-floatなのかがわからない。
まあこれはこれで、別のクエリで値タイプを判別したりも出来るものの・・
最終的にフォーマットを示す定数はどうやったら求まるの?と。フォーマット定数は単にユニークな値なのでビット演算でどうにかなる代物でもないし。
intなのかuintか、はたまたhalf-floatなのかがわからない。
まあこれはこれで、別のクエリで値タイプを判別したりも出来るものの・・
最終的にフォーマットを示す定数はどうやったら求まるの?と。フォーマット定数は単にユニークな値なのでビット演算でどうにかなる代物でもないし。
困った困った・・・みたいな感じで悩んでいた
結局
OpenGLのリファレンスページに目を通してOpenGL4までの全てのフォーマットをリストアップし、適切と思われる保存形式をポチポチと配列で打った。
工夫も何もあったもんじゃないけど、とりあえず解決
ついでにOpenGLのフォーマットラッパークラスを作って「テクスチャに使える型」「Renderbufferに使える型」
などそれぞれの用途に対応した種類だけ代入できるクラスを用意。
更に名前のフォーマット値を渡したら、それが何にセットできるのか判別する関数など。
工夫も何もあったもんじゃないけど、とりあえず解決
ついでにOpenGLのフォーマットラッパークラスを作って「テクスチャに使える型」「Renderbufferに使える型」
などそれぞれの用途に対応した種類だけ代入できるクラスを用意。
更に名前のフォーマット値を渡したら、それが何にセットできるのか判別する関数など。
今回の回り道
OpenGLのリソース使う時は必ずglBind〜()を読んでから各種オペレーションを行う決まりになっている。
このglBind。リソースをラッパークラスで管理してる場合はどう扱うべきだろうか。
シンプルに考えれば何かする度にとりあえずglBindを呼んでおけば無難である。
このglBind。リソースをラッパークラスで管理してる場合はどう扱うべきだろうか。
シンプルに考えれば何かする度にとりあえずglBindを呼んでおけば無難である。
// RenderbufferをColor0にアタッチ
void GLFramebuffer::attachColor0(GLuint rb) {
glBindFramebuffer(GL_FRAMEBUFFER, _idFb);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT_0, GL_RENDERBUFFER, rb);
}
// RenderbufferをDepthにアタッチ
void GLFramebuffer::attachDepth(GLuint rb) {
glBindFramebuffer(GL_FRAMEBUFFER, _idFb);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
}
// あくまで例。本当はRenderbufferを生のIDで扱ったりしない
そんな感じで。
でも、続けて色々設定するのであれば
どうせなら最初の一回だけ呼べればスマートじゃないですか。と考えてしまったのが運の尽き。
どうせなら最初の一回だけ呼べればスマートじゃないですか。と考えてしまったのが運の尽き。
詳細は後日。ソースをアップしてからまた書く
(2013/08/12)
本当は今頃からグラフィック関連技術のあれこれを始めてる予定だった訳だが。しかし。
回り道
フォントのキャッシュに関して散々悩んだ挙句、出した結論は
- キャッシュの整理(shrink)は一旦全消しして既にあるテキストオブジェクトに対して確保し直す
さんざん引っ張っておいてなんだこれは?と。
フォントデータは既に生成してあるんだからメモリコピーして使い回す?文字の使用回数によって配置を替える?とか
色々考えたんだけど実装の手間の割に効果は期待できなそうだし逆に遅くなる事も考えられるしで
シンプルなアルゴリズムに落ち着いた。
この辺の見切りがさっさと出来ればと、いつも思う。
色々考えたんだけど実装の手間の割に効果は期待できなそうだし逆に遅くなる事も考えられるしで
シンプルなアルゴリズムに落ち着いた。
この辺の見切りがさっさと出来ればと、いつも思う。
文字数が多くなってくると1つのキャッシュ用テクスチャじゃ収まりきらずに
1つの文字列で2回以上の描画コールが必要になる場合があるんだけど「なるべく1回にしたいなー」と考えてしまったのが運の尽きだった。
冷静になれば今時のPCスペックからしてそれが速度に響くとは考えにくい訳で、
もしどうしても1回にしたいならキャッシュ用テクスチャのサイズを大きく取れば良い話。
1つの文字列で2回以上の描画コールが必要になる場合があるんだけど「なるべく1回にしたいなー」と考えてしまったのが運の尽きだった。
冷静になれば今時のPCスペックからしてそれが速度に響くとは考えにくい訳で、
もしどうしても1回にしたいならキャッシュ用テクスチャのサイズを大きく取れば良い話。
これからは「運用でカバーできないか?」という事も留意しておきたい。
万能なアルゴリズムなど存在しない。
万能なアルゴリズムなど存在しない。
で、どうするの
まずはちゃっちゃとシンプル仕様でテキスト描画関連のクラスを実装する。
次にカメラ、タスクシステム、ゲームループ、3Dモデル読み込み、OpenGL用のエフェクトクラスを移植
3Dの形状(球とか円柱)クラスの移植。
次にカメラ、タスクシステム、ゲームループ、3Dモデル読み込み、OpenGL用のエフェクトクラスを移植
3Dの形状(球とか円柱)クラスの移植。
ここまで行ければ3D空間を描画するサンプルが動き、無事にデモの公開に漕ぎ着ける訳で。
その後はリアルタイムシャドウやらHDRやらを加えていければいいね
その後はリアルタイムシャドウやらHDRやらを加えていければいいね
(2013/08/08)
フォントの生成とキャッシュ
これ自体はWindowsの頃にやっていたものの
至る所でnewしまくっていたしunordered_mapを幾つも使って余計にメモリを食い、
フォントの最大幅でテクスチャにフォントをキャッシュしていて隙間空きまくりだし
一度キャッシュしたフォントの削除手段が無い=全消しオンリーだったり。
ついでに言えばフォントの名前は32bitハッシュで適当に管理していてダブった時の処置は無し(表示がおかしくなる)という有様。
1文字(キャラクタ)を表現する64bit数値を
「32bit: フォント名のハッシュ, 8bit: 横サイズ, 8bit: 縦サイズ, 1bit: アンチエイリアスのフラグ・・・」みたいに分けて
std::unordered_map<uint64_t, CharaInfo> なクラスに登録してキャッシュしていた。
至る所でnewしまくっていたしunordered_mapを幾つも使って余計にメモリを食い、
フォントの最大幅でテクスチャにフォントをキャッシュしていて隙間空きまくりだし
一度キャッシュしたフォントの削除手段が無い=全消しオンリーだったり。
ついでに言えばフォントの名前は32bitハッシュで適当に管理していてダブった時の処置は無し(表示がおかしくなる)という有様。
1文字(キャラクタ)を表現する64bit数値を
「32bit: フォント名のハッシュ, 8bit: 横サイズ, 8bit: 縦サイズ, 1bit: アンチエイリアスのフラグ・・・」みたいに分けて
std::unordered_map<uint64_t, CharaInfo> なクラスに登録してキャッシュしていた。
で、折角だからちゃんと設計する。
このパターンで時間食い過ぎていつも完成しないんじゃないか?いうのは重々承知の上・・
このパターンで時間食い過ぎていつも完成しないんじゃないか?いうのは重々承知の上・・
要は
- フォント名をちゃんと管理
- フォントデータ(Glyph)の取得はQtとWin32APIでインタフェースを共通化
という事。
フォント名をちゃんと管理といっても何のことはない、文字列と数値を対応付けるクラスを用意する。
配列にフォント名を突っ込んで線形探索とかでも良さそうだがフォントを削除した時の隙間をどうするか(インデックスは勝手にずらすと駄目だし)
という問題があるので今回は中身をuint32_tとしたリソースハンドルで代用する。
配列にフォント名を突っ込んで線形探索とかでも良さそうだがフォントを削除した時の隙間をどうするか(インデックスは勝手にずらすと駄目だし)
という問題があるので今回は中身をuint32_tとしたリソースハンドルで代用する。
フォント作成インタフェースの共通化は文字通りwindowsや、もしかしたらandroidでも使えるようにする為だけど
今はQtのインタフェースだけ作る方針。
今はQtのインタフェースだけ作る方針。
テクスチャにフォントを並べる間隔については平均幅以下の文字を並べるテクスチャをそれ以上のを並べるテクスチャに分けて
それぞれ・・ってやりたかったが時間かかりそうなので却下。後で余裕できたらにする。
それぞれ・・ってやりたかったが時間かかりそうなので却下。後で余裕できたらにする。
色々と説明が足りない感じだけど殆ど自分用メモみたいな物なんで・・
(2013/08/07)
ver0.0.2-2公開
といってもリリース番号違い。つまり機能は変わらず不具合の改善だけ。
具体的にはlibboost_systemをスタティックリンクにした。debianパッケージの依存をlibboost_system_1.48.0としていたのだが
実際使ってるのはlibboost_system_1.54.0なので当然動かない。
多分「最初の1があってれば1.48.0でもいいのかなー」と思ってそうしたんだろうけど
メジャーバージョンがどこまでかなんてライブラリによって違うので・・
ダウンロードした人も居なかったようなのでいいか。
具体的にはlibboost_systemをスタティックリンクにした。debianパッケージの依存をlibboost_system_1.48.0としていたのだが
実際使ってるのはlibboost_system_1.54.0なので当然動かない。
多分「最初の1があってれば1.48.0でもいいのかなー」と思ってそうしたんだろうけど
メジャーバージョンがどこまでかなんてライブラリによって違うので・・
ダウンロードした人も居なかったようなのでいいか。
Qtのフォント
Qtでフォントのビットマップを取得するにはQFontでフォント指定、それをQPainterにセットしQImageにdrawText()と、
GUIで普通に描画する形で可能なようだ。
あとはQImageからビット配列ポインタを取得して色々すれば良さそう。
GUIで普通に描画する形で可能なようだ。
あとはQImageからビット配列ポインタを取得して色々すれば良さそう。
ゲーム用ライブラリ
例のごとく自分用のライブラリを用意したいがゲーム用のモデル表示なんかの処理をspinnerやboomstickに含めるのはなんか違うな?という感じがしたので
現行のgleffectを近い将来ボツにしてエフェクトファイル記述を含めたゲーム用ライブラリresonantとしてリポジトリを作り直す事にした。
まあ・・また同じ名前なんだけど、他に思いつかなかったもんで。
現行のgleffectを近い将来ボツにしてエフェクトファイル記述を含めたゲーム用ライブラリresonantとしてリポジトリを作り直す事にした。
まあ・・また同じ名前なんだけど、他に思いつかなかったもんで。
(2013/08/06)
ver0.0.2-1公開
予定通り2D物理デモのver0.0.2-1をアップした。
主な変更点はマウスドラッグで物体を掴んで振り回せるようになった事。
個人的に「物体を自由に動かせないんじゃデモと呼びたくない!」っていうのもあり。
あとは摩擦係数の変更できる範囲をマイナス限定にした。プラスにすると確実に力が発散するので。
これからちょっとした動画を作ってニコ動とyoutubeにアップしたら物理デモについては一段落とする。
主な変更点はマウスドラッグで物体を掴んで振り回せるようになった事。
個人的に「物体を自由に動かせないんじゃデモと呼びたくない!」っていうのもあり。
あとは摩擦係数の変更できる範囲をマイナス限定にした。プラスにすると確実に力が発散するので。
これからちょっとした動画を作ってニコ動とyoutubeにアップしたら物理デモについては一段落とする。
予定
本格的に3Dプログラムを作るにあたってそれ用のクラスを移植するのと
文字列表示について調べなければならんね。
文字列表示について調べなければならんね。
(2013/08/05)
明日あたり物理2Dエンジンを少し改良したものと、それの動画をアップ予定。
3Dの準備
さあ来週からグラフィック出来ればいいな!と意気込むも
これまでずっと2Dでばかり動かしてきたから3D関連のクラスとかあまり整備してないという。
具体的にはカメラ、姿勢の補間、レイピック・・・あとバンプマップのbinormalやtangentベクトルの算出方法も忘れてしまったな。
といっても前のゲームエンジンから引っ張ってくるだけの作業だが。
これまでずっと2Dでばかり動かしてきたから3D関連のクラスとかあまり整備してないという。
具体的にはカメラ、姿勢の補間、レイピック・・・あとバンプマップのbinormalやtangentベクトルの算出方法も忘れてしまったな。
といっても前のゲームエンジンから引っ張ってくるだけの作業だが。
文字列表示はどうしようか。アルファベットだけならテクスチャ一枚用意すれば済む話だが日本語は・・
Win32APIを使ってのフォント取得とFlyweightパターンならやったけどLinuxはどうすれば。
折角QtフレームワークなんだからQPixmapに変換する関数か何かあれば良いのだが。っていうかそうでないと困る。
Win32APIを使ってのフォント取得とFlyweightパターンならやったけどLinuxはどうすれば。
折角QtフレームワークなんだからQPixmapに変換する関数か何かあれば良いのだが。っていうかそうでないと困る。
(2013/08/04)
ffmpegとか
折角だからlinux上で動画撮ろうと思って久々にffmpeg + X11grabを使ってみるもロスレス圧縮が上手く行かず。
妥協して高ビットレートのx264にしてみたらそれなりに良い品質に見えたが、よく見ると色あせた感じになってる。
色空間の所為だと思われたんで-pix_fmt yuv444pとしても改善せず。よくわからん。
重要な動画ではないから別にいいんだが・・
とりあえず色あせ動画を出力したら今度はキーフレーム(Iフレーム)の間隔が超長いらしく段々とゴミが残っている。上手く行かないものだ。
妥協して高ビットレートのx264にしてみたらそれなりに良い品質に見えたが、よく見ると色あせた感じになってる。
色空間の所為だと思われたんで-pix_fmt yuv444pとしても改善せず。よくわからん。
重要な動画ではないから別にいいんだが・・
とりあえず色あせ動画を出力したら今度はキーフレーム(Iフレーム)の間隔が超長いらしく段々とゴミが残っている。上手く行かないものだ。
ちなみにhuffyuvコーデックを使えば問題なくロスレスで録画出来る。
1280x720の範囲を60fpsで撮るとHDDが足を引っ張ってコマ落ちしまくりで断念したが。
1280x720の範囲を60fpsで撮るとHDDが足を引っ張ってコマ落ちしまくりで断念したが。
(2013/08/02)
windows用バイナリの公開
出来た。動かないとかあったらトップのコメント欄にでもお願いします。
(2013/08/02)
一応windowsでも動いた

だがしかし。vsyncの設定を特にしてなかったせいか動きが速すぎる。
つまりUbuntuではデフォルトがvsync有り、windowsでは無しという事か。
つまりUbuntuではデフォルトがvsync有り、windowsでは無しという事か。
懸念がいくつか。
1つはスレッド。
gccでstd::threadなどでマルチスレッドを使うと内部ではpthreadがリンクされるらしく、windows環境にネイティブでPOSIXスレッドAPIは無いので
従ってコンパイラ側で無効化されている。
別途pthreads-w32のようなライブラリを使えば良いらしいが・・今回はマルチスレッドではないので単に定義をコメントアウトして対処。
1つはスレッド。
gccでstd::threadなどでマルチスレッドを使うと内部ではpthreadがリンクされるらしく、windows環境にネイティブでPOSIXスレッドAPIは無いので
従ってコンパイラ側で無効化されている。
別途pthreads-w32のようなライブラリを使えば良いらしいが・・今回はマルチスレッドではないので単に定義をコメントアウトして対処。
次に動作検証に困りそうな気がした。wineではエラーが出て落ちてしまうしVMWareで動かせるのか非常に怪しい。
動作テストのたびに再起動なんてやってらんないのだが。
windowsでコンパイルするのも、めんどいなー
動作テストのたびに再起動なんてやってらんないのだが。
windowsでコンパイルするのも、めんどいなー
それと、まだあまり速度を追求してコードを書いてないというのもあるが、にしても思ったより速度が出ないのが正直な感想。
phenomII X4 955のシングルスレッドだけど「もうちょっと行けるべ?」と思ってしまう。
まだgccのlink time optimizationを有効にしていないが良くて3割増しとかだろう。
当たり判定は適当に総当りだけど一応境界球判定してるし、GJKアルゴリズムはヒットしなければしないですぐ終わるからなぁ・・測ってみないとなんとも。
phenomII X4 955のシングルスレッドだけど「もうちょっと行けるべ?」と思ってしまう。
まだgccのlink time optimizationを有効にしていないが良くて3割増しとかだろう。
当たり判定は適当に総当りだけど一応境界球判定してるし、GJKアルゴリズムはヒットしなければしないですぐ終わるからなぁ・・測ってみないとなんとも。
(2013/08/02)
内容の詰まった記事を月に1〜2回書くべきか、それとも週3回ペースで文字通り進行状況を記したほうが良いのか。どっちだろう?
rigid2d-test for linux
試してくれる人が居るかはともかく勉強を兼ねてlinux用パッケージを公開した。
http://ux.getuploader.com/RSE/
例によってQt5のランタイムが必要で、もし公式から5.1.0のライブラリを導入していれば別途libdgqt5をインストールしなくても行ける筈。
無ければ必要なファイルだけ纏めたlibdgqt5をどうぞ。公式のからコピーしただけ。
ちなみに当然っちゃあ当然だが既に5.1.0が入ってるのにlibdgqt5を入れようとしてもエラーで進まないかと。
http://ux.getuploader.com/RSE/
例によってQt5のランタイムが必要で、もし公式から5.1.0のライブラリを導入していれば別途libdgqt5をインストールしなくても行ける筈。
無ければ必要なファイルだけ纏めたlibdgqt5をどうぞ。公式のからコピーしただけ。
ちなみに当然っちゃあ当然だが既に5.1.0が入ってるのにlibdgqt5を入れようとしてもエラーで進まないかと。
リリース時のソースはローカルのコミットをrebase --ontoで整理してからpushする予定
次はMinGW(Windows用)なのだが、どうかな。コンパイルまでは出来てるけどすんなり行くのかどうか・・
次はMinGW(Windows用)なのだが、どうかな。コンパイルまでは出来てるけどすんなり行くのかどうか・・
(2013/08/01)
今度はOpenGL関連で詰まる
OpenGLのAPIはDirectXと違ってドライバから直接関数を取得しなきゃならんのだけど
ちょっと前に自前でglx.hやglext.hを使って読み込む機構を作って、ずっとそれを使っていたのだった。
ちょっと前に自前でglx.hやglext.hを使って読み込む機構を作って、ずっとそれを使っていたのだった。
で、見ての通りglx.hというのはX11用のヘッダなのでwindowsで動かすためにはそれ用のヘッダで初期化せねばならん。
そもそもQtにはQOpenGLFunctionsというクロスプラットフォームなOpenGL APIラッパークラスが用意されてるので
少なくともOpenGL ES2 の範囲の機能を使う限り自前で初期化する必要なんて無い。
って事でQOpenGLFunctionsを使う形で書き直せばOK・・・ の筈だったのだが(最近このパターン)
そもそもQtにはQOpenGLFunctionsというクロスプラットフォームなOpenGL APIラッパークラスが用意されてるので
少なくともOpenGL ES2 の範囲の機能を使う限り自前で初期化する必要なんて無い。
って事でQOpenGLFunctionsを使う形で書き直せばOK・・・ の筈だったのだが(最近このパターン)
APIのラッパーと言いつつ関数群がstaticでない。staticでないという事は普通の関数ポインタでは指せない。
これは非常に困る。
というのも自作のエフェクトファイル解析で関数ポインタにて分岐してる箇所が幾つかあってこれらを置き換えようにも
全てのOpenGL API関数がラップされてるわけでもないので、無理。
具体的にはOpenGL ver1の頃からあるような基本的な関数は従来通りグローバルに置いてあり、ver2以降のがラップされてる。
いや、ver1とver2の関数全部ラップされてるよというなら分かるんだが、ver1はラップされてないしver2は
ヘッダを読むに”混乱を避けるため”意図的にundefしてあってグローバルから使えない。
これは非常に困る。
というのも自作のエフェクトファイル解析で関数ポインタにて分岐してる箇所が幾つかあってこれらを置き換えようにも
全てのOpenGL API関数がラップされてるわけでもないので、無理。
具体的にはOpenGL ver1の頃からあるような基本的な関数は従来通りグローバルに置いてあり、ver2以降のがラップされてる。
いや、ver1とver2の関数全部ラップされてるよというなら分かるんだが、ver1はラップされてないしver2は
ヘッダを読むに”混乱を避けるため”意図的にundefしてあってグローバルから使えない。
つまり同じOpenGL API関数でも単なる関数ポインタと、メンバ関数ポインタに分かれてしまって管理が面倒すぎる。
何故こういう設計にしたのかは知らないが今更構文解析の所をいじって無駄に複雑にしたくはないので
OpenGLの関数を取得する部分だけOS依存コードという事で分離してしまって、他はそのままという方向で書いている・・
何故こういう設計にしたのかは知らないが今更構文解析の所をいじって無駄に複雑にしたくはないので
OpenGLの関数を取得する部分だけOS依存コードという事で分離してしまって、他はそのままという方向で書いている・・
(2013/08/01)
例のごとく
おお、8月に入ってしまった。
gcc4.8.1でのコンパイルと動作確認は済んで現在MinGWを使ってWindows用にコンパイルを試みている。
MinGWのバージョンが古いからソースとってきて同じ4.8.1で合わせたり、MinGW用にboostをコンパイルしなおしたり等・・この辺は前に何回かやってるから良いとして
またしても問題発生。
gcc4.8.1でのコンパイルと動作確認は済んで現在MinGWを使ってWindows用にコンパイルを試みている。
MinGWのバージョンが古いからソースとってきて同じ4.8.1で合わせたり、MinGW用にboostをコンパイルしなおしたり等・・この辺は前に何回かやってるから良いとして
またしても問題発生。
SSEを使う都合上16byteアラインメントされたメモリが必要になる時があるんだけどその関数posix_memalign()が実質linux用である、と。
んだね。名前からしてそうだもんね。
という事で代替を探したらMinGWには__mingw_aligned_malloc()という関数があるらしい。解決。
んだね。名前からしてそうだもんね。
という事で代替を探したらMinGWには__mingw_aligned_malloc()という関数があるらしい。解決。
・・・とは行かず解放にも専用の関数__mingw_aligned_free()を呼べと言いはる。posix_memalignのは普通にfreeでやってオッケーだったのだが。
なら自分で書いたほうがlinux用と共用できていいわー
さっさとデモを公開したいのにソースの各所をいじくるのは面倒くさいがやらねば。まだ開発初期で使用箇所は大体決まってるのが救いか。
さっさとデモを公開したいのにソースの各所をいじくるのは面倒くさいがやらねば。まだ開発初期で使用箇所は大体決まってるのが救いか。