QtとC++でモダンなOpenGLプログラムを書いてみる

shaderを基本としたモッダーンなOpenGLプログラムをQtとC++で書こうって話。Qt5.9を使ってますが5.7あたりでもいけるんじゃないでしょうか。compute shaderがサポートされたのは5.9からのような気もしますが、別にQOpenGLFunctions_4_3_Coreとか使えばそれ以前からも使えないことはない…まあ、そのへんはいいか。

QtでOpenGLを使うと良い点と言えば、とりあえず色んな環境で動くようにコンパイルできることとか、ウィンドウ操作周りやらマウス入力系等をQt一式に任せられるとか、おなじみsignal/slotでのコードが書けるとか、まあ色々ありますが、個人的にQt大好きっ子ですので「かっこいい」が一番ですかねえ。
と言うことで、QtっぽくOpenGLのコードを書くぜーと言う感じでGo。

続きを読む

Qt5.5開発環境をWindows10にぶちこむよ

前置きはいりません、はいぶち込みましょう。

コンパイラはVS2013Expressにします。2015はいけるんでしょうか。分かりません。

Qtぶちこみます。VS2013の32/64bit版でいきましょうか。

QtCreator立ち上がるぜ。

早速サンプルをコンパイル。簡単なものですねえ…。

以上。簡単ですねえ。

「お前それkubuntuでも同じこと言えんの?」

 って言うAAを思いつきました。まあどうでもいいですね。

 OSのアップグレードを即やるなんてモグリですよ多少あらが出きってからアップデートするのが通でしょ推奨されてますし。と、俺も思うのですけど、なら何故しつこくなんども「新しいディストリビューションアップデートが利用できます押せ」と定期的に通知されるんですかやめてくださいよ押しちゃうでしょう。
 と言うわけで。押しました。
 
 で、kubuntuの13.04のアップグレードのお話をするわけですが、俺はひねくれておりますゆえ以下のような前提があることは留意していただきたい。
 まず、ATOKX3ユーザでございます。
 そして、Qt大好きっ子でございます。
 以前のバージョンでもKDEのアップデートはちゃんとしていたので最新KDEの乗った12.10からのアップグレードです。
 ではどうぞ。
 
 今回のアップデートは普通のubuntuだとちょっと速くなったくらいの差だそうです。まあ、使ってないのでそのへんはわかりませんが、kubuntuの場合さり気なく大きな違いが出てきております。
 それは何か。簡単な話です。Qt5がまざっとります。
 
 Qt5が混ざること自体は大した問題じゃない、ぶっちゃけどこに混ざったのかもよくわかんないかもしれないし気にならない人には全くどうでもいいことに思えるかもしれませんが、先に上げた「前提」を見て頂ければ簡単な話ではないと言うのはなんとなく想像つくかと。
 具体的に言いますと、Qt5でどうやってATOKX3で入力するんでしょう?と言うお話です。結論から言ってしまうと、俺はibus-mozcへ渋々移行することとなりました。
 
 実はアップグレードする前からQt5向け開発環境の整備を渋ってたのも理由はこれだったんですよねえ。まあ、来るべき時が来ちゃったのかなあと受け入れることにしますが、もしもそれでもATOKを使いたいのであればQt5のみibusを使うかたちにしてgtkとQt4はiiimとximでーって方法も、できなくはないですねえ。/usr/share/im-config/data/あたりのファイルをごにょごにょ・・・。
 で、このQt4/Qt5の壁にぶちあたるアプリケーションはなんだ!って話なんですが、ぶっちゃけますとqtcreatorです。やべえ俺的にchromeに継いで使うアプリケーションじゃないですか。因みにchromeは主に可愛い眼鏡の女の子のイラストを見るのに使われていますとかそんなことはどうでもよろしい。
 
 まあ、Qt5とQt4ってぶっちゃけそんな大幅なコード修正を強いられることも無く移行できる感じで、過去にあったQt3→Qt4の思い出すだけで血の涙が出そうな感覚とは随分違います。このへんは皆様誤解しないで頂きたいところです。対応するプラットフォームも増えましたし、Qt4からQt5に移行するのは全く問題ない、むしろ推奨されるべきところかとも思うのですが、やはり混在となると色々問題がねえ。そしてこのバージョンのkubuntuは、ちょっとばかし混在しとります。まあQt4向けのqtcreatorをコンパイルして突っ込むってのもありなんですけどね。
 ただまあ、Qt5でximが使えるように整えられるかどうかはわかんないし、正直整える方向が正しいのかどうかも俺にはちょっとわかんないですねえ。まあどっちにせよ、iiimqcfもありませんからQt5でATOKX3使った入力は諦める方向になりますねえ。
 
 で、それはおいといて。
 
 kubuntuのページを見ていただくとドヤ顔で「新しいスクリーンマネジメントツールだぜヒャッハー!」と紹介されているツールがありますが、すいませんapt-get remove kscreenとかさせて頂きました。理由は今までのディスプレイ設定で調整してあるデュアルモニタ構成を起動時に毎回キレイに上書きして下さるからです。ぱっと見とてもわかりやすいツールに見えますが、何故既にあるものを作りなおしたのかは俺にもまあよく分からないところですねえ。とりあえず余計なことされるのは困っちゃう。
 
 もうひとつ。
 これはkubuntuのアップグレードでってことではないのですが、スクリーンロックがどうやっても無効化できないって謎の問題を抱えているような気がしますねえ。正直KDEのコントロールセンターの配置って物凄くわかりにくいところがあるんですが、例えばスクリーンロックやスクリーンセイバーに関する設定って「ディスプレイとモニタ」以下にあったりする(以前はまた別のとこにあった気がするなあ)わけですけど、こことは別に電源管理のところにもロックに関する項目があります。前者は単に一定時間触らなかったときのソフトウエア的?な設定かと思うのですが、後者に関しては例えば電源状態に合わせて一定時間触らなかった時の設定ってのができる・・・・ってわけわからんでしょもうw。
 で、この後者のほうがどうも設定反映されないところがあるような感じですかねえ。On AC Power時のタイムアウト時間を無効にしても開きなおすとやっぱり元にもどってる。powermanagementprofilesrcあたりに記録されるんだろうなあと見てみてもどうも残っていなかったり。
 電源管理の方はActivity SettingsでUse separate settingsを選んでチェックを外していけば一応無理やりロックかかるのは外せるみたいな感じですねえ。この辺、謎です。まあ、設定が反映されないのはバグなのかなあ。ちょっと探ってみたいところ。
 
 あとちょっと気になった点としては、果たしてibusをremoveしたい人がいるかどうかは別として、ibus消そうとするとkde-l10n-jaも消しにかかるのはちょっと驚いた。いやまあ、組み合わせとしては大多数が使うんでしょうけどさあ・・・。
 
 まとめます。
 
 えっと、今までのkubuntuですんなりすべてがスムーズに進んだことがありましたか?と言う前提でお話しますと、今回も今までと変わりません。以前までを上出来とするならば今回も上出来。
 kubuntuのいいところはubuntuの便利さの上でそれなりに最新のKDEをぶん回すことができると言う点だと思うのです。とはいえ、もちろんkubuntuにしかない実装もちょろちょろあるわけですし(muonとかもそうですねえ)完全な生KDEではありませんがそれらがとにかく使えるように整備されているってところは相変わらず素敵。KDEのアップデートも比較的簡単につっこめますしねえ。
 今回はTAMはATOKを諦めると言う悲しい選択にはなったのですが、正直これレアケースのような気がします。12.10をそんなにいじらずに使ってたならそのままアップグレードでいいんじゃないですかねえ、わかんないけど。
 まあ、もしもQt5が入ってきて過去のKDE4.0とかをフラッシュバックしちゃったりする人がいるなら、そのへんはATOKX3使ったりしてない限りは安心していいんではないでしょうかねえ。まあ、KDE5が出たらまたわかんないですけど、少なくとも自分で書いたQt4向けコードはほとんどが小さな修正でコンパイルできて動いてますからねー。楽観視しておりますよ。

