2010/05/05(水)Direct 3Dの初期化とか

適当に作ったformのpicturebox内部に描画するように作成
背景を適当に塗りつぶして、四角形(三角形×2)の描画

四角形の描画のため、頂点4つ分だけメモリ確保してます
もっと大きなものを書きたければそれだけメモリ確保する必要あり

namespace書いてないとか、this->を書いてあるとか丁寧に書いてます。
適当に省略してください。
あと、ブログに載せるとき一部編集してます(変数名とか)
直し忘れとかあったらごめんなさい

プロジェクトの設定

[プロジェクト] - [xxxのプロパティ Alt+F7]の共通プロパティの参照に

  • Microsoft.DirectX
  • Microsoft.DirectX.Direct3D

を追加

使う変数の定義

public ref class Form1 : public System::Windows::Forms::Form
{
private:
    Microsoft::DirectX::Direct3D::Device^ dxDevice;
    Microsoft::DirectX::Direct3D::PresentParameters^ dxPresentParameters;
    array<Microsoft::DirectX::Direct3D::CustomVertex::TransformedColoredTextured, 1>^ dxVertexs;
    Microsoft::DirectX::Direct3D::VertexBuffer^ dxVertexBuffer;
    System::Timers::Timer^ dxRefreshTimer;
}

上から、描画のためのデバイス、そのパラメータ、描画のための頂点座標配列、ビデオメモリ上のメモリバッファ、再描画のためのタイマー

コンストラクタ

Form1(void)
{
    InitializeComponent();
    InitializeDirectX(); // 追加
}

DirextXのための初期化ルーチンを呼び出すように追加。初期化ルーチンの内容は次。

初期化ルーチン

void InitializeDirectX(void)
{
    // パラメータ
    this->dxPresentParameters = gcnew Microsoft::DirectX::Direct3D::PresentParameters();
    this->dxPresentParameters->Windowed = true;
    this->dxPresentParameters->SwapEffect = Microsoft::DirectX::Direct3D::SwapEffect::Discard;
    this->dxPresentParameters->PresentationInterval = Microsoft::DirectX::Direct3D::PresentInterval::Immediate;

    // デバイスの作成
    this->dxDevice = gcnew Microsoft::DirectX::Direct3D::Device(0,
                     Microsoft::DirectX::Direct3D::DeviceType::Hardware, 
                     this->pictureBox1,  // 表示するコントロールまたはウィンドウを渡す
                     Microsoft::DirectX::Direct3D::CreateFlags::SoftwareVertexProcessing,
                     this->dxPresentParameters);
    this->dxDevice->RenderState->Lighting = false; // 光源なし

    // 描画用の頂点配列のメモリ確保
    this->dxVertexs= gcnew array<Microsoft::DirectX::Direct3D::CustomVertex::TransformedColoredTextured, 1>(4);
    this->dxVertexBuffer= gcnew Microsoft::DirectX::Direct3D::VertexBuffer(this->dxVertexs[0].GetType(), 
                       4,
                       this->dxDevice, 
                       Microsoft::DirectX::Direct3D::Usage::None, 
                       Microsoft::DirectX::Direct3D::VertexFormats::Normal,
                       Microsoft::DirectX::Direct3D::Pool::Managed);

    // 再描画用のタイマー設定
    this->dxRefreshTimer= gcnew System::Timers::Timer();
    this->dxRefreshTimer->Elapsed += gcnew System::Timers::ElapsedEventHandler(this, &Form1::RefreshTimer_Event);
    this->dxRefreshTimer->Interval = 1000.0 / 30.0; // 30[fps]
    this->dxRefreshTimer->Enabled = true;
}

強制的に再描画させるためにタイマーを設定

描画のためのルーチン

タイマーイベント用

System::Void RefreshTimer_Event(System::Object^ sender, System::Timers::ElapsedEventArgs^ e){
    this->pictureBox1_RePaint();
}

実際の再描画

System::Void pictureBox1_RePaint() {
    this->dxDevice->BeginScene(); // 描画開始
    this->dxDevice->Clear(Microsoft::DirectX::Direct3D::ClearFlags::Target,
                          System::Drawing::SystemColors::ActiveCaption, 1.0f, 0); // 一度画面を指定色でクリア
    this->drawBox(10.0, 10.0, 30.0+i, 30.0+i); // 四角形の描画
    this->dxDevice->EndScene();   // 描画終了

    try{
        this->dxDevice->Present(); // 画面に反映
    }catch(Microsoft::DirectX::Direct3D::DeviceLostException^ e){
        // 失敗 = デバイスが使えない状態
        // 今回は5秒後に再チャレンジ
        this->dxRefreshTimer->Interval = 5000; // 5[sec]

        // デバイスがリセットできる状態になったらリセット
        int result;
        if(!this->dxDevice->CheckCooperativeLevel(result)){
            if(result == (int)Microsoft::DirectX::Direct3D::ResultCode::DeviceNotReset){
                this->dxDevice->Reset(this->dxPresentParameters);
                this->dxRefreshTimer->Interval = 1000.0 / 15.0; // 15fpsに戻す
            }
        }
    }
}

