QtOpenGLモジュール使ってOpenGL

QtのQtOpenGLモジュールを使ってみました。
何故かあんまり日本語情報無いのね。
おかげでサンプルの謎な部分が何やってるのか検索かけてもさっぱり出てこない。
みんな違うの使ってるのだろうか。
当面はソースとにらめっこすることになったりするかもしれない。


とりあえず今の所分かった必須呪文たち。

/* main.cpp */
#include "InheritQGLW.h"

int main(int argc, char *argv[]){
    QApplication app(argc, argv);
    if(!QGLFormat::hasOpenGL()){
        /* OpenGLがサポートされていない時 */
        return 1;
    }
    InheritQGLW iqglw;
    iqglw.setWindowTitle(QObject::tr("InheritQGLWidget"));
    iqglw.resize(300,300);
    iqglw.show();

    return app.exec();
}
/* InheritQGLW.h */
#include <QtOpenGL>

class InheritQGLW : public QGLWidget 
{
    Q_OBJECT
public:
    InheritQGLW(QWidget *parent = NULL)
        : QGLWidget(parent)
    {
        /*
         * OpenGLのディスプレイコンテキストを指定とか、プライベート変数の初期化とかしてるらしい。
         * QGLWidgetを継承したクラスのインスタンスを複数表示するときに困らないための呪文。
         */
        this->setFormat(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer));
    }

protected:
    // インスタンス生成後、初めてpaintGL()が呼ばれる時にpaintGL()より先に呼ばれる。以降呼ばれない。
    void initializeGL()
    {
        glClearColor(0.5, 0.5, 0.5, 1.0);
    }

    // ウィジェットサイズが変更された時に呼ばれる。中に何書けばいいかはまだちゃんと理解していない。
    void resizeGL(int width, int height)
    {
        glViewport(0, 0, width, height);
    }

    // 描画メソッド。ここで描画する。
    void paintGL(){
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    }
};


なお、initializeGL() , resizeGL() , paintGL() はQGLWidgetでvirtual付けて定義されているメソッドをオーバーライドしている形になる。
オーバーライド必須というか、普通に作れば3つとも必要になる。
また、上記3メソッドがQt側で呼ばれた流れ以外でOpenGLの関数を呼ぶ場合、OpenGLの関数より先にmakeCurrent()メソッドを呼ばないと意図しない所に描画してしまう可能性がある。

C/C++修行(4日目)

最近PerlとかPHPとかjsとかLLばっかりだったので、最近基本に戻ってC/C++で修行中。
といっても細かいアルゴリズムの確認しながら何か適当に組むっていう程度。


しかしLLから久しぶりに戻ってくるとエラーの宝庫みたいなコードを書いてしまう。
おまけに流れがダメダメ。
LLならコードの最適化とか考えなくてもコンパクトにまとまったけど、Cとかでそれをやるとカオスになってしまう。
まぁ、元々Cとかでみっちり鍛えてたわけじゃないので当然っちゃ当然なんですが。


今後の事も考えると、Cで一発目に書いたコードでせめて30〜50行に1バグくらいに抑えられるようにしたい。
いまは5行に1バグくらいの勢い。
もちろんコンパイルエラー含めて。
同時にコンパクトなコード書けるようになりたい。


2〜3ヶ月反省しながらコード書きつづければ上記目標に到達できるんだろうか。
コンパクト化は頭の出来次第だからもう少しかかるか。

Qt4:QStringをchar*にする方法と日本語を使えるようにする方法

#include <iostream>
#include <QString>
#include <QTextCodec>