KDE上でのQtのフォントおかしいよね

 おひさ。
 と言うわけでお題の通りでKDE上でのQtアプリケーション(KDEアプリケーションを除く、ね)のフォントってなんかちょっとおかしくね?を直すパッチ。ばっつりかいつまむよ。
 因みに対象はkubuntu 11.10、Qt-4.7.4でございます。
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -936,6 +936,7 @@
             // Override Qt font if KDE4 settings can be used
             if (X11->desktopVersion == 4) {
                 QSettings kdeSettings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
+                kdeSettings.setIniCodec("UTF-8");
                 fontDescription = kdeSettings.value(QLatin1String("font")).toString();
                 if (fontDescription.isEmpty()) {
                     // KDE stores fonts without quotes
 見ての通り1行です。お疲れ様でした。
 kubuntuならパッチ当ててlibqtgui4だけ入れ替えればいいかと思います。

QNetworkAccessManagerでtwitterに凸

ネットワーク上から何かしらデータを持ってくる作業と言うのは時々出てくるわけだ。twitterクライアントにしてもQOAuthでOAuthはパスできたにせよ、そのURLからデータを持ってこないとAPIアクセスはできないわけで。

と言うわけでさくっとwgetのような感じでURLからもってこいやあ!ってな実装。

  1. QNetworkAccessManagerを用意します。
  2. QNetworkAccessManager::finished(QNetworkReply*)と言うシグナルと適当なスロットをconnect。
  3. QNetworkRequestを作ってQNetworkAccessManager::get()を叩く。
  4. スロットでQNetworkReply*をあされ!。

以上。

やることはQNetworkRequestを作って読み込み開始してあとはシグナル待ちだけで済むって言う。シンプルやなー。素敵。

QNetworkReply::readAll()でもってきたデータをQByteArrayで拾えたりします。QNetworkRequestにQOAuthで作ったtwitterのAPIに渡すURLを指定してやればあっさりAPIにアクセスできるのよ。

んで拾ってきたXMLを解析してprofile_image_urlを同じようにQNetworkAccessManager経由で取得してやると、

あっさりアイコン付きに。

余談。

profile_image_urlの表示にQGraphicsWebViewを使ったらどうなるのかな?、とか思ってやってみたのだけど、普通に表示されました。が、rotateしたときに画像は回転しているものの枠が残っちゃうのよね。なのでQImageで取得した上でQGraphicsPixmapItemに。

QGraphicsItemはQObjectじゃないよなー、どうやってQImageのやりとりしよっかなーとか考えたり。アイコン一つ表示させるためにわざわざ取得用クラスを作ったり、地味に手間かかったやんよー。

「そもそもなんでお前はそんなに回したいんだ?」って感じですが、なんでだろう。でもなんかQGraphicsViewを折角使ってるんだし拡縮したり回したりしたいじゃんよ!。

QGraphicsViewでtwitterに凸

と言うわけで前にも言ったけどQOAuth使ってtwitterからXML取れてQDomDocument使ってtweetをクラスに放り込めたのであとはお好みのUI組み込むだけで俺仕様のtwitterクライアントのできあがりとなっちゃう。tweet自体をメモリに取り込んでるわけだからそこから検索するなりスコアリングするなり好きにできるのでもうつぶやきに埋もれて窒息することもないぜ!、とまではいかないけども。

で、UIの話。

普通にdesignerなんかでUI作ってもいいんだけど、折角ですからQGraphicsView使おうぜ!と言う方向でちと遊んでみる。

QGraphicsViewのいいところは通常のレイアウトを使ったWidgetの配置と違ってその自由度の高さってことになると思います。逆に言うと自由であるが故にぐちゃぐちゃにもなるって感じ。

線やテキストなんかをシーンに配置して、そのシーン(QGraphicsSceneかな)をQGraphicsViewに結びつけて表示、表示するオブジェクトに関してはQGraphicsItemと言う形でアクセスする、って感じなのですが、これがQWidgetも置くことができるわけで。アクセス方法がQGraphicsProxyWidgetってのになりますが。

ざっくりと表示例を上げると、

どーん。QLabelを使ったWidgetがscaleとrotateされてならんだりとか。

で、こいつらWidgetなので当然ボタンとかを配置して押すこともできたり。楽しいですよね。

ただ、回転なんかをかけ始めるとどうも動作が重く。そりゃそうだわなーと言う感じですが、assistantなんかを参照していただければ分かるのですが、QGLWidgetを使うこともできて、そっち使うと結構早いです。しかもQGraphicsView::setViewport()でQGLWidgetをnewして渡すだけ。

くるくる回したりズームさせたり。UI作りって楽しいですよねー。まあ、ほんと一歩間違えればぐっちゃぐちゃになるけどね!。

QDomDocumentでtwitterに凸

QDomDocumentのサンプルコードはQDomNode→QDomElementと変換してってコードになっとおけど、QDomElement::firstChild()じゃなくてもQDomElement::firstChildElement()なんて言うそのまんまの名前のものもあったりして。こりゃ使うっきゃない。どうしてもだらだらしがちだしね。

以前のQOAuth周りでゲットできたXMLをざざざーっと適当な構造体配列に突っ込む感じで。

ぶっちゃけOAuth経由でアクセスできて、XMLが取得さえできてしまえばあとは正直どうとでもなる。適当にメモリ上に格納できてしまえばあとは煮るなり焼くなり好きにした上でUIでもつけりゃtwitterクライアントのできあがり。まあ、投稿部分スルーしてるけどね。

以前上げたQOAuthのんと組み合わせれば簡単なコマンドライン型クライアントとかならさくっと作れるんじゃないでしょうか。俺は作りませんけどね。

しかしtwitterの吐くXML、status毎にuser情報持ってたりとかしていやに長い。できるだけ一回のアクセスで情報を流すって工夫だとは思うんだけど、RT元とRT自体の情報を1つのstatusが持ってたりとかするのね。いいのか悪いのかは分からんなあ。まあ取り込んで解析さえしてしまえば同じっちゃあそうだけど。

さて。

例によってかいつまむよー。ちょっとだらだら長いよー。

続きを読む