FPSを作ってみる@wiki
10)
最終更新:
slice
-
view
(2013/10/31)
元々ちょっと作るつもりで新規プロジェクトに書いたクラスを何回か本筋ライブラリへ吸収合併させている関係上、
同じ自作ライブラリの中でも無駄に複数のnamespaceが存在してたのでこれらを1つに纏めた。
昨日の作業でAndroidとPC用のビルドもフラグ1つで切り替え可能になった。
同じ自作ライブラリの中でも無駄に複数のnamespaceが存在してたのでこれらを1つに纏めた。
昨日の作業でAndroidとPC用のビルドもフラグ1つで切り替え可能になった。
とはいえまだAndroidアプリは作れない。
OpenGL関連クラスを収録したライブラリ(github上のgleffectリポジトリ)がまたしても別ライブラリとしてあるので
これを本筋のライブラリに統合(resonantリポジトリ)しなければ。
更に次はタスクシステムのリポジトリ(taskリポジトリ)を統合。
そこまで行ければサウンド、入力、タスクシステム、グラフィックとひと通り使える状態になる。
OpenGL関連クラスを収録したライブラリ(github上のgleffectリポジトリ)がまたしても別ライブラリとしてあるので
これを本筋のライブラリに統合(resonantリポジトリ)しなければ。
更に次はタスクシステムのリポジトリ(taskリポジトリ)を統合。
そこまで行ければサウンド、入力、タスクシステム、グラフィックとひと通り使える状態になる。
けど、フォントテクスチャの作成はQtライブラリ依存のルーチンしか用意してないからSDL_ttfを使ったバージョンを書く必要がありそう。
(2013/10/30)
ここんとこAndroidの為の作業ばっかし。
もしAndroid対応を捨てていたら今頃デモを公開できていただろうか・・ふと考えたりする
もしAndroid対応を捨てていたら今頃デモを公開できていただろうか・・ふと考えたりする
CMake
EclipseでやってたAndroidアプリで使う外部ライブラリのビルド(libogg, libvorbis, libvorbisfile, libSDL2)は、
どちらかと言えば現在メインで使ってるKdevelop、CMakeでビルド出来たほうが自前のライブラリと一緒にビルド出来て何かと便利なので
環境設定とかを調べて構築してた。CPUのアーキテクチャ毎にインストール先を変えるのも含め。
Eclipseは操作や処理がもたつく所もあってか、あまりそれでC++を書く気にはなれない。Javaに関しては優秀なんだけど。
どちらかと言えば現在メインで使ってるKdevelop、CMakeでビルド出来たほうが自前のライブラリと一緒にビルド出来て何かと便利なので
環境設定とかを調べて構築してた。CPUのアーキテクチャ毎にインストール先を変えるのも含め。
Eclipseは操作や処理がもたつく所もあってか、あまりそれでC++を書く気にはなれない。Javaに関しては優秀なんだけど。
「構築した」と一言で言っておいてアレだがクロスコンパイルなんて今までググってマニュアル通りにしかやったことなくてガッツリ苦戦した。
具体的にはsysrootがどうとか、CMakeの文法がどうのという辺りなんだけど
ココへ書いても面白くないので割愛してしまおう。
こういうのは日記じゃなくてちゃんと整理してから独立したページでやりたい物だが何時になるやら。
具体的にはsysrootがどうとか、CMakeの文法がどうのという辺りなんだけど
ココへ書いても面白くないので割愛してしまおう。
こういうのは日記じゃなくてちゃんと整理してから独立したページでやりたい物だが何時になるやら。
拡張apk
他には「拡張apkって実際使う時にどうするの?」とか、アップロード方法なんかをなんとなく調べたり。
拡張apkと言いつつ実体は只のバイナリデータだとは。
本体apkはダウンロードしてあるけど拡張apkが無い時の処理はこちらがやらなきゃいけないなど色々面倒そうだ。
ま、当分50Mbyteを超える予定ないから良いけどねぇ・・
拡張apkと言いつつ実体は只のバイナリデータだとは。
本体apkはダウンロードしてあるけど拡張apkが無い時の処理はこちらがやらなきゃいけないなど色々面倒そうだ。
ま、当分50Mbyteを超える予定ないから良いけどねぇ・・
Androidブランチ
gitでのプロジェクト管理について。
これまでmasterでPC向けに作って、そこからローカルのandroidブランチに専用の設定
(コンパイル設定やandroidにはないクラスの代替ヘッダを書いたり)を書いていたのだけど
これだと何かバグが見つかった時にまずmasterブランチの方で修正して
それからandroidブランチをrebaseしてと面倒な手順を踏まねばならない。
androidブランチでそのまま修正して後でmasterにmergeでもいいんだけどそれだと履歴が無駄に複雑になってしまうからやめた。
一度や二度だったらいいけどこれが毎回は辛い。
これまでmasterでPC向けに作って、そこからローカルのandroidブランチに専用の設定
(コンパイル設定やandroidにはないクラスの代替ヘッダを書いたり)を書いていたのだけど
これだと何かバグが見つかった時にまずmasterブランチの方で修正して
それからandroidブランチをrebaseしてと面倒な手順を踏まねばならない。
androidブランチでそのまま修正して後でmasterにmergeでもいいんだけどそれだと履歴が無駄に複雑になってしまうからやめた。
一度や二度だったらいいけどこれが毎回は辛い。
androidブランチへの差分は今の所そんなに大きくないからいっそ見た目が悪くなってもプリプロセッサで分岐させて統合した方が遥かにシンプルに
そして効率的になるのではないか。
と、考えたので統合中・・
そして効率的になるのではないか。
と、考えたので統合中・・
(2013/10/26)
zip, zap, zip...
さあファイル操作関連が出来たのでzlibでzipファイルを展開しようか・・
zlibはあくまでzipファイルで使われるメジャーな圧縮形式の一つ、deflateアルゴリズムを提供するだけであって
zipファイルはそれとは別にフォーマットがある。
幸いzlibにはunzip.cというサンプルソースが含まれていて、これを利用すれば特に自分で作らずとも目的は達成できる。
zlibはあくまでzipファイルで使われるメジャーな圧縮形式の一つ、deflateアルゴリズムを提供するだけであって
zipファイルはそれとは別にフォーマットがある。
幸いzlibにはunzip.cというサンプルソースが含まれていて、これを利用すれば特に自分で作らずとも目的は達成できる。
だが、こいつは文字列でファイルを指定して開く事しか出来ない。
即ちファイルシステム上に置いてあるzipファイルを展開する用途にしか使えず
既にfopenで開いたファイルは直接ファイルポインタを指定出来なくて不便だし
メモリ上に置いたファイル、Assetsに含まれるファイル(これもメモリの範囲で返される)をどうこうしようと思ったら
一旦zipファイル全体を何処かへコピーして読み込むという手順が必要で
これがまあ1Mbyteとかだったら良いけど30, 40MByteだとアレだよね。
PCはまだしもAndroidでそのくらいのファイルをコピーすると少々時間食ってしまうし、
アーカイブの中のファイルを1つ抽出したいなんて時など考えたくもない。
zipじゃないファイルは直にアクセスできるのにzipは全部展開するしかないなんて。無いでしょう。それは。
即ちファイルシステム上に置いてあるzipファイルを展開する用途にしか使えず
既にfopenで開いたファイルは直接ファイルポインタを指定出来なくて不便だし
メモリ上に置いたファイル、Assetsに含まれるファイル(これもメモリの範囲で返される)をどうこうしようと思ったら
一旦zipファイル全体を何処かへコピーして読み込むという手順が必要で
これがまあ1Mbyteとかだったら良いけど30, 40MByteだとアレだよね。
PCはまだしもAndroidでそのくらいのファイルをコピーすると少々時間食ってしまうし、
アーカイブの中のファイルを1つ抽出したいなんて時など考えたくもない。
zipじゃないファイルは直にアクセスできるのにzipは全部展開するしかないなんて。無いでしょう。それは。
と、ウズウズしてきた所で自前で展開するクラスを作ってしまった。
zipフォーマットは古くからあってか非常にシンプルなので丁寧なエラー処理さえ考えなければなんとかなる物だ。
zipフォーマットは古くからあってか非常にシンプルなので丁寧なエラー処理さえ考えなければなんとかなる物だ。
JNIなので・・
ちなみにjavaで展開という手もあるにはある。が、ファイルを個別に展開したい時にやり取りが面倒そうなのでやめた。
処理の流れ
ぐだぐだと書いたけど
- ゲームで使うリソースは全てzipに纏めた上でAssetsに1個だけ置く
- ステージ1のロードとなったらzip内のフォルダ"stage1"に入ってるリソースをメモリ上に展開して使う
- ステージが切り替わったらステージ固有のリソースを破棄して次の固有リソースをメモリ上に読み込む
という流れを想定。
一時ファイルをごちゃごちゃと置きたくないのだ。
一時ファイルをごちゃごちゃと置きたくないのだ。
(2013/10/23)
いい加減動くものを出さないと不味い気がしてきた。体裁的にも、モチベーション的にも。
ファイル操作ひと通り
ワイルドカードカードと正規表現によるファイル列挙、それとファイルの変更検知。
これらを環境依存な部分を分離して実装。
MinGWに互換用ヘッダがあると言っても実際どの位動くのかよくわからんかったのでサウンドの時と同じ様に分離した。
Windows用にはWinAPIで実装する予定。でも面倒くさいから後でやる。
ファイルの変更検知は無論、スクリプトやシェーダーのリアルタイム編集を睨んでの事。
LinuxのinotifyというAPIはAndroidにも存在している様なので
もしかしたらAndroid端末だけでテストと修正が出来るかもしれないね、と夢だけ膨らませておく。
これらを環境依存な部分を分離して実装。
MinGWに互換用ヘッダがあると言っても実際どの位動くのかよくわからんかったのでサウンドの時と同じ様に分離した。
Windows用にはWinAPIで実装する予定。でも面倒くさいから後でやる。
ファイルの変更検知は無論、スクリプトやシェーダーのリアルタイム編集を睨んでの事。
LinuxのinotifyというAPIはAndroidにも存在している様なので
もしかしたらAndroid端末だけでテストと修正が出来るかもしれないね、と夢だけ膨らませておく。
(2013/10/21)
Androidのファイル関係
mkdirで目的のディレクトリ階層を一気に作る関数なんぞ追加。
system("mkdir -p なんちゃら") ってやる手も多分あるだろうけど、もろ環境依存な機能はなるべく使わない方針で行った。
あとワイルドカード又は正規表現を使ったファイルの列挙とか。
とりあえずこれだけあればassetにあるzipをSDCardかアプリ専用ディレクトリに展開するくらいは出来そう。
2回目以降、既に展開してあったら省略するとかね。
system("mkdir -p なんちゃら") ってやる手も多分あるだろうけど、もろ環境依存な機能はなるべく使わない方針で行った。
あとワイルドカード又は正規表現を使ったファイルの列挙とか。
とりあえずこれだけあればassetにあるzipをSDCardかアプリ専用ディレクトリに展開するくらいは出来そう。
2回目以降、既に展開してあったら省略するとかね。
という訳でzip展開と読み込みのテストプログラムを書く。
#追記
ふと、MinGWでコンパイルしてみたら通らなかった。
同じsys/stat.hでもMinGWのはパーミッション関連がごっそり抜けてるらしく、フラグとかが定義されてなかった。
どうするかね。暫くはwindowsで動かなくてもいいんだけど・・
同じsys/stat.hでもMinGWのはパーミッション関連がごっそり抜けてるらしく、フラグとかが定義されてなかった。
どうするかね。暫くはwindowsで動かなくてもいいんだけど・・
そういえばboost::filesystemなんてのもあったなーと思ったけどあれってUnicode対応してたっけ?
(2013/10/20)
結局
先日のPathクラス。
その、えっとまぁ。一から作りなおしました。
何分1,2年前のソースだし、なんか元からバグあるし。無理して固定長リングバッファとか使ってるし。std::dequeでいいんじゃないかねって思ったんで。つい。
バグ修正して動作確認するんだったら大した行数でもなし、C++11の機能等使って書きなおした方がって感じで。
その、えっとまぁ。一から作りなおしました。
何分1,2年前のソースだし、なんか元からバグあるし。無理して固定長リングバッファとか使ってるし。std::dequeでいいんじゃないかねって思ったんで。つい。
バグ修正して動作確認するんだったら大した行数でもなし、C++11の機能等使って書きなおした方がって感じで。
(2013/10/19)
ディレクトリ
引き続きファイル操作関係。
CやC++の標準関数ってファイルの読み書きと消去はできるけどディレクトリの列挙って今までWinAPI使ってたよなぁと思って調べたら
やっぱりディレクトリ走査とかディレクトリだけの作成は環境依存らしい。
SDLのファイル操作関数もCの標準関数と同じ範囲の操作しかサポートしてない様だ。
CやC++の標準関数ってファイルの読み書きと消去はできるけどディレクトリの列挙って今までWinAPI使ってたよなぁと思って調べたら
やっぱりディレクトリ走査とかディレクトリだけの作成は環境依存らしい。
SDLのファイル操作関数もCの標準関数と同じ範囲の操作しかサポートしてない様だ。
Androidとlinuxは割と環境が似通ってるからsystem("mkdir -p ABC/CDE/EFG")と、システム関数を使うか
<sys/stat.h>にあるmkdir()関数なりを使えば良いけどwindowsは・・
しかしまた互換クラスを作るのも面倒くさいなあと思っていた所、MinGWにもsys/stat.hがあるじゃないですか。
これは内部でWinAPIを呼ぶ互換ヘッダらしい。
今のとこVisualC++でコンパイルは考えてないのでこれ(sys/stat.h)でいいかなと。
<sys/stat.h>にあるmkdir()関数なりを使えば良いけどwindowsは・・
しかしまた互換クラスを作るのも面倒くさいなあと思っていた所、MinGWにもsys/stat.hがあるじゃないですか。
これは内部でWinAPIを呼ぶ互換ヘッダらしい。
今のとこVisualC++でコンパイルは考えてないのでこれ(sys/stat.h)でいいかなと。
ただ、パスを操作するクラスは要るかね。古いソースから持ってこないと。
#追記
「持ってこないと」とは言ったものの、実際にソースを見てみると中途半端にワイド文字対応(イコールUTF16という訳ではない)
とかwindows専用な関数が使ってあって
非常にビミョーな雰囲気が漂っていたんでここはひとつ内部はUTF32で処理し入出力はUTF8と修正を加えたら
半分以上書き直しという形に。
まぁ、一からよりいいんだけど。動作チェックしないといかんね。
とかwindows専用な関数が使ってあって
非常にビミョーな雰囲気が漂っていたんでここはひとつ内部はUTF32で処理し入出力はUTF8と修正を加えたら
半分以上書き直しという形に。
まぁ、一からよりいいんだけど。動作チェックしないといかんね。
(2013/10/18)
Eclipseが重くなる
SDLをAndroidで使う時ってマニュアル通りにやれば
予め用意されているSDL-Androidなプロジェクトをeclipseへインポートして、そこから自分のコードを追加していく感じになろうかと思うけど
これをした途端にC/C++のインデクサ(関数とかの定義を収集して入力時に補完してくれるようなの)が何かファイルを変更する度に走って
eclipseが重くなりすぎ、メモリ食いすぎて使い物にならない現象にやきもきしている。
当方のスペックはPhenomII X955と、まぁ今となっちゃ可もなく不可もなくなCPUだけど最悪3分程かかる。
試しにインデクサを無効に=GUIの利点を台無しにしても
やっぱりビルドする度にプロジェクトのスキャンとやらが入って幾らか時間をとられる。30〜40秒位?
予め用意されているSDL-Androidなプロジェクトをeclipseへインポートして、そこから自分のコードを追加していく感じになろうかと思うけど
これをした途端にC/C++のインデクサ(関数とかの定義を収集して入力時に補完してくれるようなの)が何かファイルを変更する度に走って
eclipseが重くなりすぎ、メモリ食いすぎて使い物にならない現象にやきもきしている。
当方のスペックはPhenomII X955と、まぁ今となっちゃ可もなく不可もなくなCPUだけど最悪3分程かかる。
試しにインデクサを無効に=GUIの利点を台無しにしても
やっぱりビルドする度にプロジェクトのスキャンとやらが入って幾らか時間をとられる。30〜40秒位?
やってられない。
たかが1回テストするのに3分かかる。
ちなみにCUIから同様の処理を行うと15秒で済む。
でもCUIはCUIでコンパイルエラーが出た時にメッセージが大量に表示されて読み取りにくいという。
たかが1回テストするのに3分かかる。
ちなみにCUIから同様の処理を行うと15秒で済む。
でもCUIはCUIでコンパイルエラーが出た時にメッセージが大量に表示されて読み取りにくいという。
そもそも自分のプロジェクトにSDLのソース一式を組み込むと重くなるようなので分離すれば良いのではないかと。
SDLはSDLだけでsoファイルとしてコンパイルしておいて、自分のプロジェクトは別に作って参照すればどうだろう?と思って今試している。
ついでにliboggとかも分離したい。
SDLはSDLだけでsoファイルとしてコンパイルしておいて、自分のプロジェクトは別に作って参照すればどうだろう?と思って今試している。
ついでにliboggとかも分離したい。
#追記
libSDL2, libogg, libvorbis, libvorbisfileをメインプログラムから分離できた。インデクサを再度有効にしてもeclipseも重くない。
けど補完もあまりしてくれない。元々だけど。
次はzipファイル展開のためのzlibを入れたいところ。
#追記2
けど補完もあまりしてくれない。元々だけど。
次はzipファイル展開のためのzlibを入れたいところ。
というかzlibってAndroidにデフォルトで組み込まれてるから要らないじゃないか。
複数ファイルを展開、コピーする関数だけ書くか・・
複数ファイルを展開、コピーする関数だけ書くか・・
Androidにおけるファイル
Androidで自分のプログラムに画像やらサウンドなんかのリソースを付属させる場合、幾つか手段があって
1 実行時にサーバーからダウンロードする
2 Assetフォルダに入れる
3 resフォルダに入れる
4 拡張APKに含める
1 実行時にサーバーからダウンロードする
2 Assetフォルダに入れる
3 resフォルダに入れる
4 拡張APKに含める
1は個人じゃ難しいとして考えないことにして
2は特に形式などは定まってなく自分で自由に読みだして使えるシンプルなファイル置き場
3は・・・なんだっけな、サウンドとか画像とか置くのは2と変わらないけど種類ごとに置き場所が決まってて
ファイル名だけで管理されるから拡張子違いのファイルは駄目、あと端末の解像度によって自動で画像ファイルを読み分けてくれたりもした気がするが、忘れた。
4はプログラムを含んだAPKファイルを50MByte以上に出来ない制限があって、これを回避するためのものらしいので当分縁がないだろうからこれも考えない。
2は特に形式などは定まってなく自分で自由に読みだして使えるシンプルなファイル置き場
3は・・・なんだっけな、サウンドとか画像とか置くのは2と変わらないけど種類ごとに置き場所が決まってて
ファイル名だけで管理されるから拡張子違いのファイルは駄目、あと端末の解像度によって自動で画像ファイルを読み分けてくれたりもした気がするが、忘れた。
4はプログラムを含んだAPKファイルを50MByte以上に出来ない制限があって、これを回避するためのものらしいので当分縁がないだろうからこれも考えない。
要するに2だけ考えますという事で。
ただこれも1Mbyte以上の非圧縮ファイルは格納できないという制限があるので、
例えばzipで格納しておいて実行時に展開するような仕組みが要る(今取り組んでる)
ただこれも1Mbyte以上の非圧縮ファイルは格納できないという制限があるので、
例えばzipで格納しておいて実行時に展開するような仕組みが要る(今取り組んでる)
(2013/10/17)
what's next?
そもそも自分はゲームが作りたいのである。
サウンドを鳴らせた。OpenGLとシェーダー定義ファイルも用意し、ポリゴンやフォントを描画出来た。
キーボードやマウス、ジョイパッドの入力を処理して扱いやすくラップした。
レベルエディタ用にQt5も少しだけど練習した。
タスクシステムっぽいのも作った。SDLを使ってマルチプラットフォーム対応(Linux, Windows, Android)もやった。
プログラムが特定のCPUに依存しないよう修正もした。
Androidに限って言えばGUIの操作やJava言語、NDKの扱い方等。
キーボードやマウス、ジョイパッドの入力を処理して扱いやすくラップした。
レベルエディタ用にQt5も少しだけど練習した。
タスクシステムっぽいのも作った。SDLを使ってマルチプラットフォーム対応(Linux, Windows, Android)もやった。
プログラムが特定のCPUに依存しないよう修正もした。
Androidに限って言えばGUIの操作やJava言語、NDKの扱い方等。
後は何だ?ゲーム素材?いや、その前に・・
これらを組み合わせなければ。音だけ、画像だけ、動かすだけじゃゲームと呼べない。
(ところで何時頃からAndroidで動かそうと思ったのかわからないが・・2月のアレが原因?)
(ところで何時頃からAndroidで動かそうと思ったのかわからないが・・2月のアレが原因?)
なんにせよ、やる事ありすぎで困る。
(2013/10/16)
引き続きサウンド
フェードインとフェードアウトの実装がまだだったのでこれをやる。
時間指定をstd::chronoのDurationで行うことにしたらいちいち「これミリ秒だっけ?マイクロ秒だっけ」と悩む必要がなくなって便利だ。
使う側も好きな単位で指定できる。
フェードアウトに関しては曲の終わりをフェードアウトさせるのか、それともすぐにフェードアウトを始めるのかを選べるようにした。
時間指定をstd::chronoのDurationで行うことにしたらいちいち「これミリ秒だっけ?マイクロ秒だっけ」と悩む必要がなくなって便利だ。
使う側も好きな単位で指定できる。
フェードアウトに関しては曲の終わりをフェードアウトさせるのか、それともすぐにフェードアウトを始めるのかを選べるようにした。
あとはシークがあればサウンドに関してはもういいかな?という感じ
任意区間のループもあったら面白そうだけど必要になった時でいいや。
任意区間のループもあったら面白そうだけど必要になった時でいいや。
#追記1
シークの実装完了(OpenAL)。OpenSLでの動作を確認したらやっと一段落となる。
思えばサウンド関連を触り始めたのは約一ヶ月前で、その間OpenGLを放置していて忘れそうになっている。これは不味い。
プログラミングやればモデリング放置になり、OpenGLをやればQtを放置、今回のようにOpenAL|SLをやればOpenGLを放置。
そしてLuaには1年くらい触れてない。DirectX9やDirectSoundはまぁ忘れていいとしても。
さらに言えばboost::spirit、web関連のあれこれ(javascript, ajax, jQuery, SQL)とかもあれっきりなんで心配。
思えばサウンド関連を触り始めたのは約一ヶ月前で、その間OpenGLを放置していて忘れそうになっている。これは不味い。
プログラミングやればモデリング放置になり、OpenGLをやればQtを放置、今回のようにOpenAL|SLをやればOpenGLを放置。
そしてLuaには1年くらい触れてない。DirectX9やDirectSoundはまぁ忘れていいとしても。
さらに言えばboost::spirit、web関連のあれこれ(javascript, ajax, jQuery, SQL)とかもあれっきりなんで心配。
自分の性格上1つの事を始めたらそればかりなので必然的にそうなるのだが・・でも、どうにかならんかねコレ。
(2013/10/15)
SDL_AudioCVT
さあOpenSLでサウンド出力の確認だ。と思ってチェックしていたら謎の現象に悩まされる。
Waveの再生 => 問題なし
OggをWaveに変換して再生 => これも問題ない
Oggをストリーミングで再生 => (曲によって)砂嵐 ??
同じ再生ルーチンでOpenALを使った場合にはきちんと動作するのでOpenSL依存ルーチンに問題があるという事になる。
サウンドキューの追加方法が何か不味いのか?他の要因か・・
Waveの再生 => 問題なし
OggをWaveに変換して再生 => これも問題ない
Oggをストリーミングで再生 => (曲によって)砂嵐 ??
同じ再生ルーチンでOpenALを使った場合にはきちんと動作するのでOpenSL依存ルーチンに問題があるという事になる。
サウンドキューの追加方法が何か不味いのか?他の要因か・・
色々調べた結果。原因はSDLの周波数変換関数の挙動が不審、という事だった。
具体的には1秒未満のステレオ37800Hzのサンプルをステレオ44100Hzに変換しようとするとホワイトノイズが出力される。
この時エラーその他バッファ破壊等は無いのでこちらとしてはサンプル解析でもしない限り正常に変換できてるかが判断できない。
しかし周波数が37600Hzや37900Hzだったり、一度に変換する量が10秒分とか長ければ問題なく動作する。よくわからん。
具体的には1秒未満のステレオ37800Hzのサンプルをステレオ44100Hzに変換しようとするとホワイトノイズが出力される。
この時エラーその他バッファ破壊等は無いのでこちらとしてはサンプル解析でもしない限り正常に変換できてるかが判断できない。
しかし周波数が37600Hzや37900Hzだったり、一度に変換する量が10秒分とか長ければ問題なく動作する。よくわからん。
最新版のSDLにしてみても同じ挙動を示したので
結局音楽の周波数が37600Hz 以上 37900Hz 未満の時は37600Hzと設定する事で応急処置。
結局音楽の周波数が37600Hz 以上 37900Hz 未満の時は37600Hzと設定する事で応急処置。
(2013/10/13)
ストリーミングの終了判定
OpenSLのテストについては基本的な再生については概ねOKだけど
曲の終了判定はプレイヤーのステートがSTOPPEDになったかどうかで判断している箇所が問題。
曲の終了判定はプレイヤーのステートがSTOPPEDになったかどうかで判断している箇所が問題。
具体的には再生の終了時(またはストリーミングのバッファが途切れた時)に
OpenALでは(API内のプレイヤーが)勝手にSTOPPEDステートになるがOpenSLではPLAYINGのまま、という点が違う。
しかしよく考えるとOpenALでCPUの処理が遅れるなどしてストリーミングのバッファが切れたら音楽止まってそれっきりという事だね・・
むしろOpenAL側にSTOPPEDになっても再生するバッファに残りがある時はまたPLAYINGにセットする仕組みが必要っぽい。
OpenALでは(API内のプレイヤーが)勝手にSTOPPEDステートになるがOpenSLではPLAYINGのまま、という点が違う。
しかしよく考えるとOpenALでCPUの処理が遅れるなどしてストリーミングのバッファが切れたら音楽止まってそれっきりという事だね・・
むしろOpenAL側にSTOPPEDになっても再生するバッファに残りがある時はまたPLAYINGにセットする仕組みが必要っぽい。
プログラミングの勉強
プログラムは日頃組んでいるわけだけど、それは「仕様を考えてその通りに動く」プログラムで
純粋に「問題が与えられてその答えを出す」コンテストなんかでやるタイプのプログラミングは全然な事に気づき、練習。
今日は、前にやった覚えはあるが忘れていた動的計画法をカバーした。
そのうちTopCoderとか参加してみたいね。
純粋に「問題が与えられてその答えを出す」コンテストなんかでやるタイプのプログラミングは全然な事に気づき、練習。
今日は、前にやった覚えはあるが忘れていた動的計画法をカバーした。
そのうちTopCoderとか参加してみたいね。
(2013/10/11)
すんなり行きませんでした
最初ライブラリに付属のconfigureを使ってNDKのコンパイラを利用しliboggとlibvorbisならびにlibvorbisfileをコンパイルを試みて、まぁ四苦八苦してstatic linkの成功はしたんだけど
リンクの時にいちいち絶対パスを指定しなきゃならないし後々はdynamic linkもしたいからそこで辞めた。
コンパイラの種類分だけ手順を繰り返すのもなんか美しくない。
リンクの時にいちいち絶対パスを指定しなきゃならないし後々はdynamic linkもしたいからそこで辞めた。
コンパイラの種類分だけ手順を繰り返すのもなんか美しくない。
で、結局Android.mkをいじりながら理解しつつeclipse上でビルドをかけたらx86やARMのsoファイルを吐いてくれて
それらをdynamic linkする所まで頑張った。
経過については・・いいでしょう、もう。
それらをdynamic linkする所まで頑張った。
経過については・・いいでしょう、もう。
ともかくliboggらをdynamic linkして使える状態になった。これからSDLを組み込んでやっとこさOpenSLのテストに入れる
(2013/10/10)
OpenALのコンテキストとOpenGLのそれは、どうやら違うようで。
OpenALの場合はリファレンスにもある通りSourceとListenerがコンテキストに所属し、Bufferは共通。
そしてOpenALはスレッドセーフなAPIなのでListenerを複数使いたいのでなければ全てのスレッドで同じコンテキストを使ってOK。
ちなみにOpenSLもAndroid実装ではスレッドセーフで以下略
OpenALの場合はリファレンスにもある通りSourceとListenerがコンテキストに所属し、Bufferは共通。
そしてOpenALはスレッドセーフなAPIなのでListenerを複数使いたいのでなければ全てのスレッドで同じコンテキストを使ってOK。
ちなみにOpenSLもAndroid実装ではスレッドセーフで以下略
対してOpenGLでは(あくまで自分の理解では)テクスチャから何から全部リソースがコンテキストで別個に管理され、相互にアクセスも出来ない。
一応Context Sharingでリソースを共有することも出来るが別々のスレッドで同じコンテキストを同時に使うとエラーで落ちるし
恐らくSharingした別コンテキストで同じリソースにアクセスしても同様。使い方がちょっと難しいかも。
一応Context Sharingでリソースを共有することも出来るが別々のスレッドで同じコンテキストを同時に使うとエラーで落ちるし
恐らくSharingした別コンテキストで同じリソースにアクセスしても同様。使い方がちょっと難しいかも。
サウンドの現状
OpenSL対応の実装もひと通り終了。まだ任意のシークに対応してないけどまぁ、必要が生じたらという事で。
それで当然デバッグしたいがOpenSLはOpenSLが実装された環境でしか動かない。つまりAndroid実機かエミュレータという事になる。
サウンド関連のルーチンに自作のライブラリを組み込んでいる関係でまずはこのライブラリをAndroid向けにコンパイルするのが先だ。
で、今取り組んでいる最中・・(続く
それで当然デバッグしたいがOpenSLはOpenSLが実装された環境でしか動かない。つまりAndroid実機かエミュレータという事になる。
サウンド関連のルーチンに自作のライブラリを組み込んでいる関係でまずはこのライブラリをAndroid向けにコンパイルするのが先だ。
で、今取り組んでいる最中・・(続く
#追記1
自分のライブラリはandroid用にコンパイルしてリンクするとこまでは出来た。
最初はライブラリをARM向けにコンパイルしたのに利用するプログラムをX86でやろうとして
undefined referenceが出て「?」のパターン。気づくまで1時間ほど無駄にした。
他にcmakeの記述をARMとX86用を一発で切り替えられるように改良。
次はOgg vorbisのライブラリだが、これはすんなり行くのだろうか・・?
最初はライブラリをARM向けにコンパイルしたのに利用するプログラムをX86でやろうとして
undefined referenceが出て「?」のパターン。気づくまで1時間ほど無駄にした。
他にcmakeの記述をARMとX86用を一発で切り替えられるように改良。
次はOgg vorbisのライブラリだが、これはすんなり行くのだろうか・・?
(2013/10/09)
スタート地点へ
OpenALもOpenSLに対応するにしても
ループ処理とかフェードイン・アウトといったAPIに依存しないルーチンをを共通にしておきたかったので両対応ライブラリを作る練習と思って
クラス設計を見なおしていたら結局全部書き換えのパターンだった。
前に作ったクラスはAPIを勉強しつつだったんでバッファのクラスでソースの操作をしているとか、その逆とかしてて
端から見れば全くオブジェクト指向じゃない有様。
ループ処理とかフェードイン・アウトといったAPIに依存しないルーチンをを共通にしておきたかったので両対応ライブラリを作る練習と思って
クラス設計を見なおしていたら結局全部書き換えのパターンだった。
前に作ったクラスはAPIを勉強しつつだったんでバッファのクラスでソースの操作をしているとか、その逆とかしてて
端から見れば全くオブジェクト指向じゃない有様。
で、現在は新設計でOpenALの再生ルーチンが動いてる状態。これから依存部分を書き足せばOpenSLにも対応できる予定ではあるが・・
こう前置きしといて上手く行った試しが無くて自信がない。
逆に言えばすんなり出来たら自信が付く訳だが。どうなることやら。
こう前置きしといて上手く行った試しが無くて自信がない。
逆に言えばすんなり出来たら自信が付く訳だが。どうなることやら。
(2013/10/07)
SSEに依存していた自作のMathライブラリ、ARM CPUのNEONに対応できればベストなんだけど勉強の手間もそうだし
まだ普及率がイマイチっぽいので一先ずSSEが無くても動くように改修した。
SSEレジスタを構造体でエミュレーションしただけの簡単仕様。とりあえず動いてるようだが・・・ユニットテストを書かなきゃならんね。
Androidアプリに向けての準備が着々と整いつつある。
まだ普及率がイマイチっぽいので一先ずSSEが無くても動くように改修した。
SSEレジスタを構造体でエミュレーションしただけの簡単仕様。とりあえず動いてるようだが・・・ユニットテストを書かなきゃならんね。
Androidアプリに向けての準備が着々と整いつつある。
サウンド
当面3Dサウンドは無しでOpenALとOpenSL|ESの両対応でやっていこうと思う。
正確には3Dサウンドも用意するけどその場合はOpenALオンリー(OpenSLのマクロを定義してコンパイルするとエラー)となる感じで。
進捗は50%くらい
正確には3Dサウンドも用意するけどその場合はOpenALオンリー(OpenSLのマクロを定義してコンパイルするとエラー)となる感じで。
進捗は50%くらい
余談
AndroidとLGPLに関して調べていたらgithubに上げていたtwitterクライアントのソースをそっくりそのまま、
クレジットの部分だけ消されて販売されていた事例を目にした。
怖いね。自分とこのは完全に自己満足ライブラリだしtwitterクライアントにしても
新しいAPIに対応してなくて「修正が必要=そんな技術があれば最初から自分で作る筈」だからいいけど。
今後ちゃんとしたゲームやツールを作る際はきちんと暗号化された場所にリポジトリを作る事になりそう。
クレジットの部分だけ消されて販売されていた事例を目にした。
怖いね。自分とこのは完全に自己満足ライブラリだしtwitterクライアントにしても
新しいAPIに対応してなくて「修正が必要=そんな技術があれば最初から自分で作る筈」だからいいけど。
今後ちゃんとしたゲームやツールを作る際はきちんと暗号化された場所にリポジトリを作る事になりそう。
(2013/10/05)
OpenSLのオブジェクトは(*obj)->method(obj, ...)という風にメソッドを呼ぶことは先日書いたが
いちいち上記のように書くのが面倒だと思ったのか、気がついたらクラスでラップしていた。
けど、よく考えたらこれからラッパー作るのにラップする対象を更にラップで包んでどうすんだ!
無駄の極みである。車輪の再発明どころではない。
いちいち上記のように書くのが面倒だと思ったのか、気がついたらクラスでラップしていた。
けど、よく考えたらこれからラッパー作るのにラップする対象を更にラップで包んでどうすんだ!
無駄の極みである。車輪の再発明どころではない。
更にOpenSL
流石にそろそろケリを付けないと不味い。こればっかやってる訳には行かない。
OpenSLにはデフォルトでOggやMIDIを再生する仕組みが備わっているんだけど、これの使い方を調べたら
どうやらAudioPlayerオブジェクトをOggならOggで初期化して、それ専用にしなければならない様で。
ゲーム中に効果音を30個使いたいなら30個要るし、音楽も合わせたらそれ以上になる。
OpenSLにはデフォルトでOggやMIDIを再生する仕組みが備わっているんだけど、これの使い方を調べたら
どうやらAudioPlayerオブジェクトをOggならOggで初期化して、それ専用にしなければならない様で。
ゲーム中に効果音を30個使いたいなら30個要るし、音楽も合わせたらそれ以上になる。
当然、そんな何個もプレイヤー作ってて速度とメモリ的に心配なのか?という点と何個まで作れるかが問題になる。
少なくともエミュレータと手持ちのタブレットでは30個目を作ろうとした所でtoo many objectsと怒られて落ちた。
realizeを呼ばなくても同じなので効果音毎に1つAudioPlayerを割り当てるのは駄目。
という訳で前のようにチャンネル管理でやっていく必要がある。
どちらにせよ効果音をoggファイルで格納しておいてゲーム開始時にwaveに展開っていうのをやろうと思っていたんで
libvorbisとPCMのストリーム再生しとけばいいのか。
少なくともエミュレータと手持ちのタブレットでは30個目を作ろうとした所でtoo many objectsと怒られて落ちた。
realizeを呼ばなくても同じなので効果音毎に1つAudioPlayerを割り当てるのは駄目。
という訳で前のようにチャンネル管理でやっていく必要がある。
どちらにせよ効果音をoggファイルで格納しておいてゲーム開始時にwaveに展開っていうのをやろうと思っていたんで
libvorbisとPCMのストリーム再生しとけばいいのか。
それとOpenSL自体には3Dサウンドがあるが、Androidだとこれもエミュレータと実機共に実装されてなくて使えない。
OpenALだと全部ソフトウェアで実装されてて遅い代わり環境に左右されず使える訳だけど
OpenSLにはハードが対応して無ければソフトウェアでエミュレートなんて親切な事はしてくれないので、困った。
もうOpenALでいいかね。
OpenALだと全部ソフトウェアで実装されてて遅い代わり環境に左右されず使える訳だけど
OpenSLにはハードが対応して無ければソフトウェアでエミュレートなんて親切な事はしてくれないので、困った。
もうOpenALでいいかね。
LGPLのライセンスって難しいね。どこまでがライブラリでどうなると静的リンクなのか・・
ちょいと調べた感じだと
ちょいと調べた感じだと
- AndroidにおいてJavaのライブラリ(Jar)を使うと最終的に自分のソースとまぜこぜになってclass.dexファイルに纏められてしまうから静的リンク扱い
- Cのライブラリをsoファイルとしてコンパイルしておいて実行時にリンクするなら動的リンク
- ただしLGPL ver3の場合は最終的に生成されるapkが単なるzipファイルとはいえ結合されてしまうのでまたひと手間要るらしい。(OpenALはv2だからこの辺は大丈夫そうだ)
ま、どうでしょう。とりあえず3Dは無しでOpenSL使って後で簡易3D(音量を単純に左右に振る程度の)を加えるか。
GUIについて
JNIでAndroidのGUIと連携できる!と意気込んだものの、それだと折角マルチプラットフォーム前提で組んだゲームがAndroid依存になっちゃうし
そもそもAndroidのGUIはあまり見た目が格好いいとは・・・
ただあくまでデバッグ用と割り切れば使えないこともない。
そもそもAndroidのGUIはあまり見た目が格好いいとは・・・
ただあくまでデバッグ用と割り切れば使えないこともない。
結局ゲームを作る時のボタン類は自前って事になりそうだ。
実際Androidのゲームを幾つか試してみてもデフォルトのGUIを使ってるソフトは殆ど無い。第一ゲーム画面と違和感が出すぎる。
実際Androidのゲームを幾つか試してみてもデフォルトのGUIを使ってるソフトは殆ど無い。第一ゲーム画面と違和感が出すぎる。
(2013/10/04)
引き続きOpenSL
OpenSLは
1. AudioPlayer等のオブジェクトを生成
2. Realize関数を呼ぶ
3. メソッドを呼び出して使う
という流れで進める。
1. AudioPlayer等のオブジェクトを生成
2. Realize関数を呼ぶ
3. メソッドを呼び出して使う
という流れで進める。
だけど「1と3はわかる。2は何だ?」と思うのが当然な訳で。
結論から言うと1はC++で言うところのクラスのメモリ確保で、2はコンストラクタみたいな物に相当するようだ。
結論から言うと1はC++で言うところのクラスのメモリ確保で、2はコンストラクタみたいな物に相当するようだ。
わざわざ”みたいな”と書いたのは勿論イコールではないという事で
この辺はPDFのリファレンスでも見てもらったほうが分かりやすいが簡単に説明すると
まずオブジェクトの状態には3種類ある
この辺はPDFのリファレンスでも見てもらったほうが分かりやすいが簡単に説明すると
まずオブジェクトの状態には3種類ある
- Unrealized - 初期化されてない状態
- Realized - 音声を再生できる状態
- Suspended - 使用不可だが再生の位置などは保持されてる状態
上記で言えば1の直後はUnrealized, 2でRealizedになり
アプリケーションがスリープした時などにメモリを節約する等の意図でユーザーか又はシステムがSuspendedや場合によってはUnrealizedにするという仕組み。
ユーザーはGetState関数で今どの状態かを取得してRealizedを呼ぶなり、何なりすると。
アプリケーションがスリープした時などにメモリを節約する等の意図でユーザーか又はシステムがSuspendedや場合によってはUnrealizedにするという仕組み。
ユーザーはGetState関数で今どの状態かを取得してRealizedを呼ぶなり、何なりすると。
(2013/10/03)
Android NDKとJNI
じゃあOpenALは大体出来たから次はOpenSL
とは言うもののまずAndroidのビルドからして詰まる。
前にADT並びにeclipseを変なパスにインストールしてしまったんで一式を入れなおしたんだけど、前のプロジェクトを再利用しようとすると
ヘッダが見つからない、インクルードファイルのパスが不正だ、SDKのバージョンが不正だのエラーが。
これは結果的にマニフェストファイルのSDKバージョンを指定しなおして、プロジェクトのプロパティのSDKバージョンも設定し直すことで修正できた。
前にADT並びにeclipseを変なパスにインストールしてしまったんで一式を入れなおしたんだけど、前のプロジェクトを再利用しようとすると
ヘッダが見つからない、インクルードファイルのパスが不正だ、SDKのバージョンが不正だのエラーが。
これは結果的にマニフェストファイルのSDKバージョンを指定しなおして、プロジェクトのプロパティのSDKバージョンも設定し直すことで修正できた。
あとはNDKのビルド方法をすっかり忘れていたからそれの復習と
今までNativeActivity経由でしかC++を動かしてなかったが、Javaと連携するケースも想定してJNI関連を試したり。
これもちょっと詰まったがパスの指定漏れやクラス名の指定ミスとかだったんで省略。
今までNativeActivity経由でしかC++を動かしてなかったが、Javaと連携するケースも想定してJNI関連を試したり。
これもちょっと詰まったがパスの指定漏れやクラス名の指定ミスとかだったんで省略。
他にも複数のアーキテクチャに対応するビルド方法を調べたり、エミュレータが遅くて仕方ないので実機デバッグしかないのかと思ってやはり調べたら
なんとAMD-VかIntel VTに対応したCPUならばエミュレータのCPUをARMではなくX86と指定すると5倍以上高速に動き
「これ実機デバッグは最終確認だけでいいじゃん」と驚いたり。
いや、ホントに実機と遜色無いスピードで動くから知らない人は非常に損してる。
なんとAMD-VかIntel VTに対応したCPUならばエミュレータのCPUをARMではなくX86と指定すると5倍以上高速に動き
「これ実機デバッグは最終確認だけでいいじゃん」と驚いたり。
いや、ホントに実機と遜色無いスピードで動くから知らない人は非常に損してる。
で、ようやくスタート地点(OpenSL)へ戻る訳だが・・
OpenSL
webで探そうにも情報が殆ど無いのでフツーにNDKに付いてるサンプルと
OpenALと違ってこちらはKhronosなのでKhronosのページからPDFを落としてきて参考にする等した方が良さげ。
あとは
http://audioprograming.wordpress.com/2012/03/03/android-audio-streaming-with-opensl-es-and-the-ndk/
こういうチュートリアルとかかね。
OpenALと違ってこちらはKhronosなのでKhronosのページからPDFを落としてきて参考にする等した方が良さげ。
あとは
http://audioprograming.wordpress.com/2012/03/03/android-audio-streaming-with-opensl-es-and-the-ndk/
こういうチュートリアルとかかね。
OpenSLは例によってC言語インタフェースでXAudioみたいなクラスではないんだけど
そこはちょっと工夫がしてあって
(*object)->method(object, args...);
こんな感じに書けるようになっている。
多分普通ならフーンで何とも思わないで先に進んじゃうのかもしれない。
でも自分は何でこういう風に書けるのか?が気になってしまうタイプなので
ここで自分なりにC言語でオブジェクト思考する手段を考えてみたり、実装してみたりしてた。
そこはちょっと工夫がしてあって
(*object)->method(object, args...);
こんな感じに書けるようになっている。
多分普通ならフーンで何とも思わないで先に進んじゃうのかもしれない。
でも自分は何でこういう風に書けるのか?が気になってしまうタイプなので
ここで自分なりにC言語でオブジェクト思考する手段を考えてみたり、実装してみたりしてた。
ようやく納得いった所で次へ進む・・ (続く)
(2013/10/02)
OpenALについて
あれから出来た事と言えばOpenALでwaveと事前にデコードしたoggを鳴らすだけでストリーミングは今実装中という、あまり進んでない感じなのだが。
調べ物が中心だったかね。
調べ物が中心だったかね。
とりあえずOpenALの全容を掴みたかったので
「Open何とかと付けばまずKhronosのWebページだろ」とチェックするが、まずもって無かったり。
それもその筈、Khronosは関係無いようだ。Loki Softwareという所。
似たような名前でOpenMAX ALの表記があるけどOpenALとは直接関係ない。
「Open何とかと付けばまずKhronosのWebページだろ」とチェックするが、まずもって無かったり。
それもその筈、Khronosは関係無いようだ。Loki Softwareという所。
似たような名前でOpenMAX ALの表記があるけどOpenALとは直接関係ない。
OpenALは単なるインタフェースの定義に過ぎない。・・・と言えばOpenGLもそうなんだけど
OpenALの場合は現に同じプラットフォームで動くOpenALの実装が複数あったりする。
例えばPCで動くOpenALの実装はLGPLなOpenAL Soft(v1.15)、Creative社によるプロプライエタリなOpenAL(v2.1)と2つある。
v2.1の方はCreative X-fiカードのみ対応で製品の一部と考えても良く
個人で使う文には実質OpenAL Soft一択という事になるだろうか。
ちなみにSoftとつくのはソフトウェア実装だから、という意味らしい。
OpenALの場合は現に同じプラットフォームで動くOpenALの実装が複数あったりする。
例えばPCで動くOpenALの実装はLGPLなOpenAL Soft(v1.15)、Creative社によるプロプライエタリなOpenAL(v2.1)と2つある。
v2.1の方はCreative X-fiカードのみ対応で製品の一部と考えても良く
個人で使う文には実質OpenAL Soft一択という事になるだろうか。
ちなみにSoftとつくのはソフトウェア実装だから、という意味らしい。
で、先日「AndroidでOpenALを使うとAudioTrackのせいで遅延が酷い」と書いたけど
バックエンドがOpenSLなOpenALもあって良いはずだよね?と思って調べたらちゃんとあった。
(というかOpenAL Softのファイル群にしっかりとbackends/opensl.cが・・)
バックエンドがOpenSLなOpenALもあって良いはずだよね?と思って調べたらちゃんとあった。
(というかOpenAL Softのファイル群にしっかりとbackends/opensl.cが・・)
まだビルド方法等は調べてないものの、恐らくOpenSL ESを別途勉強しなくてもOpenALだけで済ませられそうな予感。
但しAndroidのライセンス関係はどうなんだか。全部static linkされてしまうんだっけ?shared libraryとして使えるのかよく分からん。
もし前者ならやっぱりOpenSLという形になる。
AndroidのOpenALはトラップだとか、なんとか聞くし・・
但しAndroidのライセンス関係はどうなんだか。全部static linkされてしまうんだっけ?shared libraryとして使えるのかよく分からん。
もし前者ならやっぱりOpenSLという形になる。
AndroidのOpenALはトラップだとか、なんとか聞くし・・