int main(int argc, char *argv[]){
    // utf-8な文字列をQStringが受け付けるようにする。
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf-8"));
    // utf-8な文字列をtr()が受け付けるようにする。
    QTextCodec::setCodecForTr(QTextCodec::codecFotName("utf-8"));

    QString str("QStringな文字列オブジェクトです。");
    
    // 文字コードを指定して出力。
    std::cout << str.toUtf8().data() << std::endl;
    // システムで設定されているロケールで出力されるはずのコード。うまく動かない。
    std::cout << str.toLocal8Bit().data() << std::endl;

    return 0;

とりあえず文字コードがさっぱり予想つかない状況で何か作る事は当面無いだろうから、文字コード決め打ちでしばらくはやっていくます。

gcc/g++でのライブラリの指定の仕方

参考:ƒ‰ƒCƒuƒ‰ƒŠ‚ÌŠî‘b’mŽ¯
-lオプションは、

  1. libfoo.so
  2. libfoo.a

の順にライブラリを探してリンクする。


-Lオプションは、リンク時に一時的にライブラリディレクトリのパスを一覧の先頭に追加する。


強制的にスタティックライブラリを使用する場合は以下のようにする。
$ gcc foo.c -o foo /usr/lib/libbar.a

Windowsでシンボリックリンク張るユーティリティ作ってみた

単にコマンドライン引数取ってWin32APIのCreateSymbolicLinkに投げただけ。
DOS窓以外から使う事にこだわらなければDOSにmklinkって内蔵コマンドがあるからそれを使うとお手軽気楽。
なお、OSの都合上Vista以降じゃないとシンボリックリンクは作れません。
さらに管理者権限で動かさないとシンボリックリンクは作れません。
色々面倒です。


シンボリックリンク作成コマンドの自作が面倒な人は以下のリンクからどうぞ。
http://www.oborogin.org/ar/mklnk.zip
ライセンスについてはこちら *1
使い方は同封したテキストファイルにも書いたけどこっちにも書いておきます。


DOS窓PowerShellなどから使うことを想定して作成しています。
パスの通った所に適当に配置し、mklnk リンク対象タイプ -o 出力シンボリックリンクパス -l リンク先パス と管理者権限で起動したシェルに入力します。
パスの指定は絶対パスです。
リンク対象タイプと書いてある部分には -f か -d を指定します。
リンク対象がファイルの場合は -f を、ディレクトリの場合は -d を指定します。


なお、PowerShellから使う場合は以下のようなスクリプトを挟むとさらに手間が減ります。

param([string]$link, [string]$output, [switch]$help)

if(-not($link -and $output) -or $help){
	"オプション:
  -help  ヘルプを表示
usage:
  ln -link <String> -output <String>"
}else{
	# 対象がディレクトリかファイルか判別
	$target = Get-Item $link
	if($target.GetType().Name -eq "DirectoryInfo"){
		# シンボリックリンクの対象がディレクトリ
		$parameters = "-d -l $link -o $output"
	}else{
		# シンボリックリンクの対象がファイル
		$parameters = "-f -l $link -o $output"
	}
	$shell = New-Object -com Shell.Application
	$shell.ShellExecute("mklnk", "$parameters", "", "runas")
}

mklnkではシンボリックリンクの対象がファイルなのかディレクトリなのか手動で設定し、管理者権限で動かす必要がありました。
このPowerShellスクリプトではそこを自動化して手間を減らしています。

*1:要するにudukiが著作権持ってるファイルは好きにしていいという内容のライセンス

VS2008での64bitネイティブバイナリ作成用の設定

  1. プロジェクトのプロパティ設定ダイアログを開き構成マネージャを開く。
  2. ドロップダウンではないリスト表示になっている所の64bit設定したいプロジェクト行のプラットフォーム列の項目をクリック。
  3. 新規作成を選択。
  4. x64に設定。各種設定をwin32からコピーするよう設定。
  5. 64bit開発用の設定終わり。コンパイル時にどこからともなく_WIN64プリプロセッサ定数が設定される。


WIN32定数が残ってるけど無視してOK。
気になるならWIN64にでも変更する。


各種定数参考:http://msdn.microsoft.com/ja-jp/library/b0084kay.aspx

warning! warning!! warning!!!

VCFをそのまま日本語版VisualStudioでビルドすると色々warningが出ます。
エラーは出ないのでビルドには失敗はしません。
なお、ここで出るwarningのうち、

  • FoundationKit.h
  • GraphicsKit.h
  • Control.h
  • StringUtil.h

のヘッダファイルで出る文字コード関連のwarning C4819は、後々普通にVCFを使ったアプリをビルドする時にも出てくるので先に修正をしてしまいます。


まずC4819のwarningが出たヘッダファイルの文字コードを、cp1252からcp932又はUCS2(Little endian)に変換します。
変換したらVCFをリビルドしてみます。
C4819のwarningが消えてれば完了です。おつかれさまでした。
修正するヘッダファイルは上に上げた4つ(だったと思った)なので、手動でファイルを一つ一つ指定して文字コードを変換していっても問題ないです。楽勝です。


まぁ別にC4819のwarningが出ているのは全部コメント部分なので、文字コードの変換が面倒な場合は直さなくてもそんなに大きな問題は無いです。
あるとしたらビルドに時間が掛かることくらいでしょうか。