🔖

Lem Advent Calendar 2023 - SDL2 Frontend - グラフィックスAPI編

2023/12/03に公開

これは Lem Advent Calendar の記事です。

概要

SDL2 frontendを実装したことにより、SDL2のグラフィックス機能をlem上で使えるようになりました。

lemでは大きく分けて二つの方法で図形をレンダリングできます。

  • renderメソッドをオーバーライドして、その中で描画を実装する
  • lem-sdl2/graphicsパッケージを使う

renderメソッド

lemの描画処理時に、lem-sdl2:renderというメソッドが呼び出されます。
このメソッドを新しく作ったバッファクラスでディスパッチすることで、描画方法をカスタマイズできます。

(defclass example-buffer (lem:text-buffer) ())

(defmethod lem-sdl2:render (texture window (buffer example-buffer))
  ;; 任意の描画処理を書く
  (sdl2:set-render-draw-color (lem-sdl2:current-renderer) 255 0 0 0)
  (sdl2:with-rects ((rect 10 10 500 500))
    (sdl2:render-fill-rect (lem-sdl2:current-renderer) rect)))

(let ((buffer (make-buffer "*example*")))
  (change-class buffer 'example-buffer))

lem-sdl2/graphicsパッケージ

指定したバッファやウィンドウをターゲットにして、図形を描画する機能を提供するパッケージです。

用意されている関数には以下のようなものがあります。

関数 説明
(draw-line target x1 y1 x2 y2 &key color) 線を描画します
(draw-rectangle target x y width height &key filled color) 矩形を描画します
(draw-point target x y &key color) 点を描画します
(draw-points target x-y-seq &key color) (x . y)のベクタを受け取り点を複数個描画します
(draw-string target string x y &key font color) 文字列を描画します
(load-image pathname) 画像を読み込み、画像オブジェクトを返します
(draw-image target image &key x y width height clip-rect) 画像オブジェクトを受け取り描画します
(clear-drawables target) windowやbufferをtargetとして受け取り、その中に描画されている図形を全て削除します

実装詳細

各draw関数は内部でdrawableというオブジェクトを生成します。
drawableオブジェクトは対象のbufferやwindowと関連付けて保持します。
lem-sdl2:renderメソッドで各drawableオブジェクトを描画することで、
ユーザーはオブジェクトを作るだけでよく、描画メソッドを呼び出すことを意識しなくて良いようになっています(basicみたいに図形を描けて楽しいですね)

反省

このAPIは一見便利に見えたのですが実際に何かを作るときにはrenderメソッドを直接使うことの方が多く、graphicsパッケージを使うことはありませんでした。
デモ時には便利だったのですが、リソースの余計な管理が挟まり再評価してもすぐに反映される仕組みでもないので、余計な抽象化だったかもしれません。

おわりに

三日目はこれで終わりです。
次回は、今回紹介した機能を使って作った機能についてまとめたいと思います。

Discussion