DirectX一覧

VisualStudio 2013をインストールしてみた

MSDNのほうではVisualStudio 2013がRTMになってダウンロード可能となったのでインストールしてみました。
今回はその記録です。

まず素のWindows7にインストールしようとしたら、セットアップできませんでした。
InternetExplorer10 を要求するようです。
DirectX SDKを使って開発している場合にはこれが少々問題になって、IE10インストール後はPiX for Windowsが使用できなくなるようです(詳しくはこちら)。
IE10のインストール後は、VisualStudio2012の付属のツールを使って調査して下さい、ということのようです。
・・・でもこれだとDirectX9が非対応のようで残念なのですが。時代的にもうDirectX9は積極的なサポートのほうは終了という意思の表れのように感じます。

ランタイムで気になった物のバージョンを調べてみました。

  • .NET Framework 4.5.1
  • VCランタイム 12.00.21005.1
  • Windows Kitsフォルダ内には 8.0 と 8.1 の両方のファイルが存在
    • d3dcompilerもそれぞれにあった。d3dcompiler_46/47.dll, d3dcsx_46/47.dll となっていて、これらは再配布可能フォルダにあった。

Windows8 RTMでは .NET Framework 4.5 だったのでわずかに上がってます。Windows7 SP1のころでは、.NET Frameworkは 3.5.1だったので、4がスキップされてますね。

続きを読む


DDSのRGB 10bitフォーマットの罠

今更といえば今更な話なのですが、あまり情報がないようにみえたのでここにメモしておきます。DDSフォーマットの A2R10G10B10 や A2B10G10R10 の並びの画像データについて罠というか、マイクロソフトも承知のバグが潜んでいました。具体的には、チャンネルのマスクビットが逆転しています・・・。

続きを読む


VRAMの使用量を取得するライブラリ

先日公開したVRAMの使用状況をグラフ化するツールで使用しているDLL部分について、ヘッダとライブラリの形式でまとめた物を公開します。
純粋にCインターフェースで作成しているため、C#からの呼出も割と楽に実現できます。
(通常のWin32APIの呼出手続きと同じように記述が可能です)

ダウンロード

VRAMSpaceLib ver 1.00 をダウンロード
VRAMSpaceLib ver 1.01 をダウンロード
VRAMSpaceLib ver 1.02 をダウンロード

コード使用例

以下のような感じで使います。

使ってみて動いたor動かない、改良案、感想などありましたらコメントでお願い致します。


Windows 8でXAudio2のトラブルに出遭う 解説編

前回の日記でふれたVisualStudio 2012 + XAudio2 + Windows 8 というコンボ発動で、アプリケーションを正常に起動出来ない!という罠にはまった内容を説明したいと思います。

実は、Windows 7で使用している(できる)最新のXAudio2は、 2.7 というバージョンのもので、これは DirectX SDK 2010 Juneに含まれています。またDirectXの再頒布ランタイムをインストールすることで導入できます。
一方、Windows 8で標準で使用するXAudio2は 2.8 というバージョンのものになります。これは VisualStudio 2012付属のWindows SDKを使用してアプリケーションを作成するとこちらを使うようになります。

標準状態の Windows 8 では、XAudio2は 2.8 のものだけが入っており、従来のDirectX SDKを使用していると 2.7のものを要求するために動作しません。
.Net framework をインストールした後で、DirectXのランタイムをインストールすると、Windows 8でも動作するようになりますが、これをアプリケーションを単に動かしたい人々がやるには手間もいいところです。
できるなら、そのままアプリケーションが動くのを目指したいところです。

これを表にするとこうなります。

DirectX SDKを使ってXAudio2 Windows 8ではそのまま動作しない
VS2012のWindowsSDKでXAudio2 Windows8では動作、Windows7では動かない

Windows7までの環境では対応したDirectX再頒布パッケージがあるのでそれをインストールすることができます。
ただそれらをインストールすること無しで XPから8まで、単一アプリケーションとしてサウンドを再生するには、実はDirectSoundを使用すると良さそうです(XPの標準状態でもDirectSoundは含まれていました)。

おそらくVista以降のDirectSoundはXAudio2より上位にレイヤーとしては位置付けられているようなので、
これを使うことでXAudio2に関係する依存関係を断ち切ってくれそうです。
ただし、DirectSoundは既にレガシーなAPIとなっているため、そのあたりが懸念事項でしょうか。
ただ互換性の点からOSから使用できない・削除されているわけではないため、XPから8まで一応使うことは出来るようです。

※ そのため単一アプリとして提供する際にはとても都合がよかったり。

DirectX9とXAudio2と。

D3DX関連のAPIもVS2012のWindows SDKに入っていないので、DirectX9+XAudio2という構成は VisualStudio 2012での開発にとってはなかなかの鬼門といえそうです。シェーダーのコンパイルはD3DXですし、XAudio2は今回のような問題があるし。