描画補助(四角形の描画)

System::Void drawBox(float x, float y, float w, float h){

    // 頂点を指定する順番に注意(左上、右上、左下、右下)
    this->dxVertexs[0].X  = x;    this->dxVertexs[0].Y  = y;
    this->dxVertexs[0].Tu = 0;    this->dxVertexs[0].Tv = 0;
    this->dxVertexs[0].Z  = 0;    this->dxVertexs[0].Color = Color::Pink.ToArgb();
    this->dxVertexs[1].X  = x+w;  this->dxVertexs[1].Y  = y;
    this->dxVertexs[1].Tu = 1;    this->dxVertexs[1].Tv = 0;
    this->dxVertexs[1].Z  = 0;    this->dxVertexs[1].Color = Color::Pink.ToArgb();
    this->dxVertexs[2].X  = x;    this->dxVertexs[2].Y  = y+h;
    this->dxVertexs[2].Tu = 1;    this->dxVertexs[2].Tv = 1;
    this->dxVertexs[2].Z  = 0;    this->dxVertexs[2].Color = Color::AliceBlue.ToArgb();
    this->dxVertexs[3].X  = x+w;  this->dxVertexs[3].Y  = y+h;
    this->dxVertexs[3].Tu = 0;    this->dxVertexs[3].Tv = 1;
    this->dxVertexs[3].Z  = 0;    this->dxVertexs[3].Color = Color::AliceBlue.ToArgb();

    Microsoft::DirectX::GraphicsStream^ dxGraphicsStream = this->dxVertexBuffer->Lock(0, 0, Microsoft::DirectX::Direct3D::LockFlags::None);
    dxGraphicsStream->Write(this->dxVertexs); // 頂点座標をバッファに書き込み
    this->dxVertexBuffer->Unlock();

    this->dxDevice->SetStreamSource(0, this->dxVertexBuffer, 0);
    this->dxDevice->VertexFormat = Microsoft::DirectX::Direct3D::CustomVertex::TransformedColoredTextured::Format;
    this->dxDevice->DrawPrimitives(Microsoft::DirectX::Direct3D::PrimitiveType::TriangleStrip, 0, 2); // 描画
}

TriangleStripで三角形の描画を指定、それを2個描画することで四角形になる

参考

検索用

[DirectX] [Direct3D] [Visual Studio 2008] [.net] [cpp/cli] [c++]

2010/05/04(火)CPP/CLI + DirectX

辞書が欲しい
関数調べるのにわざわざネット繋ぐのだるい
世の中快適なブロードバンドばかりだと思うなー

それはいいとして、マネージコード上でDirectXを使うときの注意
普通に古い?DirectXのライブラリを使おうとするとローダー上でマネージコードを実行するなと怒られます

マネージ デバッグ アシスタント 'LoaderLock' では 'c:\Users\serika\Documents\Visual Studio 2008\Projects\MyDXApp\Debug\MyDXApp.exe' に問題を検出しました。
追加情報: DLL 'C:\Windows\assembly\GAC\Microsoft.DirectX.DirectDraw\1.0.2902.0__31bf3856ad364e35\Microsoft.DirectX.DirectDraw.dll' は、OS ローダー ロック内でマネージ実行を試行しています。DllMain またはイメージ初期化関数内でマネージ コードを実行しないでください。この動作は、アプリケーションをハングさせる原因になる可能性があります。

.NET開発者のためのDirectX連携手法の2ページ目によると、ライブラリが古いのが悪いらしい(汗

一応問題ないらしいので、[デバッグ] - [例外]の[Managed Debbuging Assistants] - [LorderLock]のチェックを外してしまえばよい模様

検索用

[Visual Studio 2008] [.net] [DirectX] [Direct Draw] [CPP] [CLI]

Alice in Wonderland

2010/05/01未分類

Alice in Wonderland
見てきました

有名な不思議の国のアリスのアフターストーリーの一つ

とても3Dしてました
目が悪いので眼鏡かけていたけど、ちゃんと3D眼鏡を上からかけられました
(微妙に違和感あったけど、そこまでひどくはないかな)

久しぶりに熱中して見られた気がします

ストーリーとかは別段新しいものでは無いと思う...
赤の女王を倒して白の女王を~って感じ

2010/04/30(金)キンモクセイ? ウスギモクセイ?

庭に育っているキンモクセイ
秋になると毎年いい香りがしています

キンモクセイは日本には雄株しか無いらしく、本来であれば実を付けないのですが...
なぜかこの冬に実を付けました
何が起きたんだ?とググってみると...

どうやら、キンモクセイに似たウスギモクセイというのが存在する模様
ウスギモクセイは雌株も日本に着ているので実を付けてもおかしくないようです

というわけで、実はうちの木はキンモクセイでは無かったのかもしれない事が判明
言われてみれば確かに、黄色ではなく、薄い感じがしたかもしれない
秋にまた花を咲かせるでしょうから、その時期になったら確認してみたいと思います

2010/04/18(日)yahoo BBの勧誘?

なんかよくわからない勧誘っぽい電話がありました

  1. 回線の案内
    相手「今のADSLよりも速い回線があるので乗り換えませんか?50Mの速度を保証します」
    私「保証!?それならすぐに乗り換えます。速度が出なかった場合の対処はどうなりますか?」
    相「上司に確認してみます」
    ...
    相「50Mの回線というだけで、保証はちょっと~」
  2. PCについて
    相手「最近のパソコンをお使いですよね。だいたい10年以内の」
    私「はい。7-8年前に組んだlinuxを使ってます」
    相「え?いなっくす?」
    私「いや、linuxですって」
    相「上司に...」
    ... INAXは確かに有名企業ですが、PCは扱ってないと思います
    相「大丈夫だそうです」
  3. 使い方、契約について
    相「モデムを送りますので、それを接続するだけです」
    私「作業はだれがするの?」
    相「それはお客様の方で~」
    ...まあ、それくらいなら
    相「1ヶ月無料期間がありますので、その間に決めてもらえればいいです。気に入らなければ電話一本で解約できます」
    私「無料期間中は、yahooとplalaと2重契約になるの?」
    相「できれば、plalaは解約してほしいのですが」
    私「yahoo気に入らなかったら、plala再契約になるだろうけど、そのときの再契約金は?」
    相「お客様持ちで~」
    ... yahoo気に入ったら解約してくれ。が正解だと思うのだけど?
  4. 書類とモデムの郵送について
    相「では、書類とモデムの郵送先について」
    私「いやいや、どんな料金プランになるのか、先に説明してくださいよ」
    相「今回のプランは12Mプランになりまして...」
    私「先ほど、50Mとか言ってなかった?12M契約で50M保証するって素晴らしいですね」
    相「え?あれ?おかしいですね...」

個人的にタイムリミットだったのでここで終了
もうちょっと勉強してから掛けなさいとお説教しておきましたw
こういう微妙な勧誘で、サポートが苦労するわけですね

2010/04/16(金)データの復旧

「デジカメのデータが消えてしまった。なんとか取り出せないか」
良くある話です

適当なデータ復旧ツール使えばいいかーと思いつついろいろ試すも意外と出てこない
パンドラもPC Inspectorもだめ
本気で消えてしまったのか?と思いつつ、れじゅーむちぇっかー使うと、なんかデータはありそう
でも、結局どのツールを使ってもダメでした

仕方ないので、linuxでメモリースティックを4GB分ダンプ
分割ツールで1GBずつに分けて、データの入っていそうな最初の1GBをバイナリエディタで確認
画像っぽいところを抜き出してみたら、データ発見
やっぱり入ってる、ということで、取り出し作業を続けることに

けど、結局ツールは当てにならないということで、ダンプしたデータからjpegデータを抜き出すプログラムを作成
チェックは面倒なので、SOIマーカをすべて列挙
実際はマーカではなく、単なるデータも混じってるのでSystem::Drawing::Bitmapで読み込めるかテスト
読めたらそこからjpegだと判断し、そこからEOIまでを抽出

これくらいのことやってくれるフリーソフトありそうなんだけど
見つかりませんでした
シェアウェアに手を出せばよかったのかなぁ...
でも買ってから使えませんでしたはイヤだし

ちなみに、読み出したデータの一部は、やはり壊れてました
でも、まるまる無くなるよりはいいよね

ハート・ロッカー

2010/03/20映画

爆弾解体技師のお話?

イラク戦争のドキュメンタリー的な感じ
死の恐怖というか、生と死の境目で何かが狂ってしまったような主人公でした

まあ、ネタバレとかそんなのはあまり無いかな
戦争の悲惨さとかを考えさせられるものでした