投稿

ラベル(Java)が付いた投稿を表示しています

Java を Kotlin へ

Kotlin については Google の公式ドキュメントが多数あるが、 Kotlin への変換 という Codelabs の片隅にあった文章が、最初に知りたかったことだけが物凄く完結にまとまっていた。最初にこの文章にアクセスできていればと思ったほど。もちろん、Java ベースの Android プログラミングのベースがある人限定の話になるが。 Java Kotlin final オブジェクト val オブジェクト equals() == == === データのみを保持するクラス data クラス コンストラクタでの初期化 init ブロックでの初期化 static フィールドおよび関数 companion object で宣言されているフィールドと関数 シングルトン クラス object 例えば、当初、companion object を見て、「何で Java の static オブジェクトと同じものを、わざわざ名前を変えて companion object とかいう名称にしているんだ?」と思ったが、実は良く考えられているようだ。Java の static オブジェクトの場合はオブジェクト毎の modifier として宣言するのに対して、Kotlin の companion object はクラス内のブロックとして宣言されている。これは可読性の点で優れている。 Kotlin は Java をベースにしながらも、(上の表からは割愛されているが)埋め込みテキストなど、可能な限り、可読性のために Python などのスクリプト系言語の簡潔な表現を取り入れようとしている感じかもしれない。

Android / Java と OpenGL ES 2.0 の要点

以下のような人(要するに僕自身のケースと同じ)を対象にしている: Android / Java のアプリ開発についての一般的な理解はある ImageView.onDraw や SurfaceView による動画ならそれほど苦労せずに理解できた しかし、OpenGL (ES 2.0) のことになると色んな解説やサンプルコードを見ても理解に苦しんで中々はかどらない なぜ OpenGL はわざわざああいうことをするようになっているのか? ImageView.onDraw や SurfaceView による動的グラフィックスなら理解しやすかった人にとって、動画とは、パラパラ漫画のようなものというほとんど無意識的な大前提があるわけだ。パラパラ漫画に限らず、映画やアニメなど、世の中の映像記録方式としては、こちらが圧倒的主流。ImageView.onDraw や SurfaceView の場合も、ループを回して、フレームバッファに次々とコマを描き込むだけ。 ところが、OpenGL はそれを許してくれないので、何か物凄く高度な、GPU のハードウェア的な性能を引き出すために、OpenGL の API を通じて描画する必要があるのかと、勘違いする。実際はそう(高度な GPU のハードウェア的な性能を引き出した上でレンダリングするのが目的の API 体系)ではないので、架空の妄想を相手に戦う羽目になり、決して勝利することができない戦いに挑む形になる。 OpenGL はそもそも、パラパラ漫画的なことをプログラマーが自らやることを想定していない(GPU 側の内部処理として行われる)。その一歩手前の部分(モデリング)を主にするのがプログラマーの仕事。モデルを基にしてラスタライズしてフレームバッファに落し込む処理は、GPU 側が(プログラマーが予め定義したフラグメントシェーダーに従って)内部的に行う形になっている。つまり、プログラマーがすべき仕事の領域がそもそも異っている点に気付かなければならない。 言ってみれば、フレームバッファ描き込みによるパラパラ漫画的動画はチカチカと瞬く GIF アニメみたいなもので、OpenGL はヌルヌル動く Flash アニメーションみたいなもの(Flash ももう過去の遺物だが……)。他にも、ペイント系グラフィック(ビットマップ

Android の OpenGL ES と SurfaceView / GLSurfaceView

イメージ
今さらながら Android の OpenGL ES に初めて手を付けてみた。これまでは ImageView の onDraw のカスタムか、ゲーム的なものでも、2D で SurfaceView の画面を丸ごと FrameBuffer として更新するような使い方しかしてこなかった。ところが今回、ちょっと凝った 2D のマップアプリのようなものを作ることになり、先述の通り従来は ImageView の onDraw カスタムで対処してきたのだが、できれば、SurfaceView か、さらには OpenGL ES 化して、Google Map のようなヌルヌルしたものにできないかと思い、3D 用だと思って敬遠してきた OpenGL ES の領域にまで足を踏み入れてみることにした。 SurfaceView 以前、使ったことがあると言っても、ちょっとした 2D ゲームのサンプルで使った程度であり、非ゲームのアプリに利用するというような場合も含めて SurfaceView 自体を研究したことはなかったので、まずは SurfaceView をいじってみることにした。 レンダリング用スレッドを使用する Activity 側で SurfaceHolder.Callback を implement するなりして、レンダリング用スレッドの生成や終了処理を行う。レンダリング用スレッド中では、SurfaceHolder を通じて Surface への(Canvas の描画命令を使った)描画を行う。 Canvas → SurfaceHolder → Surface という 3 重のバインド構造になっているの( 参考 )で初見では戸惑うかもしれないが、やっていることは Surface(framebuffer のようなもの)へのデータの書き込みである。 val canvas: Canvas = holder.lockCanvas() // Canvas#drawBitmap 等を使った描画処理 holder.unlockCanvasAndPost(canvas) レンダリング用スレッドを使わないで、そのままメイン UI スレッドで同様のことを行うこともできるが、圧倒的に処理が重くなる。SurfaceView を使う意味がない。 SurfaceView を使うこと