コンテンツにスキップ

Processing 風の描画 (P5)

P5 は Processing / p5.js 風の描画 DSL です。FmrbGfx を内部でラップしており、fill / stroke / translate / rotate などの状態を持った p5 スタイルで図形を書けます。picoruby-fmrb-app に組み込まれているため、追加の require は不要です。

使い方

class MyApp < FmrbApp
  def on_create
    @p5 = P5.new(@gfx)
  end

  def on_update
    @p5.background(P5::BLACK)
    @p5.fill(P5::RED)
    @p5.no_stroke
    @p5.rect(10, 10, 60, 40)
    @p5.present
    33
  end
end

MyApp.new.start

構築

P5.new(gfx)

引数: FmrbApp#@gfx(FmrbGfx インスタンス)。サブクラス側で @p5 = P5.new(@gfx) として保持します。

スクリーン

メソッド 用途
width キャンバス幅
height キャンバス高さ
background(color) 全画面を color で塗る
present (commit のエイリアスあり) フレームを画面に反映

カラー定数

FmrbGfx::* のミラー(RGB332)。

P5::BLACK / WHITE / RED / GREEN / BLUE / YELLOW / CYAN / MAGENTA / GRAY

任意の色は P5#color(r, g, b) (内部で FmrbGfx.rgb_to_332 呼び出し)または直接 RGB332 整数で指定可。

描画状態

メソッド 用途
fill(color) / no_fill 塗り色/塗り無効
stroke(color) / no_stroke 線色/線無効
stroke_weight(w) 線幅(>1 は平行線で実装)
blend_mode(mode) 合成モード(後述)

合成モード

P5::REPLACE / P5::ADD / P5::XOR / P5::SUBTRACT / P5::MULTIPLY / P5::SCREEN の定数を提供します。

合成モードの制限

バックエンドが対応するのは REPLACE / ADD / XOR のみで、しかも 矩形塗り (rect(), background()) でしか効きません。それ以外の形状や SUBTRACT / MULTIPLY / SCREEN は REPLACE と同じ動作 にフォールバックします。

基本図形

メソッド シグネチャ
point(x, y) 1 ピクセル(stroke 色)
line(x0, y0, x1, y1) 直線
rect(x, y, w, h) 矩形(fill + stroke)
circle(cx, cy, r) 円
ellipse(cx, cy, rx, ry) 楕円
triangle(x0, y0, x1, y1, x2, y2) 三角形
arc(cx, cy, r, start, stop) 円弧(角度は ラジアン)
bezier(x1, y1, x2, y2, x3, y3, x4, y4) 3 次ベジエ(20 セグメント直線分割)
curve(x1, y1, x2, y2, x3, y3, x4, y4) Catmull-Rom スプライン
quad(x0, y0, x1, y1, x2, y2, x3, y3) 四角形 (4 点指定)
begin_shape / vertex(x, y) / end_shape(close = false) 自由な多角形。開いて、点を足して、閉じます。end_shape(true) で最後の点と最初の点をつなぎます

alpha は何もしません

p5.js 向けに書いたコードがそのまま動くように受け付けるだけです。本体にアルファ チャンネルはなく、色は 256 色のどれかで不透明です。半透明が要るときは blend_rect か下の blend_mode を使ってください。

arc のモード

p5.js の OPEN / CHORD / PIE モードはサポートしません。常に パイ形 (fill_arc)と 外周リング (draw_arc)の組合せで描画されます。

アフィン変換

p5.js / Processing と同じ post-multiply 合成 (M' = M * op)。translate(tx, ty); rotate(theta); rect(-30,-20,60,40) で 平行移動後のローカル原点を中心に回転 する標準的な動作です。

メソッド 用途
translate(tx, ty) 平行移動
rotate(angle) 回転(ラジアン)
scale(sx, sy = sx) 拡大縮小
push_matrix / pop_matrix 行列のセーブ/リストア
reset_matrix 単位行列に戻す

行列が translate のみ のときは高速パス、回転・スケーリングが含まれると三角形分解などの低速パスに切り替わります。

テキスト

メソッド 用途
text_font(font, wide_font = nil) フォント切替。:default / :ja, 8 / :ja, 12
text_color(color) 文字色
text_align(h, v = :top) 整列。h: :left / :center / :right、v: :top / :center / :bottom
text_leading(pixels) 行送り(状態保持のみ。\n は未対応)
text_width(str) 文字列の描画幅(固定幅前提)
font_height いまのフォントの高さ (画素)
text(str, x, y) 描画

日本語フォントについては FmrbGfx ▸ 日本語テキスト を参照。

@p5.text_font(:ja, 12)
@p5.text_color(P5::BLACK)
@p5.text_align(:center, :center)
@p5.text("こんにちは", @p5.width / 2, @p5.height / 2)

画像

メソッド 用途
image(image_id, x, y, scale_x = 1.0, scale_y = 0.0) FmrbGfx#create_image_from_file で得た ID を描画。scale_y = 0.0 で scale_x と同値
image_masked(image_id, mask_data, x, y, w, h) 1bpp マスク付き描画

ピクセル操作

メソッド 用途
set_pixel(x, y, color) 直接書き込み
get_pixel(x, y) 読み戻し(グラフィックス側まで往復するため遅い)

get_pixel のコスト

get_pixel は同期呼び出しです。未送信の描画コマンドをすべて送り出し、グラフィックス側で読み出して、答えが返るまで待ちます。Retro ではその答えが UART を往復するので 1 ピクセルに数ミリ秒かかります。Modern はもっと軽いとはいえ往復には変わりありません。ループで多数読むのは避けてください(ピクセル単位の参照より、自前で持つ二次元配列に描画状態を保持する方が高速)。

サンプル

class P5Spinner < FmrbApp
  def on_create
    @p5 = P5.new(@gfx)
    @angle = 0.0
  end

  def on_update
    @p5.background(P5::BLACK)
    cx = @p5.width / 2
    cy = @p5.height / 2

    @p5.push_matrix
    @p5.translate(cx, cy)
    @p5.rotate(@angle)
    @p5.fill(P5::CYAN)
    @p5.no_stroke
    @p5.rect(-20, -20, 40, 40)
    @p5.pop_matrix

    @p5.present
    @angle += 0.1
    33
  end
end

P5Spinner.new.start

PicoRuby デモ (/app/demo/picoruby.app.rb) の P5 のページに、基本図形・アフィン変換・ベジエ・テキスト・円弧・blend・get_pixel が一通り入っています。

関連

  • FmrbGfx — 内部ラッパ。P5#@gfx で取り出せます
  • Sprite — より低レベルな描画とパフォーマンス重視の API
  • サンプル集 — p5_test を含むデモアプリ一覧