「独創アプリ開発日記」カテゴリーアーカイブ

デアゴスティーニ商法作業管理第2弾 1日目

アプリ作成の下準備として、描画方式によるメモリ使用量の比較を行いたいと思います。

今回は WebGL 1.0 の GL_TRIANGLES と GL_TRIANGLE_STRIP でテクスチャ付きの立方体を描画した場合、どのくらいメモリ使用量に差が出るか確認しました。

以下が結果です。

注意:この表を鵜呑みにしないで下さい。私の想定(立方体に対して自由にテクスチャを貼るとか)に縛られた部分で最適化出来ずにバイト数が大きくなってしまっている部分があります。

単位:バイト
立方体の数GL_TRIANGLESGL_TRIANGLE_STRIP
1個864336 (38.89%)
10個8,6403,432 (39.72%)
100個86,40034,392 (39.81%)

情報としては、頂点座標(float型*4バイト3)とテクスチャ座標(float型4バイト*2)を使用し、頂点数分のインデックスバッファ(unsinged int型 4バイト*頂点数)を使って描画(drawElementsのAPI)した場合を計算しています。

GL_TRIANGLESは独立した三角形を組み合わせて立方体を描画した場合で、1つの立方体を描画するのに12の独立した三角形の情報が必要です。

1つの三角形を描画するのに必要なバイト数は、頂点 (x, y, z)*3 + テクスチャ座標 (x, y) * 3 + インデックスバッファ * 3 = (9 + 6 + 3) * 4 = 72バイト

1つの立方体を描画するのに12の三角形が必要なので、72*12 = 864バイトとなります。

GL_TRIANGLE_STRIPは同じく三角形を組み合わせた描画ですが、2つ目以降の三角形は、1つ前の三角形と辺を共有しています。このリンク先のイメージを見てもらうとわかるのですが、立方体が14の頂点情報で定義できます。ただし、立方体と立方体を離れた別の場所に同時に描画する際、繋がらないように縮退三角形を利用する必要があり、2個以上の立方体を1回のドローコールで描画する場合は、2個目以降の立方体に対して2つの余分なインデックスバッファ(unsinged int型 4byte * 2)を使う必要があります。

1つの立方体を描画するのに必要なバイト数は、(3 + 2) * 14 * 4 + 14 * 4 = 336バイト で、2個目以降は 344バイトです。

結果の表を見てわかる通り、2倍以上の差が出ました。かなり大きな差なのではないでしょうか。

明日はインスタンシング(drawElementsInstancedANGLE)を利用して更に削減します。

デアゴスティーニ商法作業管理第2弾 0日目

昨年から今年にかけて、デアゴスティーニ商法作業管理法という、デアゴスティーニ商法に習って作業を細切れにする開発手法を独自に編み出して(?)実践しました。

すると、毎日少しずつですが確実に作業を進めることに成功して、Lifegame Lightningアプリを無事リリースすることが出来ました。

Lifegame Lightningアプリはおかげさまで好評のような気がします。たぶん。怖くてまだ売上本数を確認していませんが。どこかの国で売れに売れまくっているのではないでしょうか。1億本くらい。たぶん。

ㅤ○○○
○ ・ω・ ○ がおー
 ○○○