再頒布ランタイムをとりあえず強引にででもインストールさせるのであれば、DirectX SDK 2010 Juneを使って開発しておくでOKでしょう。
なるべくなら標準の状態で開発&配布したいと考えるなら、DirectX9やXAudio2を諦めて、OpenGLとDirectSoundを選択しておくと、余計なことを考えずともどこでも動く状態の物ができあがるように思います。

Windows Vista以降だけでよいというなら、WASAPI も選択肢に上がってくるかと思いますが、これは使うのが大変なので手軽にという点も考慮するなら、やはり情報も多いDirectSoundでお茶を濁しておくのが手っ取り早いでしょう。

参考元
XAudio2 Versions


VisualStudio 2012とDirectX SDK 再び

以前の日記にて、Visual Studio 2012 と DirectX SDK (2010June) を使って開発する際の手順を書きましたが、
どうやら最近ではマイクロソフトのほうに注意書きが用意されているようです。

そのページがこちら(http://msdn.microsoft.com/en-us/library/windows/desktop/ee663275(v=vs.85).aspx)です。

基本的には、DXSDK_DIRのインクルードとライブラリを標準のものより優先されるようにすること、という以前の日記情報と同じです。
ただ上記URLの中身ではそれよりももうちょっと踏み込んで、手順が書いてありました。

  • コンフリクトするので DXGIType.h をインクルードしているコードを修正する(インクルードしないように)。
  • テクスチャ関連は DirectXTex や DirectXTK といったものを利用するように検討すること
  • 算術に関しては D3DX から DirectXMath の実装へ切り替えを検討すること
  • XInput や XAudio2 を使う場合には要注意

気になった点をざっと列挙してみました。
XAudio2は厄介そうです。 使用するDLLがVS2012とDXSDKとで異なってしまうようで・・・。
どこでも動くように、というならば DXSDKのものをつかわないといけない、ということのようです。


D3DXでERROR_MOD_NOT_FOUND

ある環境でプログラムを動かそうとしたら、D3DXAssembleShaderFromFile 関数で ERROR_MOD_NOT_FOUND というエラーコードが返ってきた!
こんなエラーは初めてで、エラーメッセージのログも何もなくとても困った・・・。

よくよく調べてみるとこのエラーは、必要なモジュール(DLL)がロードできなくてエラーとなったことを意味しており、今回の件も、確かに強引にプログラムを動かそうとしていたことが原因となっているようでした。
DirectX の再頒布ランタイムをインストールすれば問題は解決になりそうです。

追記

さらなる調査の結果、どうやらシェーダーコンパイラである D3DCompiler_XX.dll が見つからなかったために起こった模様。
これが原因だとすると、D3DXAssembleShader系だけでなく、D3DXCompileShader系やD3DXEffect系もおそらく同じようなエラーになるだろうと推測します。


透明ウィンドウ(半透明ウィンドウ)の話 その3

透明なウィンドウということで、このシリーズも第3回。今回が最後となりそうです。
ようやく Windows7,Windows8両方ともで動かせるやり方が発見できました。
なお、Windows7のAeroGlassOFF状態でも動くので、注意して実装すればWindowsXPでもこの方法でいけるのではないかと思います。

その方法は、レイヤードウィンドウを使う方法です。
これを使っての半透明ウィンドウはWindows7,Windows8ともに正常に動作することが手元では確認できました。
ただし、レイヤードウィンドウの簡単なサンプルによくあるSetLayeredWindowAttributes関数を使ってしまうと、ウィンドウ全体での半透明設定や、カラーキーによる抜き色指定になってしまうため、背景とうまく溶け込ませた半透明の処理があまりうまく出来ないため、使用しないでおきます。

半透明もうまく処理するレイヤードウィンドウの作り方としては、DIBとUpdateLayeredWindowとを使って実現します。
DIBで半透明用のメモリ上のフレームバッファを用意して、その中にデータを書き込み、その結果をUpdateLayeredWindow関数で転送して、画面に表示します。この部分はGDIに関係する処理となります。
この手順の中で、「その中にデータを書き込み」の部分ですが、レイヤードウィンドウの各ピクセルの条件において、乗算済みアルファであることを要求されるので、その点に注意しながら実装を行います。

さて、ピクセル列にまでなったデータを表示する方法はこれでわかりました。あとはこれをどう用意するかですが、これにはDirectXであれOpenGLであれ、一度書いたデータをメインメモリ上に読み直す、取得し直すことが必要になってきます。いくつかの方法はあるでしょうが、環境に合わせてパフォーマンスと相談しながら実装を検討することになるかと思います。手頃で簡単なものは、DirectXであればバックバッファをロックできるようにフラグを立ててしまうか、OpenGLならglReadPixelsの関数で読み出してしまうとか。
ただ、ラスタライズした結果を読み戻す処理になるのでそれなりに負荷がかかるのは仕方のないことでしょう。
(ただ、今はPCI-Express接続になっているし、昔のAGP接続に比べて転送がネックになることが少なくなってきている、との話もあるので実際に計測してみないことには何とも。)

結果

手元で実装したものの結果を貼っておきます。まずはWindows7で動かした物です。
背景にコードが若干見えると思いますが、これはOpenGLで実装しているものです。

一方で、これをWindows8で実行したものです。こちらはスマホのカメラで撮ったのでちょっと画質がイマイチです。

でも、どちらの場合でも描画した結果をデスクトップ上に半透明も有効にして重ねて描画できていることが確認できるかとおもいます。

 

追記

この透明ウィンドウ関連の話をされている、こちらhttp://umezawa.dyndns.info/wordpress/?p=3455 のページでもレイヤードウィンドウを使ってWindows8で期待通りに動いてくれる、とあります。 Windows8ではやはりこの方法できまり、という感じですかね。


透明ウィンドウの話 その2

アプリで透明なウィンドウっていう部分は1つのウリになる部分で、やっぱりWindows 7(Vista)でしか動かないってのはやっぱまずいと思うんですよ、ということでもう少し調べて何か方法はないかと考えてみました。以下にその考えてみた話をメモっておこうと思います。

まず、DWM OFF状態でそもそも目的の動作が出来ない時点でまずいでしょう。Vista,7でBasicテーマであっても背景透過なアプリとして動くべき。この方法を確立しなくてはいけないのかな。

続いて、Windows8でも動作できること。
挙動から完全なるDWM OFFではなさそうなので、これも厄介そう。上記のベーシックモードでも動くような実装で、こちらの方法が動くようであれば問題は一気に解決する。

現在とりあえず実験中。

前者のWindows7,VistaでのDWM OFF時の状態でも動くようにという点で、いろいろと試してみたところ、LayeredWindowならば、実装の仕方によっては正常に動くようです!
変に実装すると全く描画されないようですが・・・・。(その境目を現在調査中)

これがもしそのままWindows8で動くとすれば、問題は解決になるのかなと思います。

DirectXであれ、OpenGLであれ、レンダリング済み画像をバックバッファのロックという方法で取得して、LayeredWindow用のHBITMAP内のビットイメージに再書き込みという方法でいけるのかなと考えてます。

ちなみに GDIサーフェースに直接描くって方法は、ちょっとできないでしょう。
というのもLayeredWindowで要求される仕様が事前乗算済みアルファの形式を求めてるようで。
この処理をどうしても最後に処理してあげないといけないため、描画して終了という形にはならないのかなと思います。

※ バックバッファのロックってパフォーマンスペナルティが大きいので、どこまで実用になるかは未検証です


透明ウィンドウとWindows8

ようやくWindows8が発売されていろいろと話題になっているようですが、Aeroがなくなってしまった点は個人的に残念に思います。また、このAeroがなくなったことで、透明なウィンドウの扱いがちょっと困ったことになっているように見受けられます。

参考: http://umezawa.dyndns.info/wordpress/?p=3335

Windows Vista/Windows7 では、DWMの機能をつかってうまく実現できていたようですが、これが半透明は無効状態になったことで出来なくなったのかなと思います。

具体的に出来なくなっているように見られたのが、DirectXやOpenGLを用いた結果をデスクトップ上に半透明を有効にした状態での合成という点です。単純にアルファ無しの不透明で、背景を抜くような方法についてはうまくいくようです。

今回DirectX用に使ったサンプルは DWMTestという下記のサイトで公開されていたものを利用させて頂きました。

参考: http://nyaruru.hatenablog.com/entry/20060628/p2

また、OpenGL用には自分で作ったプログラムです。うまく行かなくてちょっと試行錯誤していたので、こちらはWin7ではかろうじて動いているもののもしかしたらよくない作りをしているかもしれません。

これらのプログラムをWindows7で動かすとこのようになります。

どちらの場合もDirectX, OpenGLでのアルファ付き描画の結果を、透過なウィンドウに対してうまく動いているように見えています。

これらをAeroをOFFにして動かす(ベーシックやクラシックのテーマで動かす)と、以下のようになります。

透過して欲しいところが全く抜けていない状態となっています。

さて、これをWindows8で動かしてみて画面をキャプチャしてみます。

このキャプチャ結果を見ると一見うまく動いているようにみえますが、先ほどの結果と比較すると色がちょっとおかしいことに気付くと思います。DirectXのほうは概ね問題ないように見え、OpenGL側はちょっとアルファが効き過ぎている、そんな感じでしょうか。

しかし、キャプチャしたデータではなく実際に動かすと、これらの両方ともの透明部分が妙な動きをするのです!それゆえどちらも正常に動いているとは言いがたい状況です。この部分は参考(1)のサイトさんのほうに詳しくかかれています。

まとめ

どうも今までの作りでうまくいっていた半透明ウィンドウ(透過型のアプリ)はちょっと作りを考え直さないといけないのかもしれません。Vista, Windows7とAeroの流れはどうやらここで終わりのようです。半透明のウィンドウ枠は結構好きだったので残念です。

※ Windows8でもこれらDirectXやOpenGLを併用した半透明でもうまく合成できる方法をご存じの方は教えて頂けるとうれしいです。