Debian LinuxとWacomペンタブレットでお絵描きを始める
私は年末にWacomのペンタブレット「One by Wacom」を購入して、それをDebian Linuxにつなげてお絵描きを始めました。
インターネット上を調べてみると、デジタル環境でイラストを描きたいと思ったとき、まず定番ツールの記事が目立ちます。 Adobe PhotoshopやIllustrator、CLIP STUDIO PAINT (クリスタ)を使おうとすると、やっぱりWindows環境の話になってしまいます。
Linuxでお絵描きは無理なのかも、と諦めてしまう人がいるかもしれないので、ここに情報を載せておこうと思います。
私の環境とペンタブレットの接続
2022年の2月までDebian Linux 7 (wheezy)を使っていて、今はメインマシンを刷新してDebian Linux 11 (bullseye)を使っています。 Window Managerにはxfceを使っています。
「One by Wacom」のほうは、Mサイズのものを約6000円くらいで購入しました。 B5のノートよりちょっとだけ大きいくらいのサイズ感です。
気になる「One by Wacom」とマシンとの接続ですが、デフォルトでWacomタブレット用のドライバがインストールされていたため、USBで接続した瞬間に使用できました。 古いDebian Linux 7でも、新しい11でも、それは同じです。
これについてはWacomの解説ページにも少し触れています。
私の場合は、まったくペンタブレットの設定をしていません。
Ubuntu LinuxはDebian Linuxの派生ディストリビューションですが、こちらもUSBを接続しただけで使えたという話を聞きます。
今はあまり苦労せずに、すぐに使い始められるのかもしれませんね。
お絵描きソフト
Linux環境にもお絵かきソフトはいろいろありますので、すべてを知っているわけではないですが、自分が体験したことをお伝えできたらと思います。
私はこれまでGimpとKritaを使用していましたので、特にこの2つについてお伝えします。
Gimp
Gimpに関して言えば、ペンタブを購入する前までは、かなり頻繁に画像に文字や写真を追加したり、エフェクトをかけたりするのに使っていたため、慣れ親しんでいました。
そういうこともあって、お絵描きをするときもGimpでスタートしてみました。
しかし、Gimpに搭載されているブラシの種類は少なく、おそらく細かく設定を調節すれば思ったような描き心地のペンを作れたのかもしれませんが、いちいちそんなこともできなかったので諦めてしまいました。
特にできなかったのが、ペンを細く描き始め、徐々に太くなり、描き終わりを再び細く描くような、「入り」と「抜き」の調整でした。
出来上がったイラストの色合いを調節したり、他の画像と合成したりする際には良さそうなのですが、いざペンで描こうと思うと残念な印象です。
ネット上の評判を見てみても、お絵描きに関して言えばGimpよりも他のソフトのほうが評判が良さそうでしたので、いったん他のソフトを見ることにしました。
Krita
Gimpと比べるとKritaはあまり知らなかったのですが、こちらのほうがイラストに特化したソフトになっています。
ブラシの種類が豊富で、先程お伝えした「入り」と「抜き」に対応したブラシもあります。
イラストを印刷するときはRGBではなくCMYKの色相に変換する必要がありますが、それについても対応しています。
Krita 5.0には、イラストの作成手順をタイムラプスの動画にする機能までついているようです。
KritaはKDEプロジェクトの一環で開発されているソフトウェアだそうで、機能の改善についても前向きに取り組んでいるようです。
Photoshopに慣れている人のために「Photoshop から来た人のために Krita を紹介」というページも用意されています。 こちらも使い始める前に覗いておくと、よく使うショートカットがわかります。
ちょっと細かいことですが、イラストを作成する際に、上位レイヤーが下位レイヤーの「アルファの継承」をすることがあります。 この設定を有効にすると、設定したレイヤーの直下のレイヤーの「アルファを継承」しそうですが、実はディレクトリごとに「アルファを継承」します。 そのため、これを使いたい場合は、いったんディレクトリを作り、その中に継承するレイヤーと継承させるレイヤーを入れて作業する必要があります。
多少のこのソフト特有なところがあるかもれませんが、他のイラストソフトで慣れている人であれば、Kritaはスムーズに使い始めることができるのではないでしょうか。
その他の気になるソフト
- MyPaint
- Wine + Windowsのイラストソフト
Kritaを使う際に名前を聞いたのが「MyPaint」です。 使用する前にKritaに落ち着いてしまいましたが、こちらはCorel Painterに似たUIで、油彩・水彩のようなアナログ感覚でイラストを描く方に向いているという評判です。
他にもWindowsアプリをLinux上で動作させるためのソフトWineを使って、Windows向けイラストソフトをLinux上で使っている人もいるようです。
おわりに
私は設定の変更をそれほど行わなくても、ペンタブの導入、お絵かきソフトの使用をスムーズに進めることができました。
ただ、ディスプレイの縦横比とペンタブの縦横比が大きく異なる場合などには、そこをうまく動くように設定を変更する必要があります。
また、お絵描きソフトごとに、ペンタブの筆圧の加減を調整する必要がある場合もあるでしょう。
そのあたりは環境に依存するところが大きいので、他のサイトの情報に期待したいと思います。
また、最近、Pixivでアカウント取りましたので、そちらで私の作品を見ていただけたら嬉しい限りです。
最後に、直近で上手く描けた初音ミクさんを添付して終わりにしたいと思います。(笑)
この絵を見て、Linux環境でもこういうものを描けるのかと、後押しをできたら嬉しいです。
2020年の振り返り:書籍『実践Rustプログラミング入門』の出版
2021年になったので、まずは久しぶりに2020年の振り返り記事を書くことにしました。
昨年の私のハイライトは、共著で『実践Rustプログラミング入門』を出版したことでした。
いまでは電子書籍版もリリースされたので、AmazonのKindleを始め、様々な電子書籍のプラットフォームでお求めできるようになっております。
Rustは様々な分野で使うことができるプログラミング言語ですが、この『実践Rustプログラミング入門』もコマンドラインプログラム、Webアプリケーション、WASM、GUI、組み込みなど、様々な分野で使用した場合の例を載せています。
Rustの活躍できる舞台が広いことを体現したような書籍にできあがったような気がして、私も感慨深い気持ちになりました。
私は以前『RustではじめるOpenGL』という書籍を執筆していたこともあって、『実践Rustプログラミング入門』ではGUIの章を担当させていただきました。
GUIの章では、GUIのクレートである「iced」を使ったストップウォッチの実装例を紹介していますが、執筆メンバーやネットのコメントなどでも、なかなか評判が良かったので安心しております。
いまでもGUIやOpenGLは大好きで、これらを使ったゲームの製作を続けながら、Slackコミュニティの「rust-jp」の「#gamedev」チャンネルに顔を出したりしています。
最近はゲーム開発の他にも、Rustを使ったエミュレータの作成にも興味を持ち始めています。
昨年は書籍の執筆が終わった後、完全に燃え尽きていて、ブログの執筆をお休みしていましたが、今年はまたブログで情報の共有をしていけたらと思います。
本年もよろしくお願いいたします!
Rust GUI crate調査: iced
この記事には作り方に関する情報は、ほとんど書いておりません。
あくまで、このcrateが持つ機能や使いやすさなどをお伝えすることを目標としております。
icedの概要
今回紹介するicedは、クロスプラットフォームで、renderer-agnostic (レンダラーに依存しない) crateを目指している、Rust GUI界の希望の星です。
Rust自体がクロスプラットフォームで動作するバイナリファイルを生成できるため、GUIも苦労せずにクロスプラットフォームで動作するものがほしいですよね!
内部ではGPUを利用したレンダリングをしており、環境によってVulkan、Metal、DX11、DX12を使用して動作するようになっています。
「GPU持ってないよ〜」という方も多いと思いますが、私のマザーボード (2015年製 H170M-PLUS)のオンボードのグラフィック機能でも普通に描画できていたので、すごく古いPCでなければ動作するのではないかと思っています。 (2011年発売のThinkPad X220上のDebianではダメでした……。)
Webアプリケーションのための言語であるElmからインスピレーションを受けているため、独自のThe Elm Architectureという考え方を踏襲しているそうです。
このアーキテクチャを勉強する必要こそありますが、クロスプラットフォームでどこでも軽快に動くGUI crateは、大変魅力的であります。
ここからは、導入のしやすさ、ウィジェットの充実度、軽快さ、クロスプラットフォームという切り口で、調べた内容を記述していきます。
それぞれの切り口で、個人的な評価を4段階 (Very Good、Good、Bad、Very Bad) でつけております。
導入のしやすさ: Very Good
別言語のGUIライブラリをバインディングしているわけではないため、Cargo.tomlにicedのcrate情報を書き込むだけで導入できます。
そのため、WindowsでもLinuxでも、特別なことをせずとも導入できます。 素晴らしいです。
ウィジェットの充実度: Good
まだまだ開発段階ではあるものの、基本的なウィジェットであるボタン、スライダー、チェックボックス、テキストボックスなどを使えます。
各ウィジェットのレイアウトもきれいに配置させることができます。 (Responsive Layout)
将来の開発ロードマップの中には、レイヤー、アニメーション、キャンバス、テキストやフォント関連、グリッドレイアウトやテキストレイアウトなどが含まれています。
軽快さ: Very Good
ウィンドウやウィジェットの動きの軽さを調べるため、サンプルコードの「tour」をビルドしました。
ウィンドウのサイズを大きくしたり、小さくしたり、スクロールさせたり、ボタンを連打したり、あんなことしたり、こんなことしても、激しい画面のくずれなどはなく、きちんと描画されていました。
「それ、普通では?」と思うかもしれませんが、他のGUI crateを触っていると、そうでもないものがあります。 (OrbTkとか……。たぶん、フレームバッファのサイズ変更か何かがおかしい。)
クロスプラットフォーム: Very Good
「クロスプラットフォーム」を謳っていても、環境によって動作に差があったりします。 また、動作は軽快でも、準備に手間のかかるライブラリもあります。(Gtkとか)
しかし、icedは導入も簡単な上、いくつかの環境で問題なく動作することを確認できましたし、言うことないです。
私の手元には、Windows 10、Debian Linux 10.3の環境がありますが、その両方でビルドと実行に成功し、軽快に動作をしました。
しかも、icedはWebにも対応しており、ネット上には「tour」のサンプルコードからビルドしたWebサイトが、誰にでも触れるように公開されています。 (「tour」のサンプルコードをビルドしたWebページへのリンク)
Macの環境では確認できていませんが、対応しているレンダラの中にあえて「Metal」の文字があるので、サポート対象であることはわかっています。
欠点
どうもVirtualBox上の仮想マシンはGPUをうまく使えないようで、ビルドこそ成功するものの、実行時にクラッシュしてしまうようです。
最初、私はVirtualBox上のDebian Linuxで挙動の確認を試みていました。 そこではicedのサンプルコードがクラッシュしてしまいました。 icedは内部でwgpuのcrateを使用しているのですが、どうもwgpuのサンプルコードを実行しても落ちてしまうのです。
エラーの内容としては、GPUの情報を取得できないようなことが書かれており、そこでVirtualBoxが原因であると気づきました。
VirtualBoxを使わずに、直にWindows 10やDebian Linuxをインストールしているマシンでは、問題なく動きました。
ですので、これはicedの欠点というか、VirtualBoxの欠点でもあります。
余談
昨年11月に、icedの開発者であるHéctor Ramón氏 (a.k.a. hecrj) はCryptWatch Teamに所属することになり、そして同チームがicedのスポンサーになったため、安定して開発に専念できるようになりました。 (ブログ記事)
GitHub上の活動を見ても、とても活発に開発が進められていることがわかるので、これからも期待できそうです。
また、GUI関連ライブラリを確認していると、不吉なエラーメッセージと共に終了するアプリを目にすることがあるのですが、icedのアプリはそういうことがなかったので、そういう点でも地味に好印象です。(笑)
まとめ
まだ開発中とはいえ、どこでもビルドが通り、軽快な動作を確認できました。
将来の展望も明るく、大変期待しています。
- 導入のしやすさ: Very Good
- ウィジェットの充実度: Good
- 軽快さ: Very Good (ただしVirtualBox上では動かず)
- クロスプラットフォーム: Very Good
Rust GUI界の期待の星、icedのご紹介でした。
『RustではじめるOpenGL』が商業出版で販売スタート
昨年、技術同人誌のためのイベント「技術書典7」にて頒布した『RustではじめるOpenGL』が、装いも新たに商業出版で販売開始することとなりました!
電子書籍版はすでにAmazonのKindleストアや、紀伊國屋書店のKinoppyなどで販売しており、紙版の本も2月26日からAmazonで販売されます。
販売しているショップに関しては、こちらのリンクをご確認ください。
紙版の書籍については、プリントオンデマンドによる出版のため、オンラインショップからの注文を受けてから印刷し、すぐに発送するような体制になっています。
書籍の内容
プログラミング言語のRustには、OpenGLの3Dプログラミングに向いている特徴がいくつかあります。
- C/C++にも負けない処理速度を出せるプログラムで、フレームレートを60 FPSで描画させることができる
- ガベージコレクションがないので、画面がカクつくことがない
- モダンな言語なので、新しいライブラリの導入が容易
このような利点から、最近ではRustによるゲーム開発も活発に行われるようになり、「Rust Game Development Working Group」では月次のレポートが発表されたりと、賑わいをみせています。
以前、作成した同人誌版では、OpenGLの最も基本的なところから実装をスタートさせ、徐々に機能を追加していくことで、段階的にステップアップしながら学べるようなスタイルの書籍を目指しました。
今回の書籍では、同人誌版の分かりづらかったところにイラストを追加したり、説明の改善をしたほかに、新たに第7章でフレームバッファーオブジェクト(FBO)についての記事を加えました。
画面に直接3Dオブジェクトを描画するのではなく、いったんFBOに描画し、そこにGLSLのシェーダーを適用することで、様々なエフェクトをかけることができるようになります。 これによって、表現方法に幅が生まれ、画面の雰囲気が格段に良くなるでしょう。
書籍の目次
書籍のより詳しい目次をここに記します。
- ギャラリー
- はじめに
- 商業出版に寄せて
- 想定読者
- 使用するライブラリーとプラットフォーム
- ソースコードのダウンロード
免責事項
第 1 章 開発環境の準備
第 2 章 SDL
第 3 章 OpenGL
第 4 章 Dear ImGui
- 4.1 準備
- 4.2 プログラムの作成
- 4.2.1 初期化
- 4.2.2 イベント処理
- 4.2.3 ウィンドウの作成
- 4.2.4 ウィジェットの生成
- 4.3 プログラムの完成
- 4.4 効果的な使い方
第 5 章 3D オブジェクト
第 6 章 テクスチャー
- 6.1 準備
- 6.2 プログラムの作成
- 6.2.1 ソースコードの全体
- 6.2.2 テクスチャーの準備
- 6.2.3 頂点座標、法線ベクトル、テクスチャー座標
- 6.2.4 テクスチャーと照明を追加したシェーダー
- 6.2.5 ユニフォーム変数
- 6.2.6 テクスチャーの描画
- 6.3 プログラムの完成
- 6.4 光の効果
第 7 章 フレームバッファーオブジェクト
おわりに
まとめ
もしRustでOpenGLプログラミングを始めたい方がいらしたら、参考書の一つとして選んでいただけたらと思います!
謝辞
このたびは商業出版するにあたって、声をかけていただいたインプレスR&Dの山城 敬 編集長、イラストレーターのはこしろさん、直接関わることはありませんでしたが、タイトルデザイン、校正、編集に協力してくださった方々に感謝いたします。
特に、はこしろさんには、表紙のわがままを聞いてくださり、苦労をおかけしました。 はこしろさんからいただいた白い箱は、とても気に入っております!
そして、さらにタイトルデザインのデザイナーさんに良いフォントを選んでいただいたおかげで、表紙に魔法がかかったように思いました。ありがとうございました!
Rustで使いまわしの良いactix-web製HTTPサーバモジュールの基礎を作る
目的
必要にかられてRustでHTTPサーバを実装することになりました。
HTTPサーバは何かと使い勝手が良く、今後も気軽に立てたくなることがあるはずなので、ここで一つすごくシンプルなHTTPサーバのモジュールを書いてみました。
せっかくなのでRustが誇る高速なHTTPサーバであるactix-webを使い、startとstopのインターフェイスを持たせました。
正直言うと、actix-webのexamplesのレポジトリにはとても参考になるソースコードがたくさんあるので、私もそれを使って実装しています。皆さんもactix-webを使うときには、このレポジトリを参考にしたら良いと思います。
ただ、GoogleでHTTPサーバを調べたときに、もっとお手軽なソースコードがヒットしてもよかろう、という気持ちがあり、この記事を書くことにしました。
使用したRustのバージョンは、1.40。
ソースコード
Cargo.toml
dependenciesのところだけ抜粋しています。 actix-webと、そのランタイムを扱うactix-rtを使いました。
[dependencies] actix-web = "2.0.0" actix-rt = "1.0.0"
http_server.rs
使っている構造体などがどのcrate由来のものなのかわかるように、あえてuseを使わずに書いています。
エラーハンドリングはほとんどunwrap()しています。
pub struct HTTPServer { server: Option<actix_web::dev::Server>, } impl HTTPServer { pub fn new() -> HTTPServer { HTTPServer { server: None } } pub fn start(&mut self) { self.stop(); let (tx, rx) = std::sync::mpsc::channel(); std::thread::spawn(move || { let mut system = actix_rt::System::new("start_server"); let server = actix_web::HttpServer::new(|| { actix_web::App::new() .service( actix_web::web::resource("/ok").to(|req: actix_web::HttpRequest| { println!("{:?}", req); actix_web::HttpResponse::Ok().body("ok") }), ) .service( actix_web::web::resource("/ng").to(|req: actix_web::HttpRequest| { println!("{:?}", req); actix_web::HttpResponse::Ok().body("ng") }), ) }) .bind("0.0.0.0:8888") .unwrap() .run(); tx.send(server.clone()).unwrap(); system.block_on(server).unwrap(); }); self.server = Some(rx.recv().unwrap()); } pub fn stop(&mut self) { if let Some(server) = &self.server { let mut system = actix_rt::System::new("stop_server"); system.block_on(server.stop(true)); } self.server = None; } }
main.rs
mod http_server; fn main() { let mut server = http_server::HTTPServer::new(); server.start(); std::thread::sleep(std::time::Duration::from_secs(10)); server.stop(); }
解説
HTTPServerをstart()させるときには、裏で勝手に動き出してほしいので、別スレッドでactix-webのHTTPサーバを起動させています。
actix_web::HttpServer::new()などでインスタンスを作成できますが、サーバを止めたいときには再びこのインスタンスを使う必要があります。
そのため、HTTPServer構造体の中に保存できるようにします。OptionでServerを包み、HTTPServer構造体をnew()したときには中身がNone、start()したらインスタンスを入れられるようにしました。
pub struct HTTPServer { server: Option<actix_web::dev::Server>, }
ここで問題になるのが、スレッド内で作ってしまったインスタンスをどうやってメンバ変数self.serverに入れるのかです。
今回は、std::sync::mpsc::channel()を使って、スレッドの中から外へのチャンネルを作成しています。 この抜け道を辿って、サーバのインスタンスをスレッドの外へ逃し、HTTPServer構造体のメンバ変数として保存しています。 (The Bookのこちらの記事が参考になります。)
また、今回のHTTPServerを実装する上で、呼び出す側が「asyncを付けなきゃいけない」ということを意識させたくない作りにしたかったので、awaitは使わず、system.block_on(server)しています。
main.rsでは10秒間だけ動くHTTPServerを実装しています。
受け付けるHTTPリクエストのパスは「/ok」「/ng」だけ実装しました。 ここは、その時々に応じて修正しましょう。 呼ばれるパスごとに関数を用意したり、テンプレートエンジンを使うのも良いでしょう。
まとめ
これを使いまわせば、スムーズにHTTPサーバが作れます。
もう少し複雑なことでも、actix-webのexamplesのレポジトリにはとても参考になるソースコードがたくさんあるので、このレポジトリを参考にすると良いです。
Rust GUI crateの調査
私はRustでOpenGLを使った3Dプログラミングの実装を行っています。
それと関連して、RustでGUI系のcrateを利用して、その使い心地を調べるようなことをよくしています。
ここにその調査結果を少しずつ残して、どのcrateが目的に合っているのか記述していきたいと思います。
ちなみに、私の観点で大切にしたいことは、軽快に動く、導入が楽、ウィジェットが充実、クロスプラットフォームだったら申し分ない、といったところです。
(ちょっとずつ書いていくので、お楽しみに!)
仕組みを学べるシンプルなターミナルエミュレータ「eduterm」
私たちがよく使用するターミナル。
毎日使っているはずなのに、あまりその仕組みを知らない方も多いはず。
先日、私も思い立ってxtermのソースコードを読んでみようしたら、C言語のifdefの嵐に圧倒され、途中で中断してしまいました。
xtermは様々なプラットフォームで動作することを期待されているので、ifdefでたくさんの場合分けをしており、思いのほか読みづらいのです。
もっとシンプルなターミナルはないものかと、インターネットをさまよっていたところ、ちょうどよいターミナルを発見しました。
それが、この「eduterm」です。
edutermのソースコードは、たった1つのソースコードeduterm.cに書かれており、448行しかありません。 しかも、たくさんのコメントを残してくれていて、とても親切なソースコードです。
コンパイルして実行すると、Xウィンドウシステムをサポートしており、ウィンドウが立ち上がります。 (ウィンドウの処理も、ターミナルとしての処理も、そしてコメントもたくさん入っているのに、この程度の行数で済んでいることに驚きです。)
ターミナルは内部で擬似端末を用意し、シェルを起動して、入力を待ち受けるようになります。
「ls」とコマンドすれば、その返答が返ってきます。
ただし、「vi」とコマンドしようものなら、わけのわからないエスケープシーケンスがたくさん表示されてしまいます。
viはlsと違って、出力に複雑なことをしています。 viは画面上の適切な位置に、文字やカーソルを表示しなければいけないため、「VT100」というプロトコルを使っています。 そして、edutermはVT100のエスケープシーケンスをサポートしていないのです。
正直、このままでは普段使いのターミナルになることはないでしょう。
しかし、ターミナルの基本的な動きを学習するには、最適なソースコードなのです。
edutermを紹介している作者のブログ記事がこちらにあるので、興味のある方は合わせて読んでおくとよいかもしれません。
「出来の悪い子ほどかわいい」とよく言いますが、このターミナルをベースにして少しずつ鍛え上げていき、VT100の機能を追加し、フォントを変えたり、色を変えたりして、自分たちのターミナルを作ってみるのも楽しいですね!