c(_uuノ

というわけで本題です。

次にリリースするアプリの構想とタイトルが決まったので、本日からデアゴスティーニ商法作業管理法によるアプリ開発第2弾をスタートしたいと思います。

今回制作するのはハイクオリティ(自分の中では)3DグラフィックMMOで、タイトル名は「隣の田所さん」です。

毎週月曜日に、その週に実施する作業計画を立てます。無理はしません。毎日サクッと終わる分量にします。デアゴスティーニ商法ですから。

1日目(9/3火):立方体の描画方式によるメモリ使用量の比較 — GL_TRIANGLES、GL_TRIANGLE_STRIP
2日目(9/4水):立方体の描画方式によるメモリ使用量の比較 — drawElementsInstancedANGLE
3日目(9/5木):土地の描画 その1
4日目(9/6金):土地の描画 その2
5日目(9/7土):プレーヤーの描画 その1
6日目(9/8日):プレーヤーの描画 その2
7日目(9/9月):予備日(次の週の予定を立てる)

もう一度書きます。タイトル名は「隣の田所さん」です。

デアゴスティーニ商法作業管理での136日目作業

今日の作業は「iPhoneアプリでロード時にサイズがおかしい対策」です。

現在作成中のライフゲームは通常の画像を読み込んでライフパターンとして利用する機能があります。

で、何枚か読み込んで気づいたのですが、小さい画像はその画像が収まるようにライフのサイズを調整して正常に読めていたのですが、大きい画像の場合はライフサイズを最小にしても画面からはみ出していただけでした。

画像サイズを調整して読み込むことも考えましたが、ドットバイドットで読み込めないとせっかく正確に作ったライフパターンが読み込めないケースが出てくると考え、画面に収まりきらない画像読み込み時は警告を表示することで対策としました。

今日は以上です!

デアゴスティーニ商法作業管理での134-135日目作業

重大発表です。私の中では。

今現在開発しているアプリ名が決定しました。アプリ名は

Lifegame Lightning

にしました!

‹‹(´ω` )/››

GPUのシェーダーを利用して、ハードウェア性能を極限まで引き出したライフゲームです。超細かいライフを稲妻のように超高速で動かすことが可能です!

昨日と今日はライフの動作を超高速化してました。超高速化の作業内容やコードは超企業秘密です。

あとは超売れればいいんだけど。

デアゴスティーニ商法作業管理での133日目作業

今週の予定です。

134日目:タッチ時のパフォーマンス改善その1
135日目:タッチ時のパフォーマンス改善その2
136日目:iPhoneアプリでロード時にサイズがおかしい対策
137日目:iPhoneアプリでセーブ機能をネイティブ対応その1
138日目:iPhoneアプリでセーブ機能をネイティブ対応その2
139日目:iPhoneアプリでセーブ機能をネイティブ対応その3
140日目:予備日(次の週の予定を立てる)

いよいよ大詰です。今週の作業が終われば、一応iPhoneアプリとして完成となります。

追加機能を実装したい気持ちもありますが、いつまでたってもリリース出来なくなってしまうのでとりあえずサクッとリリースを目指したいと思います。

そういえばこのアプリの開発動機ってシェーダーの練習だったはずのなのに、もう130日も経ってたんだな・・・

デアゴスティーニ商法作業管理での132日目作業

今日の作業は「警告ウィンドウの表示」です。

javascriptのalertやconfirmを、WKWebViewで表示対応します。Swiftのバージョンは5.0.1です。

class ViewController: UIViewController, WKUIDelegate {

    private var _webView : WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        _webView = WKWebView()
        _webView.uiDelegate = self
〜以下略〜

上記の赤い部分でデリゲートを指定し、alertは以下のプロトコルを実装することにより、

func webView(_ _webView: WKWebView, runJavaScriptAlertPanelWithMessage alert: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
        
        let alertController = UIAlertController(title: "", message: alert, preferredStyle: .alert)
        let otherAction = UIAlertAction(title: "OK", style: .default) {
            action in completionHandler()
        }
        alertController.addAction(otherAction)
        self.present(alertController, animated: true, completion: nil)
    }

confirmは以下のプロトコルを実装することにより、アプリで表示可能になります。

func webView(_ _webView: WKWebView, runJavaScriptConfirmPanelWithMessage confirm: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
        
        let alertController = UIAlertController(title: "", message: confirm, preferredStyle: .alert)
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) {
            action in completionHandler(false)
        }
        let okAction = UIAlertAction(title: "OK", style: .default) {
            action in completionHandler(true)
        }
        alertController.addAction(cancelAction)
        alertController.addAction(okAction)
        self.present(alertController, animated: true, completion: nil)
    }

javasriptによりalertやconfirmを使うと


if (window.confirm('どっちにするんですかゴルァ?')) {
    alert("やるのかゴルァ?");
} else {
    alert("ごめんなさい。");
}

キャンセルを押します。

はい、アプリ上で表示されましたね。

以上です!

デアゴスティーニ商法作業管理での131日目作業

今日は、「RAND EDGE」が効かない事がある対策を行いました。

conwayのライフゲームは、ライフが一定のルールに従って状態が変化する様がとても面白いゲームです。

全てのライフをランダムに初期化した後、しばらくはライフが変化し続けて楽しめるのですが、一定時間が経つと状態が固定して動きが無くなってしまいます。

「RAND EDGE」とは、画面端のライフを常にランダマイズ処理して、常に動きをつけて楽しめるようにした機能です。

この画像には alt 属性が指定されておらず、ファイル名は スクリーンショット-2019-05-31-8.15.44-1024x574.png です

で、この機能なんですが、「LOOP」という画面端を繋げる機能をオフにすると効かなくなったので今日はその調査と対策を行いました。(ちなみに原因は、「LOOP」オフの場合には画面端が繋がらないのでランダマイズ範囲が狭すぎたためです。)

これで、どんな状況でも永遠にライフが動き続ける様子を、ぼーっと眺めて楽しめます。

ʕ•̫͡•ʕ*̫͡*ʕ•͓͡•ʔ-̫͡-ʕ•̫͡•ʔ*̫͡*ʔ-̫͡-ʔ

デアゴスティーニ商法作業管理での130日目作業

今日の作業は「UIの表示が範囲外になる事がある対策」です。

今作っているWebGLライフゲームアプリのUIは、画面が横長の場合はUIが隠れてしまいます。

右側のSIZE、SPEED、COLORのその下の部分が見えていませんね。このUI部分をドラッグしてスクロールする事で、見えない部分を表示する事ができます。

ライブラリなしで自力で作り込んでいます。

で、ウィンドウサイズが変更された時に、場合によってはUIの表示範囲がおかしくなって何も表示されないことがあったため、今日はこの部分を調整していました。

具体的にはスクロールの最大量、現在のスクロール位置を確認して、範囲外には行かない制御ですね。コードにすると以下のような形になります。


if (0 < this.scrollMax) {
    if (this.scroll < 0) {
        this.scroll = 0;
    } else if (this.scrollMax < this.scroll) {
        this.scroll = this.scrollMax;
    }
} else {
    this.scroll = 0;
}

これでUIの表示が消えることはなくなりました!

今日は以上です!

本家デアゴGTR-NISMO箱積状況:4箱 (38号,39号,40号,41号)

デアゴスティーニ商法作業管理での129日目作業

今日の作業は「iPhoneアプリ化で起動時に画面を触るとずれる対策」です。

今作っているWebGLのガワネイティブ アプリはシングルページアプリケーション(SPA)なので、スクロールは不要です。

なので、WkWebViewのスクロール関連機能をオフにしました。

Swiftのバージョンは5.0.1(xcodeは10.2.1)です。

_webView = WKWebView()

// スクロール禁止
_webView.scrollView.isScrollEnabled = false
_webView.scrollView.panGestureRecognizer.isEnabled = false
_webView.scrollView.bounces = false

バージョンが5になってまた書き方が変わったようです。プロパティ名が変わった?のかな。

正直もう変わらないでほしいですね。頻繁に変わりすぎるからWebGLとかに避難する方向で行っています。

以上です!

デアゴスティーニ商法作業管理での128日目作業

今日の作業は「iPhoneアプリ化で音が出ない原因を調査して対策」です。

・・・

・・

mp3ファイルへのパス間違えていただけでした。

[二二ミ
  ∥   ヾ
  ∩∧∧ ヾ_
  || ゚∀)  | | 
 /⌒二⊃= | |
(  ノ  %∴∵ ⊂⌒ヽ
  ) ) )   ) ̄ ̄(0_)
  \)) (___) (_(

自作の音再生jsライブラリの中にmp3へのパスを書くんですが、自分で作っていてすっかり忘れてました。

正しいパスに直したら、全く何の問題もなくiPhoneアプリ内で音が鳴りました。

アプリ化が原因で鳴らないと思って真剣に悩んでたのに・・・

以上です・・・

本家デアゴGTR-NISMO箱積状況:4箱 (38号,39号,40号,41号)