忍者ブログ

Memeplexes

プログラミング、3DCGとその他いろいろについて

[Windows® API Code Pack for Microsoft® .NET Framework] C#でDirectX11をつかう その2 背景のクリア

前回作った雛形にコードを追加していきます。 

今回はDirect3Dのデバイスを作成して
ウィンドウの背景をクリアします。


using Microsoft.WindowsAPICodePack.DirectX.Direct3D11;
using Microsoft.WindowsAPICodePack.DirectX.Graphics;

class Program
{
    static void Main()
    {
        using (Game game = new Game())
        {
            game.Run();
        }
    }
}

class Game : System.Windows.Forms.Form
{
    SwapChain swapChain;
    DeviceContext deviceContext;
    RenderTargetView renderTargetView;

    public void Run()
    {
        initDevice();
        Show();

        while (Created)
        {
            Draw();
            System.Windows.Forms.Application.DoEvents();
        }
    }

    private void Draw()
    {
        deviceContext.ClearRenderTargetView(renderTargetView, new ColorRgba(0, 0, 1, 1));
        swapChain.Present(0, PresentOptions.None);
    }

    private void initDevice()
    {
        D3DDevice device = D3DDevice.CreateDeviceAndSwapChain(this.Handle);
        this.swapChain = device.SwapChain;
        this.deviceContext = device.ImmediateContext;

        using (Texture2D texture2D = swapChain.GetBuffer<Texture2D>(0))
        {
            this.renderTargetView = device.CreateRenderTargetView(texture2D);
            this.deviceContext.OM.RenderTargets = new OutputMergerRenderTargets(new[] { renderTargetView });
        }
    }
}
 これは背景を青でクリアしています。

directX11TutorialClearRenderTarget.jpg

最初にDirect3Dに関連したオブジェクトを初期化し
それを使ってwhileループの中で
延々と背景を青にクリアし続けています。

大まかに説明すると
こうなります:
クラス名 説明 XNAで言うと
SwapChain
 
 
 
これはダブルバッファリングを行うための2つのバッファを持っています。
 
(片方が描画対象、もう片方はディスプレイに表示されるバッファ)
 
この2つのバッファは、描画が終わって実際にディスプレイに表示するときに
 
役割が交代(スワップ)します
GraphicsDeviceがこれの機能を持っています
DeviceContext
描画を行うオブジェクトです。
これを使ってポリゴンとかいろいろなものを描画します。
GraphicsDeviceがこれに近いです。
RenderTargetView 描画する対象です。 RenderTarget2Dでしょうか

これら3つのオブジェクトを手に入れるためにD3DDeviceをつくっています。
SwapChainとIntermediateContextプロパティを通じて2つのオブジェクトを手に入れています。

「プロパティがあるんだからわざわざ2つもメンバ変数にしなくていいじゃない?
必要に応じてプロパティにアクセスすればメンバ変数は一つ減らせるし」
、と思われるかもしれません。

が、Windows API Code Packのソースを読めばわかりますが、
実はこのプロパティは内部で新たに生成して返しています。
今後実装が変わる可能性もありますが、ここでは念のためメンバ変数として確保しておきます。


エラーが起きる場合

64bit OSを使っている場合、
Windows API Code Packに含まれるx64のアセンブリを使いたくなるかもしれません。

しかしx86ではなくそっちを使うと、
BadImageFormatExceptionがスローされると思います。

しかしx86のアセンブリに切り替えて実行すると
今度はFileLoadExceptionがスローされるかもしれません。
にっちもさっちもいきません。
この原因は、アセンブリのランタイムバージョンが2.0だからです。

これはプロジェクトに.configファイルを次のように作れば解決します。
要はランタイムのバージョンが2.0であるアセンブリを使うことを示してやれば良いのです。

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0"/>
  </startup>
</configuration>



 

拍手[1回]

PR

[Windows® API Code Pack for Microsoft® .NET Framework] C#でDirectX11をつかう その1 下準備

(対象読者は「XNAが使えるけどDirectXはちょっとめんどくさいなぁ」と感じている人を想定しています)

XNAではDirectX11世代の技術は使えない

簡単に3Dゲームを作れるXNAですが、
限界もあります。

XNAはDirectX9世代ですが、
現在DirectXの最新世代は11なのです。
つまりXNAでは最新技術を使えません

ではXNAがDirectX11以上に将来対応するかというと、
おそらくいつかはするのでしょうが、
Xbox360との兼ね合いですぐには難しいでしょう。

MicrosoftとしてはXNAで作ったゲームはXbox360
で動いて欲しいはずですが、
肝心のXbox360がDirectX9固定です。
XNAが11に対応してしまえば、XNAで作ったゲームが
Xbox360で動かせないケースが出てくるはずです。

ですから、XNAが11移行に対応するとすれば
それはXbox360の次の世代のゲーム機が発売された時だと思われます。
しかし残念なことにそれは、まだまだ先のことのようです。



Windows API Code Pack for Microsoft .NET Framework

つまりC#で最新技術に追いつくのはやや面倒なことになっているのですが、
一方で救いもあります。
 Windows® API Code Pack for Microsoft® .NET Frameworkというものがあるのです。

ここでは最新APIの数々がC#で使えるようにラッパーが書かれています。
DirectX11もその中に含まれています。

C#でDirectX11が使えるわけです

しかし見たところすべての機能がラップされているわけではありません。
たとえばMatrix4x4Fにファクトリメソッドは一つもありません
XNAの豊富なメソッド群と比べるとまだまだ貧相です。
今すぐ使うのはまだ難しいけれど、将来に期待といったところでしょうか。
ただ動作を確認するだけなら今でもできるはずです。

使ってみましょう。


Windows API Code Pack for Microsoft .NET Frameworkのインストール

インストールはここ

Windows API Code Pack v1.1 (Binaries, Source Docs)

というリンクをクリックします。
現在バージョンは1.1で、2010年9月のもののようです。

クリックすると

Windows API Code Pack Self Extractor.exe

というファイルがダウンロードされますので、実行します。
すると同じディレクトリに

Windows API Code Pack 1.1.zip

というファイルが展開されます。
この中に.netのアセンブリが含まれています。
Visual StudioのProjectフォルダかどこかに移動して展開しましょう。


出来たフォルダの中を見ると、

binaries > DirectX > x86

にDirectXのラッパーアセンブリがあります。

Visual C#のプロジェクトを作ってこれを参照追加してみましょう。


コードの雛形

いきなりDirectXを使ってみるというのは
その複雑さから言って無謀です!

順序良く行きましょう。
シンプルなものから少しずつ発展させていくのです。

まずはWindows Formsを使って
ウィンドウを表示します。

Program.cs

class Program
{
    static void Main()
    {
        using (Game game = new Game())
        {
            game.Run();
        }
    }
}

class Game : System.Windows.Forms.Form
{
    public void Run()
    {
        Show();

        while (Created)
        {
            System.Windows.Forms.Application.DoEvents();
        }
    }
}



このコードはウィンドウを一つ表示します。

directX11TutorialCreateWindow.jpg

Application.Run()ではなくwhileループを使っているのは
そのほうが後に書くことになるプログラムの構造に近いからです。

ちなみにどことなくクラス名メソッド名などが
XNAに似ているのはわざとです。

今後もこの調子で
続けていきます。




拍手[1